rag 检索增强生成 原理

接入与开发

把检索增强生成拆成进料、切块、向量化、召回、拼装、生成六个环节,讲清每一步在做什么、新人容易卡在哪。

刚接触 RAG 的人常卡在两处:一是把它当成「给模型加个搜索」,二是照抄代码跑通了却说不清哪一步出的问题。这篇按数据流顺序把整条链路走一遍,每段只讲这一环的输入输出和常见坑,不给具体参数和版本号,需要看数字时告诉你到站内哪一页核对。

刚接触 RAG 的人常卡在两处:一是把它当成「给模型加个搜索」,以为接上检索就万事大吉;二是照抄示例代码跑通了,效果一塌糊涂却说不清哪一步出的问题。这两种情况其实是一个毛病——脑子里没有完整的数据流。

这篇按数据流顺序把整条链路走一遍,拆成进料、切块、向量化、召回、拼装、生成六个环节。每段只讲这一环的输入输出和新人容易踩的坑,不给具体参数和数字,需要看当下行情时我会告诉你到站内哪一页核对。

先想清楚:为什么要在生成前面插一步检索

模型参数里没有你的私有资料。直接问它公司内部流程,它要么编,要么含糊其辞。检索的作用就是在生成之前,把「可能相关的原文片段」塞进上下文,让模型照着原文写,而不是凭记忆写。这一步的价值不在于聪明,而在于把答案锚定在你自己的资料上。

新知识
训练截止之后发生的事,模型本身不知道,必须靠外部资料补
内部资料
产品文档、工单记录、规章制度,压根不在公开语料里
可溯源
答案要能指出「这话出自哪份文件的哪一段」,纯生成做不到

但 RAG 不是万能药。纯推理题、写代码、通用常识类任务,加检索通常没有收益,反而多一层延迟和噪声。什么情况下不适用:资料量很小(几十页以内),直接全塞进上下文更简单可靠;资料本身就是错的、过期的,检索只会把错误更稳定、更有说服力地喂给模型——这种情况该先修资料,不是先修检索。

两条并行的路:离线建库和在线问答

整条链路其实是两条并行的路,很多人把它们揉成一条,导致线上出问题时查错方向。离线那条是建库:整理原始文档,清洗,切块,向量化,写入向量库。它慢、可以批处理、出错就得重建。在线那条是问答:用户提问,问题向量化,召回片段,可选重排,拼提示词,交给模型生成回答。它要快、每次请求都跑一遍。

维度离线建库在线问答
触发时机资料更新时批量跑一次每次用户提问实时跑
耗时容忍度分钟到小时级都可以用户等不起,越快越好
出错代价要重建整个索引,成本高单次答错,重试或兜底即可
常见故障点清洗、切块、向量化召回、重排、拼装、生成

切块:决定检索上限的一步

块是检索的最小单位。切得太大,一段里混了好几个主题,召回后模型容易被无关内容带偏;切得太小,一句半截话脱离上下文,向量也表达不出完整意思。这一步做坏了,后面重排、提示词怎么调都救不回来,因为库里根本没有「对的片段」可供召回。

  1. 先清洗,再切块去页眉页脚、去乱码、去重复段落,扫描件先做 OCR。判断标准:随便抽十个块,看里面有没有混进目录页、页码、水印文字。
  2. 按语义边界切优先沿标题、段落、表格行、代码块边界切开,再按长度兜底截断。别纯粹按固定字数硬切,很容易把一句话拦腰截断。
  3. 给每块加元信息带上来源文件名、章节路径、页码、更新时间。这些字段后面用来做过滤,也用来给答案标出处。
  4. 抽样验证随机抽二十个块通读一遍,问自己:如果只看到这一段,能不能独立理解它在说什么。做不到就说明切得太碎。

文档清洗要先于切块。PDF 双栏、跨页表格、代码块、扫描件是最容易在这步坏掉的四类内容,脏数据进来,后面怎么调都白搭。

向量化与召回:相似度到底在比什么

向量化是把一段文本映射成一串数字,语义越接近的两段文本,向量方向越接近。检索就是拿问题向量去库里找方向最接近的若干个块。听起来很美,但「相似」不等于「有用」:口语化提问和正式文档之间常有语义落差,纯向量召回会漏掉关键词精确匹配的场景。

  • 混合召回:向量检索和全文检索各召回一批,再合并去重,覆盖语义相似和字面匹配两种场景
  • 召回数量是取舍:太少可能漏关键片段,太多会挤占上下文、拉高成本、把噪声带进去
  • 用否定词和缩写测一测:这类提问最容易暴露纯向量召回的短板
  • 具体召回条数的临界值只能拿自己的样本集测,别照搬别人的默认值

召回数量怎么定,取决于你的资料密度和上下文窗口。想看不同方案的取舍,可以到 /tools/speed-test 看清各类检测工具在延迟和吞吐上的表现,再结合自己场景判断。

重排与拼装:把片段变成一段能用的提示词

初筛召回追求「不漏」,重排追求「排前面」。用更精细的模型对候选片段逐条打分再截取,是提升命中率最直接的一环。这一步的成本比向量检索高,但候选集小,通常划算。

拼装时要处理冲突和重复:同一事实出现多个版本、片段互相矛盾时,要在提示里明确优先级,或者让模型指出来源不一致,而不是默默取第一条。这决定了回答可不可信。

环节在追求什么搞砸了会怎样
初筛召回不漏掉相关片段正确答案根本不在候选里
重排把最相关的排最前对的片段被噪声挤出上下文
拼装把片段组织成可读提示片段打架,模型随机选一个
生成只依据资料作答模型用自己的记忆补全,编得更像真的

生成环节要明确约束「只依据给定资料回答,资料里没有就说没有」。否则模型会用自己的记忆补全,反而比不检索更容易让人误信,因为答案是带着出处样子的。

下一步把链路走通只是第一步,真正影响效果的是各环节的参数取舍和工具选型。到 /rankings 看看当前主流方案在检索质量上的对比数据,再决定从哪一环开始调优。

常见问题

RAG 和微调该选哪个?

先看需求类型。要模型「知道某些事实」用 RAG,资料能随时更新、还能给出处;要模型「学会某种风格或固定输出格式」才考虑微调。两者不冲突,很多项目是检索打底、微调调风格。判断标准是:如果资料每天在变,微调的成本和滞后基本不可接受。

不做向量库,直接把资料贴进提示词行不行?

资料总量小、更新少的时候完全可以,实现简单、没有召回误差。一旦超过上下文能容纳的量,或者资料会增长,就会遇到三件事:超长会被截断、每次请求都贵、关键信息淹没在中间。这时再上检索才划算,别为了架构好看提前上。

检索出来的内容明明是对的,为什么模型还是答错?

大概率出在拼装和约束上。检查三点:正确片段是否排在前面、是否被大量无关片段稀释、提示词有没有明确要求依据资料作答。另外确认片段本身是否被截断成半句话。定位时先把实际发给模型的完整提示词打出来看一遍,通常一眼就能看出问题。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。