0%

GraphRAG 与普通 RAG 的应用分析

企业在搭建知识库问答系统时,经常面临一个选择:用普通的向量检索 RAG,还是用微软提出的 GraphRAG?两者的技术路线差异很大,适用场景也不同。选错了方案,要么检索精度不够,要么工程复杂度过高。这篇文章从实际应用场景出发,分析两种方案各自的能力边界和最佳使用时机。

普通 RAG 的实际能力范围

RAG(Retrieval-Augmented Generation)的核心机制可以概括为:文档切 Chunk,做向量 Embedding 存入向量数据库;用户查询时,将 Query 向量化,通过语义相似度检索 TopK 个 Chunk,喂给大模型生成答案。这套机制的本质是文本片段的相似度匹配,它能做好的事情和做不好的事情,边界非常清晰。

普通 RAG 最擅长的是单点事实类问题,即答案完整地存在于某个 Chunk 里的查询。比如”接口超时时间是多少””产品支持哪些功能””GPT-4 什么时候发布”这类事实性问题。只要答案在某个 Chunk 里写得明明白白,普通 RAG 基本都能精准召回。这类问题占据了企业知识库 70% 以上的查询量,也是 RAG 架构最稳固的基本盘。

它真正做不到的事

普通 RAG 的短板在于,它只能找到片段,但不一定能把片段之间的关系连起来。来看一个真实场景:用户输入一个多条件查询,想找一款适合拍视频、续航不错、而且用户评价稳定的手机。普通 RAG 可能召回 Chunk A”XX 手机影像系统强大,视频拍摄能力突出”、Chunk B”XX 手机电池 5500mAh,续航表现优秀”、Chunk C”用户评价:用了半年,系统稳定”。问题在于,A、B、C 可能来自三篇不同的文档,描述的是三款不同的手机。普通 RAG 把三个 Chunk 一起扔给大模型,大模型也不知道到底哪款手机同时满足这三个条件。

这就是普通 RAG 的根本局限:它的检索单元是文本片段,不是实体,更不是关系。它擅长”找到相似的文字”,不擅长”找到满足多个关系约束的答案”。这个局限在以下四类场景中会变得无法回避。

多维度关联查询

多维度关联查询不是简单的多条件过滤。多条件过滤是 价格 < 5000 AND 品牌 = 华为,这是 SQL 能干的事。多维度关联查询指的是:多个维度之间存在结构化的关系,需要沿着关系做导航和交集运算。

商品推荐系统是一个典型场景。商品知识不是一张扁平的表,而是一个关系网络:每款商品连接着品牌、价格段、核心卖点、适用人群、用户口碑等多个属性节点。用户输入”有没有适合拍视频、性能强、口碑稳定的旗舰机”,普通 RAG 的做法是在文本里模糊匹配,分别召回”影像强””性能强””口碑好”的片段,最后让大模型自己猜。GraphRAG 的做法是把知识建成图,然后沿着关系边做导航:找到”影像旗舰”节点、”性能旗舰”节点、”用户口碑稳定”节点,取它们关联的商品实体的交集。这不是语义相似度的问题,而是图遍历的问题。

失效的根本原因在于检索空间的错配。普通 RAG 的检索空间是向量空间,衡量的是两段文本像不像;而多维度关联查询需要的检索空间是关系空间,需要沿着实体关系做路径查找。两个完全不同的空间,用错工具效果天差地别。

全局总结与隐性关系发现

全局总结类问题问的不是某个点,而是整体。比如”最近几年高端手机的发展趋势””目前 AI Agent 行业的技术格局””公司各部门的业务关联情况”。这类问题的答案是分散在整个语料库中的,不在任何一个 Chunk 里。普通 RAG 召回的 TopK 个最相似 Chunk 往往是碎片化的:Chunk 1 讲影像,Chunk 2 讲芯片,Chunk 3 讲价格,Chunk 4 讲 AI 功能。大模型拿到这些碎片化的信息只能硬拼,最后生成一个面面俱到但毫无洞察的答案,读起来像目录,不像分析。

GraphRAG 通过社区发现和分层摘要来解决这个问题。它的做法分三步:第一步用社区发现算法(如 Leiden 算法)把知识图谱划分成若干个语义社区,每个社区内的实体关系紧密,社区之间相对松散;第二步对每个社区分别做摘要生成局部摘要;第三步把所有局部摘要汇总生成全局视图。这个分层摘要机制天然适合回答”整体趋势””行业格局”这一类问题,因为它不是从碎片拼凑,而是从结构化的社区出发,每个社区有自己的主题和洞察,合并起来就是全局视图。

另一类普通 RAG 无能为力的问题是隐性关系发现。两个实体之间,文本里从来没有直接说明它们有关系,但通过中间节点可以推断出关联。比如产品 A 和产品 B 从来没有被任何文档直接比较过,但它们的属性高度重叠:价格段都是高端,目标人群都是商务用户,核心能力都是影像。在图结构里,产品 A 和产品 B 虽然不直接相连,但它们共享了多个相同的邻居节点,这种结构上的接近性就是隐性关系。普通 RAG 的检索基于 Query 和 Chunk 的语义相似度,如果没有任何文档把产品 A 和产品 B 放在同一段文字里,就完全没有办法发现它们之间的联系。

依赖隐性关系发现的业务场景其实相当广泛。竞品分析中需要发现没有被直接对比但实质上高度重叠的产品,风控排查中需要从多个看似无关的账户通过中间节点发现它们共享同一控制人,药物研发中需要发现两种没有被同一篇论文提及但通过通路网络发现处于同一信号通路的靶点蛋白。这些都是普通 RAG 根本做不到的事,因为它的信息组织单位是文本片段,不是实体关系图。

分散信息的因果链追溯

有些问题的答案需要从多个文档中串联多条信息才能推导出根因。典型的例子是”XX 项目延期的根本原因分析”,真实的答案可能分散在:需求文档里记录了中期发生的重大需求变更,排期表显示关键开发人员被借调到其他项目,研发周报提到接口联调出现了预期外的问题,测试反馈指出某个第三方 SDK 有 Bug 阻塞了测试进度,客户沟通记录显示客户在验收阶段新增了功能点。

普通 RAG 最可能召回的是某一篇文档中的一个片段,比如会议纪要里的一句话:”本次会议确认项目延期两周,主要原因是需求变更。”这个答案不算错,但不完整。真正的根因是多个因素叠加的结果,只看其中一个会误导决策。

GraphRAG 把人、需求、任务、时间、风险、依赖关系全部建模成图的节点和边。从”项目延期”这个现象出发,沿着关系边可以追溯到多条因果路径:需求变更影响了任务 A 进而阻塞了任务 B 最终导致延期,开发人员借调导致任务 A 人力不足引发延期,SDK Bug 导致联调阻塞造成延期,客户新增需求导致验收阶段返工带来延期。这是图上的多路径汇聚问题,不是文本相似度能解决的。

为什么不能无脑上 GraphRAG

讲完 GraphRAG 擅长解决的问题,必须正视它的工程代价。GraphRAG 的索引阶段和普通 RAG 完全不在一个量级。

环节 普通 RAG GraphRAG
文档处理 切 Chunk 实体抽取 + 关系抽取
索引构建 向量 Embedding 图构建 + 社区发现 + 每社区摘要
LLM 调用量 低(只做 Embedding) 极高(抽取、摘要都在调 LLM)
索引时间 分钟级 小时级甚至天级(视语料规模)
查询延迟 毫秒到秒级 秒级到十秒级(遍历 + 合成)
存储成本 向量数据库 图数据库 + 向量库 + 摘要存储

举个量化的例子:一份 100 万 Token 的企业知识库,普通 RAG 的索引成本可能只需要几美元的 Embedding 费用。而 GraphRAG 的索引阶段(实体抽取、关系抽取、社区摘要)可能需要几十甚至上百美元的 LLM 调用费用。这还没有算查询阶段的开销,每次查询 GraphRAG 需要遍历更多节点、读取更多关系、合成更长的上下文,这些都是 Token 成本。

如果你的场景 80% 以上都是简单事实类问题,上 GraphRAG 就是过度设计。花钱更多,延迟更高,简单问题的回答质量可能还更差。

混合路由架构

真正做过线上系统的人,不会在普通 RAG 和 GraphRAG 之间二选一。正确的做法是混合路由:根据查询类型路由到不同的处理引擎,简单事实走普通 RAG,结构化查询走 SQL,关系推理和全局总结走 GraphRAG,最后统一做答案合成。

Query Router 是整个混合路由的核心,职责是判断用户问题属于哪一类然后路由到对应的检索引擎。实现方式有三种,从轻到重。第一种是规则路由,基于关键词和句式模式匹配,速度快成本低:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def route_query(query: str) -> str:
# 全局总结类关键词
summary_keywords = ["趋势", "格局", "整体", "总结", "概括", "发展"]
if any(kw in query for kw in summary_keywords):
return "graphrag_summary"

# 结构化查询类关键词
if "多少" in query or "什么时候" in query or "是什么" in query:
return "normal_rag"

# 关系推理类关键词
relation_keywords = ["关联", "影响", "原因", "依赖", "共同"]
if any(kw in query for kw in relation_keywords):
return "graphrag_relation"

return "normal_rag" # 默认走普通 RAG

第二种是 LLM 分类路由,用一个小模型(如 GPT-4o-mini)对 Query 做分类,准确率更高,但有额外延迟和成本:

1
2
3
4
5
6
7
8
9
10
ROUTER_PROMPT = """
请将以下用户问题分类为以下类型之一:
- factual:简单事实查询,答案在某段文本中
- sql:可转为结构化查询的问题
- relation:需要跨实体关系推理的问题
- summary:需要全局总结或趋势分析的问题

用户问题:{query}
类型:
"""

第三种是混合路由,规则优先,规则无法判断时再调 LLM,在成本和延迟之间取得平衡。

路由策略的核心原则是:默认走普通 RAG,只在明确需要时路由到 GraphRAG。大部分查询都是简单事实类问题,GraphRAG 应该是特种部队而非常规军。如果反过来所有问题都走 GraphRAG,成本上去了,延迟上去了,简单问题的准确率反而下降了,因为 GraphRAG 的上下文更长、噪声更多,大模型反而更容易被干扰。

场景与工具对照

问题类型 举例 推荐工具 原因
单点事实 “接口超时时间查询” 普通 RAG / SQL Chunk 里有答案,杀鸡不用牛刀
多条件过滤 “价格 < 5000 的华为手机” SQL / 结构化查询 这是数据库的活
多实体关系推理 “适合拍视频、口碑好的旗舰机” GraphRAG 需要沿关系边做交集
全局趋势 “AI Agent 行业格局” GraphRAG 需要社区摘要机制
隐性关系发现 “两个账户的关联分析” GraphRAG 需要图结构推断
跨文档因果追溯 “项目延期的根因” GraphRAG 需要多路径汇聚
简单对比 “A 和 B 的区别” 普通 RAG 两段文本拼起来就行

技术选型的正确思路不是列举某个技术的优点,而是先说清楚现有方案的能力边界,再说新方案补的是什么,最后在工程上把两者结合起来。能把这个选型逻辑讲清楚,就说明不是在追热点,而是真的做过系统、踩过坑、想清楚了。

扫描二维码分享