RAG 评测生产实战:Golden Dataset、分层指标、LLM Judge 与发布门禁
从证据标注、检索与上下文指标、Claim 级 Faithfulness、LLM Judge 校准、实验统计到线上反馈和发布门禁,搭建一套可复现、可解释、可持续迭代的生产级 RAG 评测系统。
RAG 系统最容易陷入一种危险状态:
换了 Embedding,几个演示问题看起来更好;
增加 Reranker,团队觉得答案更专业;
调整 Chunk,某些长文档终于能回答;
修改 Prompt,拒答率下降了。但只要继续追问,很多团队就无法回答:
- 哪一类问题变好了?
- 哪一类问题退化了?
- 正确证据是在召回、融合、重排还是 Context Pack 阶段丢失的?
- LLM Judge 的分数是否真的和人工判断一致?
- 平均分上涨,是否掩盖了权限越界和关键业务问题回归?
- 同一套评测半年后还能复现吗?
- 新版本应该发布、灰度,还是回滚?
生产级 RAG 评测不是“调用几个自动指标”,而是一套测量系统:
版本化数据集
+
证据与行为标注
+
分阶段执行记录
+
确定性指标
+
经过校准的模型评审
+
统计不确定性
+
新旧版本实验对比
+
发布门禁
+
线上反馈闭环资料快照:本文依据 RAGAS、ARES、RAGChecker、LangSmith、Phoenix 等官方资料,以及 G-Eval、MT-Bench LLM-as-a-Judge 等原始论文核查,截止日期为 2026-08-05。不同框架的指标名称、默认 Prompt 和 API 会持续变化;生产系统应冻结自己的评测 Schema、Judge Prompt、模型版本和数据集版本,而不是把工具当前默认值当成长期标准。
图 1:RAG 评测不是一个端到端平均分,而是从数据集、检索、上下文、答案到发布决策的分层测量系统。
一句话结论
RAG 评测必须同时回答四个问题:
- 正确证据是否有机会进入候选集?
- 有限 Context 是否保留了足够且干净的证据?
- 答案中的每个关键 Claim 是否被证据支持?
- 质量提升是否值得增加的延迟、成本和安全风险?
推荐的评测主链路是:
真实问题与安全样本
→ 冻结 Dataset Version
→ Baseline / Candidate 分别运行
→ 检索、融合、重排、Context、答案分层打分
→ Judge 与人工校准
→ Case-level Diff + 置信区间
→ Release Gate
→ Canary / Online Eval
→ Bad Case 回流数据集1. 先建立完整评测架构
图 2:四层指标回答四个不同问题:证据是否被找到、Context 是否可用、答案是否有依据,以及质量收益是否值得新增成本和风险。
这套系统至少包含五类独立版本:
dataset_version
pipeline_version
index_manifest_version
judge_version
metric_schema_version任何一项变化,都可能改变分数含义。
2. 评测单位:一次 Query、一次 Turn,还是整个 Session
评测单位必须与产品任务一致。
| 单位 | 适合什么 | 主要问题 |
|---|---|---|
| Query | 无状态搜索、单问题 QA | 最容易离线复现 |
| Turn | 带会话历史的一次问答 | 需要冻结当时可见历史和 Scope |
| Session | 多轮任务完成情况 | 需要评估状态保持、追问和最终目标 |
| Workflow | Agent / 多工具 / 多跳任务 | 需要评估步骤、工具、恢复和人工介入 |
本文重点讨论 Query 与 Turn,但数据模型应为未来的 Multi-turn 和 Agent 留出空间。
一个生产样本不能只有:
{
"question": "如何解决索引被旧消息覆盖?",
"answer": "使用版本号"
}它还应冻结:
- 用户角色与租户;
- 允许访问的知识库;
- 时间语境;
- 需要命中的证据;
- 不能出现的证据;
- 预期行为是回答、拒答、追问还是调用工具;
- 业务严重程度;
- 当前基准为何被加入数据集。
3. 数据集不是一个 JSON 文件,而是版本化产品
3.1 建议的数据集分层
| 数据集 | 来源 | 目的 | 更新节奏 |
|---|---|---|---|
| Golden Set | 业务专家与核心流程 | 衡量基本能力是否稳定 | 谨慎更新 |
| Regression Set | 历史 Bad Case | 防止已修问题复发 | 持续增长 |
| Safety Set | 权限、敏感信息、Injection | 硬门禁 | 按威胁持续更新 |
| Freshness Set | 时间、版本和更新问题 | 防止答案使用旧资料 | 随数据版本更新 |
| Stress Set | 长问题、多跳、噪声、冲突 | 测极端边界 | 定期扩充 |
| Shadow Set | 近期真实流量抽样 | 检测分布变化 | 高频滚动 |
| Synthetic Set | 从文档或 Schema 自动生成 | 扩大覆盖、发现候选方向 | 可快速重建 |
Synthetic Set 很有价值,但不能替代真实用户问题。自动生成的问题通常更贴近文档措辞,容易高估检索质量;真实用户会省略上下文、混用术语、写错名称,并带有权限、时间和多意图约束。
3.2 数据集版本必须不可变
推荐使用:
rag-eval-core@2026-08-05.1
rag-eval-safety@2026-08-05.3
rag-eval-shadow@2026-W32一个 Dataset Version 发布后,不直接修改原样本。修正标注时创建新版本,并记录:
parent_version
change_reason
added_cases
removed_cases
label_changes
reviewers
created_at否则两次实验都声称使用 golden-set,实际上样本已经不同,指标无法比较。
4. 一份可用的 Eval Case Schema
{
"case_id": "rag_eval_00042",
"dataset_version": "rag-eval-core@2026-08-05.1",
"question": "为什么 external version 删除后仍建议保留 Tombstone?",
"conversation": [],
"query_type": "concept_with_constraint",
"severity": "high",
"language": "zh-CN",
"time_context": "2026-08-05T10:00:00+08:00",
"scope": {
"tenant_id": "tenant_001",
"knowledge_base_ids": ["kb_rag"],
"acl_groups": ["employee", "rag-team"]
},
"expected_behavior": "answer_with_citations",
"expected_answer_rubric": [
"说明 external version 能阻止较旧版本覆盖",
"说明删除版本信息只保留有限时间",
"说明 Tombstone 应覆盖消息延迟、重试和 DLQ 重放窗口",
"说明 Repair 仍需检测 Orphan"
],
"required_claims": [
{
"claim_id": "c1",
"text": "删除后的版本信息不是永久保存",
"weight": 0.35
},
{
"claim_id": "c2",
"text": "Tombstone 可以在重放窗口内阻止旧 UPSERT 复活",
"weight": 0.4
},
{
"claim_id": "c3",
"text": "仍需 Repair Job 检查孤儿文档",
"weight": 0.25
}
],
"evidence_groups": [
{
"group_id": "g1",
"requirement": "all_of",
"evidence": [
{
"knowledge_id": "doc_es_consistency",
"chunk_id": "chunk_gc_deletes",
"source_revision": 43,
"relevance": 3
},
{
"knowledge_id": "doc_es_consistency",
"chunk_id": "chunk_tombstone",
"source_revision": 43,
"relevance": 3
}
]
}
],
"forbidden_evidence": [
{
"knowledge_id": "private_security_playbook",
"reason": "当前用户无权限"
}
],
"tags": ["elasticsearch", "delete", "versioning", "tombstone"],
"provenance": {
"source": "production_bad_case",
"trace_id": "trace_abc",
"created_by": "rag-quality-team",
"reviewed_by": ["retrieval-owner", "domain-expert"]
}
}4.1 为什么要标注 required_claims
长答案很难只用一个标准字符串判断。
把答案拆成 Claim 后,可以分别评估:
Claim 是否出现
Claim 是否正确
Claim 是否被 Context 支持
Claim 的 Citation 是否准确
Claim 是否和其他 Claim 冲突这比“整体答案 0.83 分”更容易定位问题。
4.2 为什么 Evidence 需要 Group
多跳或多证据问题可能有不同满足方式:
all_of
→ 必须同时找到多个证据
any_of
→ 多个等价来源命中任意一个即可
at_least_n
→ 至少命中 N 个来源如果只存一串 evidence_ids,就无法表达这些语义。
5. 相关性标注不要只有 0 和 1
推荐至少使用四级相关性:
3:直接且完整支持核心问题
2:包含关键事实,但需要与其他证据组合
1:主题相关,但不能回答核心问题
0:不相关或误导这样可以计算 NDCG,并区分:
- 真正可回答证据;
- 只是在同一主题下的背景资料;
- 容易被 Reranker 错排到前面的“看起来相关”内容。
5.1 标注单位要稳定
同一份文档可能在不同 Chunk 策略下产生不同 chunk_id。因此 Evidence 最好同时保存:
knowledge_id
source_revision
section_anchor
page / timestamp
character offsets
content_hash
chunk_idchunk_id 用于当前检索评测,稳定来源定位用于索引重建后的标注迁移。
6. 检索评测:先判断正确证据是否有机会被看到
检索评测应在不调用生成模型的情况下完成。
6.1 Hit@K
Hit@K =
前 K 个结果中是否至少出现一个合格证据适合单证据问题,输出通常是 0 或 1。
6.2 Recall@K
Recall@K =
前 K 个结果命中的相关证据数
÷
全部相关证据数多证据问题更有意义。
6.3 Precision@K
Precision@K =
前 K 个结果中的相关证据数
÷
K它反映候选噪声,但第一阶段召回不应过早只追求 Precision。
6.4 MRR
Reciprocal Rank = 1 / 第一个相关结果的排名
MRR = 所有 Query 的 Reciprocal Rank 平均值适合“第一个正确证据越早越好”的单答案场景。
6.5 NDCG@K
NDCG 使用分级相关性,奖励高相关证据排在前面,并用理想排序归一化到可比较范围。
它特别适合:
- 多个证据都有价值;
- 证据相关程度不同;
- 比较 RRF、Reranker 和不同权重的排序质量。
6.6 MAP
Mean Average Precision 对每个 Query 计算所有相关结果位置上的 Precision,再做平均,适合一个 Query 有多个相关证据的情况。
6.7 Union Recall 与 Unique Relevant Gain
Hybrid Search 应分别记录:
BM25 Recall@K
Dense Recall@K
Union Recall@K并计算:
Unique Relevant Gain from Dense
→ 只被 Dense 找到的正确证据
Unique Relevant Gain from BM25
→ 只被 BM25 找到的正确证据如果新增一条召回通道只带来大量重复候选,却没有独有正确证据,它可能只是增加成本。
7. Filter 评测:权限正确不等于召回没有损失
检索失败有时不是 BM25 或 Embedding 问题,而是正确证据在召回前被 Filter 排除。
推荐记录:
eligible_evidence_count
filtered_evidence_count
filter_recall_loss
filter_reason常见原因:
tenant_mismatch
acl_denied
doc_archived
doc_disabled
language_mismatch
version_stale
time_range_excluded
source_not_selected安全样本中,越权内容被排除是正确行为;普通样本中,误过滤正确证据则是召回回归。
7.1 权限指标必须单独做硬门禁
Unauthorized Retrieval Rate
Unauthorized Context Rate
Unauthorized Citation Rate这些指标不能和普通质量分数平均。一次严重越权不应被 999 次正常回答抵消。
8. Multi-hop 与 Evidence Set 评测
多跳问题的关键不是“是否找到任意相关文档”,而是是否找齐推理链所需证据。
例如:
角色 A 关联的场景使用了哪些资产?可能需要:
角色 A → Scene IDs
Scene IDs → Asset IDs推荐指标:
| 指标 | 含义 |
|---|---|
| Hop Recall | 每一跳所需证据是否命中 |
| Complete Chain Rate | 整条证据链是否完整 |
| Stable ID Usage Rate | 后续 Query 是否使用真实检索 ID |
| Hallucinated Entity Rate | Planner 是否生成不存在的实体 |
| Unnecessary Hop Rate | 是否产生无价值额外步骤 |
对于 Sequential Retrieval,还要保存每一跳的中间结果和停止原因。
9. Context 评测:从候选集到模型可用证据
正确证据进入 Candidate Set,不代表最终会进入 Prompt。
中间还可能经历:
RRF 截断
Rerank
Parent 回填
文档去重
MMR
Token Budget
Context Compression
Citation 可用性过滤9.1 Context Precision
最终 Context 中真正有用的内容比例实现时可以按 Chunk、句子或 Claim 粒度衡量。
9.2 Context Recall
回答所需证据有多少进入最终 Context注意:Retrieval Recall 高,但 Context Recall 仍可能低,因为正确证据被重排、去重或预算裁掉。
9.3 Evidence Coverage
required_claims 中,
有多少 Claim 在 Context 中至少有一个支持证据它比单纯统计 Chunk 命中更贴近答案可回答性。
9.4 Redundancy Ratio
重复或近重复 Token
÷
Context 总 Token重复可能来自:
- 同一 Parent 的多个 Child;
- 同一内容的新旧版本;
- FAQ 改写;
- 多个数据源复制同一文档。
9.5 Token Efficiency
有效证据 Token
÷
Context 总 Token只追求 Context Precision 可能会漏掉必要背景,因此应与 Context Recall 一起看。
9.6 Conflict Rate
当 Context 中包含互相冲突的版本、政策或事实时,应记录:
conflicting_evidence_count
newest_revision_selected
source_authority_selected
conflict_explained_in_answer10. 答案评测要拆成 Claim,而不是只看整体相似度
10.1 Answer Correctness
检查答案是否与业务事实和 Rubric 一致。
它可能需要:
- 标准答案;
- 必须出现的关键点;
- 禁止出现的错误结论;
- 数值、时间和实体的精确比较。
10.2 Answer Relevance
检查答案是否直接回应用户问题,而不是只输出相关背景。
10.3 Completeness
required_claims 中,
有多少在答案中被正确覆盖10.4 Faithfulness
Faithfulness 不等于“事实在世界上正确”,而是:
答案中的 Claim
是否能被提供给模型的 Context 支持Phoenix 官方的 Faithfulness Evaluator 也把它定义为检查回答是否由给定 Context 支撑,而不是验证模型训练知识中的一般事实。
10.5 Citation Precision
答案给出的引用中,
有多少真正支持对应 Claim10.6 Citation Recall
需要引用的关键 Claim 中,
有多少提供了有效引用10.7 Refusal Accuracy
需要区分:
应该回答却拒答
→ False Refusal
证据不足却强行回答
→ False Answer
无权限仍回答
→ Security Failure
信息不足时正确追问
→ Correct Clarification11. Claim 级评测示例
{
"answer": "External version 可以阻止旧版本覆盖,但删除版本只保留有限时间。因此应保留 Tombstone 覆盖重试和重放窗口,并通过 Repair Job 检测孤儿文档。",
"claims": [
{
"claim_id": "a1",
"text": "External version 可以阻止旧版本覆盖",
"correct": true,
"supported": true,
"citation_ids": ["cite_1"]
},
{
"claim_id": "a2",
"text": "删除版本只保留有限时间",
"correct": true,
"supported": true,
"citation_ids": ["cite_2"]
},
{
"claim_id": "a3",
"text": "Tombstone 应覆盖重试和重放窗口",
"correct": true,
"supported": true,
"citation_ids": ["cite_3"]
},
{
"claim_id": "a4",
"text": "Repair Job 需要检测孤儿文档",
"correct": true,
"supported": true,
"citation_ids": ["cite_4"]
}
]
}在 Trace 中保留 Claim 与 Citation 的映射,可以把 Faithfulness 和 Citation Accuracy 分开计算。
12. LLM-as-a-Judge 应该怎样设计
LLM Judge 适合评估开放式答案、Faithfulness、Rubric 覆盖和 Pairwise Preference,但它不是天然可靠的测量仪器。
G-Eval 使用评测步骤和结构化打分来提高与人工判断的一致性;MT-Bench 的研究则系统讨论了 Position、Verbosity、自我偏好和有限推理能力等 Judge 偏差。
12.1 Pointwise、Pairwise 与 Listwise
| 方式 | 输入 | 适合什么 | 风险 |
|---|---|---|---|
| Pointwise | 单个答案 | Rubric 打分、Faithfulness | 尺度漂移 |
| Pairwise | Baseline vs Candidate | 版本对比、用户偏好 | Position Bias |
| Listwise | 多个候选 | 排序多个版本或答案 | 输出复杂、成本高 |
12.2 推荐结构化输出
{
"verdict": "pass",
"score": 4,
"criteria": {
"correctness": 4,
"completeness": 3,
"faithfulness": 4,
"citation_accuracy": 4
},
"failed_claims": [],
"missing_rubric_items": [
"没有说明 Tombstone 的具体保留窗口"
],
"explanation": "核心结论正确且有证据,但实施细节不完整。"
}不要只让 Judge 返回一个浮点数。
12.3 Judge Prompt 必须版本化
judge_name
judge_prompt_version
judge_model
judge_model_revision
temperature
sampling_seed
rubric_version
output_schema_versionJudge Prompt 变更应被视为评测系统变更,而不是普通文案修改。
13. 一个可复用的 Judge Prompt
你是 RAG 评测器。只能依据提供的:
1. 用户问题
2. 预期行为
3. Rubric
4. 检索 Context
5. 系统答案
6. Citation 映射
进行评判。
要求:
- 先把答案拆成原子 Claim。
- 对每个 Claim 判断:正确、被 Context 支持、引用是否匹配。
- 不使用模型自己的外部知识补全证据。
- 未在 Context 中出现的事实,即使看起来正确,也不能算 Faithful。
- 缺少 Rubric 项应列入 missing_rubric_items。
- 如果问题要求拒答或追问,要按 expected_behavior 判断。
- 输出必须符合指定 JSON Schema。
- 不输出 JSON 以外文本。生产中应将 Rubric 和样本输入分隔清楚,避免样本内容中的 Prompt Injection 改变 Judge 规则。
14. Judge 校准:自动分数必须对齐人工 Gold Labels
图 3:自动 Judge 只有在人工校准集上通过一致性、严重错误召回和位置偏差检查后,才适合进入生产评测。
14.1 建立 Judge Calibration Set
从完整数据集中抽取:
- 不同 Query Type;
- 不同语言;
- 不同答案长度;
- 正确、部分正确、错误和拒答样本;
- 容易出现 Position Bias 和 Verbosity Bias 的样本;
- 高严重度权限样本。
由至少两名人工评审标注,争议样本进入仲裁。
14.2 评估哪些统计量
| 指标 | 说明 |
|---|---|
| Exact Agreement | 自动 Judge 与人工是否完全一致 |
| Cohen's Kappa | 扣除随机一致后的分类一致性 |
| Weighted Kappa | 有序分数之间的距离也计入 |
| Spearman | 排名相关性 |
| Kendall Tau | Pairwise 排序一致性 |
| Precision / Recall | 对 Pass、Fail 或严重错误的识别能力 |
| Calibration Error | Judge 的置信度是否可信 |
只看 Exact Agreement 可能高估 Judge 质量。生产门禁尤其关注:
Critical Failure Recall
→ 严重错误能不能被 Judge 找出来14.3 定期做 Position Swap
Pairwise 评测可以执行两次:
第一次:A 在前,B 在后
第二次:B 在前,A 在后只有结论稳定时才接受;否则标记为 judge_inconsistent,进入人工复核或第三 Judge。
14.4 控制长度偏差
答案更长不等于更好。Judge Rubric 应明确:
- 不奖励无关扩写;
- 以覆盖必需 Claim 为主;
- 单独记录冗余和直接性;
- 对比时隐藏模型名称和版本。
15. Reference-free 不等于 Human-free
RAGAS 提供 Context Precision、Context Recall、Noise Sensitivity、Response Relevancy、Faithfulness 等多类指标,适合快速搭建自动评测;ARES 使用合成数据训练轻量 Judge,并用少量人工标注配合 Prediction-Powered Inference;RAGChecker 则从 Claim 和模块层面提供更细粒度诊断。
这些框架的共同价值是缩短迭代周期,但生产落地仍需要:
人工 Gold Set
Judge Meta-Evaluation
领域 Rubric
版本冻结
严重样本抽查自动指标可以扩大覆盖,不能定义业务正确性的最终标准。
15.1 RAGAS 适合什么
- 快速覆盖 Faithfulness、Context 和 Response 维度;
- Reference-free 或 Reference-based 评测;
- 试验不同 RAG 配置;
- 自定义 Metric 和 Prompt。
15.2 ARES 提供的启发
ARES 评估 Context Relevance、Answer Faithfulness 和 Answer Relevance,使用合成训练数据和轻量 Judge,并通过少量人工标注校正总体估计。
工程启发是:
不是所有样本都必须人工评;
但自动 Judge 需要小而高质量的人工校准集。15.3 RAGChecker 提供的启发
RAGChecker 强调对 Retrieval 与 Generation 的细粒度诊断,而不是只输出一个端到端分数。
这与生产系统的目标一致:
知道变差
不如
知道是 Retriever Recall、Noise Sensitivity、Context Utilization 还是 Hallucination 变差16. 评测 Runner 必须冻结完整 Pipeline Manifest
{
"run_id": "eval_run_20260805_001",
"dataset_version": "rag-eval-core@2026-08-05.1",
"pipeline": {
"application_commit": "abc123",
"query_plan_version": "query-plan-v5",
"rewrite_prompt_version": "rewrite-v7",
"embedding_model_key": "bge-m3|endpoint-a|v2",
"index_alias": "kb_chunks",
"physical_indices": ["kb_chunks_v3"],
"projection_schema_version": 4,
"bm25_config_version": "bm25-v6",
"rrf_config_version": "rrf-v4",
"reranker_model_key": "bge-reranker-v2-m3|gpu-a",
"reranker_config_version": "rerank-v8",
"context_packer_version": "context-v4",
"answer_prompt_version": "answer-v12",
"generation_model": "model-x",
"guardrail_version": "guard-v3"
},
"judge": {
"judge_model": "judge-model-y",
"judge_prompt_version": "judge-v9",
"metric_schema_version": "rag-metrics-v5"
},
"environment": {
"region": "ap-beijing",
"started_at": "2026-08-05T10:00:00+08:00"
}
}如果没有这份 Manifest,同一个分数无法被复现。
17. Baseline 与 Candidate 应做 Paired Experiment
同一批 Case 必须分别运行:
Baseline
Candidate并按 case_id 一一对齐比较。
不要只比较两个独立平均值,因为不同样本之间难度不同。
17.1 Case-level Diff
{
"case_id": "rag_eval_00042",
"baseline": {
"retrieval_recall_at_20": 0.5,
"context_recall": 0.5,
"faithfulness": 1.0,
"answer_correctness": 0.7,
"latency_ms": 930
},
"candidate": {
"retrieval_recall_at_20": 1.0,
"context_recall": 1.0,
"faithfulness": 1.0,
"answer_correctness": 0.95,
"latency_ms": 1110
},
"classification": "improved",
"notes": "新增 Query Rewrite 找回第二条必需证据"
}17.2 报告必须列出回归样本
Improved Cases
Regressed Cases
Unchanged Cases
New Failures
Fixed Bad Cases
Judge Inconsistent Cases平均分上涨也必须审查高严重度回归。
18. 置信区间和统计不确定性
评测集只有几十或几百个样本时,分数波动可能来自抽样噪声。
推荐至少使用:
- Bootstrap Confidence Interval;
- Paired Bootstrap;
- 对二元通过率使用 Wilson Interval;
- 报告 Effect Size;
- 对多次模型采样报告均值和方差。
18.1 Bootstrap 示例
from __future__ import annotations
import random
from dataclasses import dataclass
from statistics import mean
from typing import Sequence
@dataclass(frozen=True)
class ConfidenceInterval:
estimate: float
lower: float
upper: float
def paired_bootstrap_ci(
baseline: Sequence[float],
candidate: Sequence[float],
*,
samples: int = 10_000,
confidence: float = 0.95,
seed: int = 42,
) -> ConfidenceInterval:
if len(baseline) != len(candidate):
raise ValueError("baseline and candidate must have the same length")
if not baseline:
raise ValueError("at least one paired observation is required")
rng = random.Random(seed)
deltas = [c - b for b, c in zip(baseline, candidate, strict=True)]
n = len(deltas)
bootstrap_means = []
for _ in range(samples):
draw = [deltas[rng.randrange(n)] for _ in range(n)]
bootstrap_means.append(mean(draw))
bootstrap_means.sort()
alpha = 1.0 - confidence
lower_index = int((alpha / 2.0) * samples)
upper_index = min(samples - 1, int((1.0 - alpha / 2.0) * samples))
return ConfidenceInterval(
estimate=mean(deltas),
lower=bootstrap_means[lower_index],
upper=bootstrap_means[upper_index],
)不要把 +0.01 的平均提升自动解释成真实改进。要看置信区间、高严重度 Case 和成本变化。
19. 非确定性模型需要重复运行
即使 temperature = 0,模型服务、后端实现和并行调度也可能导致差异。
对于答案或 Judge 波动较大的配置,可以:
每个 Case 重复 N 次
→ 记录均值、方差、最差值和通过率需要区分:
Pipeline Variance
Judge Variance不要让不稳定 Judge 把稳定 Pipeline 判成波动。
20. Ablation:一次只改变一个主要因素
典型实验:
| 实验 | 只改变什么 | 主要看什么 |
|---|---|---|
| BM25 vs Dense | 召回通道 | Recall@K、Unique Gain |
| Dense vs Hybrid | 增加 BM25 | Query Cohort Delta |
| RRF Window 50 vs 100 | 融合窗口 | Recall、MRR、Latency |
| Reranker A vs B | 精排模型 | NDCG、Context Precision、P95 |
| Chunk 384 vs 768 | 分块 | Recall、Context Recall、引用粒度 |
| Rewrite Off vs On | Query Plan | Anchor Loss、Union Recall、Drift |
| Prompt v11 vs v12 | 生成 Prompt | Faithfulness、Completeness、Refusal |
如果一次同时换 Embedding、Chunk、Reranker 和 Prompt,即使结果提升,也无法知道原因。
20.1 必须支持组合实验时
可以采用小规模 Factorial Design,但要控制组合数量并明确交互效应。例如:
Embedding × Chunk × Reranker有些模型在某种 Chunk 长度下才表现好,单因素结论不能直接推广。
21. Offline Evaluation 与 Online Evaluation
LangSmith 当前将评测分为:
Offline Evaluation
→ 上线前在数据集上比较版本
Online Evaluation
→ 对真实生产交互持续评分两者不能互相替代。
21.1 Offline 的优势
- 可复现;
- 可快速比较版本;
- 可以覆盖安全和边界样本;
- 能在发布前拦截回归。
21.2 Online 的优势
- 覆盖真实分布;
- 发现离线集没有的措辞和需求;
- 检测数据新鲜度和外部系统变化;
- 收集用户反馈和业务结果。
21.3 Online 指标的偏差
点赞率
追问率
复制率
停留时间
人工升级率都只是代理指标。
例如用户没有追问,可能是答案很好,也可能是已经放弃。线上信号需要和抽样人工评审、Trace 与实际业务结果结合。
22. Shadow、Canary 与 A/B
Shadow 适合
- 新 Retrieval Pipeline;
- 新 Judge;
- 新 Prompt;
- 新模型;
- 需要真实请求但不想影响用户的实验。
A/B 适合
- 用户可感知的回答质量;
- 业务转化;
- 交互偏好。
安全和权限逻辑不适合通过 A/B 试错。
23. 评测服务的数据模型
执行事实尽量不可变;后续人工反馈、Judge 和重算分数作为新的 Score 追加。
24. Eval Runner 的最小接口
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Protocol
@dataclass(frozen=True)
class EvalCase:
case_id: str
question: str
scope: dict[str, Any]
expected_behavior: str
required_claims: list[dict[str, Any]] = field(default_factory=list)
evidence_groups: list[dict[str, Any]] = field(default_factory=list)
@dataclass(frozen=True)
class PipelineOutput:
answer: str
citations: list[dict[str, Any]]
trace_id: str
retrieval_candidates: list[dict[str, Any]]
context_manifest: list[dict[str, Any]]
latency_ms: int
cost: float
degraded: bool
class RAGPipeline(Protocol):
async def run(self, case: EvalCase) -> PipelineOutput:
...
class Evaluator(Protocol):
name: str
version: str
async def evaluate(
self,
case: EvalCase,
output: PipelineOutput,
) -> dict[str, Any]:
...Runner 负责:
- 并发和速率限制;
- 重试与超时;
- 缓存;
- Baseline / Candidate 对齐;
- Artifact 保存;
- Judge 调用;
- Score 写入;
- 生成报告。
Evaluator 不应偷偷重新运行 Pipeline。
25. 确定性指标优先于 LLM Judge
能用代码直接算的指标,不要全部交给模型:
Recall@K
MRR
NDCG
Latency
Token
Cost
Unauthorized Rate
Citation ID 是否存在
Source Revision 是否匹配
是否正确拒答
JSON Schema 是否有效LLM Judge 更适合:
- 开放式正确性;
- Claim 拆分;
- Faithfulness;
- Rubric 覆盖;
- Pairwise Preference;
- 解释错误原因。
这样可以降低成本,也减少模型 Judge 的不确定性。
26. 成本评测不能只看 Token
一次 RAG 请求可能包含:
Query Rewrite
Query Embedding
BM25 / kNN
RRF
Reranker
Context Compression
Generation
Judge建议分阶段记录:
| 阶段 | 成本单位 |
|---|---|
| Embedding | 输入 Token / 字符、调用次数 |
| Elasticsearch | 查询 CPU、向量候选数、请求数 |
| Reranker | Pair 数、总 Token、GPU 时间 |
| LLM | 输入、输出、缓存读写、推理 Token |
| Judge | Judge Token、重复评审次数 |
| Storage | Trace、Artifact、数据集和索引 |
实验报告应同时提供:
quality_delta
latency_delta
cost_delta例如:
NDCG@10 +2.4%
P95 +38 ms
Cost +4.1%由业务决定是否值得。
27. 延迟评测要看分布和降级
不要只记录平均延迟。
至少记录:
P50
P95
P99
Timeout Rate
Fallback Rate
Queue Time
External Model Time按 Query Cohort 分组:
Exact ID
Concept
Multi-query
Multi-hop
Large Context
No RetrievalCandidate 可能在普通 Query 上很快,却让 Multi-hop P99 爆炸。
27.1 降级也是评测结果
embedding_timeout → bm25_only
reranker_timeout → rrf_fallback
rewrite_invalid → original_query
web_failed → kb_only需要评估:
- 降级后答案是否仍可接受;
- 用户是否被明确告知 partial;
- 安全边界是否仍然生效。
28. Release Gate 不应只有一个总分
图 4:安全与关键能力由 Hard Gate 零容忍保护;质量、延迟和成本由 Soft Gate 与 Case Review 共同决策。
28.1 Hard Gates
- 权限越界:0;
- Critical Safety Case:100% 通过;
- Schema / Citation ID 错误:0;
- 核心高严重度 Case 不得回归;
- P99 不得超过系统硬 Deadline;
- Trace Contract 必须完整。
28.2 Soft Gates
- Recall@K;
- NDCG;
- Context Precision;
- Faithfulness;
- Citation Accuracy;
- P95;
- Cost;
- 用户代理指标。
Soft Gate 可以允许有解释的小幅波动,但必须列出受影响 Case 和 Owner。
29. 一份可执行的 Gate 配置
release_gate_version: rag-gate-v4
datasets:
- rag-eval-core@2026-08-05.1
- rag-eval-regression@2026-08-05.7
- rag-eval-safety@2026-08-05.3
hard_gates:
unauthorized_retrieval_rate:
max: 0
unauthorized_context_rate:
max: 0
unauthorized_citation_rate:
max: 0
critical_case_pass_rate:
min: 1.0
invalid_citation_rate:
max: 0
trace_contract_pass_rate:
min: 1.0
p99_latency_ms:
max: 5000
soft_gates:
evidence_recall_at_10:
max_drop: 0.005
ndcg_at_10:
max_drop: 0.01
faithfulness:
max_drop: 0.005
citation_accuracy:
max_drop: 0.005
p95_latency_ms:
max_increase_ratio: 0.15
cost_per_request:
max_increase_ratio: 0.10
case_rules:
high_severity_regressions:
max: 0
medium_severity_regressions:
max: 5阈值只是示例,必须根据业务风险和历史分布设定。
30. 数据泄漏与 Benchmark Overfitting
当团队长期针对同一批 Golden Case 调参时,可能把系统优化成“只会做考试题”。
建议:
- 保留隐藏 Holdout Set;
- Shadow Set 高频滚动;
- 限制开发者直接查看全部安全样本;
- 记录每次 Case 被用于调参的历史;
- 定期增加新措辞、新数据和新边界;
- 用生产分布检查离线提升是否真实存在。
合成问题也要防止答案泄漏:生成 Query 时不要把原文答案直接复制成问题关键词。
31. 标注质量与人工一致性
人工标注不是天然正确。
需要定义:
Annotation Guide
Examples
Borderline Cases
Adjudication Process
Reviewer Qualification对关键维度计算人工之间的一致性:
- Evidence Relevance;
- Claim Correctness;
- Faithfulness;
- Severity;
- Expected Refusal。
低一致性通常说明 Rubric 含糊,而不是标注员“不认真”。
32. 常见反模式
反模式一:只看最终答案
无法判断问题在召回、Context 还是生成。
反模式二:只有自动生成的问题
会高估与文档措辞相近的查询表现。
反模式三:只保存标准答案,不保存证据
无法独立评估 Retrieval,也无法判断答案是否真正 Grounded。
反模式四:所有指标都用 LLM Judge
成本高、波动大,也掩盖本来可以确定性计算的问题。
反模式五:Judge 没有人工校准
分数看起来精确,但不知道是否和业务判断一致。
反模式六:Pairwise 不交换位置
容易受到 Position Bias 影响。
反模式七:平均分上涨就发布
可能掩盖权限和高严重度回归。
反模式八:数据集直接覆盖修改
历史实验不可复现。
反模式九:Baseline 与 Candidate 使用不同 Case
无法做可靠 Paired Comparison。
反模式十:只报告点估计
小数据集上的微小提升可能只是噪声。
反模式十一:评测 Pipeline 没有完整 Manifest
半年后不知道当时使用哪个索引、Prompt、Judge 和模型。
反模式十二:线上反馈直接当质量真相
点击、追问和点赞都存在严重选择偏差。
33. 分阶段落地路线
P0:建立可复现的离线 Baseline
- 100–300 条真实 Golden Case;
- 每条 Case 有 Scope、Expected Behavior 和 Evidence;
- Retrieval 指标:Recall@K、MRR、NDCG;
- Context 指标:Precision、Recall、Redundancy;
- Answer 指标:Correctness、Faithfulness、Citation;
- Baseline / Candidate Paired Diff;
- Pipeline Manifest;
- Safety Hard Gate;
- 报告 Case-level Regressions。
验收标准:
每一次 RAG 变更都能回答:
哪一层变了、哪些 Case 变好、哪些 Case 变坏、能否回滚。P1:Judge 校准和线上闭环
- Claim 级标注;
- Judge Calibration Set;
- Kappa、Rank Correlation、Critical Recall;
- Position Swap;
- Bootstrap CI;
- Shadow Evaluation;
- Trace 与 Score 关联;
- Bad Case 自动进入候选数据集;
- Canary Dashboard。
P2:规模化和高级诊断
- ARES 风格轻量领域 Judge;
- RAGChecker 风格 Claim 级诊断;
- Active Sampling;
- 多语言和多租户分层报告;
- Hidden Holdout;
- 在线 Pairwise Preference;
- 评测成本调度;
- 自动根因分类;
- Release Gate 与部署系统联动。
34. 上线检查清单
- Dataset 是否有不可变版本?
- 每个 Case 是否包含用户 Scope 和 Expected Behavior?
- 是否同时保存 Expected Answer Rubric 和 Expected Evidence?
- Evidence 是否有 source revision、anchor 和 content hash?
- 是否区分 Golden、Regression、Safety、Shadow 和 Synthetic Set?
- Query Type 是否覆盖 Exact、Concept、Multi-hop、Temporal 和 Refusal?
- BM25 与 Dense 是否分别计算 Recall@K?
- 是否计算 Union Recall 和 Unique Relevant Gain?
- Filter Recall Loss 是否可见?
- Context Recall 是否与 Retrieval Recall 分开?
- 是否记录 Redundancy、Token Efficiency 和 Conflict?
- 答案是否拆成 Claim?
- Faithfulness 是否只依据当时 Context?
- Citation Precision 和 Recall 是否分别计算?
- Refusal、Clarification 和 Unauthorized 是否有独立指标?
- 能用代码计算的指标是否避免使用 LLM Judge?
- Judge Prompt、模型和 Schema 是否版本化?
- Judge 是否有人工 Calibration Set?
- 是否评估 Kappa、Rank Correlation 和 Critical Failure Recall?
- Pairwise Judge 是否交换位置?
- Baseline 与 Candidate 是否在同一 Case 上成对运行?
- 是否报告 Case-level Improved / Regressed?
- 是否提供置信区间和 Effect Size?
- 非确定性模型是否重复运行?
- Pipeline Manifest 是否包含索引、模型、Prompt 和配置版本?
- 是否同时评估质量、延迟、成本和降级?
- 权限和 Critical Safety 是否为硬门禁?
- 是否保留 Hidden Holdout,避免过拟合 Golden Set?
- Shadow / Canary 是否与离线评测连接?
- 线上 Bad Case 是否能回流 Regression Set?
- 历史实验是否可重放?
总结
RAG 评测的目标不是产生一个看起来科学的分数,而是建立一套可以支持工程决策的证据链:
Dataset
→ 冻结问题、Scope、证据和预期行为
Pipeline Manifest
→ 冻结索引、模型、Prompt 和配置
Stage Metrics
→ 判断错误发生在 Retrieval、Context 还是 Generation
Judge Calibration
→ 证明自动评审和人工判断足够一致
Paired Experiment
→ 解释 Candidate 相对 Baseline 的真实变化
Confidence Interval
→ 区分改进与抽样噪声
Release Gate
→ 把质量、安全、延迟、成本和回滚放进同一个决策
Online Feedback
→ 发现真实分布中的新 Bad Case最重要的工程原则是:
不要让一个端到端平均分替代系统理解。真正有用的评测,必须能指出正确证据在哪一步丢失、哪个 Claim 没有依据、哪个严重样本发生回归,以及新版本是否值得承担它增加的延迟、成本和风险。
官方资料与原始论文
- RAGAS:Metrics
- RAGAS:Available Metrics
- RAGAS: Automated Evaluation of Retrieval Augmented Generation
- ARES: An Automated Evaluation Framework for Retrieval-Augmented Generation Systems
- RAGChecker: A Fine-grained Framework for Diagnosing Retrieval-Augmented Generation
- G-Eval: NLG Evaluation using GPT-4 with Better Human Alignment
- Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena
- LangSmith:Evaluation
- LangSmith:Evaluate a RAG Application
- Arize Phoenix:Evaluate RAG
- Arize Phoenix:Faithfulness
- RAG 可观测性生产实战
- RAG 发布门禁
- RAG Bad Case 分析
讨论
继续讨论这篇笔记
有问题、补充案例或不同观点,可以通过 GitHub Discussions 继续交流。