Skip to content

7.1.3 为什么“召回”与“排序”要拆开看? ​

先给结论:因为召回和排序解决的是两类不同问题。召回解决“不要漏掉可能相关的内容”,排序解决“在这些候选里谁应该优先进入最终上下文”。把两者混在一起,系统设计和问题排查都会变得很模糊。

这也是很多团队做 RAG 时会卡住的地方:

  • 问题明明出在候选优先级
  • 却一直去改召回器

或者反过来:

  • 问题其实是根本没召回来
  • 却一直在调 rerank

召回阶段到底在解决什么 ​

召回阶段最核心的目标通常是:

  • 尽量不要漏掉真正可能相关的内容

它更关心的是:

  • 覆盖面
  • 候选池质量
  • 候选多样性

也就是说,召回更像是在搭一个:

  • “可能有答案”的候选池

排序阶段到底在解决什么 ​

排序阶段更核心的目标通常是:

  • 在已有候选里,把最值得优先给模型的内容顶上来

它更关心的是:

  • 优先级
  • 冲突消解
  • 去噪
  • 结果精选

也就是说,排序更像是在回答:

  • 在这些候选里,谁最该先被用

为什么这两层不能混成一个模糊动作 ​

因为它们的优化方向常常不同。

例如:

  • 召回阶段可能希望多带一点候选,防止漏掉
  • 排序阶段则希望把更少但更关键的内容放前面

如果把两者混成一个黑盒,你就很难判断:

  • 是根本没找回来
  • 还是找回来了但顺序错了

一个更实际的例子 ​

假设用户问:

  • “企业版普通商品支持七天无理由退货吗?”

系统可能出现两种完全不同的问题:

情况一:没召回来 ​

候选里根本没有企业版相关规则。

这时问题更像出在:

  • query rewrite
  • 检索策略
  • embedding / BM25 信号
  • filter / routing

情况二:召回了,但没排前面 ​

企业版规则其实在候选里,但排在第 8 条。

这时问题更像出在:

  • 排序
  • rerank
  • 去重
  • 结果精选

如果不先把召回和排序拆开看,你就很容易在错误层上用力。

为什么这会直接影响系统设计 ​

因为一旦把召回和排序拆开,系统设计也会更清楚:

  1. 第一层先负责“找回来”
  2. 第二层再负责“排清楚”

这样你后面引入:

  • hybrid retrieval
  • reranker
  • result selection

都会更自然。

如果不拆开,系统就容易变成:

  • 一个大黑盒检索器

而黑盒系统最难做的,恰恰就是定位问题。

一个常见误区 ​

很多人会把排序问题也归因成“检索不准”。

这会让后面的调优长期发散。

更稳的做法通常是先问清:

  1. 正确内容有没有进入候选池
  2. 如果进了,为什么没有排到该有的位置

先把这两个问题分开,调优方向才不容易乱。

一句话总结 ​

召回与排序要拆开看,因为召回解决的是候选覆盖,排序解决的是候选优先级。两者目标不同、调优手段不同、失败表现也不同。把它们拆开,系统设计和问题诊断都会清楚得多。