从 RAG 到 GraphRAG:当检索增强生成遇上知识图谱

Posted on 四 26 3月 2026 in tech

从 RAG 到 GraphRAG:当检索增强生成遇上知识图谱

传统 RAG 已经暴露出越来越多的局限性,GraphRAG 的出现为我们打开了一扇新的大门。本文将深入剖析 RAG 的痛点,并全面探讨 GraphRAG 的原理、架构与实践。


一、RAG 回顾:为什么我们需要检索增强生成?

RAG(Retrieval-Augmented Generation)的核心思想很简单:先检索,再生成

大语言模型(LLM)虽然强大,但存在几个天然缺陷:

  • 知识截止:训练数据有时间边界,无法获取最新信息
  • 幻觉问题:模型会"一本正经地胡说八道"
  • 领域知识不足:对企业私有数据一无所知

RAG 通过在生成前引入外部知识检索,有效缓解了这些问题。典型的 RAG 流程如下:

用户提问 → 文本向量化 → 向量数据库检索 → 拼接上下文 → LLM 生成回答

这套方案在很多场景下效果不错,但随着应用深入,痛点也逐渐暴露


二、传统 RAG 的六大痛点

痛点 1:语义孤岛 —— 只见树木,不见森林

传统 RAG 将文档切分为 chunk(文本块),每个 chunk 独立嵌入向量空间。这导致了一个根本问题:chunk 之间的关联关系丢失了

举例:
- Chunk A: "张三是公司的 CTO"
- Chunk B: "CTO 负责公司的技术战略"
- Chunk C: "公司的技术战略聚焦于 AI 和云计算"

用户问:"张三负责什么?"
→ 检索可能只命中 Chunk A,无法串联出完整答案

每个 chunk 就像一座孤岛,缺乏上下文连接,导致回答片面、不完整。

痛点 2:多跳推理无能为力

当回答一个问题需要跨越多个文档、多个实体进行推理时,传统 RAG 几乎束手无策。

问题:"哪些与李四合作过的研究员发表了关于 Transformer 的论文?"

这需要:
1. 找到李四的合作者
2. 确认哪些合作者是研究员
3. 检查这些研究员是否发表过 Transformer 相关论文

传统 RAG 无法完成这种多跳推理链

痛点 3:全局性问题的盲区

传统 RAG 擅长回答局部性、细节性的问题,但对于需要全局视角的问题表现糟糕:

  • ❌ "这个数据集的主要主题有哪些?"
  • ❌ "公司过去一年的战略变化趋势是什么?"
  • ❌ "请总结所有项目之间的依赖关系"

这类问题需要对整个语料库有全局理解,而向量相似度检索天然是局部的。

痛点 4:Chunk 切分的两难困境

  • Chunk 太小:语义不完整,上下文丢失
  • Chunk 太大:噪声增多,检索精度下降,且受限于 LLM 的上下文窗口

无论怎么调整 chunk 大小和重叠策略,都无法从根本上解决问题。

痛点 5:检索与生成的语义鸿沟

用户的问题和文档的表述方式往往存在差异:

用户问:"怎么提高系统性能?"
文档写的是:"通过引入缓存层和数据库索引优化,响应时间降低了 60%"

语义相关,但词汇层面差异很大,向量检索可能错过这段内容

痛点 6:缺乏可解释性

传统 RAG 返回的结果往往是"黑箱"的:

  • 为什么检索到这些 chunk?
  • 这些 chunk 之间是什么关系?
  • 回答的推理路径是什么?

用户只能看到最终答案,无法理解和验证推理过程。


三、GraphRAG:用知识图谱重新定义 RAG

3.1 什么是 GraphRAG?

GraphRAG 是微软研究院在 2024 年提出的一种新范式,其核心思想是:

将非结构化文本转化为知识图谱,利用图结构进行检索和推理,再结合 LLM 生成回答。

传统 RAG:  文档 → Chunks → 向量索引 → 相似度检索 → LLM 生成
GraphRAG: 文档 → 知识图谱 → 社区检测 → 图检索/遍历 → LLM 生成

与传统 RAG 相比,关键差异在于多了一层结构化的知识表示。一句话概括:向量相似度能找到近义词,但找不到因果链;图谱遍历可以。

3.2 GraphRAG 的核心架构

GraphRAG 的流程可以分为两个阶段:索引阶段(Indexing)查询阶段(Querying)

索引阶段

┌─────────────┐    ┌──────────────┐    ┌──────────────┐    ┌───────────────┐
│  源文档      │ →  │  实体/关系    │ →  │  知识图谱     │ →  │  社区检测      │
│  (Documents) │    │  抽取 (LLM)  │    │  构建         │    │  & 摘要生成    │
└─────────────┘    └──────────────┘    └──────────────┘    └───────────────┘

Step 1: 文本分块与实体关系抽取

利用 LLM 从文本中抽取实体(Entity)和关系(Relationship),形成三元组:

{
  "entities": [
    {"name": "张三", "type": "Person", "description": "公司CTO,负责技术战略"},
    {"name": "AI战略", "type": "Strategy", "description": "公司核心技术方向"}
  ],
  "relationships": [
    {"source": "张三", "target": "AI战略", "description": "主导制定", "weight": 0.9}
  ]
}

我的经验是:宁可少抽、抽准,也不要贪多抽乱。 噪声三元组会严重污染图谱检索结果。针对你的领域定制 schema 和 few-shot examples,通用 prompt 的抽取质量往往不够。

Step 2: 知识图谱构建

将抽取的实体和关系组织成图结构:

[张三] --主导制定--> [AI战略]
  |                      |
  |--担任CTO-->  [公司]  |--包含--> [大模型研发]
  |                      |--包含--> [云计算平台]
  |--合作-->  [李四]

Step 3: 社区检测(Community Detection)—— Leiden 算法详解

这是 GraphRAG 最关键的创新之一。微软 GraphRAG 使用 Leiden 算法 对知识图谱进行层次化社区检测,将紧密关联的实体自动聚类成社区,然后为每个社区生成摘要。

为什么是 Leiden 而不是 Louvain?

Leiden 算法是 Louvain 算法的改进版,由荷兰莱顿大学(Leiden University)的研究者在 2019 年提出。Louvain 虽然快,但有一个已知缺陷:它可能产生内部不连通的社区——把一些实际上没有直接联系的节点分到了同一组。这在 GraphRAG 场景下是不可接受的,因为社区摘要需要基于真正有关联的实体来生成。

Leiden 算法的三阶段迭代
1. 局部移动(Local Moving)
   → 每个节点尝试加入邻居所在的社区,选择模块度增益最大的

2. 细化(Refinement)  ← Leiden 的关键改进
   → 在每个社区内部再做一次划分,确保社区内部是连通的
   → 解决了 Louvain 的"断裂社区"问题

3. 聚合(Aggregation)
   → 把每个社区压缩成一个超级节点,形成新的图
   → 回到第 1 步,继续迭代,直到收敛

打个比方:你有一群人的社交关系网络。Louvain 像是粗略地按"谁跟谁聊得多"分组,但可能把两个互不认识的人分到同一组。Leiden 多了一步组内检查,确保同一组里的人确实都能通过组内关系连起来。

模块度(Modularity):优化目标

两种算法都在优化模块度 Q,简单说就是:社区内部的实际边数,比随机情况下期望的边数多多少。Q 越高,社区划分质量越好。

Leiden vs Louvain 对比
维度 Louvain Leiden
社区连通性 不保证 保证
速度 略慢(多了细化步骤)
划分质量 更好
大规模图支持
在 GraphRAG 中的多层级社区

Leiden 产生的层次化社区结构正好满足 GraphRAG 的需求:

Level 0 (最细粒度):  [张三, AI战略, 大模型研发] [李四, 云计算, 基础设施]
Level 1 (中等粒度):  [技术部门: 张三, 李四, AI, 云计算]
Level 2 (最粗粒度):  [整个公司: 技术, 业务, 运营...]

每个社区会由 LLM 生成一份社区摘要(Community Summary),捕获该社区的核心主题和关键信息。不同粒度的问题可以在不同层级找到答案。

查询阶段

GraphRAG 提供两种查询模式:

Local Search(局部搜索)

适用于:具体的、需要详细信息的问题

用户提问 → 实体识别 → 图邻域遍历 → 收集相关实体/关系/chunk → LLM 生成

工作流程:

  1. 从问题中识别关键实体
  2. 在知识图谱中定位这些实体
  3. 遍历其邻域节点和边(可多跳)
  4. 收集相关的社区摘要、实体描述、原始文本
  5. 构建上下文,交给 LLM 生成回答

Global Search(全局搜索)

适用于:宏观的、需要全局视角的问题

用户提问 → 选择社区层级 → 收集社区摘要 → Map-Reduce → LLM 生成

工作流程:

  1. 根据问题选择合适的社区层级
  2. 将所有社区摘要作为上下文
  3. 使用 Map-Reduce 策略:先对每个社区摘要生成中间答案,再汇总生成最终答案
  4. 这使得 GraphRAG 能够回答"全局性"问题

3.3 混合检索策略

实际检索时,GraphRAG 通常采用混合策略:

# 伪代码示意
def hybrid_retrieve(query):
    # 1. 向量检索:找相关文本块
    text_chunks = vector_search(query, top_k=10)

    # 2. 实体识别:从 query 中提取实体
    entities = extract_entities(query)

    # 3. 图谱检索:沿关系扩展上下文
    graph_context = graph_traverse(entities, max_hops=2)

    # 4. 合并去重,送入 LLM
    context = merge(text_chunks, graph_context)
    return generate_answer(query, context)

max_hops 是个关键参数。跳数太少,信息不够;跳数太多,噪声太大。一般 2-3 跳是个不错的起点。

3.4 GraphRAG 如何解决 RAG 的痛点

RAG 痛点 GraphRAG 解决方案
语义孤岛 知识图谱天然连接实体和关系,消除信息孤岛
多跳推理 图遍历支持多跳路径探索
全局性问题 社区摘要 + Global Search 提供全局视角
Chunk 切分困境 信息以实体和关系形式存储,不依赖 chunk 边界
语义鸿沟 实体和关系提供结构化的语义桥梁
缺乏可解释性 图路径提供清晰的推理链条

四、GraphRAG 实践:关键技术细节

4.1 实体关系抽取的 Prompt 工程

实体关系抽取的质量直接决定了知识图谱的质量。以下是一些关键策略:

  • 定义清晰的实体类型和关系类型 — 不要让 LLM 自由发挥,给出明确的 schema
  • 提供 few-shot examples — 用你领域内的真实样本做示范
  • 分步抽取 — 先抽实体,再抽关系,比一步到位效果更好
  • 设置置信度阈值 — 低置信度的三元组宁可丢弃

4.2 图谱存储选择

方案 适用场景 优势 劣势
NetworkX(内存) 原型验证、小规模 简单快速 不持久化、不支持大图
Neo4j 中大规模生产 成熟的图查询语言 Cypher 运维成本
Nebula Graph 大规模场景 国产、高性能 学习曲线
直接用 JSON/Parquet 微软 GraphRAG 默认 零依赖 查询灵活性差

4.3 什么时候该用 GraphRAG?

不是所有场景都需要 GraphRAG。我的判断标准:

适合用 GraphRAG 的场景:

  • 文档间有大量实体交叉引用(如法规、技术规范、医学文献)
  • 用户经常问多跳关系问题("A 影响了 B,B 又导致了什么?")
  • 需要全局性总结和主题概览

不需要 GraphRAG 的场景:

  • 单文档内的简单问答
  • 文档之间关联性弱
  • 对延迟和成本敏感(GraphRAG 的索引成本显著高于传统 RAG)

五、工具和框架

目前比较成熟的 GraphRAG 实现:

  • Microsoft GraphRAG:微软开源实现,支持 Global/Local Search,社区检测用的是 Leiden 算法
  • LlamaIndex + KnowledgeGraphIndex:LlamaIndex 内置的图谱索引,适合快速原型
  • Neo4j + LangChain:用 Neo4j 存图谱,LangChain 做编排,灵活但需要自己搭
  • Nebula Graph + RAG:国产图数据库方案,适合大规模场景

六、总结

GraphRAG 的本质是给 RAG 加上了结构化推理能力。它不是传统 RAG 的替代品,而是在特定场景下的增强方案。

核心取舍很清楚:

  • 收益:多跳推理、全局总结、实体关系理解、可解释的推理路径
  • 代价:索引成本高、实体抽取质量要求高、系统复杂度上升

行动清单

  • [ ] 评估你的场景是否真的需要多跳推理
  • [ ] 先跑通传统 RAG baseline,记录 bad case
  • [ ] 挑 20-50 个 bad case,分析是否因为缺少实体关系导致
  • [ ] 如果是,用 Microsoft GraphRAG 或 LlamaIndex 跑个 POC
  • [ ] 重点关注实体抽取质量,建立评估机制
  • [ ] 初期控制图谱规模在几千到几万节点,避免维护成本失控
  • [ ] 设计增量更新流程,不要每次全量重建图谱

一句话:不要因为 GraphRAG 听起来酷就上,要因为你的 bad case 需要它才上。

参考资料