☰
GraphRAG原理与落地:从向量检索到知识图谱的RAG升级实践
2026/10/20 23:43:16 网站建设 项目流程

普通向量检索做到一定规模之后,你会发现一个很拧巴的现象:问它“某份合同里约定了什么”,它能答得头头是道;问它“这几份合同之间的付款条款有没有冲突”,它就开始东拼西凑。这是传统检索增强生成(RAG)的天花板,它擅长找“最相似的片段”,但不擅长梳理“片段与片段之间的关系”。GraphRAG(基于知识图谱的检索增强生成)就是冲着这个缺口来的:先让大模型把文档里的实体和关系抽出来画成一张知识图谱,再基于图谱去检索和推理。这篇文章我会从原理讲到实操,把GraphRAG的完整工作流、落地路径和我在真实项目中踩过的一组坑一次说清楚,适合刚接触RAG、想升级知识库问答能力的开发者,也适合只需要判断“我要不要引入GraphRAG”的决策者。

1. 从“找相似片段”到“摸清关系网”:传统RAG为什么卡在天花板

1.1 常规RAG的检索逻辑是“向量相似度”

先看大多数人已经跑通的普通RAG:把文档切成小块,每块做向量化,存进向量数据库。用户提问时,同样把问题向量化,在向量库里召回相似度最高的若干块,拼进上下文交给大模型回答。这套路短期内效果不错,因为它本质上是在做一个“关键词/语义的近义匹配”,适合“问题对应的答案就藏在某一段话里”的场景。

但问题一旦从“某个定义是什么”升级成“多个实体之间的相互影响”“整套文档隐含的结构性矛盾”,普通RAG就力不从心了。原因不复杂:向量相似度衡量的是“这段文字和问题像不像”,而不是“这段文字在全局信息网络中处在什么位置”。你问“某公司的风险管理策略是否覆盖了所有子项目”,正确答案可能需要跨越三十份文档、把十几个实体的关系串起来才能得到,但向量召回天然偏向局部相似,串不起来。

1.2 普通RAG解决不了的三类问题

我在本地知识库项目里反复碰到以下三类问题,基本是普通RAG的盲区:

第一类是跨文档关联问题。“A项目的验收标准是否满足B项目的交付依赖?”这是一个关系型问题,答案分布在多份文档、多个段落里,单靠召回几个片段无法建立联系。第二类是全局总结问题。“过去一年所有项目评审中最常见的风险点是什么?”这个问题没有唯一答案片段,需要像人类一样先通读全库再归纳。第三类是结构一致性检查。“当前所有供应商合同里,有哪些条款和合规清单不一致?”这需要把合同里的条款实体逐一和合规清单做对照,本质上是图匹配,不是文本相似度。

这些问题的共同点是:需要知道“谁和谁有关、关系是什么”,而不只是“哪段话像答案”。

1.3 一个让普通RAG直接翻车的实测案例

我之前帮某公司做过一批市场分析报告的问答系统,总共一百多份文档。用户问“目前市面上的这几家竞品,哪些和我们在同一价格带且主渠道重叠?”普通RAG把所有文档切成块之后召回的结果非常分散,要么只提到价格,要么只提到渠道,大模型硬生生凑出来的答案存在多处张冠李戴。后来我把同样的语料换成GraphRAG管线,先抽实体和关系构建图谱,再回答这个问题时,模型能沿着“竞争对手—销售价格—主渠道”的路径把重叠实体找出来,回答质量立刻不一样了。

所以GraphRAG解决的不是“检索更准”这个层面的事,而是让机器从“读片段”进化成“读关系”。下面我拆解它的完整工作流。

2. GraphRAG的工作流拆解:让大模型先画图、再答问

GraphRAG标准管线可以分成五步:文本切块、实体关系抽取、实体消歧与图谱构建、社区检测、生成社区摘要并入库。这五步全部发生在索引(Indexing)阶段,也就是说“画图”是一次性的离线工作,之后每次提问都在这张图上进行。

2.1 第一步:把文档拆成标准化文本块

这一步和普通RAG的切块逻辑类似,但目的不同。普通RAG切块是为了让每个块“自带完整语义”以便向量召回;GraphRAG切块是为了给大模型提供一个“能完整抽取实体和关系的上下文窗口”。

经验上推荐每个文本块控制在600到1200个Token之间,并且尽可能按文档的自然结构切。比如章节标题、列表、表格都应该保留在同一个块内。一个常见错误是直接用固定长度硬切,导致一个表格被拦腰截断,抽取出来的关系直接错乱。对于PDF文档,我通常先做版面解析,保留标题层级再做切分。

2.2 第二步:用大模型抽取实体与关系

这是GraphRAG最核心的一步:对每个文本块调用大模型,要求它识别出所有实体(Entity)和关系(Relationship),并且以结构化JSON输出。实体可以是公司、产品、人、地点、指标、事件;关系是实体之间的语义连接,例如“A公司收购了B公司”“C指标影响D指标”。

我通常会在prompt里明确要求输出格式,例如:

{ "entities": [ {"name": "竞品甲公司", "type": "公司", "description": "主打中低端市场"}, {"name": "渠道S", "type": "渠道", "description": "电商平台"} ], "relationships": [ {"src": "竞品甲公司", "dst": "渠道S", "type": "合作", "description": "主要销售渠道"} ] }

需要注意的是,抽取质量直接决定图谱质量。如果prompt没写清楚,模型会抽出一堆噪音关系,比如把“市场增长”这种泛泛词汇也当成实体。我的做法是在prompt里附上本领域的关键实体类型清单,让模型只关注与业务强关联的对象,同时每块文本允许返回“无实体”。

2.3 第三步:实体消歧与图谱构建

每个文本块独立抽取,所以同一个实体可能以多种写法出现在不同块里,比如“甲公司”和“A公司”指的是同一个对象。如果不做消歧,图上会出现两个节点,关系也会被拆散。这一步一般用大模型做聚类判断,或者用规则(大小写归一化、别名表)辅助合并。

合并完之后,把所有实体作为节点、关系作为边,写入图数据库。图数据库的选择看团队情况:数据量小可以直接用Python的图分析库,数据量大建议用原生图数据库。我在中小规模项目里用Python库足够,几千节点、上万边的规模跑社区检测毫无压力。

2.4 第四步:社区检测与层次化摘要

构建好图之后,我们需要理解“这张图里哪些实体抱团”。社区检测的算法有很多,比较常用的是Leiden算法。它的思想可以看作用一个微信群分组:把联系紧密的节点分成一组,彼此之间联系稀疏的部分分成另一组。

GraphRAG会做多层次的社区检测:先在粗粒度上把图分成大社区,再在大社区内部递归地分小社区,形成树状结构。分完之后,对每个社区调用大模型生成一段自然语言摘要,描述“这个社区里的实体之间主要是什么关系、核心主题是什么”。层次化摘要的好处是:回答全局问题时,不用把整个图塞给模型,而是从社区摘要里层层筛选,大大压缩上下文的规模。

2.5 第五步:入库与双模式检索

最终入库内容有两类:一类是百科式的社区摘要(供全局检索用),另一类是最底层的实体、关系、文本块映射(供局部检索用)。查询阶段对应两种检索模式,我下一章会详细说。

到这里,“画图”工作就完成了。下面聊技术选型,因为这一步很多新手会卡住。

3. 落地路径怎么选:低代码工具包和自建管线谁适合谁

很多人一上来就问“GraphRAG支持什么平台”,其实是问错了。GraphRAG具有自己的标准流程,而落地方式基本分两类:直接用现成的GraphRAG开源框架,还是自己写一套编排管线。两者没有绝对优劣,取决于你的数据规模、定制需求和团队能力。

3.1 路径A:直接用现成的GraphRAG框架

目前主流的GraphRAG开源项目已经涵盖了我在上一章讲的五步流程,命令行里配置好大模型API、embedding模型和输入目录就能跑。它自带社区检测、摘要生成和两种查询模式,适合标准场景:非结构化文档为主、需要快速上线、对抽取逻辑没有特殊定制。

优点是上线快,几十页文档当天就能跑出效果;缺点是配置像一个“半黑盒”,遇到特殊领域(比如法律条款表意非常精确)时,你很难精准调控抽取prompt,出了问题排查链路也长。如果团队暂时没有算法背景的人员,建议先走这条路跑通demo,用结果反推是否要深入定制。

3.2 路径B:自组管线

自组管线的意思是用大模型API加上按钮式脚本,把切块、抽取、消歧、建图、社区检测、摘要生成每一步都自己写。优点是每一步都可控,prompt可以针对领域反复调优,实体类型可以按业务自定义,图存储可以选分布式方案支持海量数据。

缺点是工程量大,要踩的坑多。需要自己维护切块逻辑、API调用并发、断点续跑、增量更新。数据只有几百份文档的话,我不建议一上来就自组;等温数据量到了一定规模、且涌现了工具包解决不了的场景时,再迁移到自组管线不迟。

3.3 我的决策建议

直接给一个判断逻辑:数据量小于访谈级(例如几百份文档)、需要快速验证效果,选现成框架;数据量持续增长、实体类型特别垂直、或者要求输出结构化的图谱数据,选自组管线。我见过不少团队一上来就自研,结果光处理API限流和断点续传就折腾了两周;反过来,也有团队用工具包硬撑,最后发现抽取实体的类型不满足业务要求,被迫推倒重来。先想清楚自己的核心诉求比选择哪个框架更重要。

4. Indexing阶段实操:我从空目录跑到实体图谱的完整过程

4.1 数据准备:清洗是第一优先级

GraphRAG的索引质量高度依赖输入文档的整洁度。代码里最好第一步做文本清洗:去掉页眉页脚、统一编码、把扫描件先过OCR。我踩过一个典型坑:某次采集了带大量水印的PDF,水印文字被当成正文抽取进实体,图谱里出现了一堆“机密、内部资料”噪音节点,事后清洗用了两轮。

清洗的优先级是:先做格式归一化(PDF/Word/HTML统统转成Markdown或纯文本),再做内容去噪(去水印、去重复页、去除无关广告块)。如果文档本身结构混乱,可以先用版面解析工具把标题、表格、段落还原好,再喂给切块阶段。

4.2 核心配置项怎么设

进入Indexing之前,有四个参数值得花时间调:

  • chunk_token_size:建议600到1200。块太小,实体跨块断裂;块太大,抽取时上下文过载,模型注意力分散,容易漏抽。
  • 抽取模型:优先选指令遵循能力强、且支持结构化输出的模型。推理速度慢没关系,抽取质量是首要。
  • embedding模型:用于局部检索的文本块匹配,以及实体描述的向量召回能力,建议选与后续查询语言一致的模型。
  • 并行度与限速:API有并发限制,并行度过高会导致大量429错误;过低又会让索引时间翻倍。建议从低并发起步,观察错误率再逐步上调。

4.3 运行输出与产物解读

正常情况下,Indexing完成后会输出一个目录,里面包含实体表、关系表、文本块表、社区层级表和每个社区的摘要。以下是一个模拟项目的产物结构示例:

output/ entities.parquet relationships.parquet text_units.parquet communities.parquet community_reports.parquet

运行完第一步要看统计数字:实体数量是否有常识性,关系数量是否合理,社区数量是否过多。社区过多通常意味着抽取的实体过于碎片,需要回去调整抽取prompt。

4.4 时间成本与API消耗估算

给一个实际运行过的模拟参考:约一百份文档、每份平均三千字,最终产出约八百个实体、两千条关系,用中等规模的商用模型调用做抽取,成本主要在实体抽取阶段。全部索引流程大约消耗了60万到100万Token,跑完耗时约二十分钟。直接结论是:GraphRAG的索引成本比普通RAG高一个数量级,因为它对每块文本都要做大模型推理。如果你有十万份文档,直接跑完整索引成本会很高,必须先做筛选分级。

5. 查询阶段的变化:为什么回答“对比类”和“总结类”问题更靠谱

GraphRAG的查询模式分两种:全局搜索(Global Search)和局部搜索(Local Search)。这两种模式是它和普通RAG最大“姿势”差异所在。

5.1 全局搜索:适合“通读全文后总结”的问题

全局搜索的思路是“先看社区摘要,再逐层筛选”。它把之前生成的社区摘要全部取出,结合用户问题和各社区摘要的相关性进行评分,挑选最相关的几个社区摘要喂给大模型综合回答。这相当于给模型配了一位“先查目录、再看章节总结”的助手,而不是直接丢几十段碎片。

典型适用问题:“该数据集中最主要的风险因素是什么”“这些文档对某方案的整体评价如何”。我在实测中,这类问题用全局搜索回答的完整度比普通RAG高很多,因为它能覆盖到分散在各文档中的证据,而不是被两三个高相似片段带偏。

5.2 局部搜索:适合“围绕特定实体”的细节问题

局部搜索则是从用户问题中识别出核心实体,然后在图谱上沿着关系扩展邻居节点,再从这些邻居关联的文本块中召回证据,组合成答案。它相当于把“和这个实体直接相关的人和事”全都拎出来,形成一个以目标实体为中心的局部子图。

典型适用问题:“某某产品的价格调整历史”“某供应商的交付能力怎么样”。局部搜索的召回逻辑从“文字相似”变成了“关系相近”,所以在回答实体属性、关系链类问题时明显更稳。

5.3 结合问题类型选择或混合

实际使用中,问题往往不是绝对的全局或局部,而是混合形态。我的经验是先用意图分类判断问题类型:如果问题是“总结”“对比”“趋势”类,走全局搜索;如果问题是“某某是什么”“某某和某某之间怎样”这类实体主导的,走局部搜索;更复杂的问题可以同时跑两种,再把两路答案让大模型做一次合并,用全局结果做框架,用局部结果做论据。

值得注意的是,GraphRAG也不是万能的。如果你问的是纯粹的事实抽取题,例如“某报告第30页的统计数字是多少”,普通向量检索反而更快更准。GraphRAG更适合“关系密集型”问题,这也是它在分析型知识库场景中真正值钱的原因。

6. 我实测中踩过的一组坑,以及对应的调优思路

6.1 实体抽取的“漏抽”和“错抽”

首先是漏抽。模型往往会把“与主题无关的实体”筛掉,这在全局总结类任务中会直接影响答案完整性。对比类问题里尤其明显。我的对策是:将自定义类型清单写进prompt,并增加一个“请输出所有符合条件的实体,不要遗漏长尾对象”的指令。另外,对同一份文档做两轮抽取(不同温度)后合并去重,能有效降低漏抽率。

错抽则往往表现为“把形容词当作实体”,例如把“快速增长”误认为趋势实体。这种情况需要加强prompt中的实体约束描述,同时加入后置规则过滤明显异常:太低频的实体、过长的实体名、纯符号实体都值得怀疑。

6.2 图谱膨胀与冗余

图谱不是越大越好。如果不加约束,模型会产出大量弱关系,比如“关于”这种没有信息量的连接。冗余关系会直接拖慢社区检测,并且稀释摘要质量。我常用的优化手法是:设定关系置信度阈值,删除出现频率极低的孤立实体,合并同名不同写的节点。另外,每运行完一轮Indexing,都做一次统计复核,观察实体数量是否随文档数量线性增长;如果超线性增长,说明抽取器可能把同一对象拆成了多个变体。

6.3 表格和PDF带来的切块灾难

PDF里的表格是GraphRAG的头号敌人。固定长度切块会把一行行表格切散,实体抽取看到的信息不完整,关系会直接错乱。我的处理方式是对含表格的文本单独标记,整表保留在同一个块内,不做跨块切分。如果表格特别长,就先把表格转成自然语言描述,再参与切块。这个方法看起来繁琐,但能显著提升实体抽取准确度。

6.4 索引成本与幻觉控制

GraphRAG索引阶段的大模型调用次数是普通RAG的数十倍,幻觉风险也随之上升。比如实体抽取阶段,模型可能会凭空捏造关系,尤其当prompt里的类型清单不合适时。缓解手段包括:使用温度更低的参数、对抽取输出做基于规则的检查(节点必须有出处文本块)、以及摘要生成之后做一次事实一致性校验。成本控制上,建议面对大规模语料时先做一个小批试点,估算Token消耗与完整语料的近似比例,再决定是否需要分级索引。

6.5 一张调优检查表

我在每次做GraphRAG项目时都会按以下顺序检查:先看实体数量的常识性,再看关系类型的分布,接着抽样检查社区摘要的准确性,最后拿三组典型问题测试全局搜索和局部搜索的回答质量。哪一环不对,就回溯到对应的上游环节调优,而不是盲目调查询参数。

7. 小白收藏向:一页速查表

7.1 术语对照表

  • RAG:检索增强生成,先检索相关知识再交给大模型生成回答。
  • 向量化:把文本变成数值数组,让计算机算“相似度”。
  • 实体:知识图谱的“节点”,例如公司、产品、人。
  • 关系:知识图谱的“边”,例如“收购”“依赖于”。
  • 社区检测:把图谱中联系紧密的节点自动分组。
  • 社区摘要:对一组节点及其关系的自然语言总结。

7.2 参数速查表

参数/环节推荐值或做法说明
文本块大小600至1200 Token按文档结构切分,表格不跨块
实体类型清单按业务自定义写进抽取prompt可降低噪音
抽取温度0.1至0.3越低越稳定,防止虚构关系
实体消歧规则与大模型结合大小写归一化、别名表
社区检测Leiden算法层次化递归分组
查询策略意图分类后路由总结类走全局,实体类走局部
索引成本控制小批量试点先估算Token消耗再全量

7.3 问题到方案的快速映射

问“哪段话包含某个关键词”用普通RAG就够了;问“多个实体之间的关联、全局风险、趋势对比、结构一致性”才需要GraphRAG。如果语料中实体之间的关系天然稀疏,也没必要引入图谱;反之,如果业务本身就是要分析关系网络,GraphRAG的收益会非常明显。

就我个人的实操体会而言,GraphRAG并不是普通RAG的替代品,而是一种互补结构。真正判断该不该上它,取决于你是否需要回答“关系型”和“全局型”问题。如果你正在做知识库问答,建议先用一个规模适中的数据集跑通完整Indexing,亲手看看实体图谱长什么样,再决定是在现有RAG基础上叠加图谱能力,还是整体迁移到GraphRAG架构。这个自己动手验证的过程,比看任何教程都更有价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询