一个 RAG 答案错了,最没用的结论是“模型不够好”。相关文档可能根本没进索引,query rewrite 可能删掉专有名词,retriever 可能漏召回,reranker 可能把噪声放在前面,上下文可能截断例外条款,生成器也可能在证据完整时仍然编造。只评最终答案,会把六种问题压成一个分数。

本文面向已经有 RAG trace、准备建立持续回归的开发者。你需要了解 recall、precision 与基本标注流程。目标是建立能定位模块、比较版本并暴露数据空洞的评测系统,而不是追求一个漂亮总分。

RAG 的数据、检索、上下文、回答和引用五层评测矩阵

图 1(1600 × 900):WEB/SUN 原创 SVG。每层都有独立对象、指标和失败标签;最终分数不能替代故障定位。

评测样本必须包含证据,不只是问答

最小样本不应只有 questionexpectedAnswer,而要保存:知识库 revision、用户权限、时间条件、可回答性、支持事实、相关文档与原文跨度、允许的答案变体、必须拒绝的错误,以及问题类型。

type RagEvalCase = {
  id: string;
  query: string;
  corpusRevision: string;
  accessScope: string[];
  answerable: boolean;
  requiredClaims: Array<{ claim: string; evidenceSpans: string[] }>;
  forbiddenClaims: string[];
  relevantDocuments: string[];
  slice: string[];
};

answerable: false 的样本非常重要。它检验系统能否在知识库没有答案、权限不足、版本冲突或问题含糊时停止,而不是用模型记忆补齐。对于开放式问题,标注核心事实和证据比写一段唯一标准答案更稳健。

数据来自产品规格、领域专家、已获许可并脱敏的真实查询、历史失败和合成边界样本。OpenAI 的评测最佳实践建议先定义目标,再收集数据、定义指标、运行比较并持续扩展;同时反对与真实分布脱节和只凭感觉的评测。合成数据能补覆盖,不能取代专家核验与真实切片。

按切片设计,而不是随机平均

随机划分容易让同一文档的改写问题同时进入训练调参和测试。应按文档、时间或主题分组,保留真正未见的 holdout。切片至少覆盖:精确 ID/错误码、语义改写、多跳、时间敏感、表格、否定问题、冲突来源、不可回答、跨语言、长尾实体、权限隔离和提示注入文档。

报告每个切片和样本数量,不只报告全局平均。一次更新可能提高常见 FAQ,却让版本问题和否定问题恶化;平均值会隐藏它。BEIR 研究通过多种领域和检索任务展示异质评测的重要性,论文也发现不同架构在跨域泛化与成本间存在差异,见BEIR。自己的系统同样需要覆盖真实异质分布。

第一层:先测检索有没有把证据带回来

对每个 query,使用标注的 relevant document 或 evidence span 计算 Recall@k:所需证据是否进入前 k;MRR 关注第一个相关结果的位置;nDCG 能处理多级相关性和排序。对于多跳问题,单个相关文档命中不代表完成,另加 evidence set coverage,检查所有必要子事实是否至少有一段候选。

Precision@k 反映噪声,但不能孤立优化。把 k 降到 1 会提高精确率,却可能丢掉限定条件。先为召回设最低门禁,再在满足覆盖的候选中优化噪声与成本。稀疏、稠密、混合和重排各自保存指标,才能知道提升来自哪一段。

检索失败标签应具体:not_indexedacl_filteredrewrite_lost_termchunk_boundarysparse_missdense_missrerank_dropstale_revision。看到 miss 后直接换 embedding 模型,可能掩盖真正的数据或切分问题。

第二层:测最终上下文,而不只测候选

候选命中后,装配器仍可能因去重、token 预算或来源配额把关键证据淘汰。对送入模型的最终 context 单独计算 evidence coverage、context precision、近重复率、来源多样性与被截断跨度。

RAGAS 将 RAG 拆成检索相关性、生成对上下文的忠实度和答案质量等维度,提出无需每项都依赖人工参考答案的自动化评估思路,见RAGAS 论文。这类指标适合加速迭代,但 LLM judge 仍需与人工标注校准,不能把一个自动分数当作真值。

位置也要扰动测试:保持证据集合不变,随机改变顺序、把关键片段移到中间、增加看似相关的干扰块。如果答案随位置大幅变化,问题在上下文利用或装配,而不只是检索。

第三层:在固定证据下测生成

为隔离生成器,直接喂给它人工确认的 gold context。检查 required claim 覆盖、事实正确、是否忠实于证据、能否在证据不足时 abstain,以及是否遵循冲突处理规则。若 gold context 下仍失败,先修生成契约或模型;若 gold context 成功、真实检索失败,优先修上游。

反向也做一个“无证据”实验:移除支持片段,只保留干扰文档。可靠系统应拒绝或指出缺口。若仍自信回答,说明生成器在使用参数记忆或迎合用户,不能把这个答案标为 RAG 成功。

RAGChecker 提出同时诊断 retrieval 和 generation 的细粒度指标,目的正是避免模块化系统被单一端到端分数遮蔽,参见RAGChecker。生产评测可以采用同样原则,即使不使用其具体工具:每个失败必须落到可行动的层。

第四层:引用要测正确性与完整性

先把答案拆成需要证据的原子 claim。Citation correctness 检查被引用片段是否真正支持该 claim;citation completeness 检查所有外部事实是否都至少有支持;citation quality 还要看引用是否指向精确、可访问、当前版本的来源。

只检查链接存在会奖励“贴很多来源”。ALCE 将带引用生成的评估拆成流畅度、正确性和引用质量,并构建端到端检索—生成基准,见ALCE 论文。实际标注时,让审核者看到 claim 与引用片段,而不是只看整篇答案和文档标题。

引用错误也要分类:引用不蕴含论断、正确证据但标错 source ID、论断缺引用、引用版本过期、用户无权打开、多个来源冲突却只引一个。不同类别对应生成、映射、权限或数据修复。

四象限定位法

把“检索证据是否完整”和“固定证据下生成是否正确”放成两个轴:

检索 生成 结论
检查端到端装配、引用与体验
修数据、切分、query、召回或重排
修生成契约、模型、拒答与引用
先固定一层做对照,禁止同时盲调

每个线上失败先做两个回放:用当时 corpus revision 重放真实管线;再用 gold context 重放生成器。保留模型、prompt、索引、chunker、ranker 和装配器版本。若无法回到同一版本,就无法区分代码变化与模型随机性。

Judge、人工与统计边界

确定性指标用于 ID、排序、Schema 和引用映射;语义正确与忠实度可以用 LLM judge 辅助,但 rubric 必须具体,优先分类、成对比较或按原子 claim 判断。抽取一组人工双标样本,测 judge 与人工以及人工之间的一致性;分歧样本进入规则修订,而不是被静默平均。

不要虚构统计显著性。报告样本量、切片、重复次数和置信区间;同一模型的非确定输出要多次运行或固定可控参数。发布门禁同时包含硬不变量:零越权证据、不可回答样本的最低拒答要求、关键切片不得回退。具体阈值来自业务风险和基线,不从论文数字照搬。

持续回归和失败资产

每次数据、chunk、embedding、混合权重、reranker、prompt 或模型变化,都运行同一冻结基线,再增加针对改动的新切片。线上失败完成脱敏和授权后,转成包含证据与期望行为的永久案例;修复必须让该样本通过,同时不破坏邻近切片。

报告应输出每层指标、差异样本和失败标签分布,而不是一个 dashboard 总分。选择若干 trace 进行人工浏览:正确答案也可能恰好引用错误,错误答案也可能是知识库本身过期。自动化负责发现变化,人负责确认评测问的是正确问题。

失败模式与取舍

常见错误包括:只有问答没有证据;只测最终正确率;随机拆分造成文档泄漏;没有不可回答和权限样本;用 context precision 代替 recall;把 LLM judge 当真值;只检查引用格式;语料更新后仍用旧 evidence span;总分上升就忽略关键切片回退。

细粒度标注成本高,自动指标也不完美。可以从高风险任务和高频查询开始,先建立小而可信的 gold set,再用合成与 judge 扩大覆盖;自动数据始终带来源和审核状态。宁可有一套能定位失败的小评测,也不要一万个只有模糊标准答案的样本。

结论

RAG 评测的任务不是证明系统“平均不错”,而是指出证据链断在哪里。样本必须绑定 corpus revision、权限、可回答性、required claim 和 evidence span;检索、最终上下文、固定证据生成与引用分别评估;反事实和 gold-context 回放用于隔离模块。

当一次失败能被标记为“query rewrite 丢失专有名词”或“证据已召回但 citation completeness 不足”,团队才有明确修复对象,持续回归也才真正保护系统质量。

Sources