首页/AI/RAG 与向量库速查/召回差 vs 重排差的区分

召回差 vs 重排差的区分

判断问题在召回还是重排:用精确检索或人工挑出的理想片段对比——理想片段不在候选池内是召回问题;在池内但没进上下文是重排/截断问题;两者修复动作完全不同。

RAG 与向量库速查AI更新于 2026-10-13

先分清是哪一环的问题

回答质量差时要先判断问题在召回还是在重排:用人工挑出的理想片段做对照,看它有没有进入检索候选池。理想片段根本不在候选池里,是召回问题(切分、embedding、过滤条件、索引参数);在池内却没进最终上下文,是重排或截断问题(重排模型、候选数量、上下文预算)。两者修复动作完全不同,判断错了会白花力气。

基本信息

召回覆盖gold 片段出现在 top-k 候选池中的比例
终选覆盖gold 片段出现在最终送入生成的片段中的比例
诊断顺序先看候选池,再看终选,最后才动生成参数
常见结论召回低改切分与模型,终选低改重排与预算

典型使用场景

  • 效果下滑排查:先定位层次再动参数,避免盲目换模型
  • 重排上线验证:确认重排把候选池里的 good 片段提到了前面
  • 上下文预算调整:终选覆盖低时检查是不是片段数被截断
  • 切分方案评审:用召回覆盖数据判断切分是否把答案切碎
  • 模型选型对比:候选池覆盖率是比最终答案更干净的对照指标

分层定位脚本

分层定位脚本
pool = {q: [c.id for c in retrieve(q, top_k=50)] for q in queries}   # 候选池
final = {q: [c.id for c in final_top8[q]] for q in queries}            # 送生成
gold_in_pool = {q: [g in pool[q] for g in gold[q]] for q in queries}
gold_in_final = {q: [g in final[q] for g in gold[q]] for q in queries}
print("召回覆盖:", sum(map(all, gold_in_pool.values())) / len(queries))
print("终选覆盖:", sum(map(all, gold_in_final.values())) / len(queries))

症状与修复方向

现象优先排查修复方向
候选池里没有 gold召回环节切分粒度、embedding 模型、过滤条件、top-k 大小
池内有 gold 但没进最终上下文重排环节重排模型、候选数量、上下文预算与截断
两者覆盖率都低切分与数据质量先查解析是否丢内容,再看切片是否割裂
指标忽高忽低参数与语料版本核对索引参数与语料快照是否一致
召回覆盖高、终选覆盖低,就优先看重排与截断;两者都低,先看切分与 embedding 质量,再考虑换库或加混合检索。
top-k 是候选池的边界:设得太小,正确答案先天进不来,后续无论怎么调重排都救不回来,排查时先把它放宽一档做对照。

易错点

  • 不区分层次直接更换 embedding 模型,改动成本高且未必命中
  • top_k 太小导致候选池先天不含正确答案
  • 只看最终答案好坏,不记录候选池与终选覆盖,排查缺少依据
  • 重排上线后未做对照评测,排序变化是否带来收益无法判断

数据来源与参考

  • Manning et al., Introduction to Information Retrieval(召回/排序分层)
  • Cohere 官方文档(Rerank 使用诊断)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌