前言
大模型(LLM)很聪明,但它有一个尴尬的问题:训练完之后,知识就"定格"了——它不知道训练之后发生的新事,也不认识你公司的内部文档。更麻烦的是,遇到不懂的问题,它还会一本正经地"编"。
RAG(Retrieval-Augmented Generation,检索增强生成)就是解决这个问题的主流方案:在回答之前,先从外部知识库里"检索"相关资料,再让大模型基于资料生成答案。
本文是一篇 RAG 的全景图,先不展开代码,把三件事讲清楚:
- RAG 到底是什么、为什么火(原理)
- RAG 和微调、长上下文怎么选(决策)
- RAG 的完整链路长什么样、怎么一步步落地(实践路径)
一、先讲一个真实的场景
理解 RAG,先从一个最核心的问题出发:
为什么需要 RAG?直接把问题丢给大模型不行吗?
要回答这个问题,先得明白 LLM 天生有三个"缺陷":
缺陷1:幻觉 → 不懂的也敢编,一本正经胡说八道 缺陷2:知识过时 → 训练数据有截止日期,新知识它不知道 缺陷3:私有知识 → 你公司的内部文档、最新资料,它根本没学过还是用中国载人登月任务举例。假设你的知识库里有这样一句话:
任务计划在2030年前执行,将实现中国人首次登陆月球你问大模型:
用户:载人登月任务什么时候执行?没有 RAG 时,大模型只会凭"训练记忆"回答,可能答错、可能编造、可能说"我不知道 2025 年之后的事"。
有 RAG 时,系统会先从知识库里"检索"到那句最相关的话,再让大模型基于它回答:
用户:载人登月任务什么时候执行? 知识库(检索到的): - 任务计划在2030年前执行,将实现中国人首次登陆月球 大模型:根据资料,中国载人登月任务计划在2030年前执行。看到了吗?答案有依据、可追溯、不编造。这就是 RAG 的价值。
二、RAG 是什么
RAG 的英文全称:
R = Retrieval 检索(先找到相关资料) A = Augmented 增强(用资料增强回答的准确性) G = Generation 生成(再让大模型生成答案)一句话定义:先检索相关资料,再让大模型基于资料回答,而不是让它凭空发挥。
2.1 完整链路图
一个生产级的 RAG 系统,完整链路是这样的:
┌──────────────────────────────────────────────────────────────┐ │ 离线阶段:建知识库 │ │ │ │ 原始文档 → 解析 → 分块 → 向量化 → 存入向量数据库 │ │ (PDF/Word/表格) (提取正文) (切成小块) (转成向量) (建索引) │ └──────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ 在线阶段:回答问题 │ │ │ │ 用户提问 → 改写 → 检索召回 → 重排 → 组装 → 生成 → 评测 │ │ (补全意图) (找Top-K) (精选) (拼上下文)(回答) (打分) │ └──────────────────────────────────────────────────────────────┘整条链路分两大块:
- 离线阶段:把文档变成"可检索"的知识库。核心产出是一堆向量,以及支撑快速搜索的索引。
- 在线阶段:用户提问后,把问题变成"检索指令",找到最相关的几段资料,喂给大模型,让它基于资料回答,最后还要评测答得怎么样。
三、RAG vs 微调 vs 长上下文,怎么选
这是理解 RAG 绕不开的对比题。先把三者说清楚:
RAG(检索增强) :给模型"外挂知识库",问的时候现查 微调(Fine-tuning) :把知识"焊死"进模型参数里,改模型本身 长上下文(Long Context):把资料全部塞进 prompt,让模型一次读完3.1 对比表
| 维度 | RAG | 微调 | 长上下文 |
|---|---|---|---|
| 实现成本 | ✅ 低(不用改模型) | ❌ 高(要训练) | ✅ 低(改 prompt) |
| 知识更新 | ✅ 随时换资料 | ❌ 更新要重新训练 | ✅ 换 prompt 就行 |
| 幻觉控制 | ✅ 有资料兜底 | ⚠️ 治标不治本 | ✅ 有资料兜底 |
| 可追溯性 | ✅ 能指出处 | ❌ 黑盒 | ✅ 能指出处 |
| 私有/最新知识 | ✅ 强项 | ✅ 强项 | ✅ 强项 |
| 上下文窗口 | ✅ 只塞相关的,省 token | ✅ 不占窗口 | ❌ 全塞进去,又贵又慢 |
| 适合场景 | 通用首选 | 特定风格/领域深度 | 小资料、单文档 |
3.2 一句话总结
RAG 是"外挂知识",微调是"内化知识"。RAG 改动小、成本低、可更新,所以能上 RAG 就先上 RAG;微调留给"学风格、学专有表达"这种 RAG 做不到的事。
四、RAG 的演进:Naive → Advanced → Modular
RAG 并不是一步到位的,它经历了三个阶段:
Naive RAG :检索 → 拼接 → 生成(最朴素) 缺点:检索质量直接决定答案质量,查不准就全崩 Advanced RAG :在检索前、检索后都做优化 检索前:更好的分块、Query改写、混合检索 检索后:重排、上下文压缩、去重 Modular RAG :把 RAG 拆成独立模块,像搭积木一样自由组合 检索、记忆、路由、编排任意组合 → 面向复杂生产系统一句话总结演进逻辑:
Naive 是"能用",Advanced 是"好用",Modular 是"可定制"。
五、RAG 的三大失败模式:查不到、查不准、答不对
RAG 做得不好,问题往往出在三个地方:
模式1:查不到 → 该检索到的资料没检索到(召回问题) 模式2:查不准 → 检索到了但排在前面的不对(排序问题) 模式3:答不对 → 资料对了但答案还是错的(生成问题)每个模式对应的根因和优化方向:
| 失败模式 | 根因 | 优化方向 |
|---|---|---|
| 查不到 | 分块不合理 / 只有向量一路 | 分块策略 / 混合检索 |
| 查不准 | 向量"语义近似"≠"精确相关" | 重排序 Rerank |
| 查不准 | 用户问得含糊 / 多轮指代 | Query 改写 |
| 查不到 | 文档解析丢了内容 | 文档解析与清洗 |
| 答不对 | 上下文冗余 / 没有评估闭环 | 后处理 + 评测 |
| 全链路 | 缺一个可运行的完整系统 | 生产级实战 |
这张表就是 RAG 优化的行动地图:遇到问题先从"查不到 / 查不准 / 答不对"三个方向定位,再对症下药。
六、用 Go 代码画出"骨架"
光看图不过瘾,用代码把这条链路的骨架画出来。每一行代表一个阶段:
packagemainimport"fmt"// ==================== RAG 管线:一张可运行的骨架 ====================// 阶段1:文档解析 —— PDF/Word/表格 变成纯文本funcparseDocument(pathstring)[]string{returnnil}// 阶段2:文本分块 —— 切成合适大小的块,块与块之间留 overlapfuncchunk(docs[]string,size,overlapint)[]string{returnnil}// 阶段3:向量化 + 入库 —— 每个块转成向量,存进向量数据库并建索引funcembedAndIndex(chunks[]string){}// 阶段0:Query 改写 —— 把"它""那个"补全成具体实体(横切步骤)funcrewrite(querystring)string{returnquery}// 阶段4:检索召回 —— BM25 + 向量 双路召回,RRF 融合funcretrieve(querystring,topKint)[]string{returnnil}// 阶段5:重排序 —— Cross-Encoder 精选 Top-Kfuncrerank(querystring,candidates[]string)[]string{returnnil}// 阶段6:上下文组装 + 生成 —— 压缩、去重、带引文funcgenerate(querystring,context[]string)string{return""}// 阶段7:评测 —— Faithfulness / Context Recall ...funcevaluate(query,answerstring)float64{return0}funcmain(){fmt.Println("RAG 完整链路:")fmt.Println("解析 → 分块 → 向量化入库 → 改写 → 召回 → 重排 → 生成 → 评测")}这段代码现在跑不出任何结果——因为每个阶段都是空的。它的意义在于:把 RAG 这条链路拆成一个个可以独立优化的小模块。后面你可以逐个把空函数填满,最后串成一个能跑的生产级系统。
七、RAG 全景自查:20 个问题
到这里,RAG 的原理和实践路径已经清楚了。为了帮你检验自己是否真正理解,我把 RAG 相关的 20 个核心问题按难度分层列出,你可以逐个自问自答:
7.1 基础层:理解 RAG 的本质
1. RAG 是什么?用一句话讲清楚 2. RAG 和微调的区别?为什么优先 RAG? 3. RAG 和长上下文怎么选? 4. RAG 的完整流程画一下 5. 一个最小可用的 RAG 系统由哪些部分组成?7.2 进阶层:深入检索质量
6. chunk 大小怎么定?overlap 有什么用? 7. 为什么向量检索对专有名词/精确匹配不友好? 8. 混合检索怎么做?BM25 和向量怎么融合? 9. Bi-Encoder 和 Cross-Encoder 区别? 10. Rerank 加在哪一步?K 取多少? 11. 多轮对话怎么处理"它/那个"这类指代? 12. HyDE 是什么?有什么坑? 13. PDF/表格/扫描件怎么进库?7.3 深度层:原理与工程落地
14. RAG 怎么评测?RAGAS 四个指标是什么? 15. 让 LLM 当裁判评测,有什么坑? 16. 召回太多、上下文太长怎么压缩? 17. 回答怎么带引用、可追溯? 18. 生产环境里 RAG 会踩哪些坑? 19. 怎么判断一个 RAG 系统到底好不好? 20. 从零到一落地一个 RAG 系统,步骤是什么?能把这些问题都答清楚,你对 RAG 的理解就算真正到位了。
八、总结
本文是 RAG 的全景图,记住五件事就够了:
1. RAG = 检索增强生成:先查资料,再让模型基于资料回答 2. 它解决 LLM 三大缺陷:幻觉、知识过时、不知道私有知识 3. 选型:能上 RAG 先上 RAG;微调留给学风格;长上下文留给小资料 4. 演进:Naive(能用)→ Advanced(好用)→ Modular(可定制) 5. 三大失败模式:查不到 / 查不准 / 答不对,各有对应的优化手段RAG 的核心就一句话:别让大模型凭空发挥,先给它"喂"最相关的资料。掌握了这条主线,你就能顺着链路一步一步把每个环节做到位。