什么是知识图谱,如何在 RAG 中使用?
知识图谱提供了一种强大的信息结构方式。知识图谱将数据表示为相互关联的元素:实体(如对象或概念)、实体属性(描述性属性)以及实体之间的关系。这种基于图的方法可以高效地存储、检索甚至推理海量信息。
请看下面一个简单的知识图谱。它显示了以希腊哲学家苏格拉底为中心的各种实体(如绘画及其创作者)及其关系。
在 RAG(检索-增强生成)模型中,知识图谱尤其有用。这是因为这些模型可以快速遍历图,找到生成响应所需的最相关信息。此外,通过利用图结构和各种实体之间的关系,RAG 模型可以执行复杂而细致的推理任务,例如多跳问题解答或根据可用信息得出结论。
与基于矢量数据库的 RAG 相比,这有助于基于知识图谱的 RAG 生成更有意义、更连贯的响应。这是因为后者只依赖于相似性搜索机制,这就使得检索到的回答变得宽泛和通用。
知识图谱中的密码查询
为了创建知识图谱,我们必须以cypher查询的形式输入数据。例如,对于上图所示的知识图谱,用于插入的cypher查询如下所示:
// Create nodes with single-character aliases
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 relationships using the aliases
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 查询将检索描绘苏格拉底的艺术作品的标题以及相关艺术家的姓名:
// Query to find artworks depicting Socrates and their creators
MATCH (a:Artist)-[:CREATOR]->(art:Artwork)-[:DEPICTS|:MAIN_SUBJECT]->(p:Person {name: "Socrates"})
RETURN a.name AS ArtistName, art.title AS ArtworkTitle
该查询使用 `MATCH`语句查找模式,其中一位艺术家创作了一件艺术品,而该艺术品描绘了苏格拉底或以苏格拉底为主要对象。模式的 `DEPICTS|:MAIN_SUBJECT` 部分允许匹配 `DEPICTS` 或 `MAIN_SUBJECT` 类型的关系。RETURN "语句指定我们要在结果中返回艺术家的姓名和艺术品的标题。
在 FalkorDB 浏览器中运行上述查询,我们会看到以下响应:
构建知识图谱 RAG 的步骤
请按照以下步骤构建知识图谱驱动的 RAG 管道。
首先确定并收集知识图谱的相关数据源。数据集可以是已经存在的预定义知识图谱。在这种情况下,只需将其插入图数据库即可。或者,数据集可以是结构化(例如 csv)或非结构化(pdf、文本)的集合。在这种情况下,我们必须将数据转换为加密查询,然后将其插入图数据库。
既然我们已经有了前面的查询,那么我们就把它插入到知识图谱中。
你可以用 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 创建一个 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 密钥,可以在这里找到。
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("Which paintings are there in the graph?")
print(out1)
> Entering new FalkorDBQAChain chain...
Generated Cypher:
MATCH (p:Artwork)
RETURN p.title
Full Context:
[['The Death of Socrates'], ['School of Athens']]
> Finished chain.
The Death of Socrates, School of Athens
out1 = chain.run("Who are the painters?")
print(out1)
> Entering new FalkorDBQAChain chain...
Generated Cypher:
MATCH (a:Artist)-[:CREATOR]->(art:Artwork)
RETURN DISTINCT a.name
Full Context:
[['Jacques-Louis David'], ['Raphael']]
> Finished chain.
Jacques-Louis David and Raphael are the painters.
这就是构建知识图谱驱动的 LLM 的方法。
我为什么选择 FalkorDB 来构建我的 RAG 应用程序
在为你的 RAG 应用程序选择合适的知识图谱时,需要考虑很多因素。知识图谱数据库应轻量级、低延迟,以提高性能。查询语言应具有足够的表现力,以便支持复杂的图遍历模式匹配。图形的设计最好还能减少内存占用--这样才能长期节省资源开销。
考虑到上述因素,我发现知识图谱 FalkorDB 是一个轻量级、高性能的图框架,适用于构建人工智能应用程序。原因如下:
低延迟
FalkorDB旨在为复杂的图遍历提供快速的查询执行。它建立在其前身 RedisGraph 的基础之上,利用内存处理技术加快查询执行速度。通过将相关数据保存在内存中,它可以减少与磁盘 I/O 操作相关的延迟。
高效利用内存的分布式架构
FalkorDB 允许创建多个读取副本,以便在不同的服务器之间分发数据集和图。用户可以创建一个与主数据库同步的数据库副本。这样,我们就可以将读取查询(在副本上运行)与写入查询(在主数据库上运行)分开。
这种方法优化了将读写操作路由到相应副本的过程,确保了高吞吐量和低延迟。
增强检索的矢量索引支持
这种方法允许将数据存储为高维嵌入,从而使用户能够使用相似性搜索来查找实体--节点和边。这样,用户的响应范围就可以扩大,包括与输入查询语义相似的数据。
支持人工智能框架
FalkorDB 为使用 LangChain 和 LLamaIndex 等人工智能框架提供支持和文档。通过将其与 LLM 相连接,有直接且易于使用的模块用于创建图索引和查询引擎对象。这些集成为用户构建检索增强生成(RAG)管道等高级人工智能应用提供了全面的工具包。
交互性图形浏览器
FalkorDB和Neo4j都配备了图形浏览器,允许交互式查看和查询图形。你可以点击此处查看 FalkorDB 图表浏览器。用户可以通过点击节点和边浏览图,展开或折叠子图,放大或缩小以关注特定感兴趣的区域。
结论
与基于磁盘存储的图相比,FalkorDB 的内存处理技术和高效的内存利用率有助于加快查询执行速度并减少延迟。在构建人工智能应用程序时,各种人工智能框架的支持和文档使其更加强大。