跳到主要内容

检索召回(Retrieval):把“可能相关”变成“可用证据”

很多 RAG / Agent 系统效果不稳定,不是模型不行,而是召回阶段没把“该看的材料”送进来。召回做得差,后面再怎么重排、再怎么提示词工程,都是“无米之炊”。

0. 面试速答(30 秒版 TL;DR)

  • 检索召回(Recall / Candidate Generation):在较低成本下,从海量文档里尽量不漏地找出一批候选(TopK),供后续 Rerank / 生成使用。
  • 目标不是“查很多”,而是:在可接受延迟内,把真正相关的证据覆盖进候选集合(高 Recall@K)。
  • 常见做法:稀疏检索(BM25)/ 稠密检索(Embedding 向量)/ 混合检索(Hybrid),再配合Query 改写、多路召回、元数据过滤
  • 工程抓手:调 K、分层检索(粗召回→精召回)、缓存、限流;用离线指标(Recall@K、MRR、nDCG)+ 在线指标(命中率、引用可用率、人工评测)闭环。

1. 先把概念说清:召回在整条链路里负责什么?

把 RAG / Agent 的检索相关链路分三层,更“面试化”:

  1. 召回(Retrieval / Recall):快速从索引里拿到候选集合(宁可多一点,也别漏关键证据)。
  2. 重排(Rerank):在候选里做更贵、更准的相关性排序(把最该看的顶上来)。
  3. 上下文组装(Context Building):把证据变成模型“能用”的上下文(去重、压缩、引用、结构化)。

面试里一句话就能拉开层次:

  • 召回追求覆盖(Coverage),重排追求排序(Ranking),组装追求可用(Usability)。

2. 怎么衡量“召回好不好”?(指标与常见误区)

2.1 离线指标:看“有没有把对的东西捞上来”

最常被追问的是 Recall@K:

  • Recall@K = TopK 里命中的相关文档数 / 全部相关文档数
  • 口述要点:K 越大,Recall 往往越高,但延迟和噪音也越大

其他常见指标(知道名字 + 一句话解释就够):

  • MRR:第一个相关结果排得靠不靠前(更关注“第一个命中”)。
  • nDCG:相关性分级时的排序质量(比“只看命中/不命中”更细)。

2.2 在线指标:看“捞上来的东西能不能被用上”

只盯离线 Recall@K 很容易踩坑:候选很多,但都是“看似相关、无法作答”的噪音。线上更关心:

  • 引用可用率:模型最终引用的片段是否支撑答案(可人工抽样评审)。
  • 命中率:关键问题是否能在 TopK 中找到“可用证据”(基于标注集或运营回流)。
  • 延迟/成本:召回 + 重排整体耗时是否可控(Agent 场景尤甚)。

3. 召回策略:从“检索器选择”到“多路召回”

3.1 三种主流检索器

  • 稀疏检索(BM25 / 关键词):对专有名词、数字、错误码、API 名称更稳;对同义表达较弱。
  • 稠密检索(Embedding 向量):对语义相似更强;对“精确词面匹配”(版本号、函数名)可能不如 BM25。
  • 混合检索(Hybrid):同时跑 BM25 + 向量,再合并去重;工程上常用来提升稳定性。

面试里建议用一句话总结取舍:

  • BM25 解决“字面精确”,向量解决“语义相似”,Hybrid 解决“稳”。

3.2 多路召回(Multi-Recall)为什么有效?

因为“相关”常常不止一种形态:

  • 有的证据靠关键词才能命中(例如接口名、报错堆栈)。
  • 有的证据靠语义才能命中(同义表达、口语提问)。
  • 有的证据要先做路由(按业务域/产品线/语言/权限筛一遍)。

常见多路召回组合:

  • BM25 + 向量(最常见)
  • 多 Query(原问题 + 改写问题 + 扩展关键词)分别检索再合并
  • 按元数据过滤后召回(product=xxxlang=zhversion>=x

4. 影响召回的“隐形大头”:切块、索引与过滤

面试里很加分的点:召回不只是“搜”,还包括“文档怎么被变成可搜的形态”。

4.1 切块(Chunking)直接决定“能不能命中”

常见坑:

  • 切得太大:噪音多、向量平均化,相关性被稀释。
  • 切得太小:因果链断裂,命中了也“证据不完整”。

工程要点(说 2–3 条即可):

  • 以“可引用的最小证据单元”为目标切块(段落/小节优先)。
  • 保留层级信息(标题、章节、来源链接)作为元数据,方便过滤与引用。
  • 适度 overlap,避免关键句跨块被切断。

4.2 元数据过滤:不是优化,而是“必要条件”

很多业务问题本质上需要“先缩小世界”:

  • 权限隔离:用户只能检索自己可见的文档
  • 版本隔离:同一 API 多版本共存
  • 语言隔离:中英混杂导致噪音

过滤做对了,召回的 K 可以更小、噪音更少、Rerank 更省钱。

5. 典型题 & 标准答法(可直接背)

Q1:为什么我把 K 调到 50,效果反而变差?

标准答法:

  • K 增大通常提升 Recall,但也引入噪音,导致:
    • Rerank 难度变大或成本上升
    • 上下文被无关片段挤占,模型注意力被分散
    • 出现“看似相关”的误导证据,诱发幻觉
  • 解决思路是:多路召回 + 更强过滤 + 分层检索 + 更好的上下文组装,而不是无脑加 K。

Q2:BM25 和向量检索怎么选?

标准答法:

  • 先看查询类型:
    • 专有名词/错误码/函数名:BM25 更稳
    • 语义问答/同义表达:向量更稳
  • 工程上常用 Hybrid 兜底,再用 Rerank 把排序做准。

Q3:怎么做“检索闭环”?

标准答法:

  • 建一套小而硬的评测集(问题→期望证据→期望答案要点)。
  • 先离线对比不同策略(Recall@K / MRR / nDCG)。
  • 再在线做抽样评审与 A/B(引用可用率、命中率、延迟/成本)。

6. 易错点 / 坑

  • 把“命中”当“可用”:命中相关主题不代表能支撑回答,必须看引用质量。
  • 只做向量检索:对数字、代码符号、产品名往往不稳,Hybrid 更通用。
  • 忽略权限/版本/语言过滤:业务场景里这是效果稳定性的关键。
  • 只调 K 不做分层:正确做法通常是“粗召回多一点、精召回少一点”。

7. 速记要点(背诵版)

  • 召回:低成本不漏;重排:高成本做准;组装:把证据变成可用上下文。
  • 指标:离线看 Recall@K / MRR / nDCG;线上看引用可用率 + 延迟/成本。
  • 策略:BM25(词面)+ 向量(语义)+ Hybrid(稳定)+ 多路召回(兜底)。