GraphRAG进阶:用知识图谱提升RAG推理能力
GraphRAG进阶用知识图谱提升RAG推理能力传统的 RAG 是平面的——把文档切成块靠语义相似度检索。它在查事实、找定义这类任务上很好用。但一旦遇到需要串起来思考的问题传统 RAG 就开始吃力了。比如“公司去年采购的 A 型传感器出了三次故障每次都和谁有关最后是怎么解决的”这个问题需要三个文档块的信息串联起来才能回答。向量检索只能找回孤立的块无法理解块之间的联系。这就是 GraphRAG 要解决的问题。大家好我是黒漂技术佬。一、GraphRAG 是什么GraphRAG RAG 知识图谱Knowledge Graph。它的核心思路是在文档之上构建一张关系网让检索不再是孤立的搜相似内容而是沿着关系走——“顺着这个人找到他的部门顺着这个项目找到相关的合同顺着这个故障找到解决方案”。传统 RAG 的认知文档是一堆孤立的碎片 [块A] [块B] [块C] [块D] [块E] ↑搜索 ↑搜索 ↑搜索 ↑搜索 用户问题 → 相似度匹配 → 返回Top-K GraphRAG 的认知文档是一张关系网 [张三] ──属于──→ [技术部] │ │ │负责 │负责 ↓ ↓ [A项目] ──关联──→ [采购合同C-2024-001] │ │产生了 ↓ [故障报告#3] ──解决──→ [解决方案R-042]在 GraphRAG 中检索不再只是找相似的文本而是在图谱中导航——从一个实体出发沿着关系边找到所有相关信息。二、知识图谱怎么建构建知识图谱分两步实体与关系抽取、图谱存储与索引。第一步从文档中提取实体和关系用 LLM 自动从文档中抽取实体和关系defextract_entities_relations(document_text:str):从文档中提取实体和关系promptf 从以下文档中提取所有重要的实体和它们之间的关系。 实体类型包括人员、部门、项目、产品、合同、事件、日期、金额。 关系类型包括属于、负责、产生、解决、关联、签署、采购。 请以 JSON 格式输出 {{ entities: [ {{name: 张三, type: 人员}}, {{name: 技术部, type: 部门}}, ... ], relations: [ {{source: 张三, target: 技术部, relation: 属于}}, {{source: A型传感器, target: 故障报告#3, relation: 产生}}, ... ] }} 【文档】{document_text}returnllm.invoke(prompt)第二步存入图数据库图数据库有很多选择Neo4j是最成熟的关系图数据库fromneo4jimportGraphDatabaseclassKnowledgeGraph:def__init__(self,uri,user,password):self.driverGraphDatabase.driver(uri,auth(user,password))defadd_entity(self,name,entity_type,doc_source):添加实体节点withself.driver.session()assession:session.run( MERGE (e:Entity {name: $name}) SET e.type $type, e.source $source ,namename,typeentity_type,sourcedoc_source)defadd_relation(self,source,target,relation):添加关系边withself.driver.session()assession:session.run( MATCH (a:Entity {name: $source}) MATCH (b:Entity {name: $target}) MERGE (a)-[r:RELATION {type: $relation}]-(b) ,sourcesource,targettarget,relationrelation)# 还有一个更轻量的选择用 NetworkX 做内存图# 适合小规模、不需要持久化的场景importnetworkxasnx Gnx.DiGraph()G.add_node(张三,type人员)G.add_node(技术部,type部门)G.add_edge(张三,技术部,relation属于)第三步将图谱与向量检索结合classGraphRAGRetriever:图谱 向量 混合检索器def__init__(self,vectorstore,graph):self.vectorstorevectorstore self.graphgraphdefretrieve(self,question:str,k5):# Step 1: 先做向量检索找到入口文档块entry_chunksself.vectorstore.similarity_search(question,kk)# Step 2: 从这些文档块中提取实体entitiesset()forchunkinentry_chunks:forentityinchunk.metadata.get(entities,[]):entities.add(entity)# Step 3: 在图谱中扩展——找到这些实体关联的其他实体和文档related_chunks[]forentityinentities:# 在图中找距离 2 跳内的所有关联节点neighborsself.graph.get_neighbors(entity,hops2)# 用这些关联的实体名去向量库二次检索forneighborinneighbors:extraself.vectorstore.similarity_search(neighbor,k3)related_chunks.extend(extra)# Step 4: 合并所有块去重重排序all_chunksentry_chunksrelated_chunks unique_chunksself._deduplicate(all_chunks)returnself._rerank(question,unique_chunks)[:k]三、GraphRAG 的实际效果我用同一份企业文档集包含项目文档、故障报告、采购合同等约 200 份对比了传统 RAG 和 GraphRAG 在两类问题上的表现测试 1单跳事实查询传统 RAG 的强项问公司的加班费计算标准是什么 传统RAG: ✅ 直接搜到《考勤制度》9 秒出答案 GraphRAG: ✅ 同样准确但多了实体导航的开销11 秒测试 2多跳推理查询GraphRAG 的强项问去年采购的A型传感器出过几次问题分别怎么解决的 传统RAG: ❌ 搜到一堆传感器相关的块但无法串起来 回答碎片化好像有一次是……还有一次可能…… GraphRAG: ✅ 从A型传感器实体出发在图谱里沿着产生故障的关系 找到 3 个故障报告再沿着解决关系找到对应方案 回答完整共3次。第一次因供电不稳定…第二次…第三次…单跳 vs 多跳什么时候该上 GraphRAG你的场景推荐方案FAQ、员工手册、制度问答传统 RAG 就够了项目管理、合同分析、故障追踪上 GraphRAG法律文档、医疗病历、财报分析GraphRAG 几乎是必须海量文档且实体关系复杂GraphRAG 混合检索四、GraphRAG 的开源实践微软的 GraphRAG微软在 2024 年开源了 GraphRAG 项目github.com/microsoft/graphrag它把实体抽取、社区发现、图谱构建、检索增强打包成了一整套流程。核心创新社区摘要Community Summaries微软 GraphRAG 不只是在检索时走图谱还用 Leiden 算法对图谱做社区发现Community Detection——把紧密关联的实体聚类成社区然后对每个社区生成一段摘要。原始图谱几百个实体 上千条关系 ↓ Leiden 社区发现 社区1[张三, 技术部, A项目, 故障#1, 故障#2, 合同C-001] 社区2[李四, 销售部, B项目, 客户X公司] 社区3[财务部, 报销制度, 预算审批流程] ↓ LLM 自动生成社区摘要 社区1摘要技术部张三负责的A项目涉及C-001号采购合同。 该项目使用A型传感器共发生两次故障均已解决……检索时先匹配到相关社区再在该社区内做细化检索。这样即使用了最简单的向量检索也能得到结构化关联化的结果。五、GraphRAG 的成本和取舍GraphRAG 不是银弹。它有几个显著的代价构建成本高实体抽取、关系构建、社区发现……每一步都在调用 LLM。一篇 10 页的文档传统 RAG 入库可能只要 0.05 元GraphRAG 加图谱构建可能要到 0.5~2 元。延迟增加检索时要在图里跳几跳增加的延迟可能是 200~500ms。维护复杂文档更新时图谱需要同步更新——删掉旧实体、添加新关系、重新社区发现。这套维护流水线比纯向量库复杂得多。我的建议先用传统 RAG 跑通整体流程上线后再分析用户提问里多跳问题的占比如果多跳问题占比 10%GraphRAG 的 ROI 不高如果多跳问题 25%且错误率高那就值得投入不要一上来就 GraphRAG——先把基础版做好再按需升级 你的场景里有没有那种需要翻好几篇文档才能回答的问题占比大概多少评论区说说你的场景我帮你判断要不要上图谱