RAG 是 Retrieval-Augmented Generation,中文常译为“检索增强生成”。它解决的问题是:模型不知道私有、最新或具体的业务知识时,先从外部资料中找到证据,再基于证据回答。
RAG 的原始思想来自 2020 年的 Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks。今天工程里的 RAG 范围更广,通常包括文档处理、检索、重排序、引用、权限和质量评测。
用一个业务问题理解
公司有 500 页制度,用户问:
北京出差住宿每天最多报销多少?
系统不应让模型凭记忆猜测,而应执行:
1 | 用户问题 |
RAG 中的三个字母正好对应这条主线:
- Retrieval:检索相关资料。
- Augmented:把资料加入模型当前 Context。
- Generation:模型基于资料生成答案。
离线入库流程
资料通常提前处理,而不是用户每问一次就重新解析全部文件。
1 | 数据源 |
解析
解析质量决定检索上限。扫描 PDF 需要 OCR;表格、标题、页码、列表和图片说明不能只当作无结构字符串。解析后应保留文档 ID、章节、页码和原文定位。
切片
切片太小会丢失上下文,太大会混入无关内容并占用更多 Token。常见做法包括固定 Token 窗口、按标题和段落切分、语义切分,以及为表格和代码使用专门策略。
一个可用的 Chunk 至少应包含:
1 | 正文 + 文档标题 + 章节路径 + 来源位置 + 权限标签 + 版本信息 |
建立索引
向量索引用于语义搜索,倒排索引用于关键词、编号和专有名词搜索。需要复杂权限时,先设计可过滤的元数据,不要在检索完成后才发现无法按用户隔离文档。
在线查询流程
1 | 问题 |
查询改写
用户的问题可能很短,包含代词或上下文。例如“那上海呢”需要结合上一轮问题补全为可检索查询。改写必须保留原意,不能悄悄替用户增加业务条件。
召回与重排序
召回阶段宁可获得一批可能相关的候选,重排序阶段再精细判断。Top K 过小可能漏掉正确证据,过大又会增加噪声和成本。
生成与拒答
Prompt 应要求模型只根据提供的资料回答、标明来源,并在证据不足或冲突时明确说明。RAG 能降低无依据回答,但不能保证绝对正确。
一个最小伪代码
1 | async function answerQuestion(question, user) { |
这段代码没有绑定具体框架。retrieve 可以连接 Elasticsearch、OpenSearch、pgvector、专用向量数据库或托管 File Search。
托管、半自建和自建
| 方式 | 自己负责什么 | 适合场景 |
|---|---|---|
| 托管式 | 上传文件、配置知识库和使用权限 | 原型、小型项目、快速验证 |
| 半自建 | 解析、切片、同步、检索策略,复用现成模型和数据库 | 多数正式项目 |
| 深度自建 | 模型部署、检索引擎和完整平台 | 强隐私、大规模或特殊算法需求 |
“自己搭 RAG”通常是把现成的解析器、Embedding 模型、搜索引擎和大模型 API 组合成可控系统,并不意味着从零训练大模型或自己实现向量数据库。
生产系统不能漏掉的部分
- 权限必须在检索阶段生效,不能先取回无权内容再依赖模型隐藏。
- 文档新增、修改、删除和失效都要同步到索引。
- 同一制度存在多个版本时,要能判断生效时间和优先级。
- 回答要带可验证引用,必要时允许用户打开原文位置。
- 需要限制 Prompt Injection 对工具和系统指令的影响。
- 记录问题、候选、最终证据、回答、耗时和成本,便于复盘。
- 建立离线问题集和线上反馈,防止修改切片或模型后质量悄悄下降。
什么时候不需要 RAG
- 资料很少,可以直接安全地放入 Context。
- 任务只是翻译、润色或格式转换。
- 需要查询精确实时数据,直接调用数据库或业务 API 更合适。
- 固定规则可以用普通代码可靠执行,不需要模型检索。
一句话记忆
1 | RAG 不是训练模型,而是先找到有权限、有效且相关的证据, |