RAG 检索增强生成入门:从原理到最小可用实现
RAG 解决的不是模型不够聪明,而是模型不知道你的数据、知识有截止日期、且会胡说。本文拆解检索、增强、生成三步,重点讲清分块策略与四类常见失败模式。
先说结论:RAG 解决的不是「模型不够聪明」
很多人第一次接触 RAG(Retrieval-Augmented Generation,检索增强生成),会以为它是用来提升模型智力的。这是个误解,而且这个误解会直接导致你把 RAG 用错地方。
RAG 真正解决的是三个具体问题:
- 模型不知道你的私有数据——你的公司文档、产品手册、内部规范,模型训练时根本没见过
- 模型的知识有截止日期——训练完成后发生的事,它一概不知
- 模型会一本正经地胡说——也就是幻觉,而这在需要准确性的场景里是致命的
注意这三个问题的共同点:它们都是知识问题,不是推理问题。RAG 的思路是「在回答问题之前,先去查资料,然后基于查到的资料回答」。
所以更准确的说法是:RAG 是给模型外挂了一个可检索的知识库,而不是让模型变聪明。
理解了这一点,后面所有的工程决策都会变得清晰。
RAG 的最小工作流程
抛开各种框架的包装,RAG 的核心流程只有三步:
用户提问
↓
1. 检索(Retrieve):从知识库中找到最相关的若干片段
↓
2. 增强(Augment):把检索到的片段塞进给模型的提示词里
↓
3. 生成(Generate):模型基于「问题 + 检索内容」生成答案
就这么简单。所有复杂的工程实践,都是在优化这三步中的某一步。
举个具体的例子。假设用户问「我们产品的退款政策是什么?」
不用 RAG,模型会:
- 完全不知道,可能说「我无法回答」
- 或者更糟——编一个听起来合理的政策
用 RAG,系统会:
- 把「退款政策」转成向量,去知识库里检索
- 找到《用户协议》里的退款条款、《FAQ》里的退款说明
- 把这些原文和问题一起给模型:「根据以下资料回答问题:……」
- 模型基于真实资料作答,还能注明出处
这个差异在客服、法律、医疗、企业内部问答等场景里,是可用和不可用的区别。
第一步:检索——最容易做砸的地方
RAG 效果不好,绝大多数问题出在这一步。而检索做不好,通常是分块(chunking)策略的问题。
分块为什么这么重要
你需要把长文档切成小片段才能做向量检索,因为:
- 模型有上下文长度限制
- 整个文档做向量会稀释语义,检索精度极差
- 检索到不相关的大段文本会干扰模型
切分方式直接决定检索质量。常见错误是按固定字数硬切:
错误示范:每 500 字切一刀
结果是句子被拦腰截断,语义破碎。比如一个完整的表格被切成两半,检索到前半段完全看不懂。
更好的原则是「按语义边界切」:
- 按标题层级切(
##一节为一块) - 按段落切,保持段落完整
- 代码、表格、列表尽量不拆开
- 块之间保留一定重叠(overlap),避免边界信息丢失
实践中,块大小在 200–800 字之间是个常见的起点,但更重要的是内容本身的结构。技术文档适合按章节切,会议记录适合按发言人或主题切,法律合同适合按条款切。
没有通用的最优分块策略,只有适合你数据的策略。
嵌入模型的选择
分块之后,要把每块文本转成向量(embedding)。这里有几个实际考量:
- 中文效果:有些英文为主的嵌入模型在中文上表现明显下降,选型时要用你自己的数据实测
- 维度与成本:维度越高通常效果越好,但存储和检索成本也越高
- 维度一致性:写入和查询必须用同一个嵌入模型,换了模型就要重建全部向量
最后一点是新手最容易踩的坑:中途换嵌入模型,但只重建了部分数据,导致检索结果诡异。嵌入模型一旦确定,就把它当成数据库 schema 一样对待。
相似度检索的局限
最基础的检索是「找向量距离最近的 Top-K 个块」。但这有个问题:
语义相似不等于答案相关。
比如用户问「RAG 有什么缺点」,可能检索到一段讲「RAG 的优点」的文字,因为两段都满是「RAG」这个词,向量距离很近。
工程上的缓解手段有:
- 混合检索:向量检索 + 关键词检索(BM25)结果融合,兼顾语义和字面匹配
- 重排序(Rerank):先粗召回 20–50 条,再用专门的 rerank 模型精排出真正相关的 Top-5
- 元数据过滤:先按分类、时间、权限等条件缩小范围,再做向量检索
其中重排序的性价比最高。粗召回阶段放宽标准(保证不漏),精排阶段严格筛选(保证准),这个两级结构在实践里效果提升非常明显。
第二步:增强——提示词怎么写才对
检索到内容后,怎么把它交给模型是有讲究的。
基本结构大致是这样:
你是一个基于资料回答问题的助手。
请严格根据以下资料回答用户问题。如果资料中没有相关信息,
明确说明「资料中未提及」,不要凭借常识推测。
资料:
[1] (检索到的片段一)
[2] (检索到的片段二)
[3] (检索到的片段三)
用户问题:{用户的问题}
请在回答末尾标注引用的资料编号。
这里有几个关键点:
1. 明确约束「只能基于资料回答」
不加这句,模型很可能把检索到的内容和自己的训练知识混在一起,你就失去了 RAG 的准确性优势。
2. 要求「不知道就说不知道」
这是抑制幻觉最有效的一招。模型有强烈的「必须给出答案」的倾向,必须显式告诉它可以拒答。
3. 给片段编号并要求引用
好处有两个:一是用户能验证答案来源,二是模型在需要引用时会更认真地对待资料内容。
4. 控制塞入的片段数量
不是越多越好。塞入过多片段会:
- 引入噪音,干扰判断
- 占据上下文窗口,挤压对话空间
- 增加 token 成本
通常 3–5 个高质量片段,比 15 个混杂片段效果好。
第三步:生成——别忽略这一环
生成看起来是最简单的一步(调模型 API 而已),但仍有几个实际问题。
上下文窗口怎么用
如果检索到的片段加起来就超过了模型窗口,你需要策略:
- 截断:按相关性排序,从最相关的开始塞,直到接近窗口上限
- 压缩:让模型先把每段压缩成要点(但这会引入额外成本和信息损失)
- 分步:先让模型筛选哪些片段真正相关,再基于筛出的内容回答
成本控制
RAG 的成本结构很特殊:每次提问都要把检索到的资料一起送进模型,这意味着:
- token 消耗比普通对话高得多
- 长文档场景下,成本可能高一个数量级
控制手段包括:
- 严格控制塞入的片段数量与长度
- 对高频问题做缓存(相同问题直接返回上次答案)
- 对简单问题路由到便宜的小模型
关于这部分,可以参考 大模型工程实战:从 Prompt 到生产上线,里面有更系统的成本优化讨论。
常见失败模式与排查
这部分是我认为最有价值的内容——别人踩过的坑。
症状一:检索不到应该能找到的内容
可能原因:
- 分块把关键信息切碎了
- 嵌入模型不适配你的领域(比如医学术语)
- 用户提问的措辞和文档措辞差异太大
排查方法:直接把用户问题和知识库所有块的相似度算出来,人工看看目标块排第几。如果目标块根本排不进前 50,就是检索层的问题,跟模型无关。
症状二:检索到了,但答案还是错的
可能原因:
- 提示词没约束住,模型在自由发挥
- 检索到的片段包含过时信息,与正确信息冲突
- 多个片段互相矛盾,模型选错了
排查方法:把实际送给模型的完整提示词打印出来看。很多时候问题一眼就能看出来。
症状三:答案对,但格式不稳定
可能原因:
- 输出格式约束不够明确
- 提示词里没有给示例
排查方法:用结构化输出(JSON schema)强约束,而不是靠自然语言描述格式。
症状四:答非所问
可能原因:这是最常见也最容易被误诊的问题。多半是多轮对话的上下文污染——用户之前问过别的话题,历史消息干扰了本轮的检索。
排查方法:检查检索时用的是原始问题,还是「结合历史改写后的问题」。多轮场景下,通常需要先让模型把「用户真正想问什么」重写成一个独立完整的问题,再去检索。
技术选型:别一上来就上框架
市面上的 RAG 框架很多,但我的建议是:先用最朴素的方案跑通,再按需引入工具。
原因很简单:RAG 的核心逻辑就是「检索 + 拼接 + 生成」三步,用几百行代码就能实现。上框架会引入抽象层,出问题时你搞不清楚是框架的问题还是你的配置问题。
建议的演进路径:
- 第一阶段:手写最简版本。向量用现成 API,存储在内存或 Postgres,检索用余弦相似度。目标是把流程跑通
- 第二阶段:数据量上来了,引入专门的向量数据库。可以看看 Qdrant 或 Pinecone,也可以先用 pgvector 撑一阵
- 第三阶段:效果不满足,加混合检索和重排序
- 第四阶段:工程复杂度上来了,再考虑 LlamaIndex 这类框架来管理
跳过前两个阶段直接上第四阶段,是新手最常犯的错误。
什么时候不该用 RAG
最后说一个容易被忽略的判断:RAG 不是万能的。
以下场景,RAG 可能不是好选择:
- 需要理解全局的问题:比如「总结这份 100 页报告的主要观点」。检索只能拿到局部片段,模型看不到全貌
- 需要多跳推理的问题:比如「A 公司的 CEO 的母校在哪」,需要先查 CEO 是谁,再查该校。单次检索做不到
- 知识库极小且稳定:如果总共就几页内容,直接全部塞进提示词就行,不需要检索
- 需要精确计算或实时数据:这些应该走工具调用(Function Calling),而不是检索
判断标准很简单:如果问题的答案分散在文档的不同位置,需要综合,那么单纯的 RAG 通常不够,你需要的是 RAG 加 Agent 的组合。
关于这个方向,AI Agent 工作流设计:状态机与工具调用 有更深入的讨论。
小结
RAG 的本质是给模型外挂知识库,核心是三步:检索、增强、生成。
实践中,90% 的效果问题出在检索环节,而检索环节里 90% 的问题出在分块策略。所以如果你要优化一个效果不佳的 RAG 系统,从分块和检索质量入手,比换模型、改提示词有效得多。
给一个可以直接用的行动建议:先把你的知识库切好块,然后拿 20 个真实用户问题做测试,看目标内容能不能稳定出现在检索结果的前 5 位。 这一步做好了,RAG 就成功了八成。