
基于知识图谱的LangChain应用实战
图检索增强生成(Graph RAG)正逐渐流行起来,成为传统向量搜索方法的有力补充。这种方法利用图数据库的结构化特性,将数据以节点和关系的形式组织起来,从而增强检索信息的深度和上下文关联性。
示例知识图谱
图在表示和存储多样化且相互关联的信息方面具有天然优势,能够轻松捕捉不同数据类型间的复杂关系和属性。而向量数据库在处理这类结构化信息时则显得力不从心,它们更擅长通过高维向量处理非结构化数据。在 RAG 应用中,结合结构化的图数据和非结构化的文本向量搜索,可以让我们同时享受两者的优势,这也是本文将要探讨的内容。
知识图谱的确很有用,但如何构建一个呢? 构建知识图谱通常是利用图数据表示的强大功能中最困难的一步。它需要收集和整理数据,这需要对领域知识和图建模有深刻的理解。为了简化这一过程,我们开始尝试使用大型语言模型(LLM)。LLM 凭借其对语言和上下文的深刻理解,可以自动化知识图谱创建过程中的大部分工作。通过分析文本数据,这些模型能够识别实体,理解它们之间的关系,并提出如何在图结构中最佳表示这些实体。基于这些实验,我们已经将图构建模块的首个版本集成到了 LangChain 中,本文将展示其应用。
相关代码已在 GitHub 上发布。
Neo4j 环境搭建
为了跟随本文的示例,您需要搭建一个 Neo4j 实例。最简单的方法是在 Neo4j Aura 上启动一个免费实例,它提供了 Neo4j 数据库的云版本。当然,您也可以通过下载 Neo4j Desktop 应用程序来创建一个本地数据库实例。
此外,您还需要一个 OpenAI 密钥,因为我们将在本文中使用他们的模型。
数据导入
在本次演示中,我们将使用伊丽莎白一世的维基百科页面。我们可以利用 LangChain 加载器 轻松地从维基百科获取并分割文档。
现在是时候根据获取的文档来构建图谱了。为此,我们开发了一个 LLMGraphTransformer 模块,它极大地简化了在图数据库中构建和存储知识图谱的过程。
您可以指定知识图谱生成链使用哪种 LLM。目前,我们只支持 OpenAI 和 Mistral 的函数调用模型。不过,我们计划未来会扩展 LLM 的选择范围。在这个例子中,我们使用的是最新的 GPT-4。需要注意的是,生成的图谱质量很大程度上取决于您使用的模型。理论上,您应该选择能力最强的模型。LLM 图转换器返回的图文档可以通过 add_graph_documents 方法导入到 Neo4j。baseEntityLabel 参数为每个节点添加了一个额外的 __Entity__ 标签,以增强索引和查询性能。include_source 参数则将节点与其原始文档关联起来,便于数据追溯和理解上下文。
您可以在 Neo4j 浏览器中查看生成的图谱。
结合混合(向量 + 关键字)和图检索方法。
请注意,这张图片仅为了清晰展示,只展示了生成图谱的一部分。
RAG 的混合检索
在图谱生成之后,我们将采用一种混合检索方法,结合向量和关键字索引以及图检索技术,用于 RAG 应用。
结合混合(向量 + 关键字)和图检索方法。
上图展示了一个检索过程,从用户提出问题开始,然后由 RAG 检索器处理。这个检索器结合了关键字和向量搜索来筛选非结构化文本数据,并将其与从知识图谱中提取的信息结合起来。由于 Neo4j 同时支持关键字和向量索引,您可以使用单一数据库系统实现所有三种检索方式。这些来源的数据将被送入 LLM,以生成并提供最终答案。
非结构化数据检索器
您可以使用 Neo4jVector.from_existing_graph 方法为文档添加关键字和向量检索功能。该方法为混合搜索方法配置了关键字和向量搜索索引,目标是标记为 Document 的节点。如果缺少文本嵌入值,它还会自动计算。
然后,您可以使用 similarity_search 方法来调用向量索引。
图检索器
另一方面,配置图检索器虽然更为复杂,但提供了更大的灵活性。在这个例子中,我们将使用全文索引来识别相关节点,然后返回它们的直接邻域。
图检索器示意图
图检索器首先识别输入中的相关实体。为了简化,我们指导 LLM 识别人物、组织和地点。为了实现这一点,我们将使用 LCEL 配合新加入的 with_structured_output 方法。
让我们来实际测试一下:
很好,现在我们能够在问题中识别出实体,接下来我们将使用全文索引将这些实体映射到知识图谱中。首先,我们需要定义一个全文索引,并创建一个函数来生成全文查询,这个查询允许一定程度的拼写错误,这里我们不详细展开。
现在,让我们整合所有步骤。
structured_retriever 函数首先识别用户问题中的实体,然后遍历这些实体,使用 Cypher 模板检索相关节点的邻域信息。让我们来实际测试一下!
最终检索器
正如我们一开始提到的,我们将结合非结构化和图检索器来创建最终的上下文,这将传递给 LLM。
由于我们使用的是 Python,我们可以使用 f-string 轻松地将输出合并。
定义 RAG 链
我们已经成功实现了 RAG 的检索组件。接下来,我们将引入一个提示,它利用混合检索器提供的上下文来生成响应,从而完成 RAG 链的实现。
最后,我们可以测试我们的混合 RAG 实现。
我还加入了一个查询重写特性,使得 RAG 链能够适应允许后续问题的对话环境。鉴于我们使用了向量和关键字搜索方法,我们需要重写后续问题以优化搜索过程。
您可以看到,'她何时出生?' 首先被重写为 '伊丽莎白一世何时出生?'。然后使用重写后的查询来检索相关上下文并回答问题。
总结
随着 LLMGraphTransformer 的引入,生成知识图谱的过程现在应该更加顺畅和易于访问,这使得任何想要通过知识图谱提供的深度和上下文来增强其基于 RAG 的应用的人更容易上手。这只是一个开始,因为我们计划进行更多的改进。
本文转载自 AI小智,作者: AI小智
