第6章:RAG——给大模型一本「开卷考试」的参考资料
系列导读:RAG 是 LLM 工程中最主流、最有实现价值的系统方案。从本章开始,建议认真跟完 RAG 模块(第6-11章),这是把 LLM 做成靠谱产品最关键的技术栈。
一、RAG 的定位:解决 LLM 的知识冻结问题
LLM 最大的硬伤是什么?知识被冻结在训练截止日期。
你问它:「我们公司上个月发布了什么新功能?」它不知道。 你问它:「我的私人笔记里关于算法的那部分内容是什么?」它不知道。
RAG 全称 Retrieval-Augmented Generation(检索增强生成),核心思路是:
在 LLM 生成答案之前,先从一个外部知识库里检索相关内容,把检索结果作为上下文喂给 LLM,让它基于这些参考资料来回答。
这就好比把闭卷考试改成了开卷考试——LLM 不需要背诵所有知识,考试时现场翻资料就行了。
二、RAG 完整工作流(一句话 + 一张图)
用户提问 → 预处理/改写 → 向量化 → 向量数据库检索 →
粗排/精排 → 拼装 Prompt → LLM 基于参考资料生成答案 → 答案
整个过程分两条线:
- 离线线:文档 → 切割 → 向量化 → 存入向量数据库(一次性预处理)
- 在线线:用户提问 → 检索 → 生成答案(每次用户提问都走)
三、离线阶段:把文档变成可检索的向量
步骤1:文档切割(Chunking)
原始文档不能整篇直接存入向量库,因为:
- Embedding 模型有输入长度限制(通常几百到几千 token)
- 长文档压缩成一个向量会「平均掉」细节,检索精度极低
所以必须**切成小块(chunk)**存储。
常见切割策略:
| 策略 | 适用场景 | 优缺点 |
|---|---|---|
| 固定大小 + 重叠 | 通用文本 | 简单,可能切到句中 |
| 按语义边界切 | 有章节结构的文档 | 语意完整,实现稍复杂 |
| 按函数/类切 | 代码文件 | 保持代码逻辑单元完整 |
| 父子切割 | 精度+全文都要 | 小块检索,大块返回 |
每条 chunk 包含三部分:
- 向量:用于相似度检索
- 原始文本:检索命中后塞给 LLM 读的内容
- Metadata:来源文件、页码、分类等附加信息
步骤2:Embedding 向量化
Embedding 是一种「语义压缩」——把文本映射成一个固定长度的浮点数向量。
核心性质:语义相近的文本,向量距离就相近(通常用余弦相似度衡量)。
举个例子:
- “猫坐在垫子上” 和 “小猫趴在毯子上面” → 向量距离很近
- “猫坐在垫子上” 和 “股票价格今日大涨” → 向量距离很远
选择 Embedding 模型的关键考量:
- 语言支持:中文场景首选 BGE 系列、M3E、智谱 Embedding
- 向量维度:维度越高精度越好,但存储成本也越大(常见 384-4096 维)
- 最大输入长度:决定能处理多长的 chunk(常见 512-8192 token)
- 评估:不要只看排行榜,要在你自己的数据上测召回率(Hit@K、NDCG@K)
步骤3:存入向量数据库
向量数据库是专门存储和检索高维向量的数据库,核心能力是近似最近邻搜索(ANN)。
在大规模(百万甚至亿级)向量中,它能在毫秒级找出最相似的几条。
不是「在 MySQL 里加个 float 数组」,也不是用 LIKE 字符串匹配——向量相似度搜索在算法层(HNSW、IVF-PQ)和硬件层(SIMD 指令、GPU 加速)专门做了优化。
四、在线阶段:从用户提问到最终答案
步骤1:Query 预处理
用户问「这个功能怎么用」,知识库里写的是「XX 模块操作指南」。
口语化的问题和正式文档表述之间存在语义鸿沟,直接检索效果很差。
解决方案:Query Rewrite(查询改写)。方法包括:
- 直接改写:让 LLM 把口语问题转成规范表述
- Query 扩展:补充相关关键词
- HyDE(假设文档嵌入):让 LLM 先假设一个答案,用这个答案的向量去检索(隐性扩展匹配面)
- Step-back Prompting:把具体问题抽象一层,检索更通用的背景知识
步骤2:向量检索
把改写后的查询向量化,去向量库中搜索最相似的 Top-K 个 chunk。
这一步叫 粗排(Retrieval),目标是「尽可能多地把相关内容召回来」(召回优先)。
步骤3:重排序(Rerank)
粗排召回的 Top-K 中可能包含很多不相关的内容(噪音)。
Rerank(重排序)用更精确的模型(如 BGE-Reranker)对粗排结果打分,只保留最相关的几条,把参数量降低同时提高精度。
步骤4:Prompt 拼装与生成
把筛选后的 chunk 和用户问题一起拼成 prompt:
请基于以下参考资料回答问题:
[参考资料1]
...
[参考资料2]
...
问题是:用户的问题是什么?
请只基于以上参考资料作答。如果资料中找不到答案,请明确说明"无法从已有资料中找到相关信息"。
关键设计:强制要求模型只基于参考资料回答,有效防止幻觉和编造。
五、RAG vs 微调(Fine-tuning)
| 维度 | RAG | 微调 |
|---|---|---|
| 原理 | 动态检索外部知识 | 修改模型参数 |
| 知识更新 | 即时替换文档即可 | 需要重新训练 |
| 成本 | 低(向量库查询+LLM调用) | 高(训练计算+标注数据) |
| 通用效果 | 适合知识密集型任务 | 适合风格/格式适应 |
| 可解释性 | 好(可追溯来源) | 差(参数变化不可见) |
经验法则:先上 RAG,RAG 真不够用再考虑微调。90% 的知识问答场景用 RAG 就够了。
六、知识问答场景的 RAG 六边形
一个成熟的 RAG 系统至少要考虑:
- 文档解析:PDF/Word/Excel/网页等各种格式的读取
- 切割策略:用什么粒度、什么策略切 chunk
- Embedding 选型:用什么模型、什么维度
- 向量库选型:规模多大、需要实时更新吗
- 检索优化:粗排+Rerank+多路召回
- 生成控制:Prompt 设计、幻觉规避、引用来源
七、本章小结
- RAG = 检索 + 生成,解决 LLM 知识冻结问题
- 离线线:切分 → Embedding → 存向量库
- 在线线:Query改写 → 向量检索 → Rerank精排 → Prompt拼装 → LLM生成
- 选 RAG 还是微调:先 RAG,真的不行再上微调
- RAG 的本质是给 LLM 提供有据可查的上下文,把闭卷考试改成开卷考试→减少幻觉、增加可解释性、知识实时更新
思考题
- 为什么 Embedding 模型在通用数据集上的排行榜分数不能直接代表你的业务场景效果?
- 如果你要构建一个企业内部文档问答系统,哪些环节最可能拖慢你的开发进度?