等级 L4 · 每天 40 分钟 · 场景:做RAG→二、检索链路怎么搭

一句话:RAG 的本质是「先查再答」——把相关资料检索出来塞进上下文,让模型基于它回答而不是靠记忆编。所以 RAG 项目做不好,九成是检索没做好,不是模型不行。它本质是个搜索工程问题。

学习地图

你的问题看哪一节
「什么时候该上 RAG」一、先判断要不要做
「整条链路怎么搭」二、检索链路怎么搭
「文档怎么切」三、切块
「检索出来的不相关」四、召回与重排
「怎么知道效果好不好」五、评估
「检索不到时怎么办」六、失败路径

前置:LLM应用开发——RAG 是在它之上加了一层检索。

一、先判断要不要做

RAG 不是默认选项。 三种更简单的方案先排除掉:

场景更该用
资料量小(几万 token 以内)且相对固定直接全塞进上下文 + prompt caching。没有检索环节就没有检索错误
只是术语/规则的口径统一写进系统提示词
结构化数据的精确查询老老实实查数据库。「上季度华东区销量」是 SQL 问题,不是 RAG 问题

上下文窗口越来越大,第一种方案的适用范围在扩大。别因为「RAG 听起来更专业」就上一套检索系统。

什么时候确实该上

  • 资料量远超上下文窗口(内部文档库、历史工单、代码库)
  • 资料频繁更新,不可能每次全量塞
  • 需要引用来源(「这个结论出自哪份文档」)
  • 全量塞成本上不划算

一个常被忽略的前提:资料本身得靠谱

RAG 的天花板是你的资料质量。资料本身过期、矛盾、缺失,RAG 只会把错误答案检索得更快。 上 RAG 前先问:这批文档有人维护吗?矛盾的版本清理过吗?

二、检索链路怎么搭

【离线】原始文档 → 清洗 → 切块 → 向量化 → 写入索引
【在线】用户提问 → 改写 → 混合检索 → 重排 → 拼上下文 → 生成 → 引用标注

每一环都可能是效果瓶颈。排查顺序应该反着来:先确认检索出来的东西对不对,再怀疑生成环节。

一个实用的诊断方法:把检索结果直接打印出来自己看。如果人看了都找不到答案,那问题在检索,调提示词没用。这一步能省掉大量瞎调。

三、切块

切块是最影响效果、也最容易被随便对付的一环。

三种切法

策略做法适用
固定长度按 token 数硬切兜底方案,效果最差
结构感知按标题层级/段落/章节切Markdown、有格式的文档,首选
语义感知按语义相似度找切分点长篇无结构文本,成本高

优先按文档自身结构切。 Markdown 按标题层级、代码按函数/类、工单按字段——文档作者已经帮你划好边界了,不用再猜。

两个关键参数

块大小:太小丢上下文(一句话不知道在说什么),太大引入噪音(一块里混了三个主题)。没有普适值——要按你的资料实测,从中等粒度开始双向试。

重叠:相邻块之间保留一定重叠,防止答案正好被切在边界上。经验值是块大小的 15~20%

给每块带上元数据

这是低成本高收益的一步:

块内容:……
元数据:文档标题 / 所属章节 / 更新时间 / 来源链接 / 权限标签

好处有三个:过滤(只检索某个产品线、某个时间之后的)、权限(用户只能检索到他有权看的)、引用(回答时能指出来源)。权限过滤必须在检索层做,不能靠提示词让模型「不要透露」——那挡不住。

四、召回与重排

只用向量检索是不够的

纯向量检索的弱点很明确:精确匹配差。用户搜一个错误码、一个产品型号、一个人名,向量检索经常召不回——因为它匹配的是语义相似度,不是字面。

默认方案应该是混合检索:向量检索(语义)+ 关键词检索(BM25,字面)结果融合。两者互补,这是当前的工程共识,不是可选优化。

加一层重排

检索先粗召回一批(比如 50 条),再用重排模型精排,取 top 几条进上下文。

为什么值得加一层:

  • 粗召回优化的是「别漏」,重排优化的是「排得准」,目标不同
  • 进上下文的条数直接影响成本和效果——塞太多反而变差(相关信息被噪音淹没)
  • 重排模型比向量检索更懂「这段是不是真的回答了这个问题」

查询改写

用户的原始提问经常不适合直接拿去检索:

  • 口语化、有指代(「它的价格呢」——「它」是上一轮说的东西)
  • 太短,信息不足
  • 一个问题里包含多个子问题

常见处理:多轮对话中把指代补全成完整问题;复杂问题拆成多个子查询分别检索。

五、评估

没有评估集,RAG 调优就是玄学。 这是 RAG 项目最容易跳过、也最致命的一步——凭感觉调,调到后面自己都不知道是变好了还是变坏了。

最小可用的评估集

不需要很大,30~50 条真实问题就能开始:

字段说明
问题真实用户会问的,不是你编的
期望答案要点不用逐字,列出必须提到的关键点
标准来源答案应该来自哪个文档/哪一段

分开评检索和生成

这是关键——两个环节要分开测,否则你不知道该改哪里:

环节看什么怎么判断
检索标准来源有没有被召回、排第几召回率、命中位置
生成答案要点覆盖了几个、有没有编造逐条人工核 / 用模型辅助打分

先保证检索指标,再调生成。 检索没召回,提示词怎么调都是无米之炊。

用模型当裁判要小心

用另一个模型给答案打分能省人力,但它自己也会出错。做法:先人工标 20 条,验证裁判模型的打分和人工一致,再用它批量跑。不验证就直接用,可能在优化一个错误的指标。

六、失败路径

生产 RAG 的核心问题不是「怎么杜绝检索失败」——它一定会失败,用户会问文档里根本没覆盖的问题。真正该设计的是:检索失败时系统怎么表现

三种表现,从坏到好:

表现后果
检索为空,仍然让模型自由回答❌ 最糟——直接输出幻觉,用户还以为有依据
检索为空,返回「没找到」🟡 及格
检索为空,返回「没找到」+ 相近内容 + 引导✅ 好

三条工程约束

① 检索结果为空/低分时要短路

设一个相关性阈值。低于阈值就直接返回「没有找到相关资料」,不要把空上下文丢给模型让它自由发挥——那正是幻觉最容易发生的地方。

② 强制要求引用

在提示词里明确:只能基于给定资料回答,每个结论标注来自哪一段;资料里没有的,明确说没有。

这不只是体验——引用让用户能自己验证,把「相信 AI」变成「核对来源」。

③ 让用户能反馈

「这个回答有用吗」的按钮不是产品需求,是你的评估集来源。用户点踩的问题,就是下一轮该补的评估用例。

常见追问

  • 上下文窗口都上百万了,还需要 RAG 吗? 需要,但门槛提高了。三个原因窗口大解决不了:(每次塞满的成本极高)、(输入越长首字延迟越高)、(相关信息淹没在无关内容里,效果反而下降)。现在的实际影响是:切块可以更粗、召回条数可以更多,但检索这一环不能省。

  • 向量库怎么选? 先问数据量。百万级以下,你现有的数据库可能就够——主流关系库和搜索引擎都有向量检索能力,省一个组件比引入一个新中间件划算得多。真到了需要专用向量库的量级时,选型考虑的是过滤能力、混合检索支持、运维成本,而不是宣传的检索速度。

  • 嵌入模型怎么选? 三个实际约束:支不支持中文(很多模型中文效果差)、维度和成本(维度越高存储和检索越贵)、能不能私有化部署(数据不出内网时是硬约束)。选定后不要随便换——换嵌入模型意味着全量重新向量化。

  • 文档更新了怎么同步? 按更新频率选:低频全量重建最简单;高频要做增量(按文档 ID 删旧块写新块)。一定要有版本/时间戳,否则删不干净会留下幽灵块——用户拿到已删除文档的内容,这是很难排查的事故。

  • RAG 和微调怎么选? RAG 解决「模型不知道这些事实」,微调解决「模型不会这种表达方式/任务格式」。知识更新用 RAG,风格定制用微调,绝大多数业务需求是前者。先把 RAG 和提示词调到极限,再考虑微调——微调的数据准备和迭代成本高一个量级。

相关