Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >利用知识图谱提高 RAG 应用的准确性

利用知识图谱提高 RAG 应用的准确性

作者头像
大数据杂货铺
发布于 2024-04-02 08:04:23
发布于 2024-04-02 08:04:23
8450
举报
文章被收录于专栏:大数据杂货铺大数据杂货铺

在 RAG 应用中使用 Neo4j 和 LangChain 构建和检索知识图谱信息的实用指南

图片由DALL-E创作

图表搜索增强生成(GraphRAG)正在蓬勃发展,并成为传统向量搜索搜索方法的有力补充。这种方法利用图数据库的形态将数据组织为节点和关系,以增强搜索信息的深度和上下文。

知识图谱示例

图表非常擅长通过结构化的方式表示和存储互连的信息,轻松获取不同数据类型之间的复杂关系和属性。相比之下,向量数据库通常难以处理这些结构化信息,因为它们的优势在于通过高维处理非格式化数据。在 RAG 应用程序中,您可以将结构化的图形数据与通过非结构化的文本进行向量搜索相结合,以实现两全其美。这就是我们将在这篇博文中演示的内容。

知识图谱很棒,但如何创造一个呢?

构建知识图谱通常是最棘手的步骤。它涉及收集和构建数据,这需要对领域和图形建模有深入的了解。

为了简化这个过程,我们一直在尝试大语言模型。借助对语言和上下文的深刻理解,大语言模型可以自动化知识图谱创建过程的重要部分。通过分析文本数据,这些模型可以识别实体、理解它们的关系,并建议如何在图形结构中最好地表示它们。

作为这些实验的结果,我们在 LangChain 中添加了第一个版本的图构建模块,我们将在这篇博文中进行演示。

该代码可在GitHub上获取。

Neo4j环境设置

您需要设置一个 Neo4j 实例。请按照本文中的示例进行操作。最简单的方法是在 Neo4j Aura上启动一个免费实例,它提供 Neo4j 数据库的云实例。或者,您还可以通过下载Neo4j 桌面应用程序并创建本地数据库实例来设置 Neo4j 数据库的本地实例。

Shell os.environ["OPENAI_API_KEY"] = "sk-" os.environ["NEO4J_URI"] = "bolt://localhost:7687" os.environ["NEO4J_USERNAME"] = "neo4j" os.environ["NEO4J_PASSWORD"] = "password" graph = Neo4jGraph()

另外,您必须提供OpenAI Key,因为我们将在本博文中使用他们的模型。

数据摄取

在本示例中,我们将使用Elizabeth I’s 维基百科页面。我们可以使用LangChain loaders从维基百科获取和分割文档。

Shell # Read the wikipedia article raw_documents = WikipediaLoader(query="Elizabeth I").load() # Define chunking strategy text_splitter = TokenTextSplitter(chunk_size=512, chunk_overlap=24) documents = text_splitter.split_documents(raw_documents[:3])

是时候根据搜索到的文档构建图了。因此,我们实现了一个LLMGraphTransformer模块,可以显着简化在图数据库中构建和存储知识图。

Shell llm=ChatOpenAI(temperature=0, model_name="gpt-4-0125-preview") llm_transformer = LLMGraphTransformer(llm=llm) # Extract graph data graph_documents = llm_transformer.convert_to_graph_documents(documents) # Store to neo4j graph.add_graph_documents( graph_documents, baseEntityLabel=True, include_source=True )

您可以定义使用哪个LLM知识图谱生成链。目前,我们仅支持 OpenAI 和 Mistral 的函数调用模型。但是,我们计划在未来扩展LLM的选择范围。在此示例中,我们使用最新的 GPT-4。请注意,生成的图的质量取决于您使用的模型。从理论上讲,您总是想使用最有能力的人。LLM图转换器返回图形文档,可以通过该方法将其add_graph_documents导入Neo4j。该baseEntityLabel参数为每个分配节点一个附加__Entity__标签,从而增强索引和查询性能。该include_source参数将节点链接到其原始文档,从而促进数据的可追溯性和上下文理解。

您可以在 Neo4j 浏览器中检查生成的图形。

生成的部分图

请注意,该图仅代表生成图的一部分。

RAG 混合检索

图生成后,我们将使用混合搜索方法,将索引和关键字与 RAG 应用程序的图搜索相结合。

结合(提供+关键字)和图混合搜索方法。图片由作者提供

该图说明了搜索过程,从用户提出问题开始,然后将问题定向到 RAG 搜索器。该搜索器采用关键字和向量搜索来搜索非结构化文本数据,并将其与从知识图谱中收集的信息Neo4j 同时具有关键字索引和向量索引,因此您可以使用单个数据库系统实现所有三个搜索选项。从这些来源收集的数据将输入大语言模型以生成并提供最终答案。

结构化数据检索器

您可以使用该Neo4jVector.from_existing_graph方法将关键字和支持搜索添加到文档中。此方法为混合搜索方法配置和支持搜索索引,以标记为的节点为目标Document。另外,如果文本嵌入值删除,它还会计算他们。

Shell vector_index = Neo4jVector.from_existing_graph( OpenAIEmbeddings(), search_type="hybrid", node_label="Document", text_node_properties=["text"], embedding_node_property="embedding" )

然后可以使用该similarity_search方法调用向量索引。

图检索器

另一方面,配置图检索更加复杂,但提供了更多自由。此示例将使用全文索引来识别相关节点并返回它们的直接邻居。

图检索器。图片由作者提供

图检索器首先识别输入中的相关实体。为简单起见,我们指示大语言模型来识别人员、组织和地点。为了实现这一点,我们将使用LCEL和新添加的with_structured_output方法来实现这一点。

Shell # Extract entities from text class Entities(BaseModel): """Identifying information about entities.""" names: List[str] = Field( ..., description="All the person, organization, or business entities that " "appear in the text", ) prompt = ChatPromptTemplate.from_messages( [ ( "system", "You are extracting organization and person entities from the text.", ), ( "human", "Use the given format to extract information from the following " "input: {question}", ), ] ) entity_chain = prompt | llm.with_structured_output(Entities)

让我们测试一下:

Shell entity_chain.invoke({"question": "Where was Amelia Earhart born?"}).names # ['Amelia Earhart']

太好了,现在我们可以检测问题中的实体,让我们使用全文索引将它们映射到知识图谱。首先,我们需要定义一个全文索引和一个函数,该函数将生成允许一些拼写错误的全文查询,这里我们不会详细介绍。

Shell graph.query( "CREATE FULLTEXT INDEX entity IF NOT EXISTS FOR (e:__Entity__) ON EACH [e.id]") def generate_full_text_query(input: str) -> str: """ Generate a full-text search query for a given input string. This function constructs a query string suitable for a full-text search. It processes the input string by splitting it into words and appending a similarity threshold (~2 changed characters) to each word, then combines them using the AND operator. Useful for mapping entities from user questions to database values, and allows for some misspelings. """ full_text_query = "" words = [el for el in remove_lucene_chars(input).split() if el] for word in words[:-1]: full_text_query += f" {word}~2 AND" full_text_query += f" {words[-1]}~2" return full_text_query.strip()

现在让我们把它们放在一起。

Shell # Fulltext index query def structured_retriever(question: str) -> str: """ Collects the neighborhood of entities mentioned in the question """ result = "" entities = entity_chain.invoke({"question": question}) for entity in entities.names: response = graph.query( """CALL db.index.fulltext.queryNodes('entity', $query, {limit:2}) YIELD node,score CALL { MATCH (node)-[r:!MENTIONS]->(neighbor) RETURN node.id + ' - ' + type(r) + ' -> ' + neighbor.id AS output UNION MATCH (node)<-[r:!MENTIONS]-(neighbor) RETURN neighbor.id + ' - ' + type(r) + ' -> ' + node.id AS output } RETURN output LIMIT 50 """, {"query": generate_full_text_query(entity)}, ) result += "\n".join([el['output'] for el in response]) return result

该structured_retriever函数首先检测用户问题中的实体。接下来,它迭代检测到的实体并使用 Cypher 模板来检索相关节点的邻域。我们来测试一下吧!

Shell print(structured_retriever("Who is Elizabeth I?")) # Elizabeth I - BORN_ON -> 7 September 1533 # Elizabeth I - DIED_ON -> 24 March 1603 # Elizabeth I - TITLE_HELD_FROM -> Queen Of England And Ireland # Elizabeth I - TITLE_HELD_UNTIL -> 17 November 1558 # Elizabeth I - MEMBER_OF -> House Of Tudor # Elizabeth I - CHILD_OF -> Henry Viii # and more...

最终检索

正如一开始提到的,我们将结合非结构化和图形检索器来创建传递给 LLM 的最终上下文。

Shell def retriever(question: str): print(f"Search query: {question}") structured_data = structured_retriever(question) unstructured_data = [el.page_content for el in vector_index.similarity_search(question)] final_data = f"""Structured data: {structured_data} Unstructured data: {"#Document ". join(unstructured_data)} """ return final_data

当我们处理 Python 时,我们可以使用 f 字符串简单地连接输出。

定义 RAG 链

我们已经成功实现了 RAG 的检索组件。接下来,我们引入一个提示,利用集成混合检索器提供的上下文来生成响应,从而完成 RAG 链的实现。

Shell template = """Answer the question based only on the following context: {context} Question: {question} """ prompt = ChatPromptTemplate.from_template(template) chain = ( RunnableParallel( { "context": _search_query | retriever, "question": RunnablePassthrough(), } ) | prompt | llm | StrOutputParser() )

最后,我们可以继续测试我们的混合 RAG 实现。

Shell chain.invoke({"question": "Which house did Elizabeth I belong to?"}) # Search query: Which house did Elizabeth I belong to? # 'Elizabeth I belonged to the House of Tudor.'

我还集成了查询重写功能,使 RAG 链能够适应允许后续问题的对话设置。鉴于我们使用向量和关键字搜索方法,我们必须重写后续问题以优化我们的搜索过程。

Shell chain.invoke( { "question": "When was she born?", "chat_history": [("Which house did Elizabeth I belong to?", "House Of Tudor")], } ) # Search query: When was Elizabeth I born? # 'Elizabeth I was born on 7 September 1533.'

您可以观察到它When was she born?首先被重写为When was Elizabeth I born?.然后使用重写的查询来检索相关上下文并回答问题。

轻松增强 RAG 应用程序

随着 引入LLMGraphTransformer,生成知识图谱的过程现在应该更加流畅且更容易访问,让任何希望利用知识图提供的深度和上下文来增强 RAG 应用程序的人变得更加容易。这只是一个开始,我们计划了很多改进。

该代码可在GitHub上获取。

原文链接:https://medium.com/neo4j/enhancing-the-accuracy-of-rag-applications-with-knowledge-graphs-ad5e2ffab663

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据杂货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Git入门学习到进阶1
描述:Git是目前世界上最先进的分布式版本控制系统(没有之一),如下面的Git生态化流程;
全栈工程师修炼指南
2022/09/28
5980
Git入门学习到进阶1
如何优雅的玩转 Git
Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方式。 从概念上来说,其它大部分系统以文件变更列表的方式存储信息,而 Git 是把数据看作是对小型文件系统的一系列快照。
硬件开源小站
2023/04/07
1.6K0
如何优雅的玩转 Git
GIT命令操作全攻略,请收下我的膝盖!
很多人都知道,Linus 在1991年 创建了开源的Linux操作系统,此后的三十多年里,Linux 系统不断发展,已然成为全世界最大的服务器系统软件了。
Java极客技术
2022/12/04
6850
GIT命令操作全攻略,请收下我的膝盖!
瑞吉外卖Day7 Git使用的入门到精通
实际上,代码开发中也需要这样的软件来管理我们的代码. 例如我们经常会碰到如下的现象:
小小程序员
2023/04/02
2.3K0
瑞吉外卖Day7 Git使用的入门到精通
Git 操作指南
**版本控制(Revision control)**是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。
星姮十织
2021/12/25
7380
Git的使用
1.代码可能被别人或自己不小心覆盖或遗失、也不知道是谁因为什么原因改了这段代码、也没办法可以复原回前几天的修改 2.团队间的协同作业,代码如何同步?
愷龍
2022/09/30
4220
Git的使用
Git必知必会
Git是一个分布式的版本控制软件,最初是由Linus Torvalds发起的开源项目。没错,就是那个写了Linux内核源码并发起开源项目的男人。2005年,为了管理Linux内核的源代码,开发并开源了git。
Coderoger
2021/10/20
6720
Git版本控制器使用总结性梳理
Git为何物? Git 是什么?大家肯定会说不就是版本控制器嘛,是的Git是目前世界上最先进的分布式版本控制系统(没有之一)。 1)那什么是版本控制器? 举个简单的例子,比如我们用Word写文章,那你一定有这样的经历:比如增加一个段落你得复制一份,你删除一个段落你又得复制一份,防止下次又要修改保留上次你要删除的段落。最后一个接一个的版本,你复制了很多版本,最后可能你自己都不知道修改了哪些?嘿嘿,然后你只能一个一个的找,太麻烦了,若是有东西帮你管理那应该多好。 2)分布式管理 你写的文章或书,你肯定会给你朋友
洗尽了浮华
2018/01/22
7600
Git版本控制器使用总结性梳理
Git的使用教程
1.代码可能被别人或自己不小心覆盖或遗失、也不知道是谁因为什么原因改了这段代码、也没办法可以复原回前几天的修改
愷龍
2022/09/13
8590
Git的使用教程
30分钟看懂Git和GitHub常用操作
GitHub是一个非常流行的全球代码托管平台,基于Git版本控制技术实现,同时GitHub也是一个活跃的开发者交流社区。许多的开源项目都在GitHub上发布。例如著名的Linux操作系统内核的源代码。
AI算法与图像处理
2020/11/06
1K0
30分钟看懂Git和GitHub常用操作
.NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练
上篇文章我带着大家通过分析了一遍ASP.NET Core的源码了解了它的启动过程,然后又带着大家熟悉了一遍配置文件的加载方式,最后引出了依赖注入以及控制反转的概念!如果大家把前面几张都理解了,那么你也就入了ASP.NET Core的大门了。但是我们还需要一个版本控制工具来提高我们的编码效率。因此这篇文章我将带着大家了解下Git这个版本控制工具以及为什么选择它。
依乐祝
2018/11/28
4040
.NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练
专栏:001: git 简易教程12:概念介绍篇3 代码示例篇3:附属篇4:参考
1、git教程框架 序号 板块 01 概念介绍篇 02 代码示例篇 03 附属篇 2:概念介绍篇 什么是git? git是一个分布式版本控制软件,由Linus Torvalds创作,最初的目的是为
谢伟
2018/06/06
6540
目前最流行的版本控制软件:Git的基本使用
版本控制(Version control)是维护项目的标准作法,能追踪项目从诞生一直到定案的过程。此外,版本控制也是一种软件工程技巧,借此能在软件开发的过程中,确保由不同人所编辑的同一程序文件都得到同步,记录项目内各个模块的改动历程,并为每次改动都编上序号。
知识分子没文化
2023/07/01
6090
目前最流行的版本控制软件:Git的基本使用
Git 30分钟简明教程
1991年,Linus创建了开源的Linux,世界各地的志愿者为Linux编写代码,但是绝大多数的内核维护工作,都花费在提交补丁和保存档案的繁琐事务上。这期间所有的源代码,都由Linus手工合并。Linus坚定反对CVS和SVN,因为这些集中式的版本控制系统,不仅速度慢,而且必须联网才能使用。
Yano_nankai
2018/10/08
5450
Git 30分钟简明教程
.NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练
上篇文章我带着大家通过分析了一遍ASP.NET Core的源码了解了它的启动过程,然后又带着大家熟悉了一遍配置文件的加载方式,最后引出了依赖注入以及控制反转的概念!如果大家把前面几张都理解了,那么你也就入了ASP.NET Core的大门了。但是我们还需要一个版本控制工具来提高我们的编码效率。因此这篇文章我将带着大家了解下Git这个版本控制工具以及为什么选择它。 下面我们将通过故事的形式从Git的历史谈起,并讲述Git的强大之处。然后通过实战演练教你如何在Github以及码云上托管我们的代码并进行代码的版本控制。 这里还想说一句,这篇文章本来昨天就能发出来的,奈何出现了一点状况,所以今天才来写,为了不浪费大家的时间我会在文章的最后再来讲述原因,这里给大家说声抱歉了。 本篇文章已经收入.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划 有兴趣的朋友可以加入.NET Core项目实战交流群637326624 进行交流。
依乐祝
2018/11/28
3200
.NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练
git使用教程之创建本地库并关联远程库(笔记整理篇一)
笔者个人博客: https://qiucode.cn/blog 微信小程序 [秋码淘好货]
游离于山间之上的Java爱好者
2022/09/21
4490
git使用教程之创建本地库并关联远程库(笔记整理篇一)
看完此文你不会Git,请来找我!
 数据是短暂的,且容易丢失。特别是作为开发人员的我们,需要频繁的对项目代码进行更新,容易产生错误的变更或者是项目文件的丢失。因此,我们需要在整个工作的过程中不断的备份和存档我们的项目文件。  在当下的项目开发环境下,一个项目往往是有多个开发者共同开发维护的,那么意味着他们需要操作同一项目文件,我们需要对文本和项目代码的变更进行记录管理,这些变更就构成了一个版本库,对版本库的管理就是版本控制。  一个可以管理或追踪软件代码的工具通常称为版本控制系统(VCS)。现在流行的版本控制工具很多,当然,我们接下来要说的就是称的上VCS界一哥的Git,它是一款功能强大、灵活且低开销的VCS,它可以让协同开发成为一种乐趣。
我就是马云飞
2019/03/08
9240
看完此文你不会Git,请来找我!
分布式版本控制-Git(一)
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
奋飛
2019/08/15
4370
GIT 之概述与架构
GIT是如今最流行的版本控制系统。曾经系统总结过一次关于GIT的使用,抽时间整理成文。
波罗学
2019/07/31
1.5K0
【干货】Git入门
想删除一个段落,又怕将来想恢复找不回来怎么办?有办法,先把当前文件“另存为……”一个新的Word文件,再接着改,改到一定程度,再“另存为……”一个新文件,这样一直改下去,最后Word文档变成了这样。
腾讯工蜂
2018/09/27
8380
相关推荐
Git入门学习到进阶1
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档