召回与离线评测
本节目标
检索优化必须回答“对哪些 query、在什么权限和时间条件下、相对哪个基线、改善了什么”。本节建立 query/qrels 数据集、四个核心指标、分层错误分类和发布门禁,并解释为什么公共 benchmark、ANN recall 或总体均值都不能单独决定上线。
评测集应代表什么
Query 集同时覆盖:
- 线上高频意图与自然频率;
- 高风险但低频的权限、财务、医疗/安全类 query;
- 短问句、长描述、口语、错别字和缩写;
- 错误码、型号、数字、日期、否定和条件;
- 同义改写、跨语言和领域术语;
- 多跳、多意图和需要澄清的 query;
- 无答案、无权限、未发布和索引延迟;
- 新文档、新租户及分布漂移。
随机抽线上 query 能保留频率,但可能淹没高风险长尾;人工模板能补边界,却可能过于整洁。二者结合,并记录 sampling 来源和权重。
避免数据泄漏
若同一原文的相邻 chunk 分别落入 train 与 test,模型可能凭近重复内容取得虚高成绩。按 canonical source/document 分组切分;时间敏感系统再增加按时间向前验证:
- train:调模型或学习融合;
- validation:选窗口、阈值、权重和 query 策略;
- test:冻结决策后一次性报告;
- shadow/online:观察真实分布与业务效果。
不要反复查看 test 再调参;那会把 test 变成 validation。
Qrels 与标注池
Qrels 常用 0~3 分级。构建流程:
- 收集 BM25、dense、hybrid、旧系统和候选新系统的 pooled top-k;
- 去重并隐藏系统来源;
- 按固定指南独立标注;
- 对冲突样本裁决;
- 补线上失败、hard negatives、无答案和权限边界;
- 保存指南、标注池、标注者、裁决与 source revision。
未进入 pool 的文档是 unjudged,不一定是不相关。系统差异很大时,应抽检新系统独有的高位候选,避免对创新候选的系统性惩罚。
四个核心指标
设某 query 的相关文档集合为 R,前 k 个结果为 。
Hit@k
只问“至少命中一个没有”。当每个 query 只需一条证据时直观,但无法反映漏掉其他相关证据。
Recall@k
分母是所有已标相关文档。若 qrels 不完整,Recall 也受影响。多证据/多跳任务应说明是按 document、canonical source 还是证据组计算。
MRR@k
找到前 k 中第一个相关结果,其名次为 r:
MRR 是 query 间 RR 的平均,强调第一条相关证据尽早出现,不关心后续相关文档是否齐全。
nDCG@k
对分级 relevance:
nDCG 同时考虑等级和位置,适合区分“直接答案”与“仅主题相关”。必须说明 gain 和 discount 公式;不同实现可能有细节差异。评测前还要验证 ranked IDs 唯一、qrels 等级合法;重复同一高等级文档会重复计 gain,使错误实现算出大于 1 的 nDCG。
无答案与安全门禁
没有正 qrels 的 query 不应机械纳入 Recall/MRR/nDCG 分母,否则“0/0”语义不清。单独报告:
- no-answer precision/recall 或正确拒答率;
- no-result rate 与弱相关返回率;
- must_not_return、安全越权次数;
- draft、expired、deleted 和跨租户泄漏;
- 系统错误是否被误报为无答案。
安全违规通常是零容忍门禁,不应被高平均 nDCG 抵消。门禁必须检查各召回通道进入融合的完整 candidate/rank window,而不只检查最终展示的 top-k;未授权文档即使随后被截断,也已经污染 trace、融合或缓存边界。项目将 guest 请求内部 runbook 设为无 qrels,并要求三个通道的完整候选都为空。
ANN Recall 与业务 Recall 分开
| 指标 | Ground truth | 问题 |
|---|---|---|
| ANN Recall@k | exact vector top-k | 近似索引漏了多少几何近邻 |
| 业务 Recall@k | 人工/行为 qrels | 相关证据是否进入候选 |
| Reranker nDCG | 候选内 graded qrels | 候选被排得多好 |
| 端到端任务成功 | 答案/操作结果 | 用户任务是否完成 |
优化 ANN 参数可能改善第一项但不改变后三项;更换 Embedding 可能改变 exact 邻居和业务质量,旧 exact top-k 不能作为新空间真值。
Macro、micro 与分层
Macro 先算每条 query 再平均,让长 qrels query 不支配结果;micro 汇总命中/相关总数,更受大集合影响。两者都可用,但要标清。
至少按以下维度切片:
- 高频/长尾、高风险;
- 错误码/实体、同义改写、数字/否定;
- 语言、query 长度、document 长度;
- 租户、ACL 规模、过滤选择率;
- 新旧文档、source revision;
- BM25-only、dense-only 与两路同时命中。
报告样本数和置信区间/重采样不确定性。10 条 query 上提高 0.1 可能只是一个样本变化,不能包装成稳定提升。
系统指标同样重要
离线 relevance 之外记录:
- p50/p95/p99 端到端和每个通道延迟;
- timeout、错误、partial/降级率;
- QPS、并发和资源/每 query 成本;
- 写后可搜、删除/权限撤销传播时间;
- rank window、候选数、近重复比例;
- query rewrite 数和缓存命中;
- index/model/analyzer/qrels revision。
同等质量下更慢、更贵或更难恢复的系统未必可上线。
错误分类
对失败 query 查看每一层:
- Corpus:正确 source 是否存在、已发布且未删除;
- Chunk:答案是否在可返回单元中;
- Representation:analyzer/encoder 是否保留关键含义;
- Filter:正例是否被错误排除,负例是否越权;
- Exact/ANN:近似索引是否漏候选;
- Fusion:弱通道、窗口或去重是否压低正例;
- Qrels:候选是否其实相关但未标;
- Downstream:reranker/生成是否错误使用已召回证据。
错误分类比“调大 top-k”更能指向修复位置。
发布门禁
一份可执行门禁可包含:
- 总体和关键切片 Recall@k/nDCG 不低于基线;
- 高风险/权限测试零违规;
- no-answer/拒答不显著退化;
- p99、错误率、成本和候选预算达标;
- 新鲜度与删除传播达标;
- 所有结果能由锁定 fixture、参数和版本复现;
- shadow/canary 有回滚阈值。
上线后用点击、任务成功、人工复核和投诉等信号监控,但点击受展示位置和旧排序偏差影响,不能直接当无偏 relevance。
练习
构造 30 条 query:
- 10 条真实高频、10 条高风险长尾、5 条无答案、5 条权限边界;
- 每条写 tenant/groups/filter 和 0~3 qrels;
- Pool BM25、dense、hybrid 的 top-10 后盲标;
- 报告 Hit/Recall/MRR/nDCG@5 和每类样本数;
- 另报 must_not_return、p95/p99 与 no-result;
- 选一个失败样本沿 8 层错误分类定位根因;
- 写出明确上线/回滚门禁。
掌握检查
- Train/validation/test 按 source 分组,无近重复泄漏。
- Qrels 指南、pool、裁决与 revision 可追溯。
- Hit、Recall、MRR、nDCG 的分母和用途清楚。
- 无答案和安全门禁不被强塞进普通相关性均值。
- ANN recall 与业务 recall 分开报告。
- 总体、关键切片、延迟、成本和新鲜度共同决定发布。
下一步:项目:离线混合检索。
参考资料
- Nguyen et al., MS MARCO
- Thakur et al., BEIR
- Muennighoff et al., MTEB
- NIST TREC Data
来源获取/复核日期:2026-07-21。返回 语义搜索目录。