AI 工程基础体系 · 第 95/100 篇。内容覆盖机器学习、深度学习与生成式 AI;模型、数据、评测、权限和成本会作为同一生产系统处理。
Graph RAG:实体关系、图构建、社区摘要、检索与适用边界
Graph RAG(Graph Retrieval-Augmented Generation,图增强检索生成)是一类把“文档检索”扩展为“实体—关系—社区检索”的 RAG 架构。它并不是一个单一算法或统一 API,而是将知识图谱、图算法、向量检索和大语言模型组合起来:先从文档中构建图,再根据问题检索相关实体、关系、路径或社区摘要,最后把这些证据交给生成模型回答。
经典 RAG 的基本形式是:给定问题 ,从外部知识库检索上下文 ,再生成答案:
其中 是文档集合。原始 RAG 论文将参数化模型知识与非参数化外部记忆结合起来,外部记忆通常以可检索文档或向量索引实现。Retrieval-Augmented Generation Paper 描述的是这一基本范式,而不是 Graph RAG 的唯一实现。
Graph RAG 将外部知识表示为图:
- :节点集合,通常表示实体,也可以表示文档、事件、时间、指标或主题;
- :边集合,表示实体之间的关系;
- :节点属性,例如实体类型、名称、来源文档、时间范围、权限标签;
- :边属性,例如关系类型、置信度、证据片段、发生时间和来源。
因此,Graph RAG 的检索结果不再只是若干相似文本块,而可能是:
其中分别代表文本片段、实体描述、关系事实、关系路径和社区摘要。
一、为什么向量检索有时不够
向量检索通常将问题和文本块映射为向量:
然后选取相似度最高的若干文本块。它擅长解决“哪段文字讨论了相似主题”,但不天然保证以下关系:
- 多跳关系是否被完整连接;
- 多个文档中的同一实体是否被合并;
- 结果是否覆盖了问题涉及的所有方面;
- 关系方向、时间和条件是否保留;
- 能否回答一个关于整个数据集的综合性问题。
例如,文档中分别出现:
- “赵宁负责支付平台。”
- “支付平台在 2024 年 7 月发生结算延迟。”
- “结算延迟由供应商接口变更引起。”
问题是:“支付平台负责人所负责的系统,为什么发生结算延迟?”
这需要沿着:
进行多跳推理。三个事实可能位于不同文档中,单纯依靠相似度未必会同时检索到它们。Graph RAG 通过显式实体和边保存这种连接。
但这不意味着图检索总是优于向量检索。若问题只是“退款政策的生效日期是什么”,一个包含完整答案的文档块通常比构建图更直接。Graph RAG 的价值来自结构化关系,而不是“使用图”本身。
二、实体、关系与证据
1. 实体不是字符串
实体(entity)是知识中具有身份的对象,例如“支付平台”“赵宁”“供应商接口变更”。字符串只是实体的表面名称:
“苹果”
可能指水果、公司或品牌。实体建模至少应包含:
Entity {
id: "company:apple-inc",
canonical_name: "Apple Inc.",
type: "Organization",
aliases: ["Apple", "苹果公司"],
source_documents: ["doc-17"],
valid_time: ["1976-04-01", null],
access_labels: ["finance"]
}
实体消歧(entity resolution)负责判断两个提及是否指向同一对象。若把“华为云”和“华为”错误合并,后续所有关系都会污染;若同一实体没有合并,则多跳路径会被割断。
2. 关系必须保留方向和语义
边不能只写成无类型的连接:
赵宁 —— 支付平台
至少应表示为:
(赵宁, 负责, 支付平台)
关系通常是有方向的:
关系还应保留限定条件。例如:
(支付平台, 发生故障, 结算延迟,
time="2024-07",
confidence=0.91,
source="doc-2")
如果忽略时间,下面两个事实可能被错误拼接:
- 2023 年由 A 团队维护;
- 2024 年由 B 团队维护。
如果忽略否定,以下句子可能被错误抽取为正向关系:
“支付平台并未受到供应商接口变更影响。”
因此,关系记录通常需要包含:
subject、predicate、object;- 事实发生时间或有效时间;
- 来源文档和原文证据;
- 抽取置信度;
- 否定、条件和适用范围;
- 权限标签;
- 版本或更新时间。
3. 证据优先于模型猜测
图中的一条边不是事实本身,而是“由某个证据支持的事实”。推荐将关系表示为:
其中:
- :起点和终点实体;
- :关系类型;
- :证据片段集合;
- :时间信息;
- :置信度;
- :访问权限。
生成答案时,应能从边回溯到原始文本。否则图摘要可能看起来结构清晰,却无法审计。
三、Graph RAG 的图构建流程
典型构建流程如下:
flowchart LR
A[原始文档] --> B[解析与切分]
B --> C[实体与关系抽取]
C --> D[实体规范化与消歧]
D --> E[事实校验与去重]
E --> F[实体关系图]
F --> G[社区发现]
G --> H[社区摘要]
B --> I[文本块向量索引]
F --> J[图索引]
H --> K[社区摘要索引]
查询时则反向组合多种证据:
flowchart LR
Q[用户问题] --> A[问题分析]
A --> B[实体链接]
A --> C[向量检索]
A --> D[图遍历]
A --> E[社区检索]
B --> F[候选证据融合]
C --> F
D --> F
E --> F
F --> G[权限过滤与去重]
G --> H[上下文压缩]
H --> I[生成模型]
I --> J[带引用答案]
1. 文档解析与切分
首先要处理 PDF、HTML、表格、代码、邮件和扫描件。切分(chunking)不是简单按固定字符数截断:
- 太短会丢失主语、条件和定义;
- 太长会降低检索精度并增加上下文成本;
- 表格需要保留行列关系;
- 标题、章节和文档版本应作为元数据;
- 权限标签必须在切分阶段继承。
一个关系抽取器如果只看到:
“该系统在次年完成迁移。”
却看不到上一段中的“该系统”指代谁,抽取结果就可能不可用。因此,抽取窗口通常需要包含邻近标题和上下文,而不是只传入孤立 chunk。
2. 实体与关系抽取
抽取可以使用规则、传统机器学习、序列标注模型、关系分类模型或大语言模型。
规则方法适合稳定格式,例如:
负责人:赵宁
所属系统:支付平台
监督模型适合有标注数据且领域稳定的场景。大语言模型适合关系类型复杂、文档格式变化大的场景,但必须约束输出 schema,并验证实体是否真实出现在证据中。
一个关系抽取结果可以要求如下结构:
{
"subject": "支付平台",
"predicate": "发生故障",
"object": "结算延迟",
"qualifiers": {
"time": "2024-07"
},
"evidence": "2024年7月,支付平台发生结算延迟。",
"confidence": 0.94
}
只要求模型输出三元组而不要求证据,会导致以下问题:
- 模型补全文本中没有出现的关系;
- 把推测当成事实;
- 无法定位错误来源;
- 无法根据新文档撤销旧事实。
3. 实体规范化与消歧
规范化把不同名称映射到候选实体:
“支付平台”“支付中台”“PayCore”
可能是同一实体,也可能只是上下游系统。常见信号包括:
- 名称和别名;
- 类型是否一致;
- 同现关系;
- 时间和组织范围;
- 文档来源;
- 描述向量相似度;
- 外部主数据或人工确认。
可以将匹配打分写成:
当 高于自动合并阈值时合并,处于中间区间时进入人工审核,低于拒绝阈值时保持独立。阈值不应只按总体准确率设定,因为“错误合并”通常比“暂时未合并”破坏性更大。
4. 去重、冲突与版本
同一个事实可能由多个文档支持:
(支付平台, 负责人, 赵宁)
应保留多个证据,而不是任意覆盖。两个文档出现冲突时,不能简单按抽取置信度选择,还要比较:
- 文档发布时间;
- 文档权威等级;
- 事实有效时间;
- 是否是修订公告;
- 是否属于不同环境;
- 是否存在条件差异。
图数据库中的“当前值”可以用于快速查询,但历史事实和证据仍应保留,否则无法解释答案为何发生变化。
四、社区发现与社区摘要
1. 什么是社区
社区(community)是图中内部连接相对密集、与外部连接相对稀疏的一组节点。它不一定等同于组织部门,也不一定是业务主题;它是由图结构发现的局部群体。
设节点划分为若干社区 。模块度(modularity)是常见的社区质量指标之一:
- :节点 是否有边;
- :节点度;
- :图中边数;
- :节点所属社区;
- :同社区时为 1,否则为 0。
直觉是:如果社区内实际连接数显著高于随机网络期望, 会较高。
实际系统常使用 Leiden 或 Louvain 等社区发现算法。它们是常见实现,不是 Graph RAG 的规范要求。算法、随机种子、边权和分辨率参数都会改变社区结果,因此社区 ID 不应被视为永久稳定的业务主键。
2. 为什么要做社区摘要
局部检索适合回答:
“赵宁负责哪个系统?”
全局问题则不同:
“这些项目反复出现的供应链风险有哪些?”
此时逐条拼接所有边会产生巨大上下文。社区摘要先把一个局部子图压缩为可检索的中间层:
社区:支付与结算稳定性
成员:支付平台、结算服务、供应商接口、赵宁、风控团队
摘要:该社区围绕支付和结算链路展开。主要风险集中在供应商接口变更、
重试策略不足和跨团队变更通知延迟。支付平台由赵宁负责,风控团队参与
异常监控。2024 年 7 月的结算延迟与供应商接口变更有关,但证据未表明
所有支付故障都由该原因导致。
社区摘要的正确作用是降低全局检索成本,而不是替代原始证据。摘要中的每个关键结论都应能映射回成员实体、关系和源文档。
3. 分层社区
大图通常需要递归划分:
公司级社区
├── 交易域
│ ├── 支付社区
│ └── 结算社区
└── 客户域
├── 身份社区
└── 客服社区
底层摘要描述具体事实,上层摘要描述多个子社区之间的共同主题。查询时可以先搜索高层摘要定位区域,再下钻到底层社区和原始证据。
但摘要会引入信息损失。若原始图包含:
A --导致--> B
C --导致--> D
摘要写成“该社区存在多项导致关系”,就丢失了具体映射。对于因果、合规和安全问题,摘要只能作为候选导航,不能作为唯一证据。
五、检索策略:局部、多跳与全局
Graph RAG 没有单一检索器,常见策略需要组合使用。
1. 局部实体检索
先将问题中的提及链接到图中实体,再检索其邻居:
例如 获取直接关系, 获取两跳邻居。优点是精确、可解释;缺点是对实体链接错误敏感,也可能遗漏不在邻域内但语义相关的文本。
2. 路径检索
对于关系问题,检索路径比检索无序节点更有意义:
可以限制:
- 最大跳数 ;
- 允许的关系类型;
- 时间一致性;
- 权限一致性;
- 边置信度;
- 路径是否经过指定实体。
例如“谁负责发生故障的系统”可约束路径模式:
人物 --负责--> 系统 --发生故障--> 故障
这比把“人物”“系统”“故障”三个节点分别召回后交给模型自由拼接更可靠。
3. 语义检索与图检索融合
一个简单融合分数是:
其中:
- :问题与文本或摘要的语义相似度;
- :实体邻近度、路径匹配度或关系覆盖度;
- :来源权威性;
- :与已选证据重复的程度。
向量检索可找到同义表达,图检索可补足结构关系。二者应在权限过滤之后或至少在候选生成阶段携带权限信息,不能先召回秘密文档再靠提示词要求模型忽略它们。
4. 全局检索
全局检索先检索社区摘要,再选择若干社区,最后回溯成员关系和原文。它适合:
- 趋势总结;
- 风险归纳;
- 组织或系统之间的整体关系;
- “主要原因有哪些”这类集合问题。
全局检索的主要风险是摘要偏差。若社区划分错误或摘要遗漏少数但关键事实,最终答案可能看似完整却忽略异常项。
六、一个可运行的最小图检索示例
下面的 Python 示例不依赖外部库,演示实体、关系、邻域检索和证据回溯。它不是完整生产 Graph RAG:关系已由人工写入,社区摘要和大模型生成需要另行接入。
from collections import defaultdict, deque
facts = [
{
"s": "赵宁", "r": "负责", "o": "支付平台",
"evidence": "赵宁负责支付平台。",
"source": "doc-1"
},
{
"s": "支付平台", "r": "发生故障", "o": "结算延迟",
"evidence": "2024年7月,支付平台发生结算延迟。",
"source": "doc-2"
},
{
"s": "结算延迟", "r": "原因", "o": "供应商接口变更",
"evidence": "调查显示,结算延迟与供应商接口变更有关。",
"source": "doc-3"
}
]
graph = defaultdict(list)
for fact in facts:
graph[fact["s"]].append(fact)
# 反向索引只用于查找邻居;输出时仍保留原始方向
graph[fact["o"]].append({
**fact, "s": fact["o"], "o": fact["s"], "reverse": True
})
def neighborhood(start, max_hops=2):
"""返回从 start 出发、最多 max_hops 跳可达的原始事实。"""
queue = deque([(start, 0)])
visited = {start}
result = []
while queue:
node, hops = queue.popleft()
if hops == max_hops:
continue
for edge in graph[node]:
result.append(edge)
nxt = edge["o"]
if nxt not in visited:
visited.add(nxt)
queue.append((nxt, hops + 1))
return result
query_entity = "赵宁"
for edge in neighborhood(query_entity, max_hops=3):
direction = "<-" if edge.get("reverse") else "->"
print(
f'{edge["s"]} {direction} {edge["r"]} {edge["o"]} '
f'[{edge["source"]}] {edge["evidence"]}'
)
在该数据上,输出会包含:
赵宁 -> 负责 支付平台 [doc-1] 赵宁负责支付平台。
支付平台 -> 发生故障 结算延迟 [doc-2] 2024年7月,支付平台发生结算延迟。
结算延迟 -> 原因 供应商接口变更 [doc-3] 调查显示,结算延迟与供应商接口变更有关。
这里反向索引的用途只是让“从对象反查主体”成为可能。例如从“支付平台”可以找到“赵宁负责它”。但是生成提示词时必须保留原始关系方向,否则模型可能把“支付平台负责赵宁”误读为事实。
生产实现还应加入:
- 实体别名到规范实体 ID 的映射;
- 关系类型白名单;
- 时间和权限过滤;
- 边去重;
- 路径数量上限;
- 证据片段长度限制;
- 失败时回退到普通文本检索。
七、端到端数据流中的状态与故障
Graph RAG 不是一次查询完成的静态函数,而是包含离线构建和在线查询两个生命周期。
离线构建状态
DISCOVERED
-> PARSED
-> CHUNKED
-> EXTRACTED
-> RESOLVED
-> VALIDATED
-> INDEXED
-> SUMMARIZED
-> PUBLISHED
每个阶段都应有版本号。例如:
corpus_version = 2025-03-08
extractor_version = relation-model-v4
embedding_version = embed-v2
community_version = leiden-seed-17
如果只更新了文档向量索引而没有更新图,系统就会出现“双重事实”:文本说法已经变化,图中仍保留旧关系。查询结果可能来自不同版本,必须在证据中暴露版本或更新时间。
常见故障路径包括:
- 解析失败:扫描 PDF 没有 OCR,导致实体和关系为空;
- 抽取失败:模型返回非法 JSON,事实被丢弃或错误重试;
- 消歧错误:两个同名实体被合并,形成跨组织错误路径;
- 社区过度切分:全局问题需要跨多个社区,却只命中一个;
- 摘要过时:图已更新,社区摘要未重建;
- 索引部分发布:向量索引已切换,图索引仍是旧版本;
- 权限遗漏:公共实体连接到了用户无权查看的私有证据。
发布时应采用不可变索引版本和原子切换:新图、向量索引、摘要索引全部通过校验后,再将查询入口从旧版本切到新版本。失败时保留旧版本,而不是让查询读取半成品。
在线查询状态
RECEIVED
-> AUTHENTICATED
-> ENTITY_LINKED
-> RETRIEVED
-> AUTHORIZED
-> COMPRESSED
-> GENERATED
-> CITED
权限检查不能只发生在生成前。更安全的顺序是:
- 根据用户身份和租户确定访问范围;
- 在图节点、边、原文证据和社区摘要上执行过滤;
- 对过滤后的候选做路径搜索和上下文拼接;
- 生成答案并附带可访问的引用。
社区摘要尤其容易造成权限旁路。一个摘要可能聚合了多个文档,其中部分内容用户无权访问。解决方法包括按权限域生成摘要,或在摘要中保存成员证据集合并在查询时重新过滤;后者更灵活,但会增加查询成本。
并发更新时,关系抽取任务可能同时写入同一实体。应使用幂等事实键,例如:
重复任务只更新版本或证据列表,不重复产生边。实体合并则需要锁、事务或后续重写任务,否则一部分边指向旧 ID,另一部分边指向新 ID。
八、生成阶段如何避免“图上有边,答案却无依据”
生成模型看到的上下文应同时包含结构和证据:
[路径]
赵宁 --负责--> 支付平台 --发生故障--> 结算延迟
[证据]
doc-1: 赵宁负责支付平台。
doc-2: 2024年7月,支付平台发生结算延迟。
[限定]
doc-3 认为延迟与供应商接口变更有关,未证明所有故障均由此导致。
如果只把路径写成自然语言而不带来源,模型可能把图算法推断出的可达性误当成文档明确陈述。可达性本身只说明:
并不等于文档陈述了某个新的因果关系。例如:
A --管理--> B
B --使用--> C
不能自动推出:
A --使用--> C
这就是图推理的常见反例:路径连接不代表关系可传递。关系是否可传递取决于语义和业务规则。“属于”可能具有传递性,“负责”通常没有;“导致”更不能因为存在两条边就任意传递。
答案生成应区分三类内容:
- 直接事实:原文明确陈述;
- 图上推断:通过允许的规则或路径得到;
- 无法确认:证据不足或存在冲突。
当证据不足时,系统应输出“不足以确认”,而不是让模型用常识补全。引用应尽量指向具体文档和文本片段,而不是只引用抽象社区 ID。
九、评测:不能只看最终答案
Graph RAG 的错误来自多个阶段,因此评测也必须分层。
图构建评测
对实体和关系标注集计算:
- 实体识别 Precision、Recall、F1;
- 实体消歧准确率;
- 关系方向准确率;
- 关系类型 F1;
- 时间、否定和条件字段准确率;
- 证据可定位率。
精确率低表示图中有大量幻觉边;召回率低表示图无法支撑多跳问题。两者不能只用最终答案质量间接推断。
检索评测
对带有证据标注的问题评估:
- Recall@K:正确证据是否进入前 K 个结果;
- nDCG:证据排序质量;
- 路径覆盖率:回答所需的关系是否被完整召回;
- 社区覆盖率:全局问题涉及的社区是否都被找到;
- 权限错误率:是否返回用户无权访问的证据。
生成评测
还需要判断:
- 答案是否被证据蕴含;
- 是否遗漏关键限定条件;
- 引用是否真正支持对应句子;
- 冲突事实是否被识别;
- 是否把推断写成原文事实;
- 延迟、token 消耗和失败率是否可接受。
一个只看“答案像不像正确”的人工评分,无法定位是实体消歧错、社区摘要错,还是生成模型引用错。
十、机器学习、深度学习与生成式 AI 在其中的角色
Graph RAG 可以完全不使用神经网络,例如使用规则抽取、关系数据库和 BFS;也可以使用深度模型完成实体识别、实体链接、嵌入和重排序;生成式 AI 则常用于复杂关系抽取、社区摘要、问题分解和最终回答。
三者的职责应分开:
- 机器学习:从标注数据学习实体或关系分类;
- 深度学习:学习文本表示、实体相似度和候选排序;
- 生成式 AI:生成结构化抽取结果、摘要或答案;
- 图算法:执行社区发现、路径搜索和结构统计;
- 数据库与索引:保存版本、证据、权限和查询状态。
不能因为关系由大语言模型抽取,就把模型输出视为权威数据库事实。模型输出需要 schema 校验、证据校验、置信度处理和人工抽样。
十一、成本与性能取舍
Graph RAG 的成本通常来自四部分:
- 文档解析和 OCR;
- 实体关系抽取;
- 向量、图和社区摘要索引;
- 在线检索、重排序和生成。
抽取阶段可能比普通向量化昂贵,因为一个 chunk 需要识别多个实体和关系。社区摘要更新也不是单条文档更新的常数操作:局部边变化可能改变社区边界,进而使多个层级的摘要失效。
常见的工程取舍是:
- 先用普通向量 RAG 建立基线;
- 只对高价值关系类型建图;
- 只对跨文档和高频实体做消歧;
- 先做局部图检索,再为确有全局问题的领域增加社区摘要;
- 缓存稳定的实体链接和社区摘要;
- 对低置信度事实保留为候选,不进入默认答案路径。
不能直接假定 Graph RAG 一定降低 token 成本。它可能减少原始文本数量,却增加图路径、证据和摘要维护成本;最终收益必须通过召回、答案正确性、延迟和维护成本共同评估。
十二、适用边界与常见误解
Graph RAG 更适合以下问题:
- 答案需要跨文档连接多个实体;
- 关系方向、层级、时间或路径很重要;
- 用户经常提出“谁与谁有关”“通过什么链路影响”的问题;
- 需要解释证据来源和关系链;
- 需要对整个知识集合做社区级归纳。
它通常不是以下场景的首选:
- 事实完整存在于一段短文中的简单问答;
- 数据变化极快且关系抽取无法及时同步;
- 文档几乎没有稳定实体和关系;
- 主要任务是长文档原文定位,而不是关系推理;
- 权限模型极其细粒度,却没有能力对图、摘要和证据同步过滤。
几个常见误解需要明确:
“有知识图谱就等于 Graph RAG。”
知识图谱只是结构化知识存储;只有它参与查询上下文构造和生成流程,才构成图增强 RAG。
“社区摘要是真实知识的压缩副本。”
摘要是生成模型对社区的再表述,可能遗漏、合并或误解事实,必须保留原始证据。
“图路径越长,答案越有价值。”
路径越长,错误边累积越多。若每条边独立正确率为 ,长度为 的路径全部正确的近似概率为:
当 、 时,路径整体正确率约为 。因此多跳检索必须限制关系类型、时间条件和证据质量。
“模型会自动修复错误图。”
模型可能把错误图解释得更流畅,反而掩盖错误。图构建、检索和生成必须分别可诊断。
“向量检索和图检索二选一。”
实际系统通常采用混合检索:向量召回语义相关文本,实体链接定位图节点,图遍历补充关系和路径,社区摘要处理全局问题。
Graph RAG 的核心不是把文本“画成图”,而是把实体身份、关系方向、限定条件、证据来源和社区结构纳入检索过程。它的收益取决于图是否真实、关系是否可审计、社区摘要是否可回溯、权限是否贯穿全链路,以及问题是否确实需要结构化连接。对于不需要关系推理的问题,普通向量 RAG 往往更简单;对于需要多跳、全局和可解释关系的问题,Graph RAG 才能提供单纯相似度检索难以稳定获得的能力。
系列导航与关联阅读
- 系列入口:AI 工程完整学习路线:从机器学习与 Transformer 到 RAG、Agent 和生产治理
- 上一篇:RAG 增量索引:变更捕获、版本、删除、重嵌入和一致性
- 下一篇:Agent 规划与任务分解:ReAct、计划执行、反思和终止条件
官方资料
本文依据研究论文、标准组织与主流框架官方文档重新梳理;正文、示例与工程清单由 WR BLOG 编写。

评论
0 条讨论