第32回 GraphRAG——图上的检索增强流程

段落相似如浮云,关系路径是铁证。
云散还须抓住线,一线牵出万重门。

第31回我们修路:抽取、立法(schema)、归一。
修好了路,接下来就问:这条路怎么用来取证?

传统 RAG(第23–29回)像在书库里“按相似度找段落”。
GraphRAG 则多了一把钥匙:
把知识从“散文段落”变成“关系网络”,检索不只靠相似,还能靠连通与路径

近年的综述把 GraphRAG 形式化为一条流水线:
图索引(Graph-based indexing)→ 图引导检索(Graph-guided retrieval)→ 图增强生成(Graph-enhanced generation)。12

这一回把它讲成一句人话:

先把世界画成图,再沿着图找证据链,最后把证据链说成话。


一、为什么“图”能补“相似度”的短板

相似度检索有两种常见尴尬:

  1. 多跳问题:答案要跨好几段文档才能拼出来
  2. 同义噪声:相似段落很多,但真正关键的是其中的关系链

而图最擅长的恰是“多跳”:

  • 你想找 A 与 C 的关系
  • 图告诉你:A—B—C
  • 这条路径本身就是解释

所以 GraphRAG 的核心不是“换一种向量”,而是“换一种证据组织方式”。


二、GraphRAG 的五件套:把流水线拆开看

把 GraphRAG 拆细一点(不同综述表述略有差异),通常离不开这些模块:2

  1. 查询处理:把自然语言问题映射到图里的实体/关系线索
  2. 检索器:在图上做走路、扩张、社区发现或图学习
  3. 组织器:把子图变成“可喂给模型的上下文”(节点表、路径、证据段落)
  4. 生成器:基于子图与文本证据生成答案,并给出引用或路径解释
  5. 数据源:图从哪里来(知识库、表格、日志、文本抽取)

你会发现:
GraphRAG 并没有否定传统 RAG,反而经常把它“收编”为图的一部分:

  • 图负责给“结构化线索”
  • 文本块负责给“原文引用”

三、两种常见检索:k-hop 子图与路径检索

工程里最常用、也最容易落地的两种图检索:

1)k-hop 子图(圈地)

给定一个实体,从它出发往外走 k 步,把周围邻居都捞出来。
优点是稳:只要实体对得上,必有结果。
缺点是粗:k 大了子图会爆炸,k 小了可能缺证据。

2)路径检索(找线索链)

给定起点与终点(或起点与目标类型),在图上找若干条候选路径。
优点是解释强:路径本身就是“因果链/依赖链”。
缺点是难:终点往往不明确,需要策略(比如先猜实体、再验证)。


四、极简可跑代码:从问题里的“实体线索”取 k-hop 子图

下面代码演示一个最小 GraphRAG 检索器:

  • 图:三元组 → 邻接表
  • 查询:从问题里“手工指定”一个实体(教学演示)
  • 检索:取 2-hop 子图
  • 输出:子图里的边(这就是“结构化证据”)
from collections import defaultdict, deque


TRIPLES = [
    ("张三", "就读于", "清华"),
    ("清华", "位于", "北京"),
    ("北京", "属于", "中国"),
    ("清华", "友校", "北大"),
    ("北大", "位于", "北京"),
]


def build_adj(triples):
    adj = defaultdict(list)
    for h, r, t in triples:
        adj[h].append((t, r))
    return adj


def khop_edges(adj, seed, k=2):
    q = deque([(seed, 0)])
    seen = {seed}
    edges = []
    while q:
        u, d = q.popleft()
        if d == k:
            continue
        for v, r in adj.get(u, []):
            edges.append((u, r, v))
            if v not in seen:
                seen.add(v)
                q.append((v, d + 1))
    return edges


if __name__ == "__main__":
    adj = build_adj(TRIPLES)
    seed = "张三"
    edges = khop_edges(adj, seed, k=2)
    print("seed=", seed)
    for e in edges:
        print(e)

你得到的不是一堆“相似段落”,而是一束“关系边”。
这束边就能直接变成回答的骨架:

  • 张三 → 就读于 → 清华
  • 清华 → 位于 → 北京

再配合传统 RAG 去原文找引用段落,就能把“骨架”补成“可核查的血肉”。


五、GraphRAG 的难点:不是图算法,是“图与文本怎么对齐”

GraphRAG 真正难的地方往往是三件事:1

  1. 实体对齐:问题里的“清华”与图里的哪个节点对应?
  2. 子图组织:子图怎么压缩成模型能读的上下文?
  3. 评估与幻觉:模型沿着子图说话,会不会把不存在的边编出来?

你看,这些难点和第24回讲的“忠实度与可引用回答”完全同源:
证据越结构化,越需要把“引用与约束”做得更严。


六、小结:GraphRAG 是“沿路取证”的升级

把第三篇与第四篇的分界线说透:

  • 第三篇:学会“取证”
  • 第四篇:学会“办案”

GraphRAG 让取证不再只靠相似度,而是靠“关系网络的线索”。
下一回(第33回)我们要给图再加一层“几何”:
把图压进向量空间,学会用嵌入做推理与泛化。

欲知后事如何,且听下回分解。


幻觉核查

  • GraphRAG 的三段式流程(索引→检索→生成):可核对综述对 GraphRAG workflow 的定义与分解。12
  • 本回代码只是最小演示:现实 GraphRAG 必须解决实体对齐、子图压缩、引用与评估等工程难题。

逻辑审计

  • 与第31回衔接:第31回修路(图谱构建),第32回用路(图引导检索)。
  • 与导读一致:导读强调“慢思考=搜索+自校验”,GraphRAG 的检索本质就是“在图上搜索线索”。
  • 为第33回铺路:图检索解决“结构”,嵌入解决“泛化”;下一回把“走路”变成“算相似”。

引用与溯源

Footnotes

  1. Peng, B., et al. Graph Retrieval-Augmented Generation: A Survey arXiv:2408.08921 (v2: 2024-09-10) https://arxiv.org/abs/2408.08921 2 3

  2. Han, H., et al. Retrieval-Augmented Generation with Graphs (GraphRAG) arXiv:2501.00309 (v2: 2025-01-08) https://arxiv.org/abs/2501.00309 2 3