跳到主要内容

掩盖检索器 Bug 的 RAG 评估反模式

· 阅读需 12 分钟
Tian Pan
Software Engineer

RAG 系统中存在一种常见的失败模式,数月内都不会被察觉:你的检索器(retriever)返回了错误的文档,但你的生成器(generator)足够擅长即兴发挥,以至于端到端的质量分数依然保持绿色。你不断调整提示词(prompt)。你升级模型。但都无济于事。这个 Bug 存在于上游三层,而你的指标对其视而不见。

这就是检索器评估反模式(retriever eval antipattern)——将整个 RAG 流水线作为一个整体进行评估,这让生成器吸收并隐藏了检索失败。其结果是,你无法区分是“生成器失败”还是“检索器失败”,从而使得系统性的改进几乎变得不可能。

修复方法并不复杂,但它要求你从端到端评估中抽身,并构建一个独立的测试框架,按照检索器自身的逻辑进行测试。这篇文章将解释如何操作。

为什么端到端评估会隐藏检索器 Bug

当你只测量最终回答的质量时——无论是通过 LLM-as-judge、人工评分还是精确匹配——你正在将一个包含四个阶段(索引、检索、重排序、生成)的流水线坍缩为一个单一信号。而这个信号是由你生成器的能力所主导的。

现代 LLM 非常擅长生成看似合理的回答,即使检索到的上下文是错误的、不完整的或完全缺失的。一个 GPT-4 级别的模型在面对无关上下文时,往往会退回到其参数化知识库中,并生成在人类审核员看来是正确的内容,尤其是对于常见的事实性查询。2025 年的研究将此正式定义为“上下文忽略”(context neglect)——即模型根据先验知识而非检索内容进行生成,即使正确的上下文确实存在。

这意味着:如果你的生成器足够强大,且查询内容接近训练数据,那么一个召回率(recall)仅为 40% 的检索器也能驱动一个端到端回答质量达到 80% 的系统。你会得出流水线运行良好的结论。但事实并非如此。边缘情况、冷门查询和特定领域的內容都会悄无声息地失败。

还有一个复合问题。检索器会系统性地偏向具有表面特征的文档:较短的文档、答案出现在开头的文档、与查询有词汇重合的文档,以及重复查询实体的文档。这些特征都与实际相关性没有可靠的相关性。你的端到端评估无法测量这种偏差,因为生成器将其抹平了。

真正重要的指标

一个仅针对检索器的评估框架需要少量精心挑选的指标。正确的选择取决于你的使用场景。

Recall@K 回答了这样一个问题:“我们到底有没有找到相关的文档?”它测量所有相关文档中出现在前 K 个结果中的比例。如果你对一个查询有 10 个相关文档,而你的检索器将其中的 6 个排在前 10 位,那么你的 Recall@10 就是 0.6。这个指标不关注排名顺序——它只计算是否存在。这是一个特性,而非缺陷:如果你下游的生成器使用了所有的 K 个结果,那么检索顺序的重要性就低于覆盖率。

当你的使用场景对完整性敏感时,请使用 Recall@K。例如法律研究、医学文献回顾、合规检查——在这些场景中,遗漏相关文档就是严重的失败。Recall@K 低于 0.5–0.6 是检索器成为瓶颈的强烈信号。

Precision@K 回答了:“我们给生成器发送了多少噪音?”它测量前 K 个结果中实际相关的比例。如果你检索了 10 个文档,而其中只有 4 个是相关的,那么 Precision@10 就是 0.4。高噪音会从两个方面损害生成器:它挤占了相关上下文(特别是下文讨论的“迷失在中间”效应),并且引入了矛盾信息,增加了幻觉风险。Precision@K 低于 0.4 表明你的检索器引入了太多噪音。

MRR (Mean Reciprocal Rank) 是适用于存在单一正确答案系统的指标——如问答助手、聊天机器人、搜索界面。它测量第一个相关结果的排名高低,并在所有查询中取平均值。MRR 低于 0.3 意味着正确答案平均排在第 3 或第 4 位之后——位置太靠后,以至于大多数用户或重排序器(reranker)都找不到它。MRR 简单且易于解释,是第一个值得接入的良好指标。

NDCG@K (Normalized Discounted Cumulative Gain) 是当文档具有分级相关性时——即某些文档高度相关,另一些部分相关,还有一些不相关时——最具信息量的指标。它同时考虑了相关性和排名位置,并对排名较低的结果进行对数衰减。如果你正在构建基于技术文档、科学文献或任何文档质量差异显著的语料库,NDCG 应该是你的首选指标。

对于大多数生产环境中的 RAG 系统,从 Recall@10 和 Precision@10 开始。如果你正在构建问答系统,请加入 MRR。当你收集了分级相关性标签后,再使用 NDCG。

构建评估框架 (Eval Harness)

该框架包含三个组件:测试集、基准事实映射 (ground-truth mapping) 和运行器 (runner)。

测试集是代表你的系统实际接收请求的查询集合。其关键属性是代表性——即查询应与生产流量具有相同的分布。这比听起来要难。通过要求 LLM 根据你的文档生成问题而创建的合成查询虽然容易收集,但往往严重偏向于简单的简单事实查找。研究表明,约 95% 的简单 LLM 生成查询属于单事实类别,这会产生不切实际的高性能预期,从而掩盖了在复杂查询上的失败。

构建测试集的更好方法包括:

  • 如果你有生产日志,从中抽取真实的候选查询。即使是来自生产流量的 100 个带有标签的示例,其价值也高于 10,000 个合成查询。
  • 对于你已知存在的常见问题类型,进行手动编写。50 个精心设计的查询成本极低且具有高度代表性。
  • 为了扩充少量的种子集,可以使用 LLM 在不同的抽象层级上生成变体:直接的事实问题、需要结合多个文档信息的多跳 (multi-hop) 问题,以及种子查询的改写版本。
加载中…
References:Let's stay in touch and Follow me for more thoughts and updates