六类 RAG 系统架构
比较 Naive、Advanced、GraphRAG、Agentic 四种可互动的 RAG 拓扑,以及 Modular 与 Multimodal 两个家族:检索路径怎么走、证据存在哪个节点、谁决定 prompt 里放什么、每种架构最常在哪里出错。
RAG 不是“向量库 + LLM”的固定模板。问题从单一事实扩展到精确关键词、实体关系、多跳推理以后,检索路径、证据存放的位置和“谁决定 prompt 里放什么”都会变。先把设计问题说清楚:这个问题的证据长什么样,检索要走几步,谁来决定下一步。
想亲手走一遍四种拓扑、注入故障再恢复,打开互动 Lab:/system-design-lab/rag-architecture-families。
有约束的设计问题
一个内部知识助手要回答员工关于产品文档、合同和运维手册的问题。大部分问题是“某个功能怎么配置”;一部分问题带着错误码或合同条款号;还有一些问的是“这批合同里哪些供应商互相关联”或者“要回答这个问题得先查 A 再查 B”。文档每周更新,LLM 和嵌入模型都是托管的模型 API。检索链路应该怎么设计?
这里只比较检索拓扑。微调、嵌入模型训练、评估框架和 prompt 注入防护属于相邻问题。
六个家族,四种拓扑
Gao 等人的综述把 RAG 分成 Naive → Advanced → Modular 三个演进阶段;GraphRAG、Agentic RAG、Multimodal RAG 是三个专门化家族。六个是教学地图,不是六种互斥的类型:改写、混合召回、重排、评估、反思都是这些架构里的组件,不是新的家族。
| 家族 | 检索路径 | 控制方式 | 证据存在哪 | 适合 | 主要代价 |
|---|---|---|---|---|---|
| Naive RAG | 问题向量化 → 向量索引取 top-K → prompt → LLM | 固定,一次走完 | 向量索引 | 单一干净知识库、单个事实 | 相似但无关的片段原样进入 prompt |
| Advanced RAG | 改写 → BM25 与向量并行 → 融合 → 重排 → LLM | 固定,有分支 | 向量索引(BM25 是同一批片段的另一个视图) | 精确词很重要、库大 | 每个问题多两次模型调用;重排可能丢掉正确片段 |
| Modular RAG | 路由器按需组合检索、记忆、评估等模块 | 由路由策略决定 | 取决于组合 | 数据源职责边界清楚 | 路由错了整条链路都错 |
| GraphRAG | 离线抽实体关系建图 → 在线局部或全局检索 → LLM | 按检索模式固定 | 知识图谱 | 实体关系、整批文档概括 | 建图是重批处理;全局检索最贵 |
| Agentic RAG | Agent 拆子问题 → 检索或调工具 → 观察写回记忆 → 再决定 | 动态循环 | 每次请求的工作记忆 | 多跳、含糊、跨来源 | 延迟和成本不稳定;循环要上限 |
| Multimodal RAG | 文本 / 图像 / 表格各自编码 → 融合 → VLM | 固定,有分支 | 各模态索引 | 文本不足以表达证据 | 不同模态的证据难对齐 |
前四行的区别不在“用不用向量库”,而在检索走几步、有没有分支、有没有循环。互动 Lab 只做了 Naive、Advanced、GraphRAG、Agentic 四种,因为 Modular 的路由和迭代模式已经分别出现在 Advanced 和 Agentic 里,Multimodal 则是在 Naive 或 Advanced 的形状上加模态编码器和融合步骤。
1. Naive RAG:一次检索直接生成
三步:建索引时把文档切成片段、用嵌入模型算向量、存进向量索引;提问时把问题算成向量,取距离最近的 K 个片段;再把问题和片段拼成一个 prompt 交给 LLM。
它的弱点也就在这三步里:
- 向量索引只按相似度排序,不判断片段能不能回答问题。问题里有几个常见词,取回的 K 个片段就可能相似度很高但都答非所问。
- 中间没有任何过滤,取回什么 prompt 里就是什么;K 越大,无关片段和重复内容越多。
- 模型可能写出片段里没有的内容。回答必须附带引用的片段,用户才能核对。
- 索引只反映上次构建时的文档。文档改了、索引没重建,回答会自信地引用过期内容。
2. Advanced RAG:检索前改写,检索后重排
在 Naive 的前后各加一段:
- 检索前:改写、扩展或路由问题,例如补全缩写、拆出关键词。原始问题要保留,改写只作为补充。
- 混合召回:关键词检索(BM25)和向量检索并行。稀疏和稠密两路捕捉的是不同的相关性信号:向量会把“错误 E1042”和“错误 E1043”看成几乎一样,只有倒排索引能把精确字符串区分开。
- 融合:两路各返回一批候选,用倒数排名融合(Reciprocal Rank Fusion)合并。每个文档的分数是
1 / (k + 名次)在两路上求和,不需要调参,两路分数也不需要可比。 - 检索后:重排器把问题和每个候选放在一起打分,重新排序并只保留前几个;上下文压缩再把 prompt 缩短。
代价:每个问题多出改写和重排两次模型调用;两个索引从同一批片段构建,必须一起重建。最容易被忽视的故障发生在重排:正确片段在融合清单里排第 2,重排器把它排到第 5,保留数是 3,模型就永远看不到它,而日志里只显示“检索命中”。
3. GraphRAG:离线建图,在线选局部或全局
两条互不相连的路径:
- 离线:把文档切成 text units,用 LLM 从每段里抽出实体、关系和主张,把关系紧密的实体分成社区,为每个社区在多个粒度层级上写报告。结果存成表,向量写进向量库。
- 在线:查询引擎按问题类型选模式。局部检索从问题里认出的实体出发,把图数据和相关原文片段组合成上下文,适合问具体实体的问题。全局检索对所有社区报告做 map-reduce:模型先对每份报告分别给部分回答,再合并,适合“整批文档在讲什么”这类问题,但要读完全部报告,是最贵的模式。DRIFT 检索把社区信息加进局部检索;基础检索就是普通 top-K,用来做对照。
代价与故障:建图每段原文都要调模型,是重批处理,新文档要等下一次建图才出现;抽取器漏掉或合并错的实体,局部检索就没有起点;把单实体问题误判成全局问题,延迟和模型调用次数会是局部检索的很多倍。
4. Agentic RAG:Agent 决定下一步并循环
Agent 不拿整个目标去检索,而是把它拆成小而具体的子问题写进工作记忆;每检索一个子问题或调用一个工具,就把观察结果写回记忆;再重读记忆判断哪些子问题已经有证据、哪些还缺。缺就再来一轮,齐了才核验并回答。它是唯一带控制循环的家族,所以能处理含糊、多跳、跨文档的问题。
必须放在 Agent 之外的三件事:
- 预算:每次请求最多几轮、几次工具调用、多少 token,由外部代码强制执行,Agent 自己不能改。
- 停止条件:计划里写明什么算答完,否则每看到新信息都会再拆一个子问题。
- 权限:工具以提问用户的权限执行,参数来自模型输出,执行前必须校验。
到达上限时用现有证据回答,并把没找到证据的子问题列出来,而不是返回超时或用猜测补上。
Modular 与 Multimodal
Modular RAG 是一个设计空间而不是一条固定路径:检索、记忆、路由、预测、任务适配等模块,按 rewrite-retrieve-read、迭代 retrieve-read、自适应检索等模式组合。面试里说“我用 Modular RAG”没有信息量,要说清路由器按什么决定组合哪些模块。
Multimodal RAG 保留 retrieve-then-generate 的形状,为文本、图像、表格各配一个编码器,检索后先融合再交给视觉语言模型。它的难点是不同模态的证据如何对齐、如何各自保留来源。
故障与恢复
| 家族 | 故障 | 用户看到什么 | 恢复 |
|---|---|---|---|
| Naive | 相似却无关的片段塞满 prompt | 自信但答非所问的回答 | 相似度阈值 + 元数据过滤;减小 K;随回答展示引用 |
| Naive | 文档更新了索引没重建 | 引用已经不存在的旧值 | 文档一变就重建受影响片段;片段带版本;展示索引构建时间 |
| Advanced | 重排器淘汰了正确片段 | 证据明明找到了,回答却没用上 | 记录重排前后清单;保护融合排名靠前的最少几个;用标准答案集评估重排召回 |
| Advanced | 改写把问题改偏 | 系统像没听懂问题 | 原始问题保留为一路输入;把改写后的问题随回答展示 |
| GraphRAG | 抽取器漏掉关键实体 | 关于该实体的问题答不出来 | 对受影响段落重跑抽取;加实体别名;图为空时退回原文检索 |
| GraphRAG | 单实体问题走了全局检索 | 等很久,回答反而更概括 | 先局部后全局;缓存常见全局问题;按更高层级报告回答 |
| Agentic | 循环不收敛 | 一直等不到回答 | 外部强制轮数上限;计划写明停止条件;到上限返回带缺口的回答 |
| Agentic | 外部工具超时或报错 | 一部分内容缺失或被猜出来 | 退避重试一次;失败写进记忆;回答里说明这部分没查到 |
贯穿六个家族的一条原则:回答必须带着产生它的片段、图元素或观察。 没有它们,“回答错了”无法分成检索错和生成错,也就没法修。
怎么选
- 一个干净的知识库、问单个事实、还没测出检索问题:Naive RAG。先建一组能暴露它失误的问题集,测出问题前不要加改写、混合召回或 Agent。
- 错误码、型号、条款号很重要,或者库大到只靠相似度会取回噪音:Advanced RAG。先测召回,再决定重排和压缩的保留数。
- 问实体关系或整批文档在讲什么,文档变化慢到能接受批处理建图:GraphRAG。
- 读完第一批结果才知道下一步查什么,产品能接受延迟和成本波动:Agentic RAG,并配上外部强制的上限和回答前的核验。
回到开头的知识助手:功能配置类问题走 Advanced RAG(错误码要靠关键词一路保住);供应商关联问题走 GraphRAG,每周随文档更新建图;“先查 A 再查 B”的问题走 Agentic RAG,轮数上限设在 Agent 之外。
面试时这样回答
- 先复述约束:问题类型、证据长什么样、文档多久变一次。
- 说检索路径:点名图上的边,例如“关键词检索和向量检索并行再融合,重排后才进 prompt”。
- 说证据存在哪:向量索引、知识图谱,还是这次请求的工作记忆。
- 说代价与一个故障:例如重排可能淘汰正确片段,要记录重排前后的清单并评估召回。
一手证据
- Lewis et al.:Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Gao et al.:Retrieval-Augmented Generation for Large Language Models: A Survey
- Elastic:Reciprocal rank fusion
- Microsoft:GraphRAG Indexing Overview
- Microsoft:GraphRAG Query Engine Overview
- NVIDIA:Agentic RAG
- NVIDIA:Multimodal Retriever