RAG 是 Retrieval-Augmented Generation 的缩写,中文通常译为「检索增强生成」。应用在 LLM 生成答案前,先从外部知识源中检索相关内容,再把这些内容与系统指令、用户问题一起交给模型。
这套方法让一次生成可以使用模型训练之外的信息,例如企业文档、产品手册、Wiki、数据库记录和持续更新的知识库。知识更新时,应用可以更新索引,无需等待模型重新训练。

2020 年发表的论文《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》把预训练模型的参数称为 parametric memory,并将外部 dense vector index 视为 non-parametric memory。现在工程语境中的 RAG 更宽泛:只要应用先检索外部信息,再用检索结果辅助生成,通常都会归入 RAG。
RAG 与 context 的关系
Context 是模型生成当前答案时能够读取的全部输入。它可能包含:
System Prompt 与开发者指令;
对话历史和当前问题;
工具调用结果;
通过 RAG 找到的文档片段;
应用在运行时补充的用户、时间或业务状态。
RAG 是应用构建 context 的一种方法。检索结果进入 Prompt 后,对 LLM 而言仍然只是输入 token。除非应用在内容中标出标题、URL、文档 ID 等来源信息,否则模型没有独立的来源通道可以判断某段文字来自用户输入、数据库还是检索系统。
可以把二者的关系写成:
Context = 指令 + 对话 + 当前问题 + 工具结果 + 检索内容 + 其他运行时信息
RAG = Retrieve(检索)+ Augment(补充 Prompt)+ Generate(生成)因此,RAG 产出的内容只是 context 的一部分;并非所有 context 都来自 RAG。
一套 RAG 系统包含两个阶段
一套可维护的 RAG 系统通常分为索引阶段和查询阶段,其中的检索也不限于「把问题转换为 embedding,再查询 vector database」。
索引阶段:把知识变成可检索数据
索引阶段负责处理知识源。PDF、Markdown、网页和数据库记录需要先解析成文本,再按标题、段落、代码块或语义边界切分。每个 chunk 通常还会保存文档 ID、版本、更新时间、访问范围和原始 URL 等元数据。
语义检索会为 chunk 生成 embedding,并写入 vector store。关键词检索则建立倒排索引。数据来自关系型数据库时,也可以保留结构化查询能力,不必先把所有记录转换为向量。
切分策略会直接影响检索结果。chunk 太小,内容可能失去标题、章节和前后条件;chunk 太大,又会引入无关信息并占用更多 context。索引更新、删除和权限变化也要同步到检索层,否则系统可能继续返回过期或无权访问的内容。
查询阶段:先找证据,再组织答案
一次查询通常包含以下步骤:
接收问题,并按需要进行查询改写、实体识别或 embedding 计算。
使用语义检索、关键词检索、SQL 或外部 API 找到候选内容。
根据租户、用户权限、时间范围和文档状态过滤结果。
对候选 chunk 进行 reranking,只保留与当前问题最相关的内容。
把来源信息、检索片段和回答规则组装进 Prompt。
由 LLM 生成答案,并返回可核对的引用。
LLM 不会直接读取 vector database。检索服务负责查询和筛选,应用负责把结果放进 Prompt,模型只处理最终收到的 context。Agentic RAG 可以让模型决定何时调用搜索工具或如何改写查询,但真正的数据访问仍由工具和应用执行。
Vector database 只是检索实现之一
RAG 描述的是工作流程,不限定存储产品或检索算法。不同知识源适合不同查询方式。
| 检索方式 | 更适合处理 | 主要特点 |
| Semantic search | 问法不同但含义接近的内容 | 使用 embedding 比较语义相似度 |
| Keyword / BM25 | 产品名、错误码、函数名等精确词项 | 对关键词和稀有词更敏感 |
| SQL | 订单、库存、权限等结构化数据 | 可以表达过滤、聚合和关联条件 |
| API / Search tool | 实时价格、工单状态或外部搜索 | 在查询时读取最新系统状态 |
OpenAI 的 Retrieval 文档把 semantic search 定义为按语义相似度返回结果,即使查询与结果几乎没有相同关键词,也可能找到相关内容。Anthropic 的 Contextual Retrieval 实践则组合 embedding、BM25 与 reranking,说明混合检索能够覆盖不同类型的匹配信号。
具体系统仍需用自己的问题集评估召回率、准确率、延迟和成本。检索方法越多,调试面也越大;没有评估数据时,很难判断新增 reranker 或查询改写是否真的改善了回答。
RAG 不保证答案正确
RAG 为模型提供外部证据,但检索和生成仍可能分别出错。
| 失败位置 | 常见表现 | 检查方向 |
| 数据源 | 文档过期、缺页或相互冲突 | 版本、更新时间与权威来源 |
| 切分 | 标题和正文分离,条件被截断 | chunk 边界、大小与重叠 |
| 检索 | 正确内容没有进入候选集 | 查询改写、索引和 recall |
| 筛选 | 相关 chunk 被阈值或权限规则排除 | filter、score 与 ACL 日志 |
| 生成 | 模型忽略证据或混合多个来源 | Prompt、引用与 groundedness |
检索到更多内容也不一定更好。无关 chunk 会占用 context,并可能干扰模型判断。合理的做法是先扩大候选集,再通过权限过滤和 reranking 压缩为少量高相关内容。
检索内容还应视为不可信输入。OWASP 将被知识库收录的恶意指令列为 indirect prompt injection 的一种来源。应用需要在数据写入、检索、工具权限和输出验证等位置共同限制影响,不能依赖 RAG 或 fine-tuning 自动消除这类风险。
RAG、long context 与 fine-tuning 处理不同问题
三种方法都可能改善输出,但改动的位置不同。
| 方法 | 改动位置 | 适合的问题 |
| RAG | 生成前检索并选择外部信息 | 私有知识、频繁更新的数据、需要引用来源的回答 |
| Long context | 一次向模型提供更多现成材料 | 文档集合较小且已知,需要跨全文理解 |
| Fine-tuning | 调整模型参数或行为模式 | 固定格式、语气、分类或稳定任务模式 |
Long context 仍然需要选择输入材料。把整个知识库放进 Prompt 往往受到 context window、延迟和成本限制,也会增加无关内容。Fine-tuning 可以改变模型如何回答,却不适合作为频繁更新业务事实的唯一载体。实际系统可以组合使用三者,例如先通过 RAG 找到权限范围内的资料,再由经过 fine-tuning 的模型按固定格式生成答案。
从可评估的检索开始
实现 RAG 前,可以先准备一组真实问题,并为每个问题标注应当命中的来源。然后分别观察两个结果:检索阶段是否找到了正确证据,生成阶段是否忠实使用了证据。
运行日志至少应保留查询文本、过滤条件、候选文档、相关性分数、最终 chunk、来源版本和答案引用。出现错误时,先判断证据是否进入 context,再判断模型是否正确使用证据。这种分层检查能把「回答不对」拆成可以定位和改进的工程问题。
延伸阅读
从聊天到交付:Agent 的可验证执行系统:继续了解 Model、Tools、Memory、Workflow 与 Guardrails 如何共同组成可执行系统。
AI 时代更需要重读《程序员修炼之道》:从工程判断、模块边界和反馈循环理解 AI 辅助开发。