这篇笔记的目标,不是把
RAG当成一个“给大模型外挂知识库”的流行词简单过一遍,而是把它拆回最核心的工程问题:为什么大模型单靠参数记忆不够、RAG 到底在哪个环节补位、一个能上线的 RAG 系统究竟由哪些模块组成。
这篇内容更偏“整体视图 + 概念辨析 + 工程边界”。它会说明
Naive RAG、Advanced RAG、Modular / Agentic RAG的差异,也会专门交代它和提示词工程、长上下文、微调、向量库之间的关系;向量索引、ANN、混合检索和数据库选型可配合站内那篇向量库笔记一起阅读。
参考资料:
Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
Datawhale - All-in-RAG 第一节 RAG 简介
Microsoft Learn - Build advanced retrieval-augmented generation systems
[TOC]
一、先把一句话定义说清楚:RAG 到底是什么
如果先用一句话概括 RAG,我会写成:
RAG = 在模型生成答案之前,先从外部知识源检索相关上下文,再把这部分上下文和问题一起交给大模型生成答案。
这个定义里最关键的不是 “Generation”,而是中间那个 “Augmented”。
它强调的不是让模型凭空回答,而是:
- 模型本身保留通用语言能力
- 具体事实、专业知识、最新资料放在外部知识库
- 回答问题时先查,再答
- 回答依据尽量来自被检索到的资料,而不是只靠参数记忆硬猜
最早那篇经典论文给出的视角很有代表性,它把知识分成两类:
parametric memory:模型参数里压缩过的知识non-parametric memory:外部可检索、可替换、可更新的知识
所以从本质上说,RAG 不是“让模型更会背书”,而是:
让模型在回答时,具备访问外部知识的能力。
这个思路和“闭卷考试”转成“开卷考试”很像,但更准确一点的说法应该是:
- 模型不是直接翻整本书
- 它先用检索系统找到最相关的几页
- 再基于这些材料组织答案
二、为什么需要 RAG:大模型单靠自己记不住也说不稳
很多人第一次接触 RAG,会默认它只是为了“补充私有知识库”。这当然对,但不完整。
RAG 真正要解决的,是大模型在知识使用上的几个天然短板。
2.1 知识是静态的,不是实时的
大模型训练完成后,它知道的世界基本停留在训练数据截止的时间点。
这意味着:
- 新政策
- 新产品文档
- 公司内部流程
- 当天刚更新的数据库内容
这些知识,模型天然不知道。
如果你不做检索增强,只靠模型参数回答,它最多只能“猜一个像样的答案”,但不能保证它真的见过这份最新资料。
2.2 模型会“像懂了”,但不一定真有依据
大模型最大的问题不是完全不会答,而是会在信息不足时,依然生成一段形式上很完整、语气上很自信、内容上却可能不可靠的话。
这就是为什么很多场景里,真正难的不是“生成”,而是:
- 降低幻觉
- 提高可追溯性
- 让回答能落到具体出处
RAG 的价值就在这里:它试图把“回答依据”从模型脑补,拉回到可检索的原始材料。
2.3 业务知识更新太快,反复微调不现实
如果知识变更频繁,理论上可以不断微调模型,但工程上通常不划算:
- 数据准备成本高
- 训练成本高
- 回归验证成本高
- 更新周期慢
- 微调更擅长改变行为和风格,不一定适合高频灌输事实
相比之下,RAG 更像是把“知识更新”从模型训练问题,转成“索引更新”问题。
这也是它在企业知识库、客服问答、文档助手、代码助手这些场景里非常常见的原因。
2.4 很多场景需要出处,而不是只要答案
在严肃场景里,用户经常不只问:
- 结论是什么
还会继续问:
- 这个结论来自哪一页
- 依据是哪份制度
- 原文具体怎么写
纯生成模型在这里天然比较弱,因为它不保证能把答案和来源严格绑定。
而一个设计得比较好的 RAG 系统,至少可以尽量输出:
- 命中的 chunk
- 对应文档名
- 页码、标题或链接
- 回答所依赖的片段
这会让系统更像“检索增强问答”,而不只是“模型聊天”。
三、不要把公式记错:RAG 不等于“Embedding + 向量库”
很多入门文章喜欢写成:
RAG = Embedding + Vector DB + LLM
这个公式对入门有帮助,但太粗了。
更接近真实系统的理解应该是:
1
2
3
4
5
6
7
8
9
RAG = 数据接入与清洗
+ 切块
+ 向量化 / 索引构建
+ 查询预处理
+ 检索召回
+ 重排 / 过滤 / 上下文压缩
+ Prompt 组织
+ LLM 生成
+ 评估与迭代
也就是说,向量库只是 RAG 里很重要的一层底座,但不是全部。
真正影响效果的,往往不是“有没有向量库”,而是下面这些问题:
- 文档切得对不对
- 元数据有没有保留
- 查询有没有改写
- 检索是否只靠向量相似度
- 是否做重排
- 给模型喂进去的上下文是否冗余
- 最终回答是否限制在证据范围内
所以如果一个项目效果差,不要条件反射地怪:
- 模型不够强
- 向量库不够强
更多时候,问题出在整条链路的中间环节。
四、先看最基础的链路:Naive RAG 是怎么工作的
最朴素的 RAG,可以拆成离线和在线两段。
4.1 离线阶段:把知识整理成可检索形态
离线阶段通常做的是:
- 收集原始资料
- 解析内容并清洗
- 切成适合检索的 chunk
- 用 embedding 模型转成向量
- 连同元数据一起写入索引或向量库
这里的“原始资料”不一定只是纯文本,还可能包括:
- 网页
- Markdown
- Word
- 表格
- 图片 OCR 结果
- 数据库记录
而“元数据”一般至少建议保留:
- 文档名
- 章节标题
- 来源链接
- 页码或段落位置
- 时间戳
- 权限信息
因为后面做过滤、溯源、权限控制时,元数据非常关键。
4.2 在线阶段:用户提问时再检索和生成
在线阶段通常做的是:
- 用户输入问题
- 把问题向量化
- 去索引里找最相关的若干 chunk
- 把这些 chunk 和问题一起塞进 prompt
- 让 LLM 生成回答
这就是最典型的 retrieve -> augment -> generate。
下面这张图很适合把最基础流程先看顺:

如果只保留这个最小链路,它当然能跑起来,但也会很快遇到一堆问题:
- 问题写得不好,召回就差
- 文档切块不合理,证据不完整
- top k 召回里有噪声
- chunk 太多导致上下文被污染
- 最后模型仍然可能忽略证据,自由发挥
这也是为什么真正可用的系统,几乎都会从 Naive RAG 继续往前演进。
五、把链路逐段拆开:RAG 每一层到底在做什么
5.1 数据接入与清洗
RAG 成败很大一部分不在模型,而在数据。
如果原始资料本身就混乱,比如:
- 页眉页脚大量重复
- 表格被解析乱了
- 标题层级丢失
- 图片里的关键信息没抽出来
- 老版本和新版本混在一起
那后面检索再怎么做,结果也容易偏。
所以这一步更像“把资料准备成机器能稳定读懂的样子”。
常见工作包括:
- 文本标准化
- 去噪
- 结构恢复
- OCR
- 表格抽取
- 元数据补全
- 版本管理
5.2 切块
切块是最容易被低估的一步。
因为检索系统并不是按“整本文件”理解世界,而是按 chunk 理解世界。
切得太大,会有几个问题:
- 一次命中内容太杂
- 噪声大
- token 成本高
切得太小,也有问题:
- 上下文断裂
- 关键定义和结论分开
- 单个 chunk 信息不足
所以切块本质上是在平衡两件事:
- 局部语义完整性
- 检索粒度
常见策略包括:
- 固定长度切块
- 按段落或标题切块
- 滑动窗口 overlap
- parent-child / small-to-big 分层切块
如果你的资料是规范文档、产品文档、接口文档,通常按标题和段落结构切,会比纯字符数硬切更稳。
5.3 向量化与索引构建
这一步负责把可读文本,变成“能按语义查找”的表示。
核心动作一般是:
- 选 embedding 模型
- 生成 chunk 向量
- 存入向量索引
- 绑定元数据
这里最容易混淆的是职责边界:
- embedding 模型决定“语义空间长什么样”
- 向量索引决定“这个语义空间怎么查得快”
所以如果检索结果差,可能是:
- embedding 不适合领域语料
- 索引参数不合适
- 元数据过滤没配好
- chunk 本身就不好
而不是永远都该先换大模型。
5.4 查询预处理
用户的问题不一定天然适合检索。
比如用户会问:
- 缩写
- 口语
- 模糊表达
- 多问题混在一起
- 带有上下文省略
所以线上系统常在真正检索前做一层查询预处理,比如:
- 拼写修正
- 补全实体名
- Query Rewrite
- Step-back 问法抽象
- 子问题拆分
- HyDE 之类的假设答案生成后再检索
这一步的目标不是“让问题更好看”,而是:
让检索器更容易命中真正需要的材料。
5.5 检索召回
检索不是一个单点动作,而是一组策略。
最常见的当然是向量检索,但真实系统里还常见:
- 关键词检索
- BM25
- 混合检索
- 元数据过滤
- 分层检索
- 多路召回
为什么很多系统要做混合检索?
因为不同信息适合不同召回方式:
- 专有名词、错误码、字段名更适合关键词
- 自然语言语义相似更适合向量检索
- 带范围和权限约束的问题,需要元数据过滤
所以一个成熟系统里,检索经常不是单路 top k,而是:
- 多种检索器并行召回
- 再在后面统一融合
5.6 重排、过滤与上下文压缩
初次召回到的结果,通常只能叫“候选集”,还不能直接喂给模型。
因为这里经常会混进:
- 相关但不最相关的 chunk
- 主题接近但答案不直接的 chunk
- 彼此重复的 chunk
- 长度过大的 chunk
所以后面一般还要做:
- rerank
- 去重
- MMR
- 上下文压缩
- 证据筛选
很多项目从“能跑”到“变稳”,核心进步就发生在这一层。
因为用户真正需要的不是 “top 10 看起来有点像的片段”,而是:
最能直接支持回答的那几段证据。
5.7 Prompt 组织与回答生成
把 chunk 检索出来之后,还不能随手一拼就交给 LLM。
提示词这一步通常至少要解决下面几个问题:
- 告诉模型只能基于已提供材料回答
- 材料不足时要承认不知道
- 尽量给出出处
- 控制输出格式
- 限制自由发挥空间
这就是为什么 RAG 不是“检索完就结束”,而是检索和生成共同设计。
如果 prompt 很弱,经常会出现:
- 明明给了证据,模型却没用
- 明明证据不足,模型还是硬答
- 回答混入外部常识,和资料冲突
5.8 评估与反馈
一个 RAG 系统好不好,不能只看“像不像人话”。
至少应该分开看几类问题:
- 检索有没有召回到对的证据
- 生成有没有忠实使用证据
- 回答有没有真的解决问题
- 延迟和成本是否可接受
常见评估维度可以粗分成:
- retrieval relevance
- groundedness / faithfulness
- answer correctness
- answer relevance
- latency
- token cost
很多团队做了很久之后才发现,RAG 的难点不是从 0 到 1 搭建,而是:
你必须知道到底是检索错了,还是生成错了。
六、从能跑到能用:为什么会从 Naive RAG 演进到 Advanced RAG
当你开始处理真实业务数据时,很快就会发现:
- 单次向量检索不够稳
- 用户问题并不标准
- 文档质量参差不齐
- 召回结果噪声大
- 上下文窗口很容易被无效信息吃掉
于是系统会自然演进到 Advanced RAG。
下面这张图展示的就是更现实的工程链路:

和最基础版本比,差异主要在两侧。
6.1 检索前增强
也就是在真正查库前,先把问题处理得更适合查。
常见做法包括:
- query rewrite
- 查询分类
- 路由到不同知识源
- 子问题拆分
- 权限或安全检查
6.2 检索后增强
也就是先召回一批候选,再做更精细处理。
常见做法包括:
- rerank
- 多路结果融合
- 上下文压缩
- 去重
- 证据打分
- 引文对齐
6.3 为什么说它本质上是“可优化点变多了”
Naive RAG 的问题在于,它几乎只有一个大旋钮:
- top k 调多一点
但 Advanced RAG 不是只把流程变复杂,而是把问题拆成很多可调节点:
- 问题写得不好,改写它
- 候选集太脏,重排它
- 资料太长,压缩它
- 某类问题召回差,单独加路由
- 多轮对话上下文乱,做查询重构
这也是为什么真正线上化之后,RAG 更像一个检索系统和生成系统的组合工程,而不是一个单独模型技巧。
七、再往前一步:模块化 RAG、Agentic RAG、Graph RAG 在变什么
这几个词最近很常见,但如果不先把基础 RAG 理顺,很容易被新名词带跑。
7.1 模块化 RAG
模块化 RAG 的重点不在“更高级”,而在“可编排”。
它会把下面这些能力拆成独立模块:
- 多路检索器
- 查询转换器
- reranker
- 工具调用
- 结果融合器
- 回答校验器
然后按不同任务动态组合。
所以它解决的不是“RAG 是不是存在”,而是:
面对不同问题类型,能不能走不同的检索和生成路径。
7.2 Agentic RAG
Agentic RAG 通常强调让模型具备更强的决策能力,例如:
- 先判断要不要检索
- 判断该查哪个知识源
- 检索一次不够就继续追问
- 需要时拆成多跳问题
- 回答前先验证证据是否充分
换句话说,它不是把 retrieve -> generate 固定死,而是让 LLM 参与流程控制。
这会带来更强灵活性,但代价也很明显:
- 链路更长
- 延迟更高
- 调试更难
- 行为更不稳定
7.3 Graph RAG
Graph RAG 的重点通常不在“向量更强”,而在“关系表达更强”。
当问题很依赖:
- 实体关系
- 多跳推理
- 跨文档关联
- 结构化约束
单纯依靠 chunk 检索可能就不够。
这时会把知识组织成图或借助知识图谱、实体关系图、社区摘要等结构,再结合向量检索完成回答。
所以它更适合回答:
- A 和 B 什么关系
- 某个事件链怎么串起来
- 多份资料里的因果链条是什么
而不是所有问题都必须上图。
八、RAG 和几个相邻概念,到底怎么区分
8.1 RAG 和提示词工程
提示词工程主要解决的是:
- 怎么问
- 怎么约束输出
- 怎么让模型更好执行任务
它通常不引入新知识。
RAG 解决的是:
- 模型回答时缺少外部事实依据怎么办
所以二者不是替代关系,而是上下游关系。
8.2 RAG 和长上下文
长上下文的思路是:
- 直接把更多原始资料塞进模型
RAG 的思路是:
- 先选,再塞
当资料量很小、问题很集中、上下文窗口足够大时,长上下文方案可能很直接;但当资料规模变大、噪声变多、成本需要控制时,RAG 的“先检索再生成”通常更可控。
8.3 RAG 和微调
一个特别容易记住的区分方式是:
RAG更偏“补知识”Fine-tuning更偏“改行为”
如果你的问题是:
- 模型不知道公司制度
- 模型不知道产品文档
- 模型不知道实时数据
优先考虑 RAG。
如果你的问题是:
- 模型输出格式总不稳定
- 某种风格、术语、流程总执行不好
- 想把某类行为模式固化下来
微调才更像正解。
8.4 RAG 和向量库
向量库是 RAG 常见底座,但不能把两者画等号。
更准确的关系是:
- RAG 是完整应用架构
- 向量库是检索基础设施之一
而且并不是所有 RAG 都只靠向量库:
- 可以混合 BM25
- 可以接 SQL
- 可以查知识图谱
- 可以接搜索引擎
- 可以接 API
所以真正要问的不是“要不要向量库”,而是:
你的知识以什么形态存在,应该用什么检索方式把它找回来。
九、RAG 为什么经常效果不稳:最常见的坑其实很朴素
9.1 资料质量不行
如果文档本身脏乱差,RAG 只会把问题更稳定地放大出来。
9.2 chunk 切坏了
定义和结论被切开、标题和正文断开、表格和说明拆散,这些都会直接影响召回质量。
9.3 只看召回,不看重排
把 top k 直接塞给模型,通常是从 demo 到生产的第一个瓶颈。
9.4 只做向量检索,不做关键词补充
对术语、编号、报错信息、接口名这类内容,纯语义检索经常不如关键词稳。
9.5 prompt 不限制模型
如果没有明确要求“仅依据资料回答”,模型非常容易把外部常识和猜测混进来。
9.6 缺少评估闭环
如果每次只靠主观体验说“感觉这次答得不错”,系统就很难真正迭代。
十、一个最小可行的 RAG MVP,至少应该长什么样
如果只是做第一版,不要一上来就追求最复杂架构。
一个比较务实的 MVP,通常至少包含:
- 文档加载与清洗
- 合理切块
- embedding + 向量索引
- 基础相似度检索
- 简单元数据返回
- 明确约束的回答 prompt
- 基础评估样本集
第一版更重要的目标不是“花活多”,而是:
- 问题能不能命中证据
- 回答有没有引用证据
- 哪类问题最容易失败
在这个基础上,再逐步加:
- hybrid search
- rerank
- query rewrite
- 多路召回
- 引文对齐
- 自动评估
这样的演进节奏通常更稳。
十一、学习 RAG 时,建议按什么顺序理解
如果现在刚开始学,我会建议按下面顺序建立认知,而不是一上来就追框架:
- 先理解 RAG 为什么出现,它解决的是哪类问题
- 再理解离线索引和在线问答两段链路
- 再理解切块、embedding、检索、重排各自负责什么
- 再看混合检索、查询改写、多跳、Agentic RAG 这些进阶形态
- 最后再进入具体框架和具体产品选型
如果顺序反过来,很容易变成:
- API 会调
- demo 会跑
- 但不知道为什么结果忽好忽坏
十二、最后收个口:RAG 不是银弹,但它是今天最实用的知识外挂方式之一
如果把结论压缩成几句话,我会这样总结:
- RAG 的本质,是让模型在生成前先接触外部证据
- 它最适合解决“知识要更新、要溯源、要领域化”的问题
- 它不是单一算法,而是一整条数据、检索、生成和评估链路
- 真正决定效果的,往往不是模型名字,而是中间链路设计得是否合理
所以理解 RAG,最重要的不是记住多少新名词,而是先把下面这个判断建立起来:
当一个系统回答不准时,到底是知识没进来、证据没召回、证据没排对,还是模型没按证据说话。
只有把这个问题拆清楚,RAG 才会从“能演示”真正走向“能落地”。