Skip to content

9.2.2 怎么评估检索结果到底好不好? ​

先给结论:评估检索结果好不好,不能只看一个分数,也不能只看离线样本里“有没有搜到”。更稳的做法是:先明确任务目标,再准备有代表性的样本,再用多指标组合看覆盖、排序和前排纯度,最后回到真实失败案例做验证。

很多人会把检索评测简单理解成:

  • 算几个指标
  • 分数高就说明好

这只完成了最表面的一步。真正有工程价值的检索评估,至少要回答三件事:

  • 该找回来的证据有没有进来
  • 该排前的证据有没有排前
  • 这些结果是否真的对后续生成有帮助

一、先明确“好”的定义 ​

检索系统的“好”,从来不是抽象的。

你要先知道当前任务更看重什么:

  • 是不漏关键证据
  • 还是前排就足够干净
  • 是单跳问答
  • 还是多证据综合

如果任务本身更像:

  • 单事实问答

你会更关心:

  • 前排质量
  • 第一条正确结果的位置

如果任务更像:

  • 多段综合

你会更关心:

  • 覆盖
  • 多条正确证据是否都能进来

二、样本集必须有代表性 ​

很多检索评测失真的根源,不在指标,而在样本。

如果你的评测集只包含:

  • 简单问题
  • 高热知识点
  • 特别容易召回的样本

那分数再高,也很难说明真实系统已经稳了。

更好的评测集至少要尽量覆盖:

  • 简单事实问答
  • 多条件问题
  • 容易混淆的近义问题
  • 长文档问题
  • 多来源问题
  • 新旧版本容易冲突的问题

只有样本结构接近真实问题分布,检索分数才更有意义。

三、不要只看一个指标 ​

真正判断检索好不好时,通常要组合看。

例如:

  • Recall@K 看覆盖
  • Precision@K 看前排纯度
  • MRR 看第一条正确结果来得够不够早
  • nDCG 看整体排序质量

如果你只看其中一个,就很容易被局部表现骗到。

四、要回到错误样本看“错得像什么” ​

即使指标已经算完,也不要停在数字层。

你还要回到真实失败样本去看:

  • 是根本没召回
  • 还是召回了但排太后
  • 还是前排被噪声挤占
  • 还是过滤条件挡掉了关键证据

只有看这些错误形态,你才能知道:

  • 下一步该调什么

一个更现实的评估流程 ​

一个更稳的检索评估流程通常像这样:

  1. 明确任务类型和检索目标
  2. 构建有代表性的评测集
  3. 为每个问题标注目标证据或目标文档
  4. 计算多种指标
  5. 回看失败样本做人工归因

这五步里,最容易被忽略但最有价值的,通常是最后一步。

一个最小示意 ​

python
for query in eval_dataset:
    results = retrieve(query.text, top_k=20)
    scores.append(
        {
            "recall@20": recall_at_k(results, query.gold_docs, k=20),
            "precision@5": precision_at_k(results, query.gold_docs, k=5),
            "mrr": mean_reciprocal_rank(results, query.gold_docs),
            "ndcg@10": ndcg_at_k(results, query.gold_docs, k=10),
        }
    )

这段代码想说明的是:

  • 检索评估通常应该是一个组合视角,而不是单一分数

一个常见误区 ​

很多人会把“检索结果好不好”理解成:

  • top1 对不对

这当然重要,但它太窄了。因为真实 RAG 里,后续还有:

  • 重排
  • 上下文构造
  • 生成

所以你不仅要关心第一条,还要关心:

  • 候选池有没有把该有的材料准备好

一句话总结 ​

评估检索结果到底好不好,不能只看一个分数,也不能只看表面 top1。更稳的做法是先明确任务目标,再用有代表性的评测集和多指标组合看覆盖、排序和前排纯度,最后回到失败样本里做人工归因。