RAG 评测不能只在流程末尾给最终答案打一个分。先分开看三件事。
例如,用户问 “标准版账号能否导出审计日志”,检索只找到允许导出的旧版规则,模型却靠自身记忆碰巧回答 “不能导出”。答案文字碰巧正确,检索、证据来源和端到端 RAG 仍然失败。系统换一个模型,或者遇到模型没有见过的新规则,正确答案就无法稳定复现。
评测开始前,先写清这次实验要支持什么决策。是在比较某个组件,还是判断候选版本能否上线。这个问题不明确,后面的样本和分数就没有统一的解释。
| 阶段 | 要做什么 | 必须留下的证据 |
|---|---|---|
| 1. 定义决策 | 写清候选版本、基线版本、预期改善和不可退化项。 | 实验假设、风险切片、发布门槛。 |
| 2. 冻结评测对象 | 固定 corpus、文档版本、chunking、索引、Embedding、retriever、reranker、Prompt、生成模型和代码版本。 | 可复现的运行版本清单,也就是 run manifest,不能只记模型名称。 |
| 3. 构造评测集 | 准备真实 query,并按任务需要标注 qrels、gold evidence、gold answer、expected behavior、用户角色和 query time。 | 数据集版本、审核记录、无答案与权限样本。 |
| 4. 执行并记录 trace | 用同一批样本运行基线与候选版本,保存 query rewrite、候选文档、排序分、最终 context、答案和引用。 | 每条样本的 run/trace ID 与阶段输出。 |
| 5. 分层评分 | 先跑 ID、qrels、ACL、schema 等确定性检查,再跑相关性、忠实度、正确性和引用支持等语义评测。 | 每个指标的实现、输入、版本、分数和错误状态。 |
| 6. 人工复核与归因 | 复核高风险、低分、临界分和 Judge 分歧样本,区分系统失败、样本错误和评测器错误。 | 人工标签、仲裁理由、主失败层和次失败层。 |
| 7. 配对比较与准出 | 按同一 query 比较基线与候选,检查平均变化、关键切片、退化样本、成本和延迟。 | 逐样本 delta、置信范围、阻断项和发布决定。 |
| 8. 线上回流 | 对生产 trace 做规则检查和抽样评测,把投诉、人工修正、低置信回答和事故补回评测集。 | 线上信号、样本来源、修复后回归结果。 |
这条流程包含两个相连的循环,离线侧负责 “可比较、可复现、可准出”,线上侧负责 “发现真实失败并补回数据集”。如果只有离线 benchmark,评测集会逐渐脱离真实用户;如果只有线上点赞点踩,又很难知道退化来自哪一层。
qrels 是 query relevance judgments 的缩写,记录某个问题与哪些检索对象相关,以及相关到什么程度。它不保存答案,也不是分数。Recall@k、MRR、nDCG 等检索指标会使用这份参考数据。
下面用一个虚构样本说明。用户问,
标准版账号可以导出审计日志吗?
假设语料中有三个检索对象,
| evidence_id | 内容 | 人工判断 |
|---|---|---|
plan-v3#audit-export |
当前版本说明,仅企业版支持导出。 | 强相关,直接支持答案。 |
plan-v3#audit-view |
标准版可以查看近期日志摘要。 | 辅助相关,用于补充替代能力。 |
plan-v2#audit-faq |
旧版本 FAQ,曾写标准版可以导出。 | 已判断不应作为当前答案依据。 |
为方便计算,记 A 为当前导出规则,B 为标准版可查看日志摘要,O 为过期规则,U 为另一租户的越权资料,X 为普通无关文档。
这份 qrels 把相关性分成 2/1/0。这只是当前评测集的等级约定,具体含义要写进 dataset card,其他 benchmark 可能采用不同分级。
query_id evidence_id relevance judgment_status
rag-policy-001 plan-v3#audit-export 2 judged
rag-policy-001 plan-v3#audit-view 1 judged
rag-policy-001 plan-v2#audit-faq 0 judged
qrels 需要先定义 evidence_id 指向什么,可以是整篇 document、一个 passage、一个 chunk 或稳定的 source span。不同实验不能一会儿按文档、一会儿按 chunk,却把分数直接比较。比较不同 chunking 时,chunk ID 会变化,最好另外保存跨版本稳定的 doc_id + section/source_span,再为各个 chunking 版本建立映射。
还要区分 “相关性为 0” 和 “没有出现在 qrels 中”,
relevance=0 表示人工看过,并明确判定不相关或不应作为证据。answerability=none、语料快照和审核结论,不能只留一份空 qrels,否则无法区分 “确实无答案” 和 “漏标”。如果一个问题必须同时找到两份证据,例如 E1 说明适用范围、E2 说明金额上限,扁平 qrels 还不够。评测集应把它们组成一个完整 evidence set,并检查两份证据是否都进入 top-k;只命中其中一份不能算完整召回。
评测集决定了分数能说明什么。题目很多,证据和预期行为却含糊,最后只会得到一堆无法解释的平均分。
第一批 query 可以从四类地方收集。
长期维护时,可以按用途把评测集分成四组。
| 分区 | 用途 | 使用限制 |
|---|---|---|
| 开发集(Dev 或 tuning) | 调 Prompt、Retriever、Reranker 和阈值 | 研发可以反复查看和调试 |
| 固定回归集(Frozen regression) | 每次发布都要复跑的稳定回归集 | 修改样本必须留下原因和版本 |
| 保留集(Holdout 或 canary) | 检查是否过拟合已知评测集 | 日常调参不能查看答案 |
| 评分器校准集(Judge calibration) | 校准自动评分器 | 与被测系统的开发集分开管理 |
如果团队一边查看所有错误样本,一边针对这些样本调 Prompt,随后又在同一批数据上宣布版本提升,评测集已经变成训练材料。Holdout 首先要保持独立,规模再按风险和统计需要确定。
Gold evidence 可以由搜索结果、文档链接或模型生成候选,正式进入回归集前仍需人工确认。审核人至少要回答几件事。
模型很适合帮人找候选和发现漏项,但它不能独自决定 gold。生成模型、被测模型和 Judge 若共享同一种错误,自动生成的标准答案会把错误一起固化。
最小样本可以这样记录。
sample_id: rag-policy-001
raw_query: 标准版账号能否导出审计日志
query_type: single_hop_policy
principal:
tenant: T1
role: standard_admin
query_time: 2026-08-19
answerability: answerable
acceptable_evidence_sets:
- [A, B]
required_claims:
- 标准版不支持导出审计日志
- 标准版可以查看近期日志摘要
forbidden_evidence: [O, U]
expected_behavior: answer_with_citation
review_status: human_verified
dataset_partition: frozen_regression
这个样本不要求模型逐字复述某个 gold answer。开放式回答更适合保存 required claims、可接受变体、禁止 claim 和引用要求。只有答案确实有唯一值时,exact match 才是合适的评分方式。
同一个问题运行后,需要留下六类数据。
原始 query 是用户真正输入的文字,
标准版能导审计日志吗?
Query rewrite 是系统为了检索而生成的查询表达,可能同时产生检索文本和结构化过滤条件,
rewritten_query: 标准版 审计日志 导出权限
filters:
plan: standard
feature: audit_log_export
policy_time: 2026-08-18
strategy: structured-rewrite-v2
要保存原始 query、改写结果、过滤条件、改写策略、Prompt/模型版本。评测重点是 “是否保留原意”,不能只看改写后召回是否提高。例如把 “标准版” 删掉后,系统可能轻易召回企业版文档,Recall 会升高,可是问题已经被改写错。
候选文档是初始检索返回、尚未重排和裁剪的结果,可以是整篇 document、passage 或 chunk。使用 hybrid retrieval 时,还要分开记录各条召回通道的结果。
- evidence_id: plan-v2#audit-faq
source: dense
rank: 1
score: 0.91
version: v2
- evidence_id: plan-v3#audit-export
source: bm25
rank: 1
score: 13.4
version: v3
需要记录 ID、文档版本、召回通道、通道内排名、原始分数和权限判断。BM25 分数与向量相似度不在同一量纲,不能直接拿 13.4 和 0.91 比大小。
排序记录的是 fusion 或 reranker 之后的顺序。至少要保存每个阶段的 rank 和 score,而不是只保留最后 top-k,
plan-v3#audit-export: candidate_rank=2 -> rerank_rank=1
plan-v2#audit-faq: candidate_rank=1 -> rerank_rank=4
这样 gold evidence 已进入候选但最终没进入 context 时,才能判断是 reranker、融合权重还是 context selection 出了问题。只保留最终结果,会把排序失败误判成召回失败。
最终 context 是真正放进生成模型 Prompt 的内容。它经过 ACL 和版本过滤、去重、重排、裁剪或压缩,通常只是候选集的一部分。
需要保存 context 中每段内容的 evidence ID、顺序、原文位置、版本、权限结果、token 数,以及是否经过摘要或压缩。评测时要问,正确证据是否完整、旧文档是否混入、重复内容是否挤占 token、多个证据是否互相冲突。
答案记录要同时保存展示文本和生成条件。
answer: 标准版不支持导出审计日志,但可以查看近期日志摘要。
model: example-model-v2
prompt_version: rag-answer-v5
temperature: 0.2
latency_ms: 820
只有保存模型、Prompt、生成参数、耗时、token 和原始输出,才能解释为什么同一 context 在两个版本中得到不同结果。清洗后的展示文本不能替代原始生成记录。
引用需要建立 “答案中的 claim 到具体证据位置” 的映射,不能只在答案结尾放一个 URL。
- claim: 标准版不支持导出审计日志
evidence_id: plan-v3#audit-export
anchor: section:审计日志与导出权限
- claim: 标准版可以查看近期日志摘要
evidence_id: plan-v3#audit-view
anchor: section:标准版日志能力
引用评测至少看两件事,需要证据的关键 claim 是否都被覆盖,以及每个引用是否真正支持它对应的 claim。还要检查来源版本、权限和原文定位;引用了一份真实但过期或无权访问的文档,仍然不能通过。
要。每个环节无需维护一套互相重复的端到端题库,评测分为两层。
只有端到端评测时,失败后很难定位责任;只有组件评测时,各段都通过,组合后仍可能因为版本、权限、接口和数据分布发生问题。生产 RAG 通常需要二者同时存在。
| 环节 | 评测输入 | 预期结果 | 主要检查 |
|---|---|---|---|
| Query rewrite | 原始 query、对话上下文、用户/时间条件 | 规范化意图、检索 query、filters、是否需要澄清 | 意图保持、关键实体/时间/角色保留、schema、下游召回变化 |
| 初始检索 | 固定 corpus/index、改写后的 query | 带 relevance 的 gold evidence 或 evidence set | Recall@k、Hit@k、完整证据集召回、ACL |
| Reranker | 固定候选池、候选文本、query | 候选的 graded relevance 和禁止证据 | nDCG、MRR、Precision@k、gold rank delta、延迟 |
| Context builder | rerank 结果、ACL、token budget | 必须进入和禁止进入的证据、完整 evidence set | Context Precision/Recall、去重、冲突、版本、权限、token |
| 最终回复 | query、最终 context、expected behavior | gold claims、可接受变体、禁止 claim、引用要求 | schema、正确性、faithfulness、完整性、引用、拒答 |
| 端到端 | 同一批样本运行基线和候选版本 | 业务任务与风险门禁 | 分层指标、逐样本 delta、失败归因、成本和延迟 |
rewrite Prompt 和 rewritten query 是两件事。
评测集保存 rewrite_prompt_version,再为每个问题标注预期的结构化结果,无需为每条样本重复保存 Prompt。检查字段和语义是否正确,比要求模型逐字输出某一句话更稳定。
semantic_intent_id: audit-export-standard-plan
raw_queries:
- 标准版能导日志吗?
- 基础套餐可以下载审计记录吗?
- 我们用的是标准版,审计日志能不能导出?
expected_rewrite:
feature: audit_log_export
plan: standard
action: check_permission
required_terms: [审计日志, 导出]
forbidden_drift: [企业版客户数据]
同一语义问题的不同问法,确实可能映射到同一个 canonical intent 或同一组结构化 filters。这种成组样本叫 paraphrase family,适合测试表达变化时意图是否保持稳定。
但不应强求改写后的自然语言字符串完全相同。以下情况合理结果可能不同,
Query rewrite 可以分三层测试。结构化字段先做 exact/schema check,语义是否保持交给人工或 Judge 抽检,最后比较改写前后的下游检索表现。
Retriever 是 “召回器” 或 “检索器”。它接收原始或改写后的 query,到搜索索引中快速找出一批可能相关的 document、passage 或 chunk,形成后续 Reranker 使用的候选池。
常见 Retriever 包括,
Retriever 和 Reranker 的职责可以这样区分。
Retriever:从几十万条资料中快速找出候选 Top-N,重点是别漏。
Reranker:在 Top-N 候选内部精细排序,选出最终 Top-K,重点是排准。
例如 Retriever 先从知识库召回 50 条候选,Reranker 再从这 50 条中选出最适合进入 context 的 5 条。Retriever 漏掉的证据,Reranker 看不到,也不可能补回来。
初始检索的首要任务是 “把可能正确的证据找进候选池”,此时覆盖比精细排序更重要。
评测集应为 query 标注 qrels 或完整 evidence set,但通常不要求 top-k 必须是一份完全固定的 ID 顺序。原因是可能存在多份等价证据,索引更新后也可能出现新的有效 passage。更稳的验收方式是,
这一层常看 Recall@k、Hit@k 和完整证据集召回。MRR、nDCG 也能观察初始排序,但如果后面有独立 reranker,retriever 的首要准出指标通常仍是候选池召回率。
设 qrels 中与问题相关的全部证据为集合 G,系统返回的前 k 条为 TopK,
Recall@k = |TopK ∩ G| / |G|
仍以 A、B 两条相关证据为例。
G = {A, B}
系统 Top-2 返回,
Top2 = {A, X}
系统找回了 A,漏掉 B。
Recall@2 = 1/2 = 0.5
Recall 只看 “找回多少”,不看顺序。{A,X} 与 {X,A} 的 Recall@2 相同。它的解释依赖 qrels 是否完整;如果还有一条实际相关的证据没有被标注,系统取回它时可能反而被误当作错误结果。
Hit@k 对单条 query 是二元结果,
Hit@k = 1,TopK 中至少有一条相关证据
Hit@k = 0,TopK 中一条相关证据都没有
Top2={A,X} 至少命中 A,因此,
Hit@2 = 1
在整个评测集上,Hit Rate@k 是命中 query 的比例。例如 100 个问题里有 82 个至少命中一条相关证据,Hit Rate@5=0.82。
Hit@k 很适合 “找到任意一条可回答证据就够了” 的单事实任务,但对多证据问题过于宽松。一个问题需要 A、B 两条证据,系统只找到 A,Hit 仍然是 1。
有些问题必须同时找到一组互相配合的证据,相关证据数量多也不代表已经满足回答条件。在这个例子里,完整回答要同时用到当前导出规则 A 和替代能力 B。
A:当前版审计日志导出规则
B:标准版可以查看日志摘要
把必需组合记作,
S1 = {A, B}
完整证据集召回可以定义为,
CompleteEvidence@k = 1,存在至少一套 S 完整包含在 TopK 中
CompleteEvidence@k = 0,没有任何一套完整证据被找齐
Top3={A,X,B} 同时包含 A 和 B,因此 CompleteEvidence@3=1。如果 Top-2 是 {A,X},即使 Hit@2=1、Recall@2 也不为 0,由于缺少 B,完整证据集仍然失败。
同一个问题可以存在多套可接受证据,
S1 = {A, B}
S2 = {D, E}
只要 TopK 完整包含 S1 或 S2 中任意一套即可通过。这个指标尤其适合多跳问答、跨文档比较和需要 “规则 + 例外条件” 的问题。
多跳问题是指,没有任何一条证据能够单独回答,必须先从一条证据得到中间事实,再把它和另一条或多条证据组合,才能形成最终结论。这里的 “跳” 就是从一个事实走到下一个事实的连接步骤。
单跳问题例如,
标准版是否支持导出审计日志?
如果一条当前版本的产品权限表已经明确写出答案,找到并读取这一条证据就够了。
多跳问题例如,
Acme 工作区的管理员能否导出审计日志?如果不能,他还能使用什么替代能力?
假设答案分散在三处,
M1:账户资料说明 Acme 当前使用 Standard Plan。
M2:权限规则说明只有 Enterprise Plan 的管理员可以导出审计日志。
M3:功能说明 Standard Plan 可以查看最近 30 天的日志摘要。
回答需要完成三步连接,
第 1 跳:由 M1 确认 Acme 是 Standard Plan。
第 2 跳:把 Standard Plan 代入 M2,得出不能导出。
第 3 跳:读取 M3,给出可查看近期摘要的替代能力。
只找到 M2,系统只知道 “企业版可以导出”,却不知道 Acme 是什么版本;只找到 M1+M2,可以判断不能导出,却无法回答替代能力。M1、M2、M3 都进入 Context,才具备完整回答条件。
问题很长不一定是多跳。例如 “请详细解释标准版导出权限” 可能仍然只依赖一份文档。一次问了两个互不依赖的问题也不一定是多跳;真正的多跳要求证据之间存在依赖或组合关系。
常见多跳类型包括,
多跳评测集不应只保存一个扁平的相关文档列表,而应表达完整证据组合和最终必须覆盖的 claim,
query_id: rag-multihop-001
subquestions:
- Acme 当前使用什么 Plan?
- 该 Plan 是否允许管理员导出审计日志?
- 不允许时有哪些替代能力?
acceptable_evidence_sets:
- [M1, M2, M3]
required_claims:
- Acme 使用 Standard Plan
- Standard Plan 不支持导出审计日志
- Standard Plan 可以查看最近 30 天日志摘要
这里保存的是可审计的子问题、证据和 claim,不需要保存或强迫模型输出隐藏的 chain-of-thought。模型可以采用不同推理路径,只要最终结论和引用能被证据验证。
多跳 RAG 需要在多个环节检查,
Hit@k 对多跳问题容易产生假象,只命中 M1 就已经等于 1。普通 Recall 能表示找回比例,但仍不能直接表达 “是否凑齐了一套可完成回答的证据”。因此需要 CompleteEvidence@k,再结合最终答案的 correctness、faithfulness 和 citation coverage。
ACL 检查权限边界,不能用普通相关性指标代替。它验证证据是否符合当前 principal、租户、角色、项目、策略版本和时间条件,需要同时看两个方向。
如果 Top-3 中的 X 只是普通无关文档,ACL 可以通过;如果这个位置出现另一租户的审计记录 U,
Top3 = {A, U, B}
forbidden_evidence = {U}
此时 Recall@3 仍然是 2/2=1、Hit@3=1、完整证据集召回也等于 1,但 ACL 必须判失败。其他质量分再高,也不能抵消越权证据进入系统。
反过来,如果 A、B 都是当前用户有权访问的 gold evidence,却被 ACL 误删,属于 false deny。它既是权限错误,也会导致 authorized Recall 下降。
不同架构的 ACL 执行位置可能不同,有的在检索前过滤,有的在候选后过滤。评测报告应明确检查点;无论内部候选如何实现,无权限内容都不能进入生成模型、用户答案或引用,敏感候选和日志本身也必须处于受控边界。
| 检查 | 回答的问题 |
Top3={A,X,B} 的结果 |
|---|---|---|
| Recall@3 | 两条相关证据找回了多少 | 2/2=1 |
| Hit@3 | 是否至少找到一条相关证据 | 1 |
| CompleteEvidence@3 | 必需组合 {A,B} 是否找齐 |
1 |
| ACL | 当前用户是否只接触允许的证据 | X 普通则通过;X 为越权 U 则失败 |
不同阶段的 k 也要分开,Retriever 可能考察 Recall@50,Reranker 考察 nDCG@10,最终 Context 只保留 5 条并考察 CompleteEvidence@5。不能只写一个模糊的 Recall@k 而不说明 k 和测量阶段。
Reranker 只能重新排列已经进入候选池的内容,无法找回 retriever 漏掉的证据。因此测试时先确认候选池里存在 gold evidence,再隔离 reranker,
先运行生产系统里的 Query rewrite 和 Retriever,再把它们的输出固化为测试输入。所有待比较的 Reranker 使用同一份 query、候选 ID、文本和版本,才能判断分数变化是否来自 Reranker。
Hard negative 是 “看起来很像正确答案、实际不应该使用” 的文档,例如旧版制度、其他产品版本、其他租户资料或只匹配关键词但不支持结论的 FAQ。它比随机无关文档更能测出 reranker 的真实区分能力。
Reranker 常用检查包括,
Precision@k 看 Reranker 最终截取的 Top-K 中有多少是相关证据,
Precision@k = TopK 中相关证据数 / k
例如 Top-5 中有三条相关证据,Precision@5=3/5=0.6。Reranker 常用它观察噪声是否被排出最终窗口,但它不区分强相关和弱相关,也不关心这三条各自在第几名。
Gold rank delta 直接记录 gold evidence 排名改善了多少。假设项目采用下面的定义。
gold_rank_delta = candidate_rank - rerank_rank
例如 A 从候选第 17 名升到重排第 2 名,
gold_rank_delta = 17 - 2 = +15
正数表示改善,负数表示退化。存在多条 gold evidence 时,应分别保存每条 delta,并报告中位数、最差证据或关键证据的变化;不要只挑改善最大的一条。若 gold 根本不在候选池,delta 应记为 N/A: retrieval miss,不能算成 Reranker 的零分。
过期证据是否被压低 可以观察 stale evidence 的 rank delta、进入 Top-K 的比例或第一条过期证据排名。比如旧制度从第 2 名降到第 18 名是好现象,更可靠的做法通常是通过版本过滤直接移除,不能只依赖 Reranker 学会 “猜哪个版本新”。
禁止或越权证据 与过期证据不同。无权限内容不能进入最终 context、答案或引用。测试中可以把禁止证据作为受控 hard negative,验证 Reranker 不会抬高它;如果架构要求候选池也不得出现敏感 ID,再把候选阶段的 forbidden_hit@k 设为 0。
多跳证据在截取 Top-K 后是否完整 复用完整 evidence-set 检查。例如回答必须同时用 A、B,Reranker 后 A 排第 1、B 排第 8,而最终只取 Top-5,则 CompleteEvidence@5=0;如果 B 被提升到第 4,则变为 1。普通 MRR 可能在两种情况下都是 1,所以必须单独检查完整性。
延迟 要按线上 SLA 选择分位数,至少保留一个长尾指标,并记录 Reranker 给端到端请求增加的时间。流量和样本量足够时再看 p99。不同版本要在相同硬件、batch size、候选数量和文本长度下比较。
成本 包括第三方 API 费用、LLM token、GPU/CPU 时间、显存、吞吐量和并发容量。Reranker 通常需要逐个或分批给 query-document pair 打分,候选池从 20 扩到 200 时,成本和延迟可能显著上升。选择版本时要把质量收益、额外延迟和费用放在一起比较,不能只选 nDCG 最高的配置。
把两个版本并排后,可以直接看到质量收益是否值得新增的延迟和成本。
| 维度 | 旧版 | 新版 | 判断 |
|---|---|---|---|
| nDCG@5 | 0.71 | 0.83 | 整体排序改善 |
| MRR | 0.76 | 0.82 | 第一条相关证据提前 |
| Precision@5 | 0.60 | 0.72 | Top-5 噪声减少 |
| CompleteEvidence@5 | 0.58 | 0.69 | 多跳证据更完整 |
| forbidden_hit@5 | 0 | 0 | 权限门禁保持通过 |
| p95 latency | 85 ms | 190 ms | 延迟明显增加,需判断是否可接受 |
| 单 query 成本 | 1.0× | 2.4× | 质量收益需要和预算一起决策 |
还要做确定性约束,reranker 输出必须是输入候选的子集,不能产生新 ID;不能重复;ACL 过滤不能被绕过;score/rank schema 必须合法。
固定候选池与真实候选池都要跑。前者隔离 Reranker 自身能力,后者验证它面对线上候选分布时是否仍有收益。
这三个指标都与 “排序质量” 有关,但回答的问题不同,
继续使用上面的 qrels。令 A=plan-v3#audit-export,相关等级为 2;B=plan-v3#audit-view,相关等级为 1;X 是不相关文档。假设系统排序结果为,
第 1 名:B,相关等级 1
第 2 名:X,相关等级 0
第 3 名:A,相关等级 2
对一条 query,先计算 Reciprocal Rank,
RR = 1 / 第一个相关结果的排名
MRR 是所有 query 的 RR 平均值,
MRR = 所有 query 的 RR 之和 / query 数量
在 B、X、A 这个排序里,第一个相关结果 B 位于第 1 名,因此这条 query 的 RR=1。这个分数看起来完美,但真正直接回答问题的强相关证据 A 直到第 3 名才出现。MRR 看不到第二条、第三条相关证据,也不关心它们的重要程度,所以它适合 “只要尽快找到一条正确结果” 的任务,不适合单独评价多证据或多跳 RAG。
nDCG 是 normalized Discounted Cumulative Gain。可以拆成三步理解,
常见公式是,
DCG@k = Σ (2^rel_i - 1) / log2(i + 1)
nDCG@k = DCG@k / IDCG@k
对于 B(1)、X(0)、A(2),
DCG@3 = 1 + 0 + 3/2 = 2.5
理想排序应该是 A(2)、B(1)、X(0),
IDCG@3 = 3 + 1/log2(3) ≈ 3.631
nDCG@3 = 2.5 / 3.631 ≈ 0.689
nDCG 发现了 MRR 没发现的问题,虽然第 1 名已经相关,但最重要的 A 排得太后,因此整体排序不是最优。它适合存在多条证据、相关性有强弱之分的任务。
需要固定 gain 公式和 relevance 等级定义。有的实现直接使用 rel_i,有的使用 2^rel_i-1;同样叫 nDCG,口径不同也不能直接比较。
普通 Precision@k 只看 top-k 中相关项的比例。在 B、X、A 中,top-3 有两个相关项,因此,
Precision@3 = 2/3
RAG 评测工具中的 Context Precision 往往还考虑相关 context 的排名。以常见的 Average Precision 式口径为例,只在每个相关项出现的位置累计当时的 Precision,
Context Precision = (P@1 + P@3) / 2
= (1 + 2/3) / 2
≈ 0.833
如果排序变成 X、B、A,仍然是三个 context 中两个相关,普通 Precision@3 还是 2/3;但相关项分别位于第 2、3 名,
Context Precision = (P@2 + P@3) / 2
= (1/2 + 2/3) / 2
≈ 0.583
Context Precision 同时检查噪声数量和顺序,噪声挡在有用证据前面时会受到惩罚。这对 RAG 很重要,因为 context 有 token 预算,排在前面的内容通常更容易进入最终 Prompt,也更可能影响生成模型。
不过 Context Precision 不是唯一固定实现,
因此报告不能只写 context_precision=0.83,还要写清采用哪个实现、是否需要 reference、由哪个 Judge 判断、检索单位是什么。
| 指标 | 最适合回答 | 主要盲区 |
|---|---|---|
| MRR | 第一条相关证据出现得是否足够早。 | 忽略后续证据和相关性强弱。 |
| nDCG | 多条、不同重要程度的证据整体排序是否合理。 | 依赖完整且可信的 graded qrels。 |
| Context Precision | 进入 context 的有用证据是否靠前、噪声是否靠后。 | 不证明所有必要证据都被找齐,也不证明来源真实或有权限。 |
它们通常需要和 Recall@k 或完整 evidence-set recall 一起看。一个系统可以 Context Precision 很高,却只找到两条必要证据中的一条;此时上下文很 “干净”,但仍然不完整。
Reranker 关心每条候选排第几,Context builder 则要把一组能够安全回答问题的材料真正装进 Prompt。它要处理多条证据之间的关系,不能简单理解成再次排序。
可以把它类比成准备会议材料,Reranker 给每份文件标出相关程度,Context builder 则要删掉无权查看和过期的文件、合并重复页、确保主规则和例外条款都在、控制总页数,并给每段材料标清来源,最后才交给回答模型。
假设 Reranker 给出下面的 Top-6,用户属于租户 T1,回答必须同时使用 A、B,Context 预算是 1,000 tokens,
| Rank | 证据 | 状态 | tokens |
|---|---|---|---|
| 1 | A,当前版导出规则 | T1、v3、强相关 | 420 |
| 2 | A2,A 的大段重叠 chunk | T1、v3、重复 | 380 |
| 3 | B,标准版可查看日志摘要 | T1、v3、必需补充证据 | 480 |
| 4 | U,另一租户的真实审计记录 | T2、越权 | 300 |
| 5 | O,旧版导出规则 | T1、v2、已被 v3 替代 | 350 |
| 6 | C,审计日志术语解释 | T1、v3、辅助相关 | 260 |
如果直接取 Reranker Top-5,总 tokens 为 1,930,不仅超预算,还包含重复 A2、越权 U 和过期 O。Context builder 会按约束处理,
最终应产生一份可审计的 context pack,不能只留下一段来源不明的拼接文本。
context_budget: 1000
tokens_used: 900
items:
- evidence_id: A
order: 1
role: primary_rule
source_version: v3
anchor: section:审计日志导出权限
tokens: 420
- evidence_id: B
order: 2
role: required_support
source_version: v3
anchor: section:标准版日志能力
tokens: 480
excluded:
- {evidence_id: A2, reason: near_duplicate}
- {evidence_id: U, reason: acl_denied}
- {evidence_id: O, reason: superseded_version}
- {evidence_id: C, reason: token_budget}
它回答 “当前用户有没有资格让这段内容进入模型”。过滤条件可能包含 tenant、user、role、project、document ACL、policy version 和 query time。
权限过滤最好尽量前置到 Retriever,避免敏感文本参与向量召回、日志或缓存;Context builder 仍应在发送给 LLM 前再次验证。测试既要检查 U 是否从最终 context 消失,也要检查它是否泄漏到 Prompt、答案、引用和不受控 trace。
同一制度可能同时存在 v1、v2、v3。系统应根据 valid_from、valid_to、supersedes、文档状态和 query time 判断哪个版本有效。
如果用户问 “2024 年当时的规则”,旧版可能正是正确证据;如果问 “现在”,旧版通常应被排除。因此 “新版本永远优先” 也不准确,测试样本必须带时间条件。
文档切 chunk 时常有 overlap,Retriever 可能返回同一段内容的多个近邻 chunk。去重包括,
去重也有边界。两份独立来源都支持一个高风险结论时,保留它们可能增加可验证性;真正要移除的是没有新增信息、只消耗 token 的重复。
多样性不等于机械规定 “每个文档只能取一条”。它让有限 Context 覆盖回答所需的不同信息。例如 A 负责主规则,B 负责例外条件,C 负责定义。
如果 top-5 全来自同一份长文的相邻 chunk,Context Precision 可能不低,但跨文档问题所需的另一条证据会被挤掉。Context builder 可以限制同一文档占用的名额,也可以按证据职责和主题覆盖选材。需要自动兼顾相关性与去重时,再使用最大边际相关性(MMR)。验收仍以必要 claim 是否覆盖为准,不能为了多样强行加入无用文档。
冲突证据需要单独处理。例如 v2 说 “允许导出”,v3 说 “不允许导出”,或者两个同级权威来源给出不同金额。
Context builder 至少要记录冲突组和处理理由,
测试应包含人工设计的冲突对,检查系统是否会盲从排名最高的一条旧证据。
模型的 context window 不能全部用来放检索证据。总预算还要留给 system Prompt、对话历史、当前 query、工具输出和回答空间,
evidence_budget
= model_context_window
- system_prompt
- conversation_history
- current_query
- answer_reserve
- safety_margin
例如模型窗口为 8,000 tokens,system Prompt 和规则占 1,000,历史对话占 1,500,query 占 200,预留回答 1,500,再保留 300 安全余量,真正能给证据的只有 3,500 tokens。
测试要验证不能因为从尾部粗暴截断,恰好把 evidence set 的 B 切掉。对于多证据问题,应先保证必需证据完整,再用剩余预算加入辅助材料。
压缩是在保留证据含义的前提下减少 token,常见方式有两种。
压缩后必须保留到原始证据的映射。测试要比较压缩前后的 required claim coverage,检查数字、否定、例外、时间和主体是否保持一致;压缩器的幻觉不能被当作原文证据。
经过过滤和选择后,仍需决定 context 中的阅读顺序。常见做法是主证据在前、补充和例外随后,或按问题的推理顺序组织。不能只照搬 Reranker score,因为全局组装可能要求先放定义,再放规则,最后放例外。
顺序测试可以比较不同 context order 下的答案正确性、faithfulness 和完整性;如果模型对顺序非常敏感,说明系统需要更明确的分段标签、引用结构或 Prompt 约束,也需要检查 Reranker。
像 Reranker 一样,组件测试时先固定输入,同一 query、同一份 reranked candidate list、相同 ACL、query time 和 token budget,再比较不同 builder 版本。
固定输入可以这样记录。
must_include: [A, B]
must_exclude:
U: acl_denied
O: superseded_version
duplicate_groups:
- [A, A2]
max_context_tokens: 1000
required_evidence_sets:
- [A, B]
确定性检查包括,
must_include 是否全部进入。must_exclude 是否全部排除,且原因正确。语义检查包括,
端到端评测还可以做三组对照,
Oracle Context:人工准备的理想证据包
Built Context:真实 Context builder 的输出
Raw Top-K:不做组装,直接拼接 Reranker Top-K
如果 Oracle 表现好、Built 表现差,问题在检索之后;如果 Built 明显优于 Raw Top-K,说明 Context builder 确实带来收益。
retrieved_docs[:k] 后直接拼成 Prompt,本身也是一种最小 Context 组装策略,只是没有独立模块。此时可以把 Reranker 与 Context 测试合并,但仍必须检查 ACL、版本、去重、token、完整 evidence set 和 citation anchor。没有独立类名,不代表这段质量责任不存在。
最终回复不应全部交给人逐条阅读,也不能完全交给 LLM-as-Judge。通常采用三层组合。
第一层是确定性检查,
第二层是 LLM-as-Judge,适合评估,
第三层是人工复核。普通样本可以抽样,高风险、Judge 分歧和发布阻断样本需要逐条仲裁。人工主要负责这些工作。
Judge 超时、限流、JSON 解析失败或 schema invalid 必须记录为 evaluator error,不能直接计成答案 0 分;否则评测基础设施不稳定会被误诊为模型质量下降。
同一个审计日志问题可能出现四种相近的结果,修复位置却完全不同。
| 情况 | Context | 最终回答 | 应怎样判 |
|---|---|---|---|
| 答案正确,证据错误 | 旧版 O 写着可以导出 | 模型凭记忆回答不能导出 | Correctness 可以通过,Faithfulness 与 Citation 失败,端到端失败 |
| 忠实复述过期证据 | 旧版 O 写着可以导出 | 回答可以导出 | Faithfulness 可能通过,当前事实正确性与新鲜度失败 |
| 多跳证据不完整 | 有 M1、M2,缺少替代能力 M3 | 回答不能导出,没有说明可查看摘要 | 主结论部分正确,Completeness 与 Citation coverage 失败 |
| 使用越权证据 | Context 中混入另一租户 U | 回答引用 U 中的信息 | ACL 直接失败,其他分数不再影响准出 |
把这些结果压成一个总分后,研发很难判断该修 Retriever、版本过滤、Context builder、Generator 还是 Judge。因此 Correctness、Faithfulness、Completeness、Citation 和 ACL 要分开记录。
Judge 上线以前也要接受评测。领域专家先写清评分规则(rubric),再标注一批代表性样本。这批样本要覆盖正常回答、无答案、冲突证据、多跳问题、长 Context、权限边界和容易混淆的术语。
其中一部分样本用于调 Judge Prompt,另一部分保留为 holdout。不能在同一批标签上反复修改 Prompt,随后又用它证明 Judge 很准。
校准时重点看这些结果。
needs_review 样本的人工仲裁结果。Judge model、Prompt、few-shot、temperature、输出 schema 和指标版本都要冻结。任何一项变化都可能让历史分数失去可比性。高风险类别更关心 false positive,宁可多交给人复核,也不能让错误答案轻易通过。
环境和环节要分开看。开发、CI、预发布和生产保留的观测对象相同,执行深度不同。下面是一种常见分工。
| 环境 | 主要执行内容 |
|---|---|
| 本地开发 | 小规模组件用例,快速检查本次修改涉及的 rewrite、retriever、reranker、context 或 generator。 |
| CI/发布前 | 固定版本的组件回归 + 端到端回归;包含 qrels、gold answer、Judge 校准和关键风险门禁。 |
| Staging | 使用接近生产的 corpus、索引、ACL、模型和并发配置,补充性能、成本和故障恢复测试。 |
| Production | 按风险全量执行低成本的 schema、ACL、引用 ID 等规则;抽样执行昂贵 Judge;采集用户反馈和业务结果并回流离线集。 |
系统真实存在的每个环节都应可观测、可单测,并在端到端运行中保留输出。系统没有 query rewrite、reranker 或独立 context builder,就不用为了凑齐评测形式去虚构这些环节。
确定性检查使用固定规则计算结果,不需要 LLM 猜测语义。上游模型仍然可能产生不同输出,但 checker 本身可以重复执行,结果也能解释。
把实际召回的 evidence_id 与 qrels 比较,用来回答正确证据有没有出现、排在什么位置、完整证据集是否找齐。它可以计算 Recall@k、Hit@k、MRR、nDCG 等指标。
例如 qrels 规定 plan-v3#audit-export 是强相关证据,但 top-5 只有旧版 FAQ,那么检索层直接失败,不需要 LLM Judge 再判断 “这些文档看起来是否相关”。
ID 检查属于工程一致性检查,没有统一的学术指标定义。常见规则包括,
它解决的是 “证据链能不能对上账”,不判断文本语义是否正确。
ACL 是 Access Control List,这里泛指访问控制规则。检查时要把当前用户、租户、角色、项目、策略版本和时间条件带入,验证,
涉及受保护信息时,越权使用或泄露通常会直接阻断发布。答案即使完全正确,也不能用平均质量分抵消这类安全失败。
Schema 检查验证数据结构是否满足约定,例如用 JSON Schema、Pydantic 或数据库约束检查,
relevance、角色、状态等枚举值是否合法。claim、evidence_id 和 anchor。valid / invalid / error 中的明确状态。Schema 通过只说明 “格式合格”,不说明 “内容正确”。一个结构完整但引用错文档的答案会通过 schema,却应在 citation support 检查中失败。
这四类检查应优先于 LLM Judge,它们成本低、规则明确,还能先排除数据损坏、越权和证据记录断裂。之后再让语义评测判断 “答案是否真正受证据支持”“是否遗漏关键含义” 等程序难以完全覆盖的问题。
把前面的字段合在一起,一条端到端评测样本可以这样记录。
sample_id: rag-policy-001
query: "标准版账号可以导出审计日志吗?"
user_role: standard_admin
gold_answer: "不可以。审计日志导出仅企业版支持;标准版管理员只能查看最近一段时间的日志摘要。"
gold_evidence:
- doc_id: product-plan-permissions-v3
section: "审计日志与导出权限"
expected_claim: "export_audit_log requires enterprise plan"
expected_behavior:
answer: "说明标准版不支持导出,并给出可查看摘要的替代能力。"
citation_required: true
forbidden: ["引用旧版定价页", "建议用户绕过权限", "给出无证据的开通承诺"]
checker:
retrieval: "gold_evidence must appear in top_5"
generation: "answer must be faithful to cited context"
citation: "citation must point to gold_evidence or equivalent current policy"
permission: "context must not include enterprise-only customer data"
一次失败 run 可能长这样,
| 环节 | 实际结果 | 判断 |
|---|---|---|
| 文档入库 |
product-plan-permissions-v3 已入库。 |
文档已存在。 |
| Retrieval top-k | top-1 是旧版定价 FAQ,gold evidence 没进 top-5。 | 检索失败或 reranker 失败。 |
| Generation | 回答 “标准版支持导出”,并引用旧版 FAQ。 | 生成错误是检索错误的下游结果。 |
| Citation | 引用存在但不是当前有效政策。 | citation accuracy 失败。 |
| 修复 owner | 检索/文档治理 owner。 | 先修文档版本权重、metadata、reranker;不要先调 judge。 |
如果同一条样本的 top-k 已经命中 gold evidence,但回答仍说 “标准版支持导出”,失败就应改归因为生成不忠实或 prompt/citation 约束不足。同一个错误答案可能来自检索,也可能来自生成,只有保存每一层输出才能分清。
版本比较要使用配对实验。同一条 query 同时运行基线版和候选版,语料快照、用户身份、时间条件和评分器保持一致。每条样本都能得到一组 delta,团队才知道新版本改善了哪些问题,又破坏了哪些问题。
模型生成和 LLM Judge 都可能波动。重要实验可以重复运行,报告均值、标准差或自助法(bootstrap)置信区间。自助法通过重复抽样估计结果的波动范围。分数只提高零点几分,置信区间却大面积重叠时,现有证据不足以证明真实提升。
假设基线版和候选版跑出下面这组结果。
| 维度 | 基线版 | 候选版 | 判断 |
|---|---|---|---|
| Recall@10 | 0.82 | 0.87 | 候选召回改善 |
| CompleteEvidence@5 | 0.61 | 0.72 | 多跳证据更完整 |
| Faithfulness | 0.92 | 0.90 | 生成忠实度轻微下降 |
| 无答案误答率 | 0.08 | 0.05 | 拒答改善 |
| ACL 阻断失败 | 0 | 0 | 安全门禁保持通过 |
| p95 latency | 1.2 s | 1.9 s | 长尾延迟明显增加 |
| 单 query 成本 | 1.0× | 1.35× | 成本增加三成以上 |
这组数据不能直接导出 “候选版更好”。如果产品对延迟敏感,可以先缩小 Reranker 候选数,或者只在复杂 query 上启用昂贵路径。若 Faithfulness 的下降集中在高风险政策问题,即使平均变化很小,也应该暂停发布。
平均分之外还要查看切片。
一种实用的发布策略是把指标分成两类。软指标允许在阈值内权衡,例如平均正确率、成本和延迟。硬门禁不允许被平均分抵消,例如越权泄露、伪造引用、过期证据进入关键回答和 P0 样本退化。具体哪些问题必须阻断,要由业务风险决定。
进入生产以后,绝大多数实时 query 没有 gold answer。线上可以按风险全量运行低成本的 schema、ACL、citation ID 和错误状态检查,再抽样运行 Faithfulness、Answer Relevance 等 Judge。用户投诉、人工纠正、低置信回答和业务失败随后进入审核队列,确认后补进离线回归集。
| 失败类型 | 判断方式 | 修复方向 |
|---|---|---|
| 文档缺失 | gold evidence 不在知识库 | 补文档或补索引 |
| chunk 错误 | 文档在库中但上下文断裂 | 调整 chunking 和 metadata |
| 检索失败 | evidence 不在 top-k | 调整 embedding、hybrid、reranker |
| 权限过滤失败 | 无权限内容进入 context 或有权限内容被过滤 | 修权限规则 |
| 生成不忠实 | context 有答案但输出编造 | 调 prompt、模型或引用约束 |
| 问题无答案 | 文档没有支撑答案 | 标注 unanswerable |
看到错误答案时,先别急着调模型。沿着证据从上游往下查,通常更快找到问题。
Gold evidence 是否存在,先固定 corpus、版本和权限范围;在这个前提下仍不存在,才归为知识缺口或样本设计错误。gold evidence 必须绑定稳定 evidence ID、原文位置、文档版本和 corpus/index snapshot。
Gold evidence 是否可访问,存在但被权限过滤,先看角色、租户、ACL 和索引权限。
Gold evidence 是否进 top-k,没进 top-k,优先排查 query rewrite、embedding、hybrid search、metadata、reranker。
Context 是否干净,命中了证据但混入旧文档、重复片段或冲突片段,优先排查 chunking、去重、版本权重和上下文裁剪。
Answer 是否忠实,context 有答案但生成错,排查 prompt、模型、answer constraint、citation requirement。
Citation 是否真实,按 claim-evidence 可定位门禁检查,答案对但引用错不能算完全通过;继续排查 citation 选择和证据绑定。
Review 是否一致,自动评分和人工分歧时,回到复核层修 rubric、judge prompt 或样本预期。