核心判断
Benchmark 分数是在特定协议下得到的一次观察,不是脱离以下条件的模型固有属性:
- 数据集和 Split;
- Prompt 和示例;
- Model 与 Decoding 配置;
- Tool 或 Retrieval Context;
- Scorer 与聚合方式;
- 时间、软件、硬件和价格;
- 污染与样本选择效应。
真正应该问的不是“哪个模型分数最高”,而是:
在可复现测试下,哪个模型满足当前工作负载的质量、安全、延迟、成本和治理约束?
分数为什么会误导
污染与记忆
公开测试题可能出现在预训练、微调、Prompt 示例、网络讨论或评估代码中。精确重合检测并不充分,因为改写题目或派生解法可以保留答案而不保留原文。
使用分层证据:
- 记录数据来源和发布日期;
- 在风险允许时保留私有或新编写的 Holdout;
- 测试改写、扰动和过程变化;
- 比较熟悉题目与新任务切片;
- 说明检查过什么、仍然不知道什么。
不要把字符串重合启发式包装成精确污染率。
天花板与饱和
当许多系统在小型测试上接近满分时,细小差异可能只是抽样噪声。报告题目级结果、置信区间或 Bootstrap 范围和切片表现。没有不确定性的排名很容易被过度解读。
题目与标签质量
评估可能测到标注不一致、题干歧义、错误参考答案或文化假设,而非模型能力。抽样审核题目,记录仲裁规则,并允许使用“无效”或“歧义”标签。
Goodhart 效应
分数成为目标后,团队可能优化分数而没有改善任务:
- 训练 Benchmark 相似样本;
- 选择更有利的 Prompt 或 Model Snapshot;
- 针对 Scorer 调整输出格式;
- 只报告最佳运行;
- 不断修改测试直到达到目标。
应预先登记协议,保留锁定 Holdout,报告相关运行,并分开探索性与确认性评估。
可复现的评估记录
每次结果都保存 Manifest:
{
"model": "provider/model@version",
"evaluation_revision": "2026-07-01",
"dataset": {
"name": "support-holdout",
"split": "test",
"digest": "sha256:pinned"
},
"prompt_revision": "prompt-12",
"decoding": {
"temperature": 0,
"seed": 17,
"max_output_tokens": 512
},
"tools": "disabled",
"retrieval": "fixed-fixture-v3",
"repetitions": 3,
"metrics": ["task_success", "policy_violation", "p95_latency", "cost_per_success"],
"environment": {
"runner": "pinned-runner",
"region": "recorded-region"
}
}
Manifest 不是安全策略,而是让结果可审计、可比较的记录。
构建任务集
一个有用的任务案例应包含:
{
"case_id": "refund-042",
"input": "redacted user request",
"context": ["approved evidence fixture"],
"expected": {
"outcome": "deny_and_explain",
"required_facts": ["refund_window"],
"forbidden_actions": ["refund_without_authorization"]
},
"oracle": "policy_and_business_rules_v2",
"risk": "high",
"provenance": "human-authored-and-reviewed"
}
根据工作负载加入正常、边界、歧义、对抗、多语言、长上下文、失败恢复和跨 Tenant 案例。生产数据应最小化并受访问控制。
按任务类型评分
不要把所有任务强行压成一个指标:
| 任务 | 更有力的证据 |
|---|---|
| 精确分类 | Accuracy、Macro-F1、Calibration、切片 Recall |
| 结构化抽取 | Schema 有效性、字段 Precision/Recall、Abstention |
| Retrieval/RAG | Evidence Recall、Citation Support、答案正确性 |
| 编码 | Tests、安全检查、Patch 范围、Review 结果 |
| 客服 | Policy 正确性、解决率、升级率、语气复核 |
| Tool Use | Tool、参数、授权、副作用、幂等 |
| 文本生成 | 事实声明、量表维度、人工复核、拒答行为 |
| 交互 Agent | 任务成功、恢复、成本、延迟、重复动作 |
BLEU、ROUGE、Exact Match 或 Judge 分数可以作为切片,但都不自动等于业务结果。
先使用确定性 Oracle
能用代码或可信参考验证的地方,优先使用确定性检查:
from dataclasses import dataclass
from typing import Mapping
@dataclass(frozen=True)
class Case:
expected_status: str
expected_fields: Mapping[str, str]
def check_result(case: Case, result: Mapping[str, object]) -> tuple[bool, list[str]]:
errors: list[str] = []
if result.get("status") != case.expected_status:
errors.append("status_mismatch")
for key, value in case.expected_fields.items():
if result.get(key) != value:
errors.append(f"field_mismatch:{key}")
return not errors, errors
高影响动作的 Oracle 应验证授权、对象所有权、Tenant、审批、幂等和副作用状态,而不只是最终文本。
谨慎使用 LLM-as-a-Judge
Judge 可以分类开放式回答,但应作为测量工具:
- 只提供量表所需的证据;
- 对 Pairwise 顺序进行盲化和随机化;
- 允许平局和“证据不足”;
- 在代表性切片上与人工标注比较;
- 报告一致性、分歧和置信信息;
- 测试 Judge Model、Prompt 和量表变化;
- 隔离敏感标识和无关风格信号。
不要用 Judge 分数作为授权、安全、删除或金融动作的唯一门禁。流畅但错误的回答也可能得到高分。
评估 Harness
评估 Runner 应同时产生原始样本和报告:
from dataclasses import dataclass
from time import monotonic
from typing import Callable, Iterable
@dataclass(frozen=True)
class Outcome:
case_id: str
passed: bool
errors: tuple[str, ...]
latency_ms: int
estimated_cost: float | None
def run_case(
case_id: str,
invoke: Callable[[], dict[str, object]],
check: Callable[[dict[str, object]], tuple[bool, list[str]]],
) -> Outcome:
started = monotonic()
try:
result = invoke()
passed, errors = check(result)
return Outcome(
case_id,
passed,
tuple(errors),
round((monotonic() - started) * 1000),
None,
)
except TimeoutError:
return Outcome(case_id, False, ("timeout",), round((monotonic() - started) * 1000), None)
except Exception:
return Outcome(case_id, False, ("unexpected_error",), round((monotonic() - started) * 1000), None)
def summarize(outcomes: Iterable[Outcome]) -> dict[str, object]:
items = list(outcomes)
return {
"cases": len(items),
"passed": sum(item.passed for item in items),
"errors": sorted({error for item in items for error in item.errors}),
"latency_ms": [item.latency_ms for item in items],
}
这是结构性 Harness 片段,不是完整的 Model Provider 集成。应将原始结果、环境 Metadata 和报告生成分开,避免摘要掩盖失败。
公平比较模型
对于每个候选模型:
- 使用相同的任务版本、Context、Tools 和 Policy;
- 固定或记录 Model 和 SDK 版本;
- 按已声明协议预热并重复;
- 保存原始结果,而不只保存平均值;
- 报告置信区间或 Bootstrap 范围;
- 同时比较质量、安全、p95/p99 延迟、每个成功任务成本和运营负担;
- 在宣布胜者前做切片分析。
某模型可能平均质量最高,却在高风险切片失败。便宜模型如果需要更多重试或人工修正,也可能有更高的成功任务成本。
发布门禁
使用面向工作负载的流程:
contract -> scenario -> replay -> abuse -> human review
-> cost/latency -> approval -> canary -> rollback
门禁应表达不变量和可接受风险,而不是通用百分比。例如:
- Abuse Suite 中不得发生跨 Tenant 访问;
- 不得产生未授权外部写入;
- 所有必需结构化字段有效;
- 任务成功不超过预先声明的回归区间;
- p95 延迟和成本保持在工作负载预算内;
- 每个失败案例都被分类或升级。
公开 Leaderboard 与厂商声明
公开排名适合发现和提出假设。做决策前核查:
- 评估日期和 Model 版本;
- Prompt、Tools 和 System Instruction;
- 抽样与平局处理;
- 参与者选择和缺失结果;
- 置信区间与切片报告;
- Scorer 或 Provider 是否存在利益冲突;
- 测试工作负载是否接近你的场景。
不要把 Leaderboard 描述成中立真相,也不要在缺少协议和来源时复述厂商结果。
企业运营实践
- 版本化任务集、Prompt、Policy、Runner 和 Model;
- 保留锁定 Holdout,持续加入新编写案例;
- 将重大线上事故加入失败分析;
- 分开探索性调优和发布评估;
- 对评估数据执行删除和访问控制;
- 仅在记录用途后抽样生产结果;
- 审查 Judge Drift 和 Oracle Drift;
- 发布包含原始样本引用和已知限制的评估报告。
总结
Benchmark 不是因为某一个分数不好就“失效”。当来源、不确定性、任务匹配、评分有效性和激励机制被隐藏时,它才会变成弱证据。把公开测试作为有边界的基线,再建立版本化工作负载评估、确定性 Oracle、校准的人类或模型复核、滥用案例、成本/延迟账本和发布门禁,模型选型才会成为工程决策,而不是排行榜竞赛。