GraphRAG
从你的文档里构建一张知识图谱,然后遍历它。它能回答跨多个来源的问题,而向量检索做不到。
点击任意一个实体。图里它的邻居会亮起来——哪怕它们从未出现在同一个文本块里。这正是标准 RAG 做不到的:「哪个团队负责 Checkout 背后的服务?」的答案来自遍历边,而不是来自一个恰好同时包含这两者的文本块。
标准的检索增强生成(RAG)检索与你的问题最相似的段落。当答案就落在少数几个段落里时,这招管用。
但只要没有任何一个段落包含答案,它就不行了:
- 这 200 份报告的主要主题是什么?
- 这个人和那家公司是怎么关联上的?
- 我们的哪些服务会传递性地依赖支付 API?
这些都需要把信息跨来源拼装起来,而不是从某一个来源里找到。向量相似度没有做这件事的机制。
做法
GraphRAG 在建立索引时就构建一个显式的结构,而不只是给文本块做 embedding。
**抽取实体和关系。**对每个文本块跑一遍模型,把实体——人、系统、概念——以及它们之间的关系抽出来。存成一张图:实体是节点,关系是边。
消解重复。「Acme Corp」「Acme」「ACME Corporation」必须变成同一个节点。这一步一点也不光鲜,却在很大程度上决定了这张图有没有用。
**发现社区。**跑一个聚类算法,找出连接密集的群体。它们对应着主题。
**为每个社区生成摘要。**写出每个簇讲的是什么,再把若干社区成组地做摘要,从而形成一套从具体到笼统的层级。
于是就有了两种向量搜索提供不了的检索模式。
局部查询与全局查询
局部问题问的是具体实体。找到相关节点,遍历到它们的邻居,把连通的子图收集起来。这样就能浮现出与你那个实体相关的信息,哪怕它从未在任何单个文本块里与该实体同时出现——而这正是多跳问题需要的。
全局问题问的是整个语料。从社区摘要作答,而不是从文本块作答。「主要主题是什么」之所以答得出来,是因为主题是在建立索引时算出来的,不是在查询时才去搜的。
第二种模式才是真正新增的能力。再怎么检索文本块,也回答不了关于整个语料的问题,因为这个答案不在任何一个文本块里。
代价
这部分得实话实说,也正是GraphRAG 没有成为默认做法的原因。
**建立索引很贵。**实体抽取意味着每个文本块都要调一次模型,社区摘要还要更多。对于大语料,这比做 embedding 贵好几个数量级;而且只要文档会变,它就不是一次性的开销。
**抽取质量决定了天花板。**漏掉的实体和编造出来的关系会传导进每一个答案。图的好坏完全取决于抽取的好坏,而抽取这一步很容易出现幻觉。
**实体消解是真的难。**做错了,图就会碎成一堆重复节点,遍历随之断掉。
**更新很别扭。**加一份文档,可能就得重算社区和它们的摘要。
**零件更多。**除了向量库,还要一个图存储,再加上抽取和聚类的管线。
什么时候它值这个价
**值:**关于关系与关联的问题;语料级别的综合;跨文档的多跳推理;以及实体与它们之间的连接本身就是主题的领域——调查取证、组织架构、依赖分析、文献综述。
**不值:**一个段落就能答的事实查询;频繁变化的语料;小到用一个大上下文窗口就能全装下的语料;以及任何还没试过标准 RAG 加混合检索加重排序的场景。
最后那条排除很要紧。有时候真正的问题是分块做得差,或者缺了关键词搜索,却被误当成需要GraphRAG。先把便宜的手段用尽——它们能解决更多真实的失败。
更轻的替代方案
有几种做法能以低得多的成本拿到一部分好处:
**元数据图。**如果你的文档本身就带有结构化的关系——代码依赖图、组织架构图、引用网络——直接拿来用。不需要抽取。
**不带图的层级式摘要。**先把文档做摘要,再对摘要做摘要。不用抽实体也能回答全局问题。
**agentic 检索。**让模型发起多次搜索,在多轮之间顺着线索追下去。多跳行为是动态实现的,而不是靠预先算好结构。查询时成本更高,但没有索引成本——这往往是一笔更划算的交易。
**混着用。**具体问题走向量检索,全局问题走图或摘要检索,按查询类型分流。
要点回顾
- GraphRAG 把实体和关系抽取到一张图里,再对它做聚类和层级式摘要。
- 它同时支持局部遍历(围绕一个实体做多跳)和从社区摘要作答的全局回答。
- 全局模式能回答任何单个文本块都装不下的语料级问题——这才是真正新增的能力。
- 代价不小:逐文本块抽取、困难的实体消解、别扭的更新、额外的基础设施。
- 先试混合检索、重排序和更好的分块;把 agentic 检索当作通往多跳的一条更便宜的路径。
下一篇: Agentic RAG