在 AI 应用开发中,RAG(检索增强生成)可以把模型回答与外部数据关联起来,但不会自动消除幻觉或保证知识新鲜度。仅切块并向量检索的基线在部分事实查询中已经足够;它的边界取决于语料结构、问题分布、访问策略和评测设计。
本文将图结构检索作为一种设计选项,而不是普遍的“下一代替代方案”。这里的 “GraphRAG” 泛指基于图的 RAG;Microsoft GraphRAG 是具有特定索引和查询模式的具体实现。
1. 为什么 Naive RAG 会“迷失在文档海”?
在 Naive RAG 架构中,核心逻辑是 Chunking -> Embedding -> Vector Search -> Generation。这种模式在处理“事实提取类”问题(如:“公司去年的营收是多少?”)时表现优异。
但当面临以下挑战时,Naive RAG 往往束手无策:
- 跨文档综合:例如“总结 A 部门和 B 部门在 Q3 季度的战略协同点”可能需要多份文档、实体关联和证据覆盖。Top-K 向量查询可能漏掉来源,但查询拆分或混合检索也可能解决问题。
- 术语歧义与语义冲突:同一个词(如“Apple”)在不同的文档块中可能指代水果,也可能指代公司。单纯的 Embedding 难以在没有全局上下文的情况下进行消歧。
- 长上下文选择:增加文档块可能降低有效证据密度,并出现“Lost in the Middle”现象;实际影响取决于模型、提示、排序和任务。
这些现象说明可以评估结构化表示,并不意味着每个负载都需要知识图谱。
2. GraphRAG:为向量插上“逻辑的翅膀”
图结构 RAG 通常在文本块之外保留实体、关系、来源和可选的社区级摘要。LLM 抽取不是必选项,且应被视为带噪声、可版本化的数据管道,而不是事实真相。
2.1 核心原理解析
在图结构 RAG 中,检索可以组合结构化和非结构化证据:
- 实体与关系抽取:把文本转成候选结构化事实,同时保留来源片段、文档修订、抽取器版本和置信信息。
- 实体消歧与社区:用明确规则及人工或基准评测处理别名;Leiden 等社区检测只是可选分析步骤,不是授权边界。
- 混合检索:在同一租户、对象、用途和留存策略下检索文本与图证据,再引用原始来源,而不是把生成摘要当作证明。
3. 实战:构建轻量级 GraphRAG 管道
下面是一个示意管道。抽取结果是不可信输入:需要校验 schema、保留来源,不能让模型创建的关系授予访问权限或触发副作用。
3.1 定义实体抽取的 Prompt
可使用结构化输出接口,但仍必须在应用代码中校验。编码应由传输层和序列化器处理,而不是依赖额外的转换步骤。
from dataclasses import dataclass
@dataclass(frozen=True)
class CandidateRelation:
head: str
head_type: str
relation: str
tail: str
tail_type: str
source_id: str
source_revision: str
start: int
end: int
# 示意 Prompt。schema、长度、关系白名单、来源片段、租户和文档修订
# 必须在模型之外校验。
EXTRACTION_PROMPT = """从 TEXT 中抽取候选实体和关系。
返回符合应用 schema 的 JSON。不要推断文本中没有的事实,并包含
source_id、source_revision 和字符区间。
TEXT:
{{TEXT}}"""
3.2 向量查询与图谱查询的融合
在查询阶段,我们需要将向量数据库召回的文本片段与图数据库召回的邻居节点进行融合拼接。
async def hybrid_search(query, auth_context, policy):
# 候选检索受租户、对象和用途策略约束。
vector_results = await vector_db.search(
query,
tenant_id=auth_context.tenant_id,
allowed_objects=policy.allowed_objects,
limit=policy.vector_limit,
)
entities = await llm.extract_entities(query)
entities = policy.validate_query_entities(entities)
graph_results = await graph_db.neighbors(
entities=entities,
tenant_id=auth_context.tenant_id,
allowed_objects=policy.allowed_objects,
max_hops=policy.max_hops,
max_edges=policy.edge_limit,
)
evidence = policy.validate_and_merge(vector_results, graph_results)
return policy.build_cited_context(evidence)
4. 常见问题 (FAQ)
Q: 构建 GraphRAG 的成本是不是很高? A: 可能更高,因为抽取、消歧、图存储和摘要刷新都会增加工作量;但倍数取决于模型、语料、批处理、缓存和刷新策略。应针对向量基线测量入库成本、查询延迟、证据覆盖和回答质量。
Q: 如何处理图谱中提取出的重复实体? A: 使用可版本化的消歧策略:规范化标识符,比较别名和类型化属性,要求来源证据,并把不确定合并交给复核。密码学哈希只能为完全相同的规范化字符串生成稳定键,不能证明两个实体相同。
Q: 什么时候不建议使用 GraphRAG? A: 当更简单的基线已经满足召回、事实依据、延迟、成本和维护要求时不必引入图。图可能帮助多跳或语料级问题,但也会增加抽取错误、刷新工作、schema 治理和权限复杂度。
总结
图结构检索是设计选项,不是必然的技术跃迁或“幻觉疗法”。只有在评测切片中证明图证据带来收益时才应采用,并在生产设计中保留来源、租户/对象授权、删除血缘、引用覆盖、拒答和回滚能力。