Appearance
7.1.3 为什么“召回”与“排序”要拆开看?
先给结论:因为召回和排序解决的是两类不同问题。召回解决“不要漏掉可能相关的内容”,排序解决“在这些候选里谁应该优先进入最终上下文”。把两者混在一起,系统设计和问题排查都会变得很模糊。
这也是很多团队做 RAG 时会卡住的地方:
- 问题明明出在候选优先级
- 却一直去改召回器
或者反过来:
- 问题其实是根本没召回来
- 却一直在调 rerank
召回阶段到底在解决什么
召回阶段最核心的目标通常是:
- 尽量不要漏掉真正可能相关的内容
它更关心的是:
- 覆盖面
- 候选池质量
- 候选多样性
也就是说,召回更像是在搭一个:
- “可能有答案”的候选池
排序阶段到底在解决什么
排序阶段更核心的目标通常是:
- 在已有候选里,把最值得优先给模型的内容顶上来
它更关心的是:
- 优先级
- 冲突消解
- 去噪
- 结果精选
也就是说,排序更像是在回答:
- 在这些候选里,谁最该先被用
为什么这两层不能混成一个模糊动作
因为它们的优化方向常常不同。
例如:
- 召回阶段可能希望多带一点候选,防止漏掉
- 排序阶段则希望把更少但更关键的内容放前面
如果把两者混成一个黑盒,你就很难判断:
- 是根本没找回来
- 还是找回来了但顺序错了
一个更实际的例子
假设用户问:
- “企业版普通商品支持七天无理由退货吗?”
系统可能出现两种完全不同的问题:
情况一:没召回来
候选里根本没有企业版相关规则。
这时问题更像出在:
- query rewrite
- 检索策略
- embedding / BM25 信号
- filter / routing
情况二:召回了,但没排前面
企业版规则其实在候选里,但排在第 8 条。
这时问题更像出在:
- 排序
- rerank
- 去重
- 结果精选
如果不先把召回和排序拆开看,你就很容易在错误层上用力。
为什么这会直接影响系统设计
因为一旦把召回和排序拆开,系统设计也会更清楚:
- 第一层先负责“找回来”
- 第二层再负责“排清楚”
这样你后面引入:
- hybrid retrieval
- reranker
- result selection
都会更自然。
如果不拆开,系统就容易变成:
- 一个大黑盒检索器
而黑盒系统最难做的,恰恰就是定位问题。
一个常见误区
很多人会把排序问题也归因成“检索不准”。
这会让后面的调优长期发散。
更稳的做法通常是先问清:
- 正确内容有没有进入候选池
- 如果进了,为什么没有排到该有的位置
先把这两个问题分开,调优方向才不容易乱。
一句话总结
召回与排序要拆开看,因为召回解决的是候选覆盖,排序解决的是候选优先级。两者目标不同、调优手段不同、失败表现也不同。把它们拆开,系统设计和问题诊断都会清楚得多。