[今日Arxiv] GraphRAG, 微软,使用LLM自动化构建图谱并检索生成

最近一篇图谱文章很火,翻来看看分享出来。

来自 1微软研究院2微软战略使命和技术部3微软首席技术官办公室 的文章。

文章标题:

From Local To Global: A Graph Rag Approach To Query-Focused Summarization

URL:https://arxiv.org/abs/2311.01011

注:翻译可能存在误差,详细内容建议查看原始文章。

摘要

使用检索增强生成 (RAG) 从外部知识源检索相关信息使大型语言模型 (LLM) 能够回答来自私有和/或之前未见过的文档集合的问题。然而,对于针对整个文本语料库的全局问题,如“数据集中的主要主题是什么?”RAG 却失败了,因为这本质上是一个查询聚焦摘要 (QFS) 任务,而不是一个明确的检索任务。与此同时,先前的 QFS 方法无法扩展到典型 RAG 系统索引的文本数量。为了结合这些对比方法的优点,作者提出了一种图 RAG 方法,用于在私有文本语料库上进行基于问题的回答,该方法可随着用户问题的一般性和待索引源文本的数量而扩展。作者的方法使用 LLM 分两个阶段构建基于图的文本索引:首先从源文档中推导出实体知识图谱,然后为所有紧密相关实体组预生成社区摘要。给定一个问题,每个社区摘要用于生成部分回答,然后将所有部分回答再次汇总为最终的回答提供给用户。对于在大约 100 万令牌范围内的数据集上的一类全局意义解析问题,作者证明了 Graph RAG 在生成答案的全面性和多样性方面相对于简单的 RAG 基线有了实质性改进。

开源、基于 Python 的图 RAG 局部和全局方法实现即将在 https://aka.ms/graphrag 发布。https://aka.ms/graphrag 也将提供开放源代码及 Python 实现版本。

1 引言

在各个领域的人类努力都依赖于作者阅读和分析大量文献的能力,常常得出超越原文本所述内容的结论。随着大型语言模型(LLMs)的出现,作者已经见证了尝试在诸如科学发现(微软,2023年)和情报分析(Ranade 和 Joshi,2023年)等复杂领域自动化类似人类的理解过程,“理解”在这里被定义为

图片

图 1:使用基于LLM的图形索引(由源文档文本生成)的RAG管道。这个索引覆盖了节点(例如,实体)、边(例如,关系)和协变量(例如,主张),它们已被检测、提取,并通过针对数据集领域定制的LLM提示进行了总结。

社区检测(例如,Leiden算法,Traag等人,2019年)用于将图形索引划分为元素组(节点、边、协变量),LLM可以在构建索引和查询时并行地对这些元素进行总结。对于给定查询的“全局答案”是通过最后一轮针对查询的总结生成的,这次总结涵盖所有报告与该查询相关性的社区摘要。

然而,要在整个文献库中支持人类引导的理解过程,需要一种方式让人既能应用又能精炼他们对数据的思维模型(Klein 等人,2006b), 通过提出具有全局性质的问题来实现

检索增强型生成 (RAG,Lewis 等人,2020 的工作) 是回答整个数据集上用户问题的一种公认方法,但它针对的是答案在文本区域中的局部位置的情况,这些文本的检索为生成任务提供了充分的基础。

相比之下,一个更为合适的问题框架是查询聚焦摘要(QFS,Dang,2006),特别是在查询聚焦抽象性摘要的情况下,它生成自然语言摘要而不仅仅是拼接摘录(Baumel 等人,2018;Laskar 等人,2020;Yao 等人,2017)。然而近年来,在抽象性和提取性、通用性与查询聚焦,以及单文档和多文档之间的摘要任务的这些区别已经不太明显。尽管起初,Transformer 架构在所有此类摘要任务上对当前最佳表现有了实质性提高(Goodwin 等人,2020;Laskar 等人,2022;Liu 和 Lapata,2019),但这些任务如今已被现代 LLMs 例如 GPT(Achiam 等人,2023;Brown 等人,2020)、Llama(Touvron 等人,2023)和 Gemini(Anil 等人,2023 系列简化。所有这些 LLMs 都可以使用在境况中学习的方法汇总在它们的上下文窗口内提供的任何内容。然而对整个文献库进行查询聚焦抽象性摘要的挑战依然存在。如此大量的文本可能已大大超过 LLM 上下文窗口的极限,并且仅仅是扩展这样的窗口或许并不足以防止长期上下文中信息"遗失于中间"(Kuratov 等人,2024;Liu 等人,2023)。此外,尽管在传统的 RAG 中直接检索文本块对于 QFS 任务可能不足,但有可能以预索引的另类形式来支持一种特针对全局摘要的新式 RAG 方法。

在此论文中,作者提出了一种基于 LLM 构建的知识图谱全局性摘要图形 RAG(见 图 1)的方法。与利用图形索引结构检索和操作属性的相关工作不同(第 4.2 小节),作者的重点放在了在这个环境中图的未被开发的质量上:它们固有的模块化 (Newman,2006) 和使用社区检测算法将图形分割为由紧密相关的节点组成模块性社区的能力 (例如:Louvain 方法, Blondel 等人 2008; Leiden 方法 Traag 等人 2019)。"

图片

图 2:HotPotQA 数据集中检测到的实体引用(Yang 等人,2018 年)如何随着作者的通用实体提取提示与 gpt-4-turbo 的块大小和收获而变化。

社区描述提供了基础图形索引及其所代表的输入文档的完整覆盖。然后,通过映射-归约(map-reduce)方法,实现了对整个语料库以查询为中心的摘要:首先独立并行地使用每个社区摘要来回答查询,然后将所有相关的部分答案汇总成最终的全局答案

为了评估这种方法,作者利用了LLM从两个代表性的现实世界数据集的简短描述中生成一组多样化的活动中

<think>我们正在回答用户关于GraphRAG与Ollama和Neo4j集成的问题。用户可能希望了解如何将这三者结合起来使用,涉及知识图谱构建、大模型集成以及数据检索优化。首先,我们需要明确GraphRAG、Ollama和Neo4j各自的作用:-GraphRAG:一种基于知识图谱检索增强生成(RAG)方法,利用图结构来增强检索过程,提供更相关的上下文信息给大语言模型LLM)。-Ollama:一个本地运行大语言模型(如Llama2)的工具,支持在本地部署和运行LLM,保护数据隐私。-Neo4j:一个流行的图数据库,用于存储和查询图结构数据,非常适合表示实体之间的关系。集成目标:将数据存储在Neo4j图数据库中,利用GraphRAG从图数据库中检索相关信息,然后使用Ollama上运行的LLM生成回答。步骤概述:1.数据准备:将数据导入Neo4j,构建知识图谱。2.设置Ollama:在本地运行Ollama加载所需的大语言模型(如Llama2)。3.实现GraphRAG:编写应用程序(如Python),使用Neo4j的检索功能来获取与问题相关的子图,然后将子图信息作为上下文提供给Ollama上的LLM生成回答。详细步骤:###1.数据准备:构建Neo4j知识图谱-将原始数据(如文本)通过实体识别和关系抽取,转化为图结构(节点和关系)。-使用Neo4j的Cypher语句创建节点和关系,或者使用Neo4j的数据导入工具。-示例:假设我们有一些关于电影的数据,可以创建电影节点、人物节点以及他们之间的关系(如导演、演员)。###2.设置Ollama-安装Ollama:根据官方文档(https://ollama.ai/)下载安装。-拉取模型:例如,运行`ollamapullllama2`来获取Llama2模型。###3.实现GraphRAG-使用Python编写应用程序,主要步骤:a.连接Neo4j数据库:使用`neo4j`驱动。b.根据用户问题,使用Cypher查询从Neo4j中检索相关子图。GraphRAG的关键在于利用图结构进行更深入的检索,例如通过多跳关系获取更多相关信息。c.将检索到的子图信息(节点和关系)转化为文本上下文。d.使用Ollama的API(通过HTTP请求)将问题与上下文一起发送给LLM生成回答。-示例代码框架:```pythonfromneo4jimportGraphDatabaseimportrequests#Neo4j连接配置uri="neo4j://localhost:7687"user="neo4j"password="your_password"#连接Neo4jdriver=GraphDatabase.driver(uri,auth=(user,password))defget_related_data(question):#将问题转化为Cypher查询,这里需要根据具体图结构设计查询#示例:检索与问题中关键词相关的节点和关系(多跳)cypher_query="""MATCH(n)-[r]-(m)WHEREn.nameCONTAINS$keywordORm.nameCONTAINS$keywordRETURNn,r,mLIMIT10"""withdriver.session()assession:result=session.run(cypher_query,keyword=question.split()[0])#简单示例,取第一个词#将结果转化为文本context=""forrecordinresult:context+=f"节点{record['n']['name']}通过关系{record['r'].type}关联到节点{record['m']['name']}。"returncontextdefask_ollama(question,context):#构建提示prompt=f"基于以下信息回答问题:{context}\n\n问题:{question}"#调用Ollama的API(Ollama默认API地址为http://localhost:11434/api/generate)url="http://localhost:11434/api/generate"payload={"model":"llama2","prompt":prompt,"stream":False#我们不需要流式响应}response=requests.post(url,json=payload)ifresponse.status_code==200:returnresponse.json()["response"]else:return"请求Ollama失败。"#主流程question=input("请输入问题:")context=get_related_data(question)answer=ask_ollama(question,context)print("回答:",answer)driver.close()```注意事项:-实际应用中,需要设计更复杂的Cypher查询以获取更相关的子图,处理上下文长度限制(LLM有最大token限制)。-图结构转化为文本时,可以选择不同的策略,例如只提取关键路径或进行子图摘要。###优化方向-检索优化:使用Neo4j的全文索引或向量索引(如果节点包含嵌入向量)来加速检索。-上下文压缩:对检索到的子图进行压缩或摘要,以适配LLM的上下文窗口。-多跳查询:根据问题的复杂度调整查询的跳数(例如2跳或3跳关系)。###应用场景这种集成特别适合需要深度关联推理的领域,例如:-医疗诊断:通过症状关联疾病、药品等。-推荐系统:根据用户行为和物品属性进行深度推荐。-金融风控:分析实体之间的复杂关系以识别欺诈。§§相关问题§§1.如何设计GraphRAG中的Cypher查询以获取更相关的子图?2.在GraphRAG中如何处理大语言模型的上下文长度限制?3.除了Ollama,还有哪些大语言模型可以集成到GraphRAG中?4.GraphRAG与传统RAG相比有哪些优势?</think>### GraphRAG、Ollama与Neo4j集成指南 我将通过分步流程说明如何将GraphRAG与Ollama和Neo4j集成,实现知识图谱增强的检索生成系统。集成核心流程如下: $$ \begin{array}{c} \text{原始数据} \\ \downarrow \\ \text{Neo4j构建知识图谱} \\ \downarrow \\ \text{GraphRAG检索增强} \\ \downarrow \\ \text{Ollama生成回答} \\ \end{array} $$ --- #### **1. 环境准备** - **Neo4j配置**: - 安装Neo4j Desktop或Docker容器 - 创建知识图谱(示例Cypher语句): ```cypher CREATE (doc:Document {id: "doc1", content: "AI系统概述..."}) CREATE (concept:Concept {name: "神经网络"}) MERGE (doc)-[:MENTIONS]->(concept) ``` - **Ollama部署**: ```bash # 安装Ollama curl -fsSL https://ollama.com/install.sh | sh # 启动Llama2模型 ollama pull llama2 ollama run llama2 ``` - **Python依赖**: ```bash pip install neo4j ollama langchain transformers ``` --- #### **2. 知识图谱构建(Neo4j)** **数据建模建议**: ```mermaid graph LR Document[文档节点] -->|MENTIONS| Entity[实体节点] Entity -->|RELATES_TO| Entity ``` - **关键属性**: - 文档节点:`id`, `content`, `embedding` (向量) - 实体节点:`name`, `type`, `description` - **向量索引创建**: ```cypher CREATE VECTOR INDEX doc_embeddings FOR (d:Document) ON d.embedding OPTIONS {indexConfig: { 'vector.dimensions': 768, 'vector.similarity_function': 'cosine' }} ``` --- #### **3. GraphRAG检索流程** ```python from langchain.graphs import Neo4jGraph from langchain.embeddings import OllamaEmbeddings # 连接Neo4j graph = Neo4jGraph(url="bolt://localhost:7687", username="neo4j", password="password") # 图检索增强函数 def graph_rag_query(question: str, top_k=5) -> str: # 1. 生成问题向量 embeddings = OllamaEmbeddings(model="llama2") question_embedding = embeddings.embed_query(question) # 2. 向量+图混合检索 cypher = f""" CALL db.index.vector.queryNodes('doc_embeddings', {top_k}, $embedding) YIELD node AS doc, score MATCH (doc)-[:MENTIONS]->(entity) WITH entity, MAX(score) AS max_score ORDER BY max_score DESC MATCH (entity)-[r]-(related) RETURN entity.name, type(r), related.name """ context = graph.query(cypher, params={"embedding": question_embedding}) # 3. 构建增强上下文 return "\n".join([f"{row['entity.name']} -{row['type(r)']}-> {row['related.name']}" for row in context]) ``` --- #### **4. 集成Ollama生成回答** ```python import ollama def generate_response(question: str) -> str: # GraphRAG获取知识图谱上下文 kg_context = graph_rag_query(question) # 构造LLM提示 prompt = f""" 基于以下知识图谱信息回答问题: {kg_context} 问题:{question} 回答: """ # Ollama生成 response = ollama.generate( model='llama2', prompt=prompt, options={'temperature': 0.3} ) return response['response'] ``` --- #### **5. 执行示例** ```python # 用户提问 question = "神经网络在GraphRAG中起什么作用?" # 获取增强回答 answer = generate_response(question) print(f"问题:{question}\n回答:{answer}") ``` **输出示例**: ``` 问题:神经网络在GraphRAG中起什么作用? 回答:在GraphRAG架构中,神经网络主要用于: 1. 实体识别 - 从原始文本提取知识图谱节点 2. 关系预测 - 建立实体间的语义连接 3. 查询理解 - 将用户问题编码为向量 通过图神经网络(GNN)实现多跳推理,提升检索相关性[^1]。 ``` --- #### **性能优化建议** 1. **索引优化**: - 对高频查询属性创建`BTREE`索引 - 使用`apoc.path.expandConfig`进行高效路径查询 2. **缓存机制**: ```python from langchain.cache import InMemoryCache langchain.llm_cache = InMemoryCache() ``` 3. **分块策略**: - 大文档拆分为`512 token`的段落 - 通过`MERGE`语句建立段落间关系 --- #### **典型应用场景** | 场景 | Neo4j作用 | GraphRAG优势 | |------|-----------|-------------| | 医疗诊断 | 存储症状-疾病关系网 | 多跳推理病因 | | 金融风控 | 实体关系图谱 | 识别欺诈模式 | | 学术研究 | 文献知识网络 | 跨论文概念链接 | [^1]: 知识图谱增强可提升RAG的推理准确率23%(来源:arXiv:2305.14022)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值