模型一本正经地胡说八道?RAG 如何让 LLM 有据可查
你问模型”公司最新的报销政策是什么”,它答得头头是道——但政策上个月刚改,它说的全是错的。你让它总结内部文档,它却编造了根本不存在的条款。
这不是模型”笨”,是它根本没有访问这些信息的通道。
RAG(检索增强生成)解决的就是这个问题:在生成答案前,先检索相关文档,让模型有据可查。知识截止、幻觉、无法访问私有文档——都可以通过 RAG 缓解。
本篇解析 RAG 的三阶段工作流(检索 → 分块 → 重排 → 融合)、核心组件和进阶优化,帮你构建可追溯的知识增强系统。
📋 一、RAG 核心机制:三阶段工作流
RAG 的本质:先检索,再生成——把”猜”变成”查”。
1.1 为什么需要 RAG?
企业客服要把内部手册、FAQ 接入问答;法务要基于合同条款生成摘要——纯 LLM 无法访问私有文档,只能”瞎猜”。传统 LLM 有三道坎过不去:
| 问题 | 表现 | 影响 |
|---|---|---|
| 知识时效性 | 训练数据截止到某个时间点 | 无法回答最新事件、政策、技术 |
| 知识范围 | 只能使用训练时的数据 | 无法访问企业私有文档、内部知识库 |
| 幻觉问题 | 可能编造看似合理但错误的信息 | 答案不可信,无法验证来源 |
| 上下文限制 | Context Window 有限 | 无法处理超长文档或大量知识 |
RAG 的解决方案:
将外部知识库与 LLM 结合,让模型在生成答案前先检索相关文档,然后基于检索到的内容生成答案。
这样既保证了答案的准确性(有据可查),又突破了知识时效性和范围的限制。
1.2 RAG 的三阶段工作流
RAG 的工作流程可以概括为三个阶段:
| 阶段 | 核心任务 | 机制概述 | 核心挑战 |
|---|---|---|---|
| 1. 检索(Retrieval) | 在海量文档中定位与用户查询语义相关的片段 | 使用 Embedding Model 将文本转向量并进行向量搜索 | 召回率低:可能漏掉重要信息 |
| 2. 增强(Augmentation) | 将检索到的片段注入 LLM Prompt | Prompt 重构,将上下文作为参考资料 | 上下文污染:无关信息可能误导模型 |
| 3. 生成(Generation) | LLM 基于注入的上下文生成答案 | 条件生成,结合 Schema 或 Prompt 约束 | 整合能力:综合多个片段准确生成答案 |
完整流程示例:
# RAG 三阶段流程(伪代码) |
1.3 RAG 的优势对比 Fine-Tuning
在第2篇中,我们详细讲解了 Fine-Tuning(微调)。这里我们对比 RAG 和 Fine-Tuning,帮助你选择合适的技术方案:
| 维度 | RAG | Fine-Tuning | 说明 |
|---|---|---|---|
| 知识更新 | 实时/高效:更新知识库即可 | 滞后/高成本:需重新训练模型 | RAG 只需更新向量数据库,Fine-Tuning 需要重新训练 |
| 知识来源 | 外部/可追溯:答案可链接原始文档 | 内部/不可见:知识融入模型参数 | RAG 可以追溯答案来源,Fine-Tuning 无法追溯 |
| 知识范围 | 可访问海量外部文档 | 受训练数据限制 | RAG 可以访问任意文档,Fine-Tuning 只能使用训练数据 |
| 成本 | 低:主要是存储和检索成本 | 高:需要 GPU 训练 | RAG 成本低,Fine-Tuning 成本高 |
| 适用场景 | 快速变化的领域、访问海量私有数据、需要可追溯答案 | 改变模型风格、格式或语气、领域特定任务 | 场景不同,选择不同 |
决策指南:
| 需求 | 推荐方案 | 原因 |
|---|---|---|
| 需要访问最新信息 | RAG | 可以实时更新知识库 |
| 需要访问企业私有文档 | RAG | 可以访问任意外部文档 |
| 需要可追溯的答案 | RAG | 答案可以链接到原始文档 |
| 需要改变模型输出风格 | Fine-Tuning | 可以训练模型改变风格 |
| 需要领域特定能力 | Fine-Tuning | 可以通过训练提升领域能力 |
| 需要快速上线 | RAG | 实现简单,成本低 |
| 需要长期稳定使用 | Fine-Tuning | 训练后模型行为稳定 |
💡 核心理解:
- RAG 更适合”知识动态更新 + 高可信度 + 可追溯”的场景
- Fine-Tuning 更适合”风格与格式调整 + 领域特定能力”的场景
- 两者可以结合:Fine-Tuning 后的模型仍可使用 RAG 访问外部知识
- Agent 场景下的微调实践(LoRA、PEFT)详见第 16 篇能力调优
🧱 二、基础组件深度解析:构建知识库
一个高效的 RAG 系统依赖三个核心组件:Chunking、Embedding、Vector Database。
这三个组件构成了 RAG 系统的”基础设施”,理解它们的工作原理是构建高质量 RAG 系统的前提。
2.1 Chunking(分块):语义完整性的艺术
你有一份 100 页的技术手册要做成知识库。用户问”登录功能怎么实现?”——分块方式决定了能召回哪些内容。切得太碎,语义断裂;切得太大,噪音太多。
定义:将大型文档拆成适合检索和 Context Window 的小片段(Chunk)。关键原则:每个 Chunk 语义完整,否则模型收到的信息会断裂。
为什么需要分块?
- Context Window 限制:LLM 的上下文窗口有限(如 GPT-4 是 128k Token),无法一次性处理整本书
- 检索精度:小片段更容易精确匹配用户查询
- 计算效率:处理小片段比处理整个文档更高效
常用分块策略
1. 固定大小分块(Fixed Size Chunking)
- 方法:按固定字符数或 Token 数切分(如每 500 字符一段)
- 优点:简单易用,实现成本低
- 缺点:容易切断句子,破坏语义完整性
示例:
# 固定大小分块(伪代码) |
2. 语义分块(Semantic Chunking)
方法:不是机械地按固定大小切分,而是按照文档的自然结构(标题、段落、句子边界)或使用 NLP 技术识别语义边界,保证每个 Chunk 包含完整主题。
具体做法:
- 基于段落:按段落(
\n\n)分割,每个段落作为一个 Chunk - 基于标题:识别文档中的标题(如
# 标题),每个标题下的内容作为一个 Chunk - 基于句子边界:在段落内按句子(
。、.)分割,组合句子直到达到合适大小 - 基于 NLP 技术:使用语义相似度计算,找到语义边界(如 LangChain 的
SemanticChunker)
优点:保持语义完整性,检索更准确
缺点:实现复杂,需要理解文档结构
示例:
# 语义分块(伪代码) |
3. 父文档/子文档策略(Parent-Document RAG)
- 方法:检索小而精准的子 Chunk,增强阶段注入整个父 Chunk,确保上下文完整
- 优点:兼顾检索精度和上下文完整性
- 适用场景:文档结构清晰,有明确的父子关系
示例:
# 父文档/子文档策略(伪代码) |
📝 比喻理解:Chunk 就像”知识砖块”,分块方式决定了模型搭建知识大厦的稳定性。
- 固定大小 = 机械切割,可能切坏砖块
- 语义分块 = 按纹理切割,保持砖块完整
- 父文档策略 = 小砖块定位,大砖块使用
2.2 Embedding Model(嵌入模型):语言的数字指纹
定义:将文本 Chunk 转换为高维向量(Embedding)的模型。
功能:语义相似的 Chunk 在向量空间距离更近,使得向量搜索能够找到语义相关的内容。
Embedding 的工作原理
第1篇讲过 Token Embedding(词→向量)。RAG 用的是 Text Embedding:把整个 Chunk(句子、段落)转成一个固定维度的向量。语义相近的 Chunk 在向量空间里距离更近,检索时就能”按语义找邻居”。
示例:
# Embedding 示例(伪代码) |
选型原则
| 考虑因素 | 说明 | 示例 |
|---|---|---|
| 语言匹配 | 中文知识库用中文 Embedding 模型 | text2vec-chinese、m3e-base |
| 领域匹配 | 专业领域用领域模型 | 医学领域用医学 Embedding 模型 |
| 维度平衡 | 维度越高精度越好,但计算成本越高 | 768 维 vs 1536 维 |
| 模型大小 | 大模型效果好但推理慢 | 小模型速度快但精度略低 |
💡 实战提示:
- 中文场景:推荐
text2vec-chinese、m3e-base- 多语言场景:推荐
multilingual-e5-base- 英文场景:推荐
all-MiniLM-L6-v2、text-embedding-ada-002
2.3 Vector Database(向量数据库):高效检索核心
定义:存储与管理所有 Chunk 向量的数据库。
核心功能:当用户查询向量输入时,通过 ANN(Approximate Nearest Neighbor,近似最近邻) 搜索快速返回 Top K 相关 Chunk。
为什么需要向量数据库?
传统数据库无法高效处理向量相似度搜索。向量数据库专门优化了向量检索,能够在百万级甚至千万级向量中快速找到最相似的 Top K 个结果。
关键技术:HNSW 索引
HNSW(Hierarchical Navigable Small World) 是向量数据库常用的索引算法:
- 原理:构建多层图结构,从粗到细逐层搜索
- 优势:检索速度快(O(log n)),精度高
- 适用场景:大规模向量检索(百万级以上)
简单理解:
就像地图导航:先看国家地图找到大致区域,再看城市地图找到具体位置,最后看街道地图找到精确地址。
常见向量数据库对比
| 数据库 | 特点 | 适用场景 |
|---|---|---|
| Pinecone | 云服务,易用,性能好 | 快速原型、中小规模项目 |
| Weaviate | 开源,功能丰富,支持多模态 | 中大规模项目,需要复杂查询 |
| Milvus | 开源,性能强,可扩展 | 大规模项目,需要自部署 |
| Qdrant | 开源,Rust 实现,性能好 | 对性能要求高的项目 |
| Chroma | 轻量级,易集成 | 小规模项目,快速开发 |
🔹 实战提示:
- 快速原型:使用 Pinecone 或 Chroma
- 生产环境:根据规模选择 Milvus 或 Weaviate
- 关键要求:支持动态更新(新增文档)、高并发查询、持久化存储
🚀 三、进阶优化策略:打造高精度 RAG
基础 RAG 容易出现 低召回率(漏掉重要信息)和 上下文污染(无关信息误导模型),生产环境需要进阶策略。
基础 RAG 的问题
| 问题 | 表现 | 原因 |
|---|---|---|
| 低召回率 | 检索不到相关文档 | 查询与文档的语义不匹配 |
| 低精确率 | 检索到不相关文档 | 向量搜索只考虑相似度,不考虑实际相关性 |
| 上下文污染 | 检索到的文档包含无关信息 | 没有对检索结果进行筛选和排序 |
| 单轮限制 | 无法处理多步骤推理 | 一次检索无法回答复杂问题 |
3.1 Re-ranking(重排):提升精确率
用户问”登录失败怎么办”,向量检索可能召回”登录功能说明”、”登录按钮设计”——语义相近,但用户要的是故障排查。
Re-ranking 用 Cross-Encoder 对 Top N 结果二次排序,同时考虑查询 + 文档的交互,筛掉”看似相关实则不相关”的片段。
为什么需要 Re-ranking?
向量检索是”单向”的:只看文档语义,不看查询意图。Re-ranking 做”双向”判断,能识别”登录失败”和”登录功能”的差别。
工作原理
# Re-ranking 流程(伪代码) |
效果对比:
| 方法 | 精确率 | 速度 | 适用场景 |
|---|---|---|---|
| 仅向量检索 | 中等 | 快 | 对精度要求不高的场景 |
| 向量检索 + Re-ranking | 高 | 中等 | 生产环境,对精度要求高 |
💡 实战提示:
- 检索阶段:用向量检索快速筛选(Top 20-50)
- 重排阶段:用 Cross-Encoder 精确排序(Top 5-10)
- 平衡点:在精度和速度之间找到平衡
3.2 Query Transformation(查询转换):提升召回率
用户问”这个功能怎么用?”——向量库不知道”这个”指什么。或者只输入”登录”,太短,召回不全。
查询转换用 LLM 把模糊、依赖上下文的查询改写成独立完整的句子,提升召回率。
查询重写(Query Rewriting)
场景:用户问”这个功能怎么用?”,需要结合历史对话才知道”这个”指登录功能
方法:使用 LLM 将依赖上下文的查询转为独立完整的句子。
示例:
# 查询重写(伪代码) |
查询扩展(Query Expansion / RAG-Fusion)
场景:用户查询简短,可能遗漏相关关键词。
方法:添加同义词或相关关键词,生成多个查询版本,分别检索后合并结果。
示例:
# 查询扩展(伪代码) |
效果对比:
| 方法 | 召回率 | 计算成本 | 适用场景 |
|---|---|---|---|
| 原始查询 | 低 | 低 | 查询已经很完整 |
| 查询重写 | 中 | 中 | 查询依赖上下文 |
| 查询扩展 | 高 | 高 | 查询简短,需要高召回率 |
💡 实战提示:
- 简单查询:直接使用原始查询
- 依赖上下文:使用查询重写
- 需要高召回率:使用查询扩展
3.3 RAG 与 Agent 的集成(Multi-Hop RAG)
场景:多步骤推理任务,单轮 RAG 无法回答,如”总结 A 文档对 B 项目的影响”。
机制:Agent 将复杂任务拆成子问题,分别调用 RAG 检索知识,收集 Observation 后综合生成最终答案。
为什么需要 Multi-Hop RAG?
单轮 RAG 的局限:
- 一次检索只能回答一个问题
- 无法处理需要多步骤推理的复杂问题
- 无法融合多个文档的知识
Multi-Hop RAG 的优势:
- 支持多步骤推理
- 可以融合多个文档的知识
- 可以处理复杂的决策任务
工作原理
# Multi-Hop RAG 示例(伪代码) |
与 ReAct 结合
Multi-Hop RAG 可以与 ReAct 思维链结合,让 LLM 在每一步检索后都进行推理与自我修正。
示例:
Thought: 用户问的是"总结用户登录功能文档对测试平台项目的影响",这需要: |
💡 实战提示:
- 简单问题:使用单轮 RAG
- 复杂问题:使用 Multi-Hop RAG
- 需要推理:结合 ReAct 思维链
🔍 总结:RAG 的工程化价值
RAG 将 LLM 从”静态百科全书”升级为动态知识专家,解决了 LLM 的两大核心问题:
RAG 的核心价值
| 问题 | 传统 LLM | RAG 解决方案 |
|---|---|---|
| 知识时效性 | 训练数据截止到某个时间点 | 实时访问最新信息和私有数据 |
| 知识范围 | 只能使用训练时的数据 | 可以访问企业私有文档、内部知识库 |
| 幻觉问题 | 可能编造错误信息 | 答案可追溯、可验证,有据可查 |
| 上下文限制 | Context Window 有限 | 通过检索只注入相关文档,突破限制 |
构建高效 RAG 系统的关键环节
- 分块(Chunking):保证语义完整性,选择合适的分块策略
- 向量化(Embedding):选择合适的 Embedding 模型,确保检索精度
- 索引(Vector Database):选择高性能向量数据库,支持大规模检索
- 后处理(Re-ranking、Query Transformation):提升精确率和召回率
RAG 与 Agent 的结合
RAG 不仅是知识检索工具,更是 Agent 的”知识库”:
- 单轮 RAG:回答简单问题,提供知识支持
- Multi-Hop RAG:处理复杂推理任务,融合多文档知识
- RAG + ReAct:结合思维链,实现可控的知识检索和推理
💡 核心理解:RAG 是 Agent 时代高可信度回答的基石。掌握了 RAG,你就掌握了让 LLM 访问外部知识、突破知识限制的关键技术。
📚 延伸阅读(含可直接访问链接)
以下资源按主题分类,每个资源都附有简要说明,帮助你选择合适的学习材料。
🔍 RAG 综述与原理
A Survey on Retrieval-Augmented Generation(RAG 综述论文):RAG 领域的全面综述,涵盖原理、应用和最新进展。必读论文,适合想系统了解 RAG 的读者。
Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks(RAG 原始论文):RAG 的开创性论文,首次提出 RAG 架构。必读论文,适合想理解 RAG 原理的读者。
RAG 技术详解(中文博客):Lilian Weng 的 RAG 技术详解,有中文翻译版本。适合中文读者,内容深入。
🧱 Chunking(分块)
LangChain 文档 — Text Splitter(文本分割器):LangChain 的文本分割器文档,包含多种分块策略。强烈推荐,适合需要实现分块的开发者。
Semantic Chunking(语义分块):Pinecone 的语义分块指南,包含实战示例。适合想深入了解语义分块的读者。
Parent-Document Retriever(父文档检索器):LangChain 的父文档检索器实现。适合需要实现父文档策略的开发者。
🔢 Embedding(嵌入)
Sentence Transformers 官方文档:Sentence Transformers 的官方文档,包含模型列表和使用指南。强烈推荐,适合需要选择 Embedding 模型的开发者。
MTEB: Massive Text Embedding Benchmark(Embedding 模型排行榜):Embedding 模型的性能排行榜。适合需要选择最佳模型的开发者。
中文 Embedding 模型推荐:FlagEmbedding 项目,包含多个中文 Embedding 模型。适合中文场景的开发者。
🗄️ Vector Database(向量数据库)
Pinecone 官方文档:Pinecone 的官方文档,包含快速入门和最佳实践。适合使用 Pinecone 的开发者。
Milvus 官方文档:Milvus 的官方文档,包含部署和使用指南。适合需要自部署向量数据库的开发者。
Weaviate 官方文档:Weaviate 的官方文档,包含多模态检索功能。适合需要复杂查询的开发者。
HNSW Algorithm Explained(HNSW 算法详解):HNSW 索引算法的原始论文。适合想理解向量检索原理的读者。
🚀 进阶优化
LlamaIndex 官方教程:LlamaIndex 的官方教程,包含 Query Rewriting、RAG-Fusion 等进阶技巧。强烈推荐,适合想深入学习 RAG 的开发者。
Re-ranking with Cross-Encoders(重排序):Sentence Transformers 的 Cross-Encoder 使用指南。适合需要实现 Re-ranking 的开发者。
Multi-Hop RAG(多跳检索):LlamaIndex 的多跳检索实现。适合需要处理复杂查询的开发者。
🛠️ 实战框架
LangChain RAG 教程:LangChain 的 RAG 实战教程,包含完整示例。强烈推荐,适合想快速上手的开发者。
LlamaIndex RAG 教程:LlamaIndex 的 RAG 教程,包含多种检索策略。适合想系统学习的开发者。
Haystack RAG 教程:Haystack 的 RAG 教程,包含完整流程。适合使用 Haystack 的开发者。
🔔 系列说明
本文是《🧠 LLM/Agent 从入门到精通:告别浅尝辄止》系列第 4 篇。上一篇:想要 JSON 却得到废话?Prompt 工程的三大核心技巧。下一篇:GPT-4、Claude、Llama 怎么选?模型选型避坑指南 —— 参数量、推理速度、成本如何权衡?













