「RAG」什么是 RAG?详细描述一个完整 RAG 系统的详细工作流程?
0 前言
本文内容整理自公众号「小林面试笔记」的文章 1. 什么是 RAG?详细描述一个完整 RAG 系统的详细工作流程?,用于记录与总结 RAG 相关的核心面试知识点。
「什么是 RAG?如何描述一个完整 RAG 系统的工作流程?」,可以这样作答:
RAG 全称 Retrieval-Augmented Generation(检索增强生成),核心思想是:在让大模型生成答案之前,先从外部知识库中检索出与用户问题相关的内容,再把「检索结果 + 用户问题」一起交给 LLM,让它基于给定的上下文来回答——本质上就是给 LLM 开卷考试,不用靠死记硬背,而是现场翻资料。
它要解决的是 LLM 的「知识冻结」困境:模型训练完知识就「冻住」了,既不知道训练截止日期之后的信息,也看不到公司内部的私有文档。与微调(把知识写进模型参数)不同,RAG 不修改模型参数,把知识放在外部、实时检索,可以热更新、成本极低。
一个完整的 RAG 系统分离线、在线两个阶段:离线阶段只做一次,提前把知识准备好(文档加载 → 文档切割 Chunking → 向量化 Embedding → 入库向量数据库);在线阶段每次提问实时执行(Query 改写 → 向量检索粗排 → Rerank 精排 → 拼接 prompt → LLM 生成)。核心价值两点:知识可热更新、答案可溯源。
1 什么是 RAG?
1.1 LLM 的「知识冻结」困境
为什么需要 RAG?得先看普通 LLM 的软肋。
大模型在训练完成的那一刻,它的知识就被"冻住"了。你可以把它想象成一个高考之后就再也不看新闻的人——你问他今天的股价、最新的热点,他完全答不上来,因为他的知识截止在训练数据结束的那一天。同样的,公司内部的规章制度、某个项目的私有文档,模型在训练时根本没见过,自然也答不上。

理论上,微调(Fine-tuning)可以更新模型的知识,但代价巨大:为了一条新知识就要重新训练一遍模型,成本高、周期长。知识一旦写进参数,想更新就得重来,就像为了让一个人记住一条新闻,让他重新上四年大学一样不划算。
1.2 RAG 的思路:给 LLM 开卷考试
RAG 走了一条完全不同的路:它不把知识塞进模型参数,而是放外面,用到的时候再取。
LLM 天生就有很强的阅读理解能力——只要相关内容出现在它的上下文(Context)里,它就能基于这段内容作答。那我们就顺着这个特性来:先生成答案之前,先去外部知识库里把相关的内容「捞」出来,连同问题一起丢进 prompt,让模型照着资料回答。

所以 RAG 和微调本质上是两种思路:
| 对比维度 | 微调(Fine-tuning) | RAG |
|---|---|---|
| 知识存储位置 | 写进模型参数 | 放在外部知识库,实时检索 |
| 是否修改模型 | 改,重新训练 | 不改,原样使用 |
| 更新知识的成本 | 高(要重新训练) | 极低(往库里加文档即可) |
| 适用场景 | 学习某种「能力/风格」 | 补充「最新信息 / 私有知识」 |
一句话总结:微调是让模型"学会",RAG 是让模型"查到"。
2 一个完整 RAG 系统的工作流程
一个完整的 RAG 系统,分离线和在线两个阶段:离线阶段只做一次,提前把知识准备好;在线阶段每次用户提问都实时执行,对响应速度有要求。

2.1 离线阶段:提前把知识准备好
离线阶段的目标,是把散落在各处的文档整理成一份「机器能快速检索」的知识库。整个过程可以分为四步:
第一步:文档加载。 原始数据可能是 PDF、Word、Markdown、网页,甚至是数据库里的记录。可以通过 LlamaIndex 或 LangChain 提供的 DocumentLoader 来读取,这类加载器通常支持几十种不同的数据源格式。

第二步:文档切割(Chunking)。 为什么要把一整篇文档切开?有两个原因:
- 向量模型有输入长度限制(一般几百到几千 token),整篇文档可能塞不进去;
- 即便塞得进去,把整篇文档压缩成一个向量,细节也会被"平均"掉。就像你问"这道菜到底怎么样",得到的却是"中国菜整体偏咸"这种笼统回答。
所以要把文档切成大小合适的块(Chunk)。切多大有讲究:太大(比如 2000 token)信息太杂、召回时容易混入不相关的内容;太小(比如 50 token)语义又不完整。实践中通常取 500~1000 token 一个 chunk,并且前后各重叠约 100 token,避免在两个 chunk 的交界处把完整语义切断。

第三步:Embedding(向量化)——最核心的一步。 把每个 chunk 的文本转成一个高维数字向量(比如 1536 维的浮点数),这一步叫向量化。可以把它理解为把文字放进一个「语义坐标系」:意思相近的文本在空间里离得近,毫不相关的离得远。

这个向量是模型训练出来的:Embedding 模型在海量文本上通过对比学习调整权重,把语义相近的文本向量拉近、把无关的推远。所以"苹果手机怎么截图"和"iPhone 如何截屏",用词不同、意思相同,它们的向量会非常接近。本质上是把「意思」编码成了数学坐标,做的是语义检索,而不是死板的关键词匹配。
第四步:入库。 把每个 chunk 的向量连同原始文本一起存入向量数据库(如 Chroma、Milvus、Qdrant、Weaviate 等)。这类数据库专门优化了高维向量的存储和相似度搜索,能支撑千万量级向量的快速检索。
2.2 在线阶段:用户提问时实时检索
在线阶段是每次用户提问都会实时跑一遍的流程,对延迟更敏感。同样分四步:
第一步:Query 处理 / 改写。 用户的问题往往是口语化、模糊的。比如"上次说的那个方案怎么样",脱离了上下文根本没法检索。这时需要用 LLM 把问题改写成适合检索的形式,或者从对话历史里补充上下文。
第二步:向量检索(粗排)。 把处理好的用户问题转成向量,在向量库里做相似度搜索,取 Top-K 个最相近的 chunk。这一步非常快,百万量级的向量库通常几十毫秒就能返回结果。但它的代价是:只比较向量距离,没有真正理解语义关系,结果里可能混入一些"看着近、其实不相关"的内容。

第三步:Rerank(精排)。 为了补救粗排的粗糙,再用一个 Cross-Encoder 结构的 Rerank 模型,把用户问题和每个候选 chunk 拼接在一起深度理解相关性,重新排序,并过滤掉不相关的结果。打个比方:粗排就像用肉眼在书架前快速扫一遍,精排则是一本本翻开目录仔细读。精排更准但更慢,所以通常只对粗排返回的 Top-20 做精排,最终留下 Top-3 到 Top-5 给模型。

第四步:生成。 把「用户问题 + 精排后的 chunk」拼成 prompt 交给 LLM。这里有个关键技巧:在 prompt 里明确告诉模型"只根据提供的资料回答,资料里没有的内容就说不知道",能有效抑制幻觉(模型编造答案)。
2.3 完整流程串联
把两阶段串起来,整个 RAG 就是这样一个闭环:
- 离线(只做一次):文档切割 → 转为向量 → 存入向量数据库。
- 在线(每次提问都跑):问题向量化 → 数据库检索 → 精排 → 拼 prompt → LLM 生成。

3 RAG 的两大核心价值
讲完流程,面试时最好再补两点价值,让回答更完整:
- 知识可热更新:往知识库里加一份新文档,就等于更新了模型的知识,完全不需要重新训练,成本极低。这是 RAG 相比微调最突出的优势。
- 答案可溯源:每一条回答都能追溯到具体的 chunk,可解释性很强。如果答错了,也能定位到是哪块知识出了问题,方便排查。
这两点一个解决了「更新难」,一个解决了「不可解释」,恰好补上了大模型落地时最头疼的两个短板。
参考
本文图片均来源于公众号「小林面试笔记」,版权归原作者所有。