知识图谱提供了一种强大的结构化信息的方式。它通过将数据表示为相互连接的元素来实现这一点:实体(如对象或概念)、它们的属性(描述性属性)以及它们之间的关系。这种基于图的方法允许对大量信息进行高效的存储、检索,甚至进行推理。
看一下下面的简单知识图谱。它展示了各种实体(如绘画及其创作者)及它们之间的关系,所有这些都围绕着希腊哲学家苏格拉底。
在 RAG(检索增强生成)模型的背景下,知识图谱尤其有用。这是因为这些模型可以快速遍历图,以找到生成响应所需的最相关信息。此外,通过利用图结构和各种实体之间的关系,RAG 模型可以执行复杂而微妙的推理任务,比如多跳问题回答或根据可用信息得出结论。
这有助于知识图谱为基础的 RAG 模型生成比基于向量数据库的 RAG 模型更有意义和连贯的响应。因为后者仅仅依赖于相似性搜索机制,这使得检索到的响应变得宽泛和通用。
为了创建一个知识图谱,必须以 Cypher 查询的形式输入数据。例如,对于上面显示的知识图谱,插入的 Cypher 查询如下所示:
// 使用单字符别名创建节点
CREATE (l:Library {name: "BEIC Digital Library"})
CREATE (d:Artist {name: "Jacques-Louis David"})
CREATE (r:Artist {name: "Raphael"})
CREATE (ds:Artwork {title: "The Death of Socrates"})
CREATE (sa:Artwork {title: "School of Athens"})
CREATE (s:Person {name: "Socrates"})
// 使用别名创建关系
CREATE (d)-[:CREATOR]->(ds)
CREATE (ds)-[:MAIN_SUBJECT]->(s)
CREATE (s)-[:PARTICIPANT]->(ds)
CREATE (r)-[:CREATOR]->(sa)
CREATE (sa)-[:DEPICTS]->(s)
CREATE (l)-[:DESCRIBED_BY_SOURCE]->(d)
CREATE (l)-[:DESCRIBED_BY_SOURCE]->(r)类似地,为了检索信息,您必须编写特定的 Cypher 查询。让我们制定一个我们可能想要使用知识图谱回答的问题:
问题: BEIC 数字图书馆中有哪些作品描绘了苏格拉底,以及创作这些作品的艺术家是谁?
以下 Cypher 查询检索描绘苏格拉底的作品的标题以及相应艺术家的名称:
// 查询描绘苏格拉底的作品及其创作者
MATCH (a:Artist)-[:CREATOR]->(art:Artwork)-[:DEPICTS|:MAIN_SUBJECT]->(p:Person {name: "Socrates"})
RETURN a.name AS 艺术家姓名, art.title AS 作品标题此查询使用 **MATCH** 语句查找模式,其中艺术家创作了作品,并且该作品描绘或以苏格拉底为主题。模式的 DEPICTS|:MAIN_SUBJECT 部分允许匹配 DEPICTS 或 MAIN_SUBJECT 类型的关系。 **RETURN** 语句指定我们希望在结果中返回艺术家的名称和作品的标题。
在 FalkorDB 浏览器中运行上述查询(稍后在博客中详细介绍),我们看到以下响应:
按照以下步骤构建知识图谱驱动的 RAG 流水线。
首先,识别并收集知识图谱的相关数据源。数据集可以是预定义的已经可用的知识图谱。在这种情况下,只需将其插入到图数据库中即可。或者,数据集可以是结构化(例如 csv)或非结构化(pdf、文本)集合的形式。在这种情况下,我们必须将数据转换为 Cypher 查询,然后将其插入到图数据库中。
在线上有许多工具可以将非结构化数据转换为知识图谱。一些流行的工具包括 LlamaIndex[1]、Diffbot[2] 和 Rebel[3]。
由于我们之前已经准备好了查询,我们将其插入到我们的知识图谱中。
您可以将查询拼接成一个 python 中的单个文本。
query = """CREATE (l
:Library {name: "BEIC Digital Library"})
CREATE (d:Artist {name: "Jacques-Louis David"})
CREATE (r:Artist {name: "Raphael"})
CREATE (ds:Artwork {title: "The Death of Socrates"})
CREATE (sa:Artwork {title: "School of Athens"})
CREATE (s:Person {name: "Socrates"})
CREATE (d)-[:CREATOR]->(ds)
CREATE (ds)-[:MAIN_SUBJECT]->(s)
CREATE (s)-[:PARTICIPANT]->(ds)
CREATE (r)-[:CREATOR]->(sa)
CREATE (sa)-[:DEPICTS]->(s)
CREATE (l)-[:DESCRIBED_BY_SOURCE]->(d)
CREATE (l)-[:DESCRIBED_BY_SOURCE]->(r)"""在您的 bash 终端中使用 docker 启动 FalkorDB 的实例。
docker run -p 6379:6379 -it --rm falkordb/falkordb:edge然后,我们将使用 Langchain[4] 创建一个 FalkorDBGraph 对象。在底层,它会自动连接到运行数据库的 6379 端口。然后,我们可以将查询插入到图中,从而创建知识库的实体。
from langchain_community.graphs import FalkorDBGraph
graph = FalkorDBGraph(database="socrates")
graph.query(query)
graph.refresh_schema()要在 FalkorDB 浏览器中可视化图形,您可以在终端中运行以下命令。
sudo docker run -p 3000:3000 -it falkordb/falkordb-browser:edge要获取整个图形,您可以在图形浏览器的终端中运行以下查询:
MATCH (n) OPTIONAL MATCH (n)-[r]->(m) RETURN n, r, m下一步是将图数据库连接到 LLM。LangChain 提供了简单直接的组件来完成这项工作。下面是一个示例代码,使用 Open AI LLM 和一个 FalkorDB QnA 链。您需要一个 Open AI API 密钥,您可以在这里[5]找到。
import os
os.environ["OPENAI_API_KEY"] = "your-api-key"
from langchain_openai import ChatOpenAI
from langchain.chains import FalkorDBQAChain
chain = FalkorDBQAChain.from_llm(ChatOpenAI(temperature=0), graph=graph, verbose=True)一旦查询传递给链,它就会在知识图谱中搜索相关上下文,然后使用它来创建简单自然语言的答案。
让我们问一个问题:
out1 = chain.run("图中有哪些绘画?")
print(out1)> 进入新的 FalkorDBQAChain 链...
生成的 Cypher:
MATCH (p:Artwork)
RETURN p.title
完整上下文:
[['The Death of Socrates'], ['School of Athens']]
> 完成链。
The Death of Socrates, School of Athensout1 = chain.run("画家是谁?")
print(out1)> 进入新的 FalkorDBQAChain 链...
生成的 Cypher:
MATCH (a:Artist)-[:CREATOR]->(art:Artwork)
RETURN DISTINCT a.name
完整上下文:
[['Jacques-Louis David'], ['Raphael']]
> 完成链。
Jacques-Louis David 和 Raphael 是画家。这就是构建知识图谱驱动的 LLM 的方法。
• Neo4j[6]
• JanusGraph[7]
• ArangoDB[8]
• Nebula-Graph[9]
• Cayley[10]
• FalkorDB[11]
在选择适合您的 RAG 应用的正确知识图谱时,有许多因素需要考虑。图数据库应该轻量级,并且具有较低的延迟以实现更高的性能。查询语言应该足够表达力,以支持复杂的图遍历以进行模式匹配。图形还应该理想地设计为具有较低的内存占用 - 这样它可以在长期内节省资源开销。
考虑到上述因素,我发现知识图谱 FalkorDB[12] 是构建 AI 应用的 轻量级和高性能图形框架。原因如下:
FalkorDB 被设计为提供对复杂图遍历的快速查询执行。它建立在其前身 RedisGraph 的基础上,利用了内存处理技术来加速查询执行。通过保持相关数据在内存中,可以减少与磁盘 I/O 操作相关的延迟。
FalkorDB 允许创建多个读取副本[13],从而将数据集和图形分布在各个服务器之间。用户可以创建与主数据库同步的数据库副本。这使我们可以将读取查询(在副本上运行)与写入查询(在主数据库上运行)分开。
这种方法优化了读写操作路由到适当副本的过程,确保操作的吞吐量高并且延迟低。
这允许将数据存储为高维嵌入,从而使用户可以使用相似性搜索找到实体 -
节点和边缘。这样,用户的响应可以扩展到包括语义上与输入查询相似的数据。
FalkorDB 提供了支持和文档,用于与 AI 框架(如 LangChain[14] 和 LLamaIndex[15])一起使用。通过连接到 LLM,这些集成为用户提供了一个全面的工具包,用于构建高级 AI 应用程序,如检索增强生成(RAG)流水线。
FalkorDB 和 Neo4j 都配备了图形浏览器,允许交互式查看和查询图形。您可以在这里[16]查看 FalkorDB 图形浏览器。用户可以通过单击节点和边缘、展开或折叠子图以及放大或缩小以聚焦特定感兴趣的区域来浏览图形。
FalkorDB 的内存处理技术和高效的内存利用有助于更快的查询执行和降低的延迟,相比于采用基于磁盘存储方法的图形。对各种 AI 框架的支持和文档增加了在构建 AI 应用程序时的稳健性。
这些功能使 FalkorDB 成为构建可扩展且高性能的 RAG 应用程序的有力选择。这种基于知识图谱的 RAG 模型有望通过生成更准确、信息量更丰富和更连贯的响应来彻底改变自然语言处理领域。
[1] LlamaIndex: https://docs.llamaindex.ai/en/latest/examples/index_structs/knowledge_graph/KnowledgeGraphDemo.html[2] Diffbot: https://www.diffbot.com/[3] Rebel: https://huggingface.co/Babelscape/rebel-large[4] Langchain: https://python.langchain.com/docs/use_cases/graph/integrations/graph_falkordb_qa[5] 这里: https://platform.openai.com/api-keys[6] Neo4j: https://neo4j.com/[7] JanusGraph: https://janusgraph.org/[8] ArangoDB: https://arangodb.com/[9] Nebula-Graph: https://www.nebula-graph.io/[10] Cayley: https://cayley.io/[11] FalkorDB: https://www.falkordb.com/[12] FalkorDB: https://www.falkordb.com/[13] 多个读取副本: https://www.falkordb.com/scale-out/[14] LangChain: https://python.langchain.com/docs/use_cases/graph/integrations/graph_falkordb_qa[15] LLamaIndex: https://docs.llamaindex.ai/en/stable/examples/index_structs/knowledge_graph/FalkorDBGraphDemo/[16] 这里: https://github.com/FalkorDB/falkordb-browser