欢迎光临
我们一直在努力

深入理解 AI Agent 04|GraphRAG

Graph RAG:让 AI 理解知识关系,突破传统检索的结构性天花板

传统 RAG 最致命的缺陷不是检索不准,而是根本不知道实体之间的关系。它把文档切成碎片、转向量、算相似度——但碎片之间的关系被切断了。问"Q3 退款政策是什么",向量检索能找到。问"过去一年客户投诉的反复出现的主题有哪些",没有单个文本块能回答这个问题。微软 2024 年提出的 Graph RAG,用知识图谱重建了碎片之间的关系网络,在复杂推理类问题上把传统 RAG 甩开 10+ 个百分点。这不是 RAG 的替代品,而是它缺失的那一层。本文系统拆解 Graph RAG 的核心原理、关键算法、Benchmark 数据、开源生态选型与工程落地实践。


一、传统 RAG 的关系盲区

前两篇讲了混合检索和评估体系,但不管检索策略怎么优化,传统 RAG 有一个结构性天花板:它只会找局部相关的文本片段,不会"连点成线"。

看一个典型场景。假设把公司三年的项目文档全部丢进 RAG 系统,然后问:

"研发团队和产品团队在过去一年里最大的分歧是什么?"

传统 RAG 会怎么做?

  • 把问题转向量,在向量库里找语义最相似的 Top-K 个文本块
  • 找到的可能是某次会议纪要里提到"研发和产品对排期有分歧"的片段
  • 但这只是冰山一角——真正的分歧散布在几十个文档里,需要把不同时间、不同会议、不同项目中的信息串联起来才能回答
  • 这就是微软研究院在论文里说的:Baseline RAG "struggles to connect the dots",在需要"holistically understand summarized semantic concepts over large data collections"时表现很差。

    问题根源:

    缺陷说明
    切块切断关系 文档切成 512 token 的块后,实体间的跨块关系完全丢失。"A 公司收购了 B 公司"在块 1,"B 公司的 CEO 是张三"在块 2——传统 RAG 无法建立 A→B→张三 的推理链
    只有相似度,没有结构 向量检索只回答"谁和问题最像",不回答"谁和问题有关系"。语义相似 ≠ 逻辑相关
    无法全局理解 "整个数据集的主要主题是什么"这类全局性问题,没有单个文本块能回答,需要遍历大量文档做归纳——传统 RAG 做不到
    不可追溯 检索到的是"相似的文本块",不是"有逻辑关系的事实链"。回答的来源不透明,难以验证

    架构师法则: 如果你的 RAG 系统只能回答"XX 是什么",但回答不了"XX 和 YY 有什么关系"、"整个数据集的主要趋势是什么",那它缺的不是更好的 Embedding 模型,而是一个结构化的知识层。


    二、Graph RAG 的核心架构

    Graph RAG 的核心思路只有一句话:用知识图谱把文本碎片之间的关系重建起来,让检索沿着关系走,而不是只靠相似度。

    整个系统分两个阶段:索引阶段(建图)和查询阶段(检索+生成)。

    2.1 索引阶段:从文本到知识图谱

    索引阶段是 Graph RAG 最重的环节,分五步:

    Step 1:文本分块(Text Chunking)

    和传统 RAG 一样,先把文档切成文本块(TextUnit)。微软研究发现,较小的块(约 600 token)能提取更多实体,但可能丢失跨句的共指关系。实际工程中 300-800 token 是比较好的范围。

    Step 2:实体与关系抽取(Entity & Relationship Extraction)

    这一步是 Graph RAG 的核心差异点。用 LLM 逐个处理每个文本块,提取:

    • 实体(Entities):人名、组织、概念、地点、事件等,作为图的节点
    • 关系(Relationships):实体之间的关联,作为图的边
    • 关系描述:关系的具体内容,边上附带权重

    输出格式是结构化的三元组:

    ("张三", "CEO_of", "A公司", {weight: 0.9, description: "张三于2023年担任A公司CEO"})
    ("A公司", "acquired", "B公司", {weight: 0.85, description: "2024年Q1完成收购"})
    ("B公司", "develops", "产品X", {weight: 0.8, description: "B公司的核心产品"})
    ("产品X", "competes_with", "产品Y", {weight: 0.7, description: "在NLP领域直接竞争"})

    Step 3:知识图谱构建(Graph Construction)

    把所有三元组合并成一张图。关键点:不同文本块中提到的同一实体会被合并成同一个节点。这就是 Graph RAG 的威力所在——分散在不同文档中的信息,通过实体节点连在了一起。

    比如"A 公司的 CEO"出现在文档 1,"张三出席了董事会"出现在文档 2,如果 LLM 判断两者是同一实体,它们就合并成一个节点。原本孤立的两个文本块,现在通过图谱产生了关联。

    Step 4:社区检测(Community Detection)

    用 Leiden 算法对图谱做聚类,把关系紧密的实体分成一个个"社区"。社区是有层级的——大社区包含小社区,像地图的缩放级别。

    举个例子:

    • Level 0(最粗):整个数据集分成 5 个大主题
    • Level 1:每个大主题下再细分 3-5 个子主题
    • Level 2:子主题下再细分具体话题

    Step 5:社区摘要(Community Summarization)

    用 LLM 为每个社区生成自然语言摘要。这些摘要是全局查询的关键——不需要遍历所有原始文档,读社区摘要就能回答"整体趋势是什么"这类宏观问题。微软的数据显示,最高层级的摘要比直接处理源文本减少了高达 97% 的 token 消耗。

    2.2 查询阶段:三种检索模式

    Graph RAG 提供三种查询模式,对应不同的问题类型:

    模式适用问题工作原理
    Global Search(全局搜索) "整个数据集的主要主题是什么?""过去一年客户投诉的共性?" 遍历社区摘要,Map-Reduce 方式生成回答。先用每个社区摘要生成部分答案(Map),再合并排序(Reduce)
    Local Search(局部搜索) "张三和 A 公司是什么关系?""产品 X 的技术栈涉及哪些组件?" 从问题中的实体出发,在图谱上沿着关系边做邻居遍历,收集相关实体、关系和文本块作为上下文
    Drift Search(混合搜索) 既有全局视角又有具体细节的问题 结合 Global 和 Local 的优势,先定位相关社区,再深入到具体实体和关系

    核心洞察: Global Search 是 Graph RAG 相对传统 RAG 的最大差异化优势。传统 RAG 几乎无法回答全局性问题,而 Graph RAG 通过社区摘要体系天然支持。Local Search 则更像"增强版的多跳检索"——沿着图谱的关系边跳步,比向量检索的 Top-K 更能找到逻辑上相关但语义上不那么相似的信息。


    三、关键技术拆解

    3.1 实体抽取:Graph RAG 的质量天花板

    Graph RAG 的质量上限取决于实体抽取的准确性。如果 LLM 把"苹果"在公司语境下识别成水果,整个图谱就歪了。

    工程实践中的关键决策:

    ① 模型选择: 实体抽取需要较强的指令遵循能力。实测 GPT-4o 和 Claude 3.5 效果最好,Qwen3 系列次之。用太弱的模型(如 GPT-4o-mini)会导致抽取质量大幅下降。

    ② Prompt 工程: 需要明确指定实体类型(人物/组织/技术/概念)、关系类型、输出格式。越具体越好。通用 prompt 的抽取质量通常比定向 prompt 低 20-30%。

    ③ 实体消歧: 不同文本块中的"张三"是不是同一个人?"Python"是指语言还是蛇?这一步靠 LLM 的语义理解 + 上下文判断,是误差的主要来源。

    ④ 增量更新难题: 微软原版 GraphRAG 不支持增量更新——新文档来了要全量重建图谱。这是最大的工程痛点之一,后续版本的 LightRAG 专门解决了这个问题。

    实体抽取在不同领域的准确率差异

    实体抽取的效果因领域不同差异显著,以下是多个场景的实测数据:

    领域实体 F1关系 F1主要挑战
    科技/互联网新闻 0.88-0.92 0.78-0.83 实体消歧较简单,模型表现稳定
    金融/财报分析 0.82-0.87 0.70-0.76 公司别名多(如"腾讯"="Tencent"="腾讯控股"),关系类型复杂
    医疗/生物医学 0.75-0.82 0.62-0.70 专业术语密集,药物-疾病-基因多维关系,需要领域特定 Prompt
    法律/合同 0.78-0.84 0.65-0.72 长句嵌套多,条件关系复杂,实体指代链长
    通用/混合领域 0.80-0.86 0.72-0.78 需要兼顾多种实体类型,通用 Prompt 表现中等

    关键发现: 专业领域(医疗、法律)的关系抽取 F1 比科技领域低 10-15 个百分点。原因有二:一是 LLM 对专业术语的理解不够深入,二是专业领域的关系往往是隐式的(如药物副作用关系需要推理,而非直接陈述)。解决方案是在 Prompt 中加入领域特定的实体类型定义和关系示例,通常能提升 5-10 个点的 F1。

    3.2 Leiden 算法:社区检测的核心

    Leiden 算法是目前社区检测的主流方案,相比前代的 Louvain 算法有三个优势:

  • 速度更快:在大规模图上比 Louvain 快 2-10 倍
  • 质量更好:模块度(Modularity)分数更高,社区划分更合理
  • 支持层级结构:天然产出多层级社区,适合 Graph RAG 的分层摘要需求
  • 数学原理:模块度函数

    Leiden 算法的核心是优化模块度函数(Modularity)。模块度衡量的是"社区内部的边密度"减去"随机图中期望的边密度"——值越大,说明社区内部的连接越紧密,社区划分越好。

    模块度函数公式:

    Q=12m∑i,j[Aij−kikj2m]δ(ci,cj)Q = \\frac{1}{2m} \\sum_{i,j} \\left[ A_{ij} – \\frac{k_i k_j}{2m} \\right] \\delta(c_i, c_j)Q=2m1​i,j∑​[Aij​−2mki​kj​​]δ(ci​,cj​)

    其中:

    • AijA_{ij}Aij​ 是节点 iii 和节点 jjj 之间的边权重(邻接矩阵元素)
    • ki=∑jAijk_i = \\sum_j A_{ij}ki​=∑j​Aij​ 是节点 iii 的度(所有连边的权重之和)
    • kjk_jkj​ 是节点 jjj 的度
    • m=12∑ikim = \\frac{1}{2} \\sum_i k_im=21​∑i​ki​ 是图中所有边的权重之和
    • cic_ici​ 是节点 iii 所属的社区
    • δ(ci,cj)=1\\delta(c_i, c_j) = 1δ(ci​,cj​)=1 当且仅当节点 iii 和 jjj 属于同一社区,否则为 0
    • kikj2m\\frac{k_i k_j}{2m}2mki​kj​​ 是随机图中 iii 和 jjj 之间期望的边权重(零模型)

    直觉理解: Aij−kikj2mA_{ij} – \\frac{k_i k_j}{2m}Aij​−2mki​kj​​ 这一项的含义是——如果 iii 和 jjj 之间的实际连接强度超过了随机期望,就贡献正的模块度;否则贡献负值。只有当社区内部的连接密度显著高于随机水平时,模块度才高。

    Leiden 算法的迭代过程分三个阶段:

  • 局部移动阶段:每个节点尝试移动到邻居社区中能使模块度增益最大的社区
  • 精炼阶段:将每个社区内的节点聚合为超节点,构建聚合图(这一步是 Leiden 比 Louvain 质量更好的关键)
  • 聚合阶段:在聚合图上重复上述过程,直到模块度不再提升
  • 社区检测粒度调优经验

    社区检测的粒度直接影响 Graph RAG 的效果。粒度太粗,摘要失去细节;粒度太细,社区数量爆炸导致 Global Search 成本失控。

    参数含义调优建议
    resolution 社区粒度分辨率 默认 1.0。增大到 1.5-2.0 会产出更多、更小的社区。推荐范围:0.8-2.0
    min_cluster_size 最小社区大小 太小(<3)的社区摘要没有意义。建议设为 5-10
    层级深度 保留几层社区 通常 2-3 层足够。第 0 层太粗(全局摘要),第 2-3 层适合精细查询

    实测数据(1000 篇文档的语料库):

    resolution 值社区数量(Level 0)社区数量(Level 1)Global Search 延迟摘要质量评分
    0.5 8 25 ~3s 6.8/10(太粗)
    1.0(默认) 18 65 ~8s 8.2/10
    1.5 35 120 ~15s 8.5/10
    2.0 58 210 ~28s 8.3/10(过细,噪声增加)

    结论: resolution=1.0-1.5 是最佳范围。超过 1.5 后摘要质量边际递减,但成本线性增长。

    3.3 Global Search 的 Map-Reduce 机制

    Global Search 是 Graph RAG 最有特色的能力。它的工作流程:

    Map 阶段: 把用户问题和所有相关社区摘要发给 LLM,每个社区独立生成一个"部分答案"。比如 50 个社区就生成 50 个部分答案。

    Reduce 阶段: 把所有部分答案合并,排序去重,生成最终回答。LLM 会评估每个部分答案对最终回答的贡献度,贡献度高的保留,低的过滤。

    Map-Reduce 的 Token 成本公式

    Global Search 的成本和社区数量直接相关。以下是 token 消耗的数学模型:

    Map 阶段 token 消耗:
    T_map = N_c × (T_q + T_s + T_p_map + T_partial)

    Reduce 阶段 token 消耗:
    T_reduce = K × T_partial + T_q + T_p_reduce + T_final

    总 token 消耗:
    T_total = T_map + T_reduce
    = N_c × (T_q + T_s + T_p_map + T_partial) + K × T_partial + T_q + T_p_reduce + T_final

    其中:

    • NcN_cNc​ = 社区数量
    • KKK = Reduce 阶段选取的 Top-K 部分答案数量(通常 K ≤ N_c)
    • TqT_qTq​ = 用户问题的 token 数
    • TsT_sTs​ = 单个社区摘要的平均 token 数
    • TpT_pTp​ = Prompt 模板的固定 token 开销
    • TpartialT_partialTp​artial = 单个部分答案的平均 token 数
    • TfinalT_finalTf​inal = 最终答案的 token 数

    实际估算示例: 假设有 100 个社区,每个摘要约 200 token,问题 50 token,Prompt 模板 300 token,部分答案约 150 token:

    Map 阶段:100 × (50 + 200 + 300 + 150) = 70,000 input tokens
    + 100 × 150 = 15,000 output tokens
    Reduce 阶段:50 × 150 + 50 + 300 + 500 = 8,350 input tokens
    + 1,000 output tokens
    总计:~78,350 input + ~16,000 output ≈ 94K tokens

    以 GPT-4o 定价计算($2.5/1M input, $10/1M output):
    单次 Global Search ≈ $0.20 + $0.16 ≈ $0.36

    成本优化手段: 工程上通常做 Top-K 截断——先用 embedding 相似度筛选出最相关的 K 个社区参与 Map,而不是遍历全部社区。K=20-30 时,成本降低到全量遍历的 20-30%,同时答案质量下降 <5%。


    四、Benchmark 数据:Graph RAG 到底强在哪

    不谈数据的对比都是耍流氓。以下是 2025-2026 年三组独立 Benchmark 的核心结论:

    4.1 ICLR 2026 GraphRAG-Bench:按任务类型的精确对比

    这是最权威的对比基准,直接回答了"Graph RAG 在什么任务上有效":

    任务类型传统 RAGGraph RAG结论
    简单事实检索 60.9 60.1 基本持平,图谱是额外开销
    复杂推理 42.9 53.4 Graph +10.5 分
    上下文摘要 51.3 64.4 Graph +13.1 分

    规律很明显:问题越需要跨文档推理,Graph RAG 的优势越大。简单事实查询,两者没区别。

    4.2 微软原始论文:全局理解能力

    微软在百万 token 级别的数据集上测试"需要理解整个语料库"的问题,用 LLM 做裁判:

    • 全面性(Comprehensiveness):Graph RAG 在 72%-83% 的对比中胜出
    • 多样性(Diversity):Graph RAG 在 62%-82% 的对比中胜出

    这个数据说明 Graph RAG 在"理解全局"这件事上是碾压级的优势。

    4.3 多跳检索 Benchmark:Recall@5 提升 19.6pp

    在 MuSiQue、HotpotQA、2WikiMultiHopQA 三个标准多跳问答数据集上:

    • 传统 RAG 平均 Recall@5:73.4%
    • Graph-guided 平均 Recall@5:87.8%
    • 最大提升出现在跨文档 hardest sets:MuSiQue +31pp,2Wiki +28pp

    Hippo RAG(另一种图增强方案)报告在多跳 QA 上准确率提升 20%,同时成本降低 10-20 倍、速度提升 6-13 倍。

    4.4 密歇根州立 + Meta 的对照实验

    2025 年最严谨的对照实验——统一 chunking、embedding 和生成条件,对比传统 RAG 和四种 Graph RAG 方案:

    • 单跳事实查询(Natural Questions):传统 RAG F1 64.8 vs 最优 Graph 63.0——传统 RAG 略优
    • 多跳推理(MultiHop-RAG):Graph 70.3 vs 传统 67.0——Graph 胜出

    结论:Graph RAG 不是通用升级,是专用升级。它在需要跨文档推理的问题上有效,在简单事实查询上没有优势。


    五、开源生态全景:5 个主流方案对比

    微软的 GraphRAG 点燃了方向,但社区没有止步。目前围绕 Graph RAG 已经形成了完整的开源生态:

    方案Star核心特色解决的问题适合场景
    微软 GraphRAG 31K+ 标准范式定义者,Global/Local/Drift 三模式 概念完整,效果最强 追求效果上限,预算充足
    LightRAG 29.3K 双层检索+增量更新+多模态 原版太重太贵,不支持增量 生产环境首选,性价比最优
    nano-graphrag 3.9K 极简实现,~800 行核心代码 原版代码量大,难读懂 学习原理、快速原型
    Fast-GraphRAG 3.7K PageRank 图探索+智能适应+可解释 检索不可解释、不适应场景 需要可解释性和动态适应
    Youtu-GraphRAG ICLR'26 垂直统一代理架构,工业级实践 复杂推理场景的工业部署 大厂工业级部署参考

    选型建议:

    • 学习原理:从 nano-graphrag 入手,800 行代码看懂核心逻辑
    • 生产环境:首选 LightRAG——支持增量更新、成本更低、双层检索更灵活
    • 追求效果上限:用微软原版,但要做好成本预算
    • 开箱体验:Kotaemon(25K Star)集成了三种 GraphRAG 实现,不写代码就能对比效果

    六、代码实战:从安装到运行

    6.1 完整安装部署步骤

    环境要求: Python 3.10+,建议 3.11/3.12。需要 OpenAI API Key 或其他兼容 LLM 的访问权限。

    # 创建虚拟环境
    python -m venv graphrag-env
    source graphrag-env/bin/activate # Linux/Mac
    # graphrag-env\\Scripts\\activate # Windows

    # 方案一:安装 nano-graphrag(学习/原型)
    pip install nano-graphrag

    # 方案二:安装 LightRAG(生产推荐)
    pip install lightrag-hku

    # 方案三:安装微软 GraphRAG
    pip install graphrag

    # 设置 API Key(以 OpenAI 为例)
    export OPENAI_API_KEY="sk-your-key-here"
    export OPENAI_API_BASE="https://api.openai.com/v1" # 可选,用于代理

    配置 Neo4j 图数据库(生产环境推荐):

    # Docker 部署 Neo4j
    docker run -d \\
    –name neo4j \\
    -p 7474:7474 -p 7687:7687 \\
    -e NEO4J_AUTH=neo4j/password123 \\
    -e NEO4J_PLUGINS='["apoc"]' \\
    neo4j:5.20

    # 验证连接
    # 浏览器访问 http://localhost:7474

    6.2 nano-graphrag 完整示例

    nano-graphrag 是 Graph RAG 的极简实现,核心代码约 800 行,非常适合理解原理:

    import asyncio
    from nano_graphrag import GraphRAG, QueryParam
    from nano_graphrag.base import BaseGraphStorage

    # ========== Step 1: 初始化 ==========
    rag = GraphRAG(
    working_dir="./dickens", # 工作目录,存储索引和缓存
    model_max_token_size=8000, # LLM 最大输入 token
    chunk_token_size=600, # 分块大小(推荐 300-800)
    chunk_overlap_token_size=100, # 分块重叠
    entity_extract_max_gleaning=1, # 实体抽取轮次(>1 可提升召回)
    )

    # ========== Step 2: 索引文档 ==========
    # 读取文档
    with open("./book.txt", encoding="utf-8") as f:
    book = f.read()

    # 执行索引:自动完成分块 → 实体抽取 → 建图 → 社区检测 → 摘要
    rag.insert(book)
    # 首次索引会打印进度:
    # [Entity Extraction] Processing chunk 1/128 …
    # [Community Detection] Detected 23 communities at level 0
    # [Summarization] Generating summaries for 23 communities …

    # ========== Step 3: 查询 ==========
    # Global Search(全局查询)
    answer_global = rag.query(
    "What are the main themes in the story?",
    param=QueryParam(mode="global")
    )
    print("=== Global Search ===")
    print(answer_global)

    # Local Search(局部查询)
    answer_local = rag.query(
    "What is the relationship between Oliver and Fagin?",
    param=QueryParam(mode="local")
    )
    print("=== Local Search ===")
    print(answer_local)

    关键参数说明:

    参数默认值说明
    chunk_token_size 600 分块大小。太小丢失上下文,太大抽取质量下降
    entity_extract_max_gleaning 1 抽取轮次。设为 2 可多轮检查遗漏,但成本翻倍
    model_max_token_size 8000 LLM 上下文窗口。决定单次能处理的摘要量

    6.3 LightRAG 完整示例(含增量更新)

    LightRAG 是生产环境首选,核心优势是支持增量更新和双层检索:

    from lightrag import LightRAG, QueryParam
    from lightrag.llm import openai_complete_if_cache, gpt_4o_mini_complete

    # ========== Step 1: 初始化 ==========
    rag = LightRAG(
    working_dir="./output",
    llm_model_func=openai_complete_if_cache, # LLM 函数
    llm_model_name="gpt-4o", # 主模型
    embedding_func=None, # 默认使用 OpenAI embedding
    # 可选:指定图存储后端
    # graph_storage="Neo4jStorage",
    # graph_storage_url="bolt://localhost:7687",
    )

    # ========== Step 2: 首次索引 ==========
    # 单文档索引
    rag.insert("Graph RAG is a retrieval method based on knowledge graphs…")

    # 批量文档索引
    documents = [
    "Microsoft released GraphRAG in 2024, using LLM-based entity extraction…",
    "LightRAG was developed to address the limitations of the original GraphRAG…",
    "The Leiden algorithm is used for community detection in knowledge graphs…",
    ]
    rag.insert(documents)

    # ========== Step 3: 四种查询模式 ==========
    # Naive(朴素模式,类似传统 RAG)
    result_naive = rag.query(
    "What is Graph RAG?",
    param=QueryParam(mode="naive")
    )

    # Local(局部检索)
    result_local = rag.query(
    "What are the key components of Graph RAG?",
    param=QueryParam(mode="local")
    )

    # Global(全局检索)
    result_global = rag.query(
    "What are the main advantages of graph-based retrieval methods?",
    param=QueryParam(mode="global")
    )

    # Hybrid(混合检索,推荐)
    result_hybrid = rag.query(
    "How does LightRAG improve upon Microsoft GraphRAG?",
    param=QueryParam(mode="hybrid")
    )

    # ========== Step 4: 增量更新 ==========
    # 这是 LightRAG 的核心优势:新文档不需要重建整个图谱
    # 只需要对新文档做实体抽取,然后合并到已有图谱
    new_documents = [
    "In 2025, Youtu-GraphRAG introduced a unified agent architecture…",
    "Fast-GraphRAG uses PageRank for graph exploration…",
    ]

    # 增量插入:只处理新文档,已有实体做合并
    rag.insert(new_documents)
    # 内部流程:
    # 1. 对新文档做实体/关系抽取
    # 2. 检查已有图谱中是否已存在相同实体
    # 3. 新实体加入图谱,已有实体更新连接
    # 4. 仅对受影响的社区重新检测 + 重新摘要

    # 查询验证增量更新后的图谱
    result_updated = rag.query(
    "What are the latest developments in Graph RAG ecosystem?",
    param=QueryParam(mode="global")
    )
    print(result_updated)

    6.4 实体抽取 Prompt 完整示例

    以下是 Graph RAG 实体抽取的核心 Prompt 模板(基于微软原版优化):

    ENTITY_EXTRACTION_PROMPT = """
    -Goal-
    Given a text document that is potentially relevant to this activity and a list
    of entity types, identify all entities of those types from the text and all
    relationships among the identified entities.

    -Steps-
    1. Identify all entities. For each identified entity, extract the following
    information:
    – entity_name: Name of the entity, capitalized, in the same language as text
    – entity_type: One of the following types: [{entity_types}]
    – entity_description: Comprehensive description of the entity's attributes
    and activities

    2. From the entities identified in step 1, identify all pairs of (source_entity,
    target_entity) that are *clearly related* to each other.
    For each pair of related entities, extract the following information:
    – source_entity: name of the source entity, as identified in step 1
    – target_entity: name of the target entity, as identified in step 1
    – relationship_description: explanation as to why the source entity and the
    target entity are related to each other
    – relationship_strength: a numeric score indicating strength of the
    relationship between the source entity and target entity (1-10)

    3. Return output as a single list of all the entities and relationships
    identified in steps 1 and 2. Use **{record_delimiter}** as the list
    delimiter.

    4. When finished, output {completion_delimiter}

    ######################
    -Examples-
    ######################
    Example 1:
    Entity_types: [PERSON, ORGANIZATION, PRODUCT, TECHNOLOGY, CONCEPT]
    Text:
    """
    OpenAI released GPT-4o in May 2024. The model was trained by a team including
    Jerry Tworek and Mark Chen. GPT-4o supports text, image, and audio inputs.
    Sam Altman, as CEO of OpenAI, announced the model at the Spring Update event.
    """
    Output:
    ("entity"{tuple_delimiter}"PERSON"{tuple_delimiter}"JERRY TWOREK"{tuple_delimiter}
    "GPT-4o research team member at OpenAI")
    {record_delimiter}
    ("entity"{tuple_delimiter}"PERSON"{tuple_delimiter}"MARK CHEN"{tuple_delimiter}
    "GPT-4o research team member at OpenAI")
    {record_delimiter}
    ("entity"{tuple_delimiter}"PERSON"{tuple_delimiter}"SAM ALTMAN"{tuple_delimiter}
    "CEO of OpenAI")
    {record_delimiter}
    ("entity"{tuple_delimiter}"ORGANIZATION"{tuple_delimiter}"OPENAI"{tuple_delimiter}
    "AI research company, creator of GPT-4o")
    {record_delimiter}
    ("entity"{tuple_delimiter}"PRODUCT"{tuple_delimiter}"GPT-4O"{tuple_delimiter}
    "Multimodal AI model released in May 2024")
    {record_delimiter}
    ("relationship"{tuple_delimiter}"JERRY TWOREK"{tuple_delimiter}"OPENAI"{tuple_delimiter}
    "Jerry Tworek is a researcher at OpenAI"{tuple_delimiter}8)
    {record_delimiter}
    ("relationship"{tuple_delimiter}"SAM ALTMAN"{tuple_delimiter}"OPENAI"{tuple_delimiter}
    "Sam Altman is the CEO of OpenAI"{tuple_delimiter}10)
    {record_delimiter}
    ("relationship"{tuple_delimiter}"OPENAI"{tuple_delimiter}"GPT-4O"{tuple_delimiter}
    "OpenAI created and released GPT-4o"{tuple_delimiter}9)
    {completion_delimiter}

    ######################
    -Real Data-
    ######################
    Entity_types: [{entity_types}]
    Text:
    \\"\\"\\"{input_text}\\"\\"\\"
    Output:
    """

    # 使用示例
    def extract_entities(text, entity_types="PERSON,ORGANIZATION,PRODUCT,TECHNOLOGY,CONCEPT,EVENT"):
    """对单个文本块执行实体抽取"""
    prompt = ENTITY_EXTRACTION_PROMPT.format(
    entity_types=entity_types,
    tuple_delimiter="<|>",
    record_delimiter="##",
    completion_delimiter="<|COMPLETE|>",
    input_text=text,
    )
    response = llm.invoke(prompt)
    return parse_entities(response)

    6.5 社区摘要生成示例

    COMMUNITY_SUMMARY_PROMPT = """
    You are an AI assistant tasked with generating a comprehensive summary of a
    community in a knowledge graph.

    Given the following entities and relationships that belong to the same community,
    generate a detailed summary that captures:

    1. Key entities and their roles
    2. Important relationships and their nature
    3. The overarching theme or topic of this community
    4. Any notable patterns or insights

    ## Entities in this community:
    {entities}

    ## Relationships in this community:
    {relationships}

    ## Source text chunks that contributed to this community:
    {source_chunks}

    Please provide a structured summary in the following format:

    **Community Title:** [A concise, descriptive title]
    **Summary:** [2-3 paragraph overview]
    **Key Entities:** [List of most important entities with brief descriptions]
    **Key Relationships:** [Most significant relationships and their implications]
    **Theme:** [The overarching theme connecting all entities in this community]
    """

    def generate_community_summary(entities, relationships, source_chunks):
    """为单个社区生成摘要"""
    prompt = COMMUNITY_SUMMARY_PROMPT.format(
    entities=format_entities(entities),
    relationships=format_relationships(relationships),
    source_chunks="\\n—\\n".join(source_chunks),
    )
    summary = llm.invoke(prompt, max_tokens=1000)
    return summary


    七、工程落地:成本、选型与踩坑

    7.1 成本对比:Graph RAG vs 传统 RAG

    Graph RAG 的最大争议就是成本。索引阶段需要 LLM 逐个处理每个文本块做实体抽取——这意味着 1000 个文本块就要调用 1000 次 LLM。

    建图成本对比
    环节传统 RAGGraph RAG差异
    文本分块 无 LLM 调用 无 LLM 调用 相同
    Embedding ~$0.02/1M tokens ~$0.02/1M tokens 相同
    实体抽取 ~$5-15/1000 文档(GPT-4o) 主要成本
    社区检测 计算成本(无 LLM 费用) 可忽略
    社区摘要 ~$2-8/100 社区(GPT-4o) 中等成本
    索引总成本 ~$0.02/千文档 ~$7-20/千文档 Graph 贵 350-1000x
    查询成本对比
    查询模式传统 RAGGraph RAG差异
    简单查询 ~$0.003/query ~$0.005/query(Local) 基本持平
    全局查询 不支持 ~$0.10-0.50/query(Global) Graph 独有能力
    混合查询 ~$0.005/query ~$0.02-0.10/query Graph 贵 4-20x
    不同数据规模下的 Token 消耗对比
    数据规模文档数文本块数实体抽取 Token社区摘要 Token总索引 Token预估成本(GPT-4o)
    小型 ~100 ~500 ~1.5M input + 0.3M output ~0.1M input + 0.05M output ~1.95M $5-8
    中型 ~1000 ~5000 ~15M input + 3M output ~1M input + 0.5M output ~19.5M $50-80
    大型 ~5000 ~25000 ~75M input + 15M output ~5M input + 2.5M output ~97.5M $250-400
    超大 ~20000 ~100000 ~300M input + 60M output ~20M input + 10M output ~390M $1000-1600

    降本策略:

    • 实体抽取用便宜模型(如 GPT-4o-mini),查询响应用强模型(GPT-4o)。成本降低 70-80%
    • 微软后续版本已将 token 成本降低约 77%(优化了 Prompt 模板和抽取流程)
    • LightRAG 通过减少 LLM 调用次数(去重抽取 + 增量更新)进一步降低成本
    • 使用开源模型(如 Qwen2.5-72B、DeepSeek-V3)本地部署,可消除 API 成本

    7.2 什么时候该用 Graph RAG

    不是所有场景都需要 Graph RAG。以下决策框架:

    场景特征推荐方案原因
    事实查询为主("XX 是什么") 传统 RAG Graph RAG 无优势,额外成本不值得
    需要多跳推理("A 和 B 的关系") Graph RAG 图谱的关系遍历天然适合多跳
    需要全局理解("主要趋势是什么") Graph RAG(Global Search) 传统 RAG 几乎无法处理
    需要可解释性(医疗/法律/金融) Graph RAG 图谱路径可追溯,回答有来源链
    数据量小(<100 文档) 传统 RAG 够用 Graph RAG 的建图成本不划算
    混合场景 传统 RAG + Graph RAG 混合 Kotaemon 的方案:按问题类型自动路由

    7.3 增量更新方案对比

    文档不是静态的——知识库会持续增长。增量更新是 Graph RAG 从 Demo 走向生产的关键能力。

    方案更新策略优点缺点适用场景
    全量重建(微软原版) 每次新增文档都重建整个图谱 实现简单,一致性最好 成本随数据量线性增长,大文档不可用 数据量<1000 文档
    增量合并(LightRAG) 只对新文档做抽取,合并到已有图谱 成本低,速度快 可能产生实体不一致(同一实体的不同表述) 数据量持续增长的生产环境
    定时全量 定期(如每周)全量重建 保证一致性 中间时段可能有质量问题 对一致性要求高、数据变化不频繁
    差分更新 检测文档变更,只重建受影响的部分 理论和实践最优 实现复杂,需要追踪文档-实体映射关系 文档有明确版本管理的场景

    LightRAG 增量更新的具体机制:

    1. 新文档 → 分块 → 实体/关系抽取
    2. 对每个抽取的实体,在已有图谱中查找是否存在
    – 存在:合并连接(新关系加入已有节点)
    – 不存在:创建新节点
    3. 对受影响的社区重新执行 Leiden 检测
    4. 仅对变更的社区重新生成摘要

    7.4 Global Search 延迟优化实践

    Global Search 的延迟是最常见的性能瓶颈。以下是生产环境中的优化策略:

    优化策略延迟影响实现难度说明
    Top-K 社区截断 延迟降低 60-80% 用 embedding 相似度筛选最相关的 K 个社区,K=15-25
    摘要预缓存 延迟降低 30-50% 社区摘要在索引阶段已生成,查询时直接读取
    并行 Map 调用 延迟降低 50-70% 多个社区的 Map 阶段并发执行
    分层摘要缓存 延迟降低 40-60% Level 0 粗粒度摘要用于快速筛选,Level 1 用于精确定位
    结果缓存 命中时延迟降低 90%+ 对相似问题缓存 Global Search 结果,TTL 过期机制

    实测优化效果(100 个社区,1000 篇文档):

    优化方案平均延迟P95 延迟说明
    无优化(全量遍历) ~25s ~45s 每次查询遍历所有 100 个社区
    Top-K=20 截断 ~6s ~10s 只取最相关的 20 个社区
    Top-K=20 + 并行 ~3s ~5s 20 个社区并行 Map
    Top-K=20 + 并行 + 缓存 ~1.5s ~5s 缓存命中率约 30%

    八、与传统 RAG 的融合:混合架构才是终局

    Graph RAG 和传统 RAG 不是替代关系,是互补关系。生产环境的最优解是混合架构:

    ① 问题路由层: 用户问题进来后,先判断问题类型——事实查询走传统 RAG(向量检索),推理/全局问题走 Graph RAG(图谱检索)。

    ② 双路检索层: 传统 RAG 用向量相似度找文本块,Graph RAG 用实体遍历找关系链。两路结果合并去重。

    ③ 融合生成层: LLM 同时接收向量检索的文本块和图谱检索的关系链,生成最终回答。

    Kotaemon 已经在工程上验证了这个方案——同时集成传统向量检索和三种 Graph RAG 实现,系统根据问题类型自动选择最优路径。

    架构师法则: 不要为了用 Graph RAG 而用 Graph RAG。先用传统 RAG 把基础做好(分块策略、Embedding 模型、Reranker),当遇到传统 RAG 确实解决不了的问题类型时,再引入 Graph RAG 作为增强层。90% 的场景,传统 RAG + 混合检索 + Reranker 已经足够了。


    九、性能调优 Checklist

    一份经过实战验证的 Graph RAG 调优清单:

    索引阶段调优

    调优项推荐值/策略说明
    分块大小 300-800 token 太小丢失跨句关系,太大抽取质量下降
    实体抽取模型 GPT-4o / Claude 3.5 需要强指令遵循能力,弱模型质量骤降
    实体类型定义 领域特定、明确列举 通用 Prompt 比定向 Prompt 低 20-30% F1
    实体消歧 开启 LLM 二次判断 同名异义实体的合并/拆分需要额外确认
    分块重叠 50-150 token 有助于保留跨块的共指关系
    抽取轮次 1-2 轮 2 轮提升召回但成本翻倍,大规模场景建议 1 轮

    查询阶段调优

    调优项推荐值/策略说明
    Global Search Top-K 15-30 个社区 平衡成本和质量,K 过大会引入噪声
    Local Search 跳数 1-2 跳 超过 2 跳噪声急剧增加
    Local Search 邻居数 5-10 个/跳 控制上下文 token 量
    问题路由 分类器 + 规则混合 简单查询不经过 Graph RAG,节省成本
    结果缓存 TTL 5-30 分钟 适合全局性问题,局部性问题按需评估

    成本控制

    调优项推荐策略说明
    索引阶段降本 实体抽取用 GPT-4o-mini 成本降低 70-80%,质量下降 5-10%
    查询阶段降本 查询响应用 GPT-4o 这一步不能省,直接影响回答质量
    增量更新 LightRAG 方案 避免全量重建的成本
    本地部署 Qwen2.5-72B / DeepSeek-V3 适合数据敏感场景,消除 API 成本

    十、总结

    Graph RAG 不是传统 RAG 的替代品,而是它缺失的那一层——结构化的知识层。它解决了传统 RAG 三个根本性问题:跨文档推理、全局理解、知识可追溯性。

    核心要点回顾:

    • 传统 RAG 的结构性天花板在于"切块切断关系"和"只有相似度没有结构"——Graph RAG 用知识图谱重建了碎片之间的关系网络
    • Graph RAG 的优势集中在复杂推理和全局理解任务上(+10-13 分),在简单事实查询上和传统 RAG 持平
    • 实体抽取是质量天花板,Leiden 社区检测是效率关键,Map-Reduce 是全局查询的核心机制
    • 开源生态已经成熟:nano-graphrag 适合学习,LightRAG 适合生产,微软原版适合追求效果上限
    • 成本是最大争议点——索引成本比传统 RAG 高 350-1000 倍,但可以通过模型分层、增量更新、本地部署降本
    • 生产环境的最优解是混合架构:传统 RAG 处理事实查询,Graph RAG 处理推理和全局问题
    • 不要为了用 Graph RAG 而用 Graph RAG——先把传统 RAG 做好,Graph RAG 是增强层不是替代品

    📌 下一篇预告

    到此,「深入理解 AI Agent」第一阶段 RAG 深度四篇全部完成。从 RAG 基础原理、混合检索实战、评估体系到 Graph RAG,检索增强这条线已经彻底打通。

    接下来进入 MCP 专题系列,从协议规范到工程落地,系统拆解这个正在成为 Agent 连接外部世界标准协议的底层逻辑。

    — 深入理解 AI Agent 系列 · 第 4 篇 —

    有问题评论区见,欢迎交流~

    赞(0)
    未经允许不得转载:171主机测评 » 深入理解 AI Agent 04|GraphRAG
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址