RAG 检索增强生成入门:从原理到最小可用实现

RAG 解决的不是模型不够聪明,而是模型不知道你的数据、知识有截止日期、且会胡说。本文拆解检索、增强、生成三步,重点讲清分块策略与四类常见失败模式。

先说结论:RAG 解决的不是「模型不够聪明」

很多人第一次接触 RAG(Retrieval-Augmented Generation,检索增强生成),会以为它是用来提升模型智力的。这是个误解,而且这个误解会直接导致你把 RAG 用错地方。

RAG 真正解决的是三个具体问题:

  1. 模型不知道你的私有数据——你的公司文档、产品手册、内部规范,模型训练时根本没见过
  2. 模型的知识有截止日期——训练完成后发生的事,它一概不知
  3. 模型会一本正经地胡说——也就是幻觉,而这在需要准确性的场景里是致命的

注意这三个问题的共同点:它们都是知识问题,不是推理问题。RAG 的思路是「在回答问题之前,先去查资料,然后基于查到的资料回答」。

所以更准确的说法是:RAG 是给模型外挂了一个可检索的知识库,而不是让模型变聪明。

理解了这一点,后面所有的工程决策都会变得清晰。

RAG 的最小工作流程

抛开各种框架的包装,RAG 的核心流程只有三步:

用户提问
   ↓
1. 检索(Retrieve):从知识库中找到最相关的若干片段
   ↓
2. 增强(Augment):把检索到的片段塞进给模型的提示词里
   ↓
3. 生成(Generate):模型基于「问题 + 检索内容」生成答案

就这么简单。所有复杂的工程实践,都是在优化这三步中的某一步。

举个具体的例子。假设用户问「我们产品的退款政策是什么?」

不用 RAG,模型会:

  • 完全不知道,可能说「我无法回答」
  • 或者更糟——编一个听起来合理的政策

用 RAG,系统会:

  1. 把「退款政策」转成向量,去知识库里检索
  2. 找到《用户协议》里的退款条款、《FAQ》里的退款说明
  3. 把这些原文和问题一起给模型:「根据以下资料回答问题:……」
  4. 模型基于真实资料作答,还能注明出处

这个差异在客服、法律、医疗、企业内部问答等场景里,是可用和不可用的区别。

第一步:检索——最容易做砸的地方

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 的核心逻辑就是「检索 + 拼接 + 生成」三步,用几百行代码就能实现。上框架会引入抽象层,出问题时你搞不清楚是框架的问题还是你的配置问题。

建议的演进路径

  1. 第一阶段:手写最简版本。向量用现成 API,存储在内存或 Postgres,检索用余弦相似度。目标是把流程跑通
  2. 第二阶段:数据量上来了,引入专门的向量数据库。可以看看 QdrantPinecone,也可以先用 pgvector 撑一阵
  3. 第三阶段:效果不满足,加混合检索和重排序
  4. 第四阶段:工程复杂度上来了,再考虑 LlamaIndex 这类框架来管理

跳过前两个阶段直接上第四阶段,是新手最常犯的错误。

什么时候不该用 RAG

最后说一个容易被忽略的判断:RAG 不是万能的

以下场景,RAG 可能不是好选择:

  • 需要理解全局的问题:比如「总结这份 100 页报告的主要观点」。检索只能拿到局部片段,模型看不到全貌
  • 需要多跳推理的问题:比如「A 公司的 CEO 的母校在哪」,需要先查 CEO 是谁,再查该校。单次检索做不到
  • 知识库极小且稳定:如果总共就几页内容,直接全部塞进提示词就行,不需要检索
  • 需要精确计算或实时数据:这些应该走工具调用(Function Calling),而不是检索

判断标准很简单:如果问题的答案分散在文档的不同位置,需要综合,那么单纯的 RAG 通常不够,你需要的是 RAG 加 Agent 的组合。

关于这个方向,AI Agent 工作流设计:状态机与工具调用 有更深入的讨论。

小结

RAG 的本质是给模型外挂知识库,核心是三步:检索、增强、生成。

实践中,90% 的效果问题出在检索环节,而检索环节里 90% 的问题出在分块策略。所以如果你要优化一个效果不佳的 RAG 系统,从分块和检索质量入手,比换模型、改提示词有效得多。

给一个可以直接用的行动建议:先把你的知识库切好块,然后拿 20 个真实用户问题做测试,看目标内容能不能稳定出现在检索结果的前 5 位。 这一步做好了,RAG 就成功了八成。

相关阅读

返回 AI 教程列表