RAG 介绍:让模型先检索再回答

RAG 介绍:让模型先检索再回答

大语言模型可以根据输入生成流畅的回答,但它并不天然知道团队内部文档、最新业务数据或某个项目的私有知识。即使模型训练时见过相关内容,也很难确认它记住的信息是否准确、是否已经过期。

RAG(Retrieval-Augmented Generation,检索增强生成)处理这个问题的思路很直接:先从外部知识库找出与问题相关的内容,再把这些内容连同问题一起交给模型回答。 模型不再只依赖参数里保存的知识,而是获得了一份针对当前问题临时准备的参考资料。

RAG 的基本链路

一个常见的 RAG 系统可以拆成离线准备和在线问答两部分。

离线阶段负责整理知识:

原始文档
  → 解析与清洗
  → 切分成文档片段
  → 建立索引
  → 保存片段及其来源信息

在线阶段负责回答问题:

用户问题
  → 理解或改写查询
  → 从索引中检索相关片段
  → 筛选、排序和组装上下文
  → 交给模型生成回答
  → 返回答案与引用来源

这里真正重要的不是“用了向量数据库”,而是模型回答前多了一条获取外部证据的路径。检索可以使用关键词搜索、向量搜索,也可以把两者组合起来。只要系统能根据问题找到合适的资料,再把资料可靠地交给模型,就属于这类思路。

文档为什么要切分

直接把整份文档塞进上下文通常并不理想。文档可能很长,相关信息只占其中一小部分;无关内容越多,成本越高,也越容易干扰模型判断。

因此,知识入库前通常会被切成较小的片段。片段太大,检索结果会带回很多噪声;片段太小,又可能丢失标题、上下文和完整语义。例如,一条接口的错误处理说明如果和接口名称被切开,即使检索到了说明,模型也未必知道它属于哪个接口。

切分不是单纯按固定字数截断。更合适的做法往往是保留文档结构,按标题、段落、代码块或业务对象划分,同时记录文件名、章节、更新时间、权限等元数据。后续检索和引用都依赖这些信息。

向量检索在做什么

向量检索会先用 Embedding 模型把问题和文档片段转换成向量,再按相似度找出距离较近的内容。它擅长匹配语义相近但用词不同的表达。例如,用户问“怎样找回账号”,文档写的是“重置登录凭证”,向量检索仍可能把两者联系起来。

不过,语义相近不等于答案正确。产品型号、错误码、人名和精确版本号通常更依赖关键词匹配。实践中常见的混合检索会同时保留关键词和向量结果,再通过规则或重排模型选出更适合进入上下文的片段。

RAG 不会自动消除幻觉

RAG 给模型增加了证据,但并不保证最终答案一定可靠。问题可能出现在链路中的任何一段:

  • 知识库里根本没有答案,或者内容已经过期。
  • 文档切分破坏了必要的上下文。
  • 查询表达与文档差异太大,检索没有召回正确片段。
  • 检索结果相关但不完整,缺少回答问题的关键条件。
  • 上下文已经包含正确答案,模型却忽略、误解或过度推断。

这意味着调试 RAG 时不能只看最后生成的文字。更有效的做法是先检查“正确证据有没有被检索出来”,再检查“模型有没有忠实地使用证据”。RAGAs 论文也把评估拆成检索相关性、回答忠实度和回答质量等不同维度,因为一个最终分数很难说明问题到底发生在哪里。

当资料不足时,系统还应该允许模型明确回答“不知道”或请求补充信息。强迫模型每次都给出完整答案,只会把检索失败隐藏成更自然的幻觉。

RAG 和模型微调的区别

RAG 主要改变模型在推理时能看到什么,适合补充经常变化、需要引用来源或不应该写进模型参数的知识。文档更新后,只需要重新处理受影响的内容,不必重新训练整个模型。

微调主要改变模型如何完成任务,更适合调整输出格式、语气、行为模式或特定任务能力。它不适合作为频繁更新事实的主要手段。两者也不是互斥关系:系统可以用微调后的模型遵循特定回答规范,同时通过 RAG 获取实时知识。

学习 RAG 需要掌握什么

刚开始学习 RAG 时,很容易先把注意力放在框架、向量数据库和模型选型上。这些工具可以帮助快速搭出 Demo,但真正决定系统效果的,通常是能不能看懂检索链路,并判断问题发生在哪一层。

大语言模型的基本使用

不需要先掌握模型训练,但要理解 token、上下文窗口、提示词和生成结果的不确定性。至少应该能够调用一个模型,控制输入上下文和输出格式,并知道模型可能忽略资料、错误推断或在证据不足时编造答案。

这里的重点是建立一个边界:模型负责理解和生成,不负责保证输入资料本身正确。RAG 给了模型参考内容,事实是否可靠仍然取决于知识库、检索结果和提示约束。

文档处理与数据建模

RAG 的知识来源很少是干净、统一的文本。实际数据可能来自 Markdown、PDF、网页、数据库和内部接口。学习时需要掌握基本的解析、清洗、去重和切分,并保留标题、来源、更新时间、权限等元数据。

这部分看起来不像 AI,却会直接影响后面的检索。文本解析错误、表格结构丢失或权限信息遗漏,无法靠换一个更强的生成模型补回来。

信息检索基础

RAG 首先是一个检索系统,因此需要理解关键词检索、Embedding、向量相似度、top-k、过滤和重排分别解决什么问题。进一步还应该知道召回率和准确率的区别:召回太低会漏掉答案,召回结果太杂则会把噪声送进模型。

不必一开始就研究向量索引的底层算法,但应该能解释一次检索为什么命中或漏掉某段内容。等数据量和性能真正成为问题,再深入近似最近邻索引、分片和量化会更自然。

RAG 链路的组织

能完成一次向量搜索只是起点。一个可用的链路还可能包含查询改写、元数据过滤、混合检索、重排、上下文去重、引用拼接和无答案处理。学习这些能力时,不要一次全部加上,而是让每个环节对应一个已经观察到的问题。

例如,错误码总是搜不到,可以补关键词检索;用户问题太口语化,可以尝试查询改写;相关片段很多但排序不准,再考虑重排。这样才能知道复杂度换来了什么,而不是把整套术语堆进流程。

评估与调试

RAG 不能只靠手动问几个问题来判断效果。需要准备一组有代表性的问题,并记录预期证据、可接受答案和无法回答的情况。评估时至少分开观察:

  • 检索是否找到了包含答案的片段。
  • 返回的片段是否相关、完整,并且没有明显冲突。
  • 回答是否忠实于检索到的证据。
  • 系统在没有证据时能否拒绝猜测。
  • 延迟、调用成本和索引更新时间是否可接受。

有了这组基线,修改切分大小、Embedding 模型、检索策略或提示词时,才知道整体效果是真的改善,还是只修好了眼前的一个例子。

工程与安全能力

RAG 最终仍然是一个需要长期运行的软件系统。API 调用、异步任务、缓存、日志、失败重试和增量更新都属于基础工程能力。知识库涉及内部数据时,还要保证检索阶段就执行权限过滤,不能先把无权访问的内容交给模型,再要求模型不要回答。

还需要把外部文档当作不可信输入。文档中的提示注入、恶意链接或错误指令不应该获得高于系统规则的权限;日志和评估数据也不应无意中保存敏感原文。

一个更自然的学习顺序

可以先选一小组结构清楚的文档,完成最小链路:解析文档、切分、建立索引、检索、组装上下文和生成带来源的回答。然后准备十几个真实问题,逐个检查检索结果,并记录失败发生在哪一步。

当最小链路能够稳定回答简单问题后,再按实际症状加入混合检索、查询改写、重排和缓存。最后才需要研究更底层的索引优化、Embedding 微调或专门训练检索器。这个顺序能先建立完整心智模型,也能避免把框架的默认行为误认为 RAG 本身。

什么时候值得使用

RAG 更适合以下场景:

  • 答案来自内部文档、产品手册、知识库或用户自己的数据。
  • 内容会持续更新,不能只依赖模型训练时的知识。
  • 回答需要附带可核对的来源。
  • 数据量超过单次上下文适合承载的范围。

如果资料很少而且变化不频繁,直接把完整内容放进上下文可能更简单。如果问题本身不依赖外部知识,例如改写文案、整理用户已提供的内容或执行纯推理任务,RAG 也不会自动带来收益。

最早系统化提出 RAG 这一名称的论文讨论的是把参数化生成模型与可检索的非参数化记忆结合起来。今天工程中所说的 RAG 范围更宽,但核心判断没有变化:模型不应该凭记忆回答所有问题,而应该在需要事实时先找到证据,再基于证据生成结果。