6.3 RAG(检索增强生成)
核心问题: 如何让 LLM 使用外部知识?
在线 Notebook
对应的交互式版本可在 Google Colab 打开,统一使用方式见 第0章说明。
问题:LLM 的知识是静态的
LLM 的知识来自预训练数据,有两个根本限制:
- 知识截止日期:训练完成后,模型不知道新发生的事情
- 私有知识盲区:公司内部文档、个人数据从未出现在训练集里
微调能解决吗? 部分能。但微调成本高,而且知识一旦更新就要重新训练。对于频繁变化的知识(新闻、产品文档、用户数据),微调不是好选择。
RAG 的思路是:不把知识烧进模型,而是在推理时动态检索。
RAG 的工作流程
用户问题:"我们公司的退款政策是什么?"
│
▼
[1. 检索] 在知识库里找到相关文档片段
│ → "退款政策:购买后 30 天内可申请全额退款..."
▼
[2. 增强] 把文档片段拼入 Prompt
│ → "根据以下文档回答问题:\n{文档片段}\n\n问题:{用户问题}"
▼
[3. 生成] LLM 根据增强后的 Prompt 生成答案
→ "根据公司政策,您可以在购买后 30 天内申请全额退款..."三个步骤,缺一不可:检索找到相关内容,增强把内容注入上下文,生成产出最终答案。
RAG 的核心风险也对应这三步:
- 检索错:相关文档没有被找出来
- 增强错:检索内容太长、太杂或顺序不合理
- 生成错:模型没有忠实使用检索内容,产生幻觉或遗漏引用
为什么向量检索有效
RAG 的核心是"找到相关文档"。关键词匹配(搜索"退款")太脆弱——用户可能问"能不能把钱要回来",关键词完全不同但语义一样。
向量检索的思路: 把文本的语义编码成向量,语义相近的文本对应的向量方向也相近。
这和第5章的 token embedding 是同一个思想:
第5章:token embedding
"king" → [0.2, 0.8, ...]
"queen" → [0.3, 0.7, ...] ← 方向相近,语义相关
RAG:文档 embedding(同样的思想,粒度更大)
"退款政策:30天内全额退款" → [0.1, 0.9, ...]
"能不能把钱要回来?" → [0.15, 0.85, ...] ← 方向相近,语义相关余弦相似度: 衡量两个向量方向的接近程度,值域 [-1, 1],越接近 1 越相似。
相似度 = cos(θ) = (向量A · 向量B) / (|A| × |B|)实际使用时,把知识库里所有文档都编码成向量存好,查询时把用户问题也编码成向量,找余弦相似度最高的几个文档——这就是向量检索。
分块策略:为什么不把整篇文档塞进去
直觉: 如果用户问退款政策,把整本产品手册(100页)塞进 Prompt,有两个问题:
- 超出上下文窗口:LLM 能处理的文本长度有限(通常 4K-128K tokens)
- 检索精度下降:文档越长,向量越"平均",语义越模糊,找到的文档越不准
实践做法: 把文档切成小块(chunk),每块 200-500 tokens,分别编码存储。检索时找最相关的几个块,而不是整篇文档。
原始文档(1000 tokens)
↓ 分块
块1(300 tokens):产品介绍
块2(300 tokens):退款政策 ← 用户问退款,只检索到这块
块3(400 tokens):联系方式块太小:上下文不完整,答案可能缺少背景。块太大:检索精度下降。这是 RAG 工程中需要调整的核心参数之一。
实际系统还需要考虑:
- 是否保留标题、章节路径和时间戳等元数据
- 是否对检索结果做重排序
- 是否让模型在回答中引用来源
- 当检索置信度低时是否拒答或转人工
RAG vs 微调:如何选择
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 知识频繁更新(新闻、产品文档) | RAG | 更新知识库即可,无需重训 |
| 私有数据(内部文档、用户数据) | RAG | 数据不进入模型,更安全 |
| 需要引用来源、可解释性高 | RAG | 可以展示检索到的原始文档 |
| 输出格式/风格要求严格 | 微调 | RAG 不改变模型行为 |
| 领域术语、专业能力不足 | 微调 | 需要改变模型的"知识结构" |
| 两者都需要 | RAG + 微调 | 微调固定格式,RAG 提供知识 |
实践建议: 先用 RAG 验证知识增强是否有效,再根据需要考虑微调。RAG 的启动成本远低于微调。
代码实验

图6.3:左图展示文档 embedding 在二维语义空间中的分布——退款、产品、配送三类文档各自聚集,查询向量(橙色箭头)与退款类文档方向最近,余弦相似度最高(★标注)。右图为各文档与查询的相似度得分。
代码文件: code/ch06_llm_applications/rag_demo.py
运行方式: python code/ch06_llm_applications/rag_demo.py
本节小结
- RAG 解决 LLM 知识静态的问题,通过"检索 + 增强 + 生成"三步动态注入外部知识
- 向量检索的有效性来自 embedding 的语义表示能力——和第5章 token embedding 是同一思想
- 分块是 RAG 的关键工程决策:块太小上下文不完整,块太大检索精度下降
- RAG 的主要失败模式来自检索召回不足、上下文拼接不当和生成阶段不忠实
- RAG 适合知识频繁更新、需要引用来源的场景;微调适合格式/风格/专业能力要求严格的场景
下一节: 6.4 Agent 框架扩展阅读: RAG 系统深度优化(混合检索、重排序、分块策略进阶、RAGAS 评估)
