跳到主要内容

RAG 入门与实践

学完 Prompt EngineeringContext Engineering 之后,最自然的下一步就是 RAG

因为很多真实场景里,模型不是“凭空回答”,而是需要:

  • 查文档
  • 查知识库
  • 查网页
  • 查企业内部资料
  • 再基于查到的内容回答

而这件事,正是 RAG 最核心的价值。

1. RAG 是什么

RAGRetrieval-Augmented Generation 的缩写,中文一般叫“检索增强生成”。

它的核心思想很简单:

  1. 用户先提问
  2. 系统先去检索相关资料
  3. 把资料放进上下文
  4. 再让模型基于这些资料生成答案

所以 RAG 不是让模型“更会背知识”,而是让模型“回答前先查资料”。

一句话理解:

RAG = 先检索,再生成

2. 为什么需要 RAG

只靠模型自身参数里的知识,通常会遇到这些问题:

  • 知识不是最新的
  • 不知道企业私有资料
  • 容易产生幻觉
  • 回答缺少依据
  • 难以处理大量文档

RAG 的意义就在于补上这些短板。

2.1 RAG 最常见的价值

  • 回答最新信息
  • 回答私有知识库
  • 给回答提供依据
  • 降低幻觉
  • 让回答更可控

3. RAG 的基本流程

一个最基础的 RAG 流程通常长这样:

  1. 用户提问
  2. Query 处理
  3. 检索相关文档
  4. 挑选最相关片段
  5. 把片段拼进 prompt/context
  6. 模型生成答案
  7. 可选:引用来源或做结果验证

可以把它拆成两大阶段:

  • Retrieval:把相关资料找出来
  • Generation:基于资料组织回答

4. 一个直观例子

假设用户问:

公司的报销流程里,差旅住宿费报销上限是多少?

如果没有 RAG,模型可能:

  • 根本不知道
  • 乱猜一个数字
  • 用通用经验回答

如果有 RAG,系统会:

  1. 去知识库里检索“报销流程”“住宿费”“差旅”
  2. 找到公司制度文档中的相关条款
  3. 把条款片段放进上下文
  4. 让模型只根据这些资料回答

最终它就能更可靠地回答:

  • 上限是多少
  • 依据在哪一条
  • 如果文档没写,明确说未提及

这就是 RAG 的典型价值。

5. RAG 的核心组件

一个完整的 RAG 系统,通常包括下面这些部分。

5.1 文档源

也就是知识从哪里来,比如:

  • Markdown 文档
  • PDF
  • 网页
  • 帮助中心
  • 数据库记录
  • Notion、Confluence、飞书文档
  • 企业内部知识库

5.2 文档切分

原始文档通常不能整篇直接拿去检索,所以要先切成更小的片段,也就是 chunk

比如把一篇很长的文档切成:

  • 每段 300 到 800 token
  • 或按标题、段落、表格结构切分

5.3 向量化

把文本变成向量表示,也就是 embedding。

有了向量之后,系统就可以做语义相似度检索,而不是只靠关键词匹配。

5.4 向量索引 / 检索库

把所有 chunk 的向量存起来,供后续检索使用。

常见实现包括:

  • 向量数据库
  • 搜索引擎
  • 混合检索系统

5.5 Retriever

也就是检索器。它负责根据用户问题找出最相关的文档片段。

5.6 Reranker

有时候检索出的前几十条不够准,这时会再加一个排序器,对候选结果重新打分排序。

5.7 Generator

也就是最终生成答案的模型。它会结合:

  • 用户问题
  • 检索结果
  • 输出要求

来组织最终回答。

6. RAG 的关键概念

6.1 Chunk

Chunk 是文档切分后的片段。

RAG 的效果很大程度上取决于 chunk 切得好不好。

如果 chunk 太大:

  • 噪音多
  • 检索不精准
  • 容易把无关内容带进去

如果 chunk 太小:

  • 上下文断裂
  • 关键信息被拆散
  • 模型读不到完整语义

6.2 Embedding

Embedding 是文本的向量表示。

它的作用是让系统能按“语义相似”而不是单纯“词面一致”来检索内容。

例如用户问:

怎么限制 API 调用频率?

系统也有机会检索到写着“限流”“rate limit”的文档,即使原文没有完全出现“调用频率”这几个字。

6.3 Top-K

Top-K 指检索时返回前多少条结果。

K 太小:

  • 可能漏掉关键内容

K 太大:

  • 噪音变多
  • 上下文变长

所以 Top-K 通常需要调优。

6.4 Recall 和 Precision

在 RAG 里非常重要。

Recall 指相关内容有没有被找回来。

Precision 指找回来的内容里,有多少是真的有用。

理想情况当然是两者都高,但实际工程里常常需要平衡。

6.5 Grounding

Grounding 指让模型回答时尽量基于检索到的资料,而不是自由发挥。

常见做法是明确告诉模型:

  • 只根据提供材料回答
  • 文档没提到就说未提及
  • 回答时引用依据

7. RAG 的常见实现路线

7.1 Naive RAG

最基础的版本:

  1. 文档切分
  2. 建 embedding
  3. 用户提问
  4. 直接向量检索
  5. 把结果塞进 prompt
  6. 输出答案

优点:

  • 上手快
  • 实现简单

缺点:

  • 容易召回不准
  • 容易上下文污染
  • 对复杂文档支持一般

7.2 Advanced RAG

在基础版上做增强,比如:

  • 混合检索
  • 查询改写
  • rerank
  • 多路召回
  • 元数据过滤
  • 来源引用

这是很多实际项目更常见的做法。

7.3 Agentic RAG

更进一步,让模型自己决定:

  • 先查什么
  • 要不要多轮检索
  • 是否需要补充追问
  • 是否需要调用别的工具

这种做法更灵活,但复杂度也更高。

8. RAG 里最常见的技巧

8.1 合理切分文档

不要机械地只按固定字符数切。

更好的策略通常是结合:

  • 标题层级
  • 段落边界
  • 代码块
  • 表格
  • 语义完整性

8.2 保留元数据

每个 chunk 除了正文,最好还保留元数据,比如:

  • 文档标题
  • 章节名
  • 来源链接
  • 更新时间
  • 文档类型
  • 权限标签

这些信息对检索过滤和最终展示都很有用。

8.3 查询改写

用户问题不一定适合直接检索,可以先改写成更适合搜索的 query。

例如把:

这个权限问题怎么开?

改成:

系统权限申请流程、账号开通、审批步骤

这通常会提高召回质量。

8.4 混合检索

不要只依赖向量检索。

很多系统会把:

  • 关键词检索
  • 向量检索
  • 元数据过滤

结合起来,也就是 Hybrid Search

这样既保留语义匹配能力,也保留精确关键词命中的能力。

8.5 加 rerank

先广泛召回,再重新排序,是非常常见的优化方式。

因为第一轮检索更像“先捞一批候选”,第二轮排序才是真正决定哪些结果最该进入上下文。

8.6 对检索结果做清洗

不要把召回结果原样全部塞给模型,通常需要:

  • 去重
  • 去噪
  • 截断
  • 合并相邻片段
  • 按相关性排序

8.7 明确回答边界

在生成阶段要明确约束模型:

  • 只根据检索材料回答
  • 没有依据就说不知道
  • 尽量引用来源

这样可以显著减少幻觉。

9. 一个典型 RAG Prompt 模板

下面是一个常见模板:

你是一个知识库问答助手。请严格根据提供的资料回答问题。

要求:
- 如果资料中能明确回答,就直接给出答案
- 如果资料中没有足够信息,请回答“资料未提及”
- 不要使用资料外的推测
- 回答后附上依据摘要

问题:
{{user_question}}

资料:
{{retrieved_chunks}}

如果要更工程化一点,还可以加来源字段、片段编号、时间戳等。

10. 实战中最常见的问题

10.1 召回不准

表现:

  • 明明知识库里有答案,但检索不到
  • 检索到了很多看起来相关、实际没用的内容

可能原因:

  • chunk 切分不合理
  • embedding 模型不适合
  • query 太口语化
  • 没有 rerank
  • Top-K 设置不合适

10.2 上下文污染

表现:

  • 检索结果太多
  • 模型抓到错误片段
  • 回答夹带无关内容

常见原因:

  • 召回太宽
  • 没做清洗
  • 没做过滤
  • 文档中噪音太多

10.3 文档有答案,但回答仍然幻觉

原因通常不是只有检索,还有生成阶段的问题,比如:

  • 没有限制模型只根据资料回答
  • 引入了太多无关上下文
  • 材料本身互相冲突
  • 模型把缺失信息自动补全了

10.4 文档更新后答案还不对

这往往意味着:

  • 索引没有重建
  • 旧 chunk 还在
  • 元数据过期
  • 多个版本没有正确区分

10.5 PDF、表格、结构化内容效果差

因为这类内容在抽取阶段就可能丢结构。

所以对这类文档常常需要:

  • 更好的解析方式
  • 保留标题和表格结构
  • 单独处理图片和扫描件

11. RAG 的评估该看什么

很多人做 RAG 只看“感觉答案还行”,但这不够。

至少应该看下面几类指标。

11.1 检索层

  • 是否召回了真正相关的内容
  • Top-K 里有多少有效片段
  • 关键文档是否稳定出现

11.2 生成层

  • 回答是否基于证据
  • 是否回答了用户问题
  • 是否出现幻觉
  • 是否引用了正确来源

11.3 端到端体验

  • 用户最终是否得到可用答案
  • 延迟是否可接受
  • 成本是否可控
  • 多轮追问时是否稳定

12. 一个实用的学习顺序

如果你想系统学习 RAG,我建议按下面顺序来:

  1. 先理解 RAG 基本流程
  2. chunk 切分
  3. embedding 和向量检索
  4. Top-K、召回和排序
  5. 学生成阶段的 grounding
  6. 学评估方法
  7. 最后再学混合检索、rerank 和 Agentic RAG

这样会比较顺,不容易一开始就陷进太复杂的系统设计里。

13. 一个简单的落地思路

如果你要自己做第一个 RAG 小项目,可以选一个很小的场景,比如:

  • 个人知识库问答
  • 某套产品文档问答
  • 某个项目的 README / docs 助手
  • 某家公司制度问答

最小可行版本可以这样做:

  1. 准备一批文档
  2. 切分成 chunk
  3. 做 embedding
  4. 建立检索索引
  5. 用户提问时先检索
  6. 把 top-k 结果拼进 prompt
  7. 要求模型严格基于资料回答

先把这个跑通,再去优化检索质量。

14. RAG 和 Context Engineering 的关系

你可以把 RAG 看成 Context Engineering 最重要的一种落地方式。

因为它本质上就是在解决:

  • 上下文从哪里来
  • 哪些材料该进入上下文
  • 进入多少
  • 怎么保证相关性

所以学完 Context Engineering 之后学 RAG,是非常自然的一步。

15. 一句话总结

RAG 的本质,不是“让模型记住更多知识”,而是“让模型在回答前先查到正确资料,再基于资料回答”。

真正决定 RAG 效果的,通常不是某一个神奇 prompt,而是下面这整条链路是不是做对了:

  • 文档怎么切
  • 检索怎么做
  • 结果怎么选
  • 上下文怎么喂
  • 回答边界怎么控

把这条链路跑顺了,RAG 才会真正好用。