一次得分只能描述一次运行。只有版本化任务、分层验收、校准 grader 和明确门禁,才能让评测参与工程决策。


引言:Agent 说“已发布”,环境却没有给出同一个答案

设想一个多仓库源码研究与文章发布 Agent。它接收研究问题和目标仓库列表,收集带来源的证据,生成草稿,等待人工批准,发布文章并保存回执。

一次运行结束时,Agent 的最终回复写着:

五个仓库均已完成研究,文章已通过评审并成功发布。

如果评测只检查这句话是否完整、流畅、符合预期格式,它可能拿到满分。但打开工作区和发布服务后,看到的是另一组事实:

  • 只生成了四个仓库的来源记录;
  • 一条引用路径不存在;
  • 人工批准的是 draft revision 6,发布请求携带的是 revision 7;
  • 发布服务保存了 request,却没有 committed receipt;
  • timeout 后的自动重试可能已经创建第二个发布。
完成声明与三层证据
完成声明与三层证据

图 1|回复完整、制品存在和环境终态正确是三层不同证据,任何一层都不能替代另外两层。

一次运行中的完成证据错配
一次运行中的完成证据错配

导读图|Agent 自报、交付制品与外部效果可以在同一次运行中彼此矛盾。

这不是某次真实生产事故,而是本文用于推动设计的受控案例。它揭示了 Agent Evaluation 最容易被忽略的边界:Agent 自报完成、交付制品完成和环境终态完成,是三件不同的事。

本文所说的 评测资产生命周期,是一次真实失败经过任务定义、环境与版本冻结、分层验收、grader 校准和多次 trial,进入能力集或回归集,并在发布门禁与后续失败中持续演进的过程。

案例使用六类稳定逻辑制品:research_plan、source_records、evidence_pack、article_draft、review_decision 和 publish_receipt。具体文件名只是这些制品的实现映射;例如 final.md 可以承载 article_draft 的发布候选版本,但不能替代逻辑制品身份。

全文使用五类陈述口径:官方源码、文档和原始论文可核验的是“公开事实”;跨样本有限归纳是“样本观察”;需要在项目中验证的是“工程建议”;研究 Agent 的方案是“案例决策”;没有固定实验支持的阈值与效果标为“待验证”。

入口问题是:

如何把一次 Agent 评测变成可信、可复现、能够驱动工程决策的证据,而不是一个孤立分数?

1. 先定义“完成”:Agent 的自报不是权威终态

失效问题

传统文本任务常把模型输出本身当作评测对象。Agent 却会修改文件、调用外部系统、等待人工、创建长期制品。最终回复仍然重要,但它只是系统产出之一。

可核验事实与样本观察

[公开事实] AgentBench 在固定源码中把 TaskOutput 与 AgentOutput 分开,前者可以包含任务状态、历史和结果,后者保存 Agent 侧输出;源码见 sources/agentbench/src/typings/output.py:10-39。任务客户端还区分初始化、交互、Agent 与环境相关错误,见 sources/agentbench/src/client/task.py:54-125。agentbench

[样本观察] 这些类型不能直接规定本文项目怎样验收,但支持一个边界:任务环境观察到的结果和 Agent 自己生成的内容可以独立保存、独立判定。

路线与代价

完成层回答的问题案例证据单独使用的风险
回复层Agent 声称做了什么最终消息可以自信地描述不存在的状态
制品层要求的交付物是否存在且合格来源记录、证据包、final.md文件存在不代表外部动作完成
环境终态层权威系统是否达到目标状态发布 revision 与 receipt终态成功可能掩盖越权过程

工程上最可靠的完成定义通常是多个条件的合取,而不是让一个 LLM judge 对最终文本给总体印象分。

案例决策

[案例决策] 案例成功必须同时满足:

  1. 所有 required repository 都有来源记录;
  2. 正文引用的文件、commit 和行号可定位;
  3. 发布内容 hash 与批准对象一致;
  4. 发布服务返回 committed receipt;
  5. 禁止副作用检查通过;
  6. 最终回复不得覆盖环境事实。

如果 Agent 说“发布成功”,但只有 request 没有 receipt,任务状态是未确认,而不是 pass。

完成契约的六项必要证据
完成契约的六项必要证据

章节图|Completion Contract 把 pass 定义为必要证据的合取,而不是一句自报。

待验证

不同领域的权威终态不同。付款、医疗记录、代码合并和文章发布不能共享同一组完成条件;人工复核是否属于成功终态,也必须由项目责任边界定义。

保守默认

把最终回复作为 trace,把制品断言与环境终态作为完成判定;任何 required evidence 缺失都不判 pass。

升级信号

任务开始产生外部副作用、长期制品、人工中断或跨系统状态后,从文本评分升级为制品与环境联合验收。

2. 先问评测支持什么决策:失败发现不等于发生率

失效问题

团队发现一个边界失败后,经常立即把它加入一个越来越大的测试集,再用平均分回答所有问题。这样的集合既想发现新失败,又想估计稳定表现,还想决定发布,最终没有一种解释足够可信。

可核验事实与样本观察

[公开事实] BFCL、AgentBench 与 SkillsBench 都按任务类别、环境或 task set 组织评测。SkillsBench 还为任务集合计算稳定 digest,见 sources/skillsbench/skillsbench_agentbeats/task_sets.py:75-125,146-171。skillsbench 公开 Benchmark 可以暴露能力维度,但其任务分布、工具环境和错误损失不等于当前项目的线上分布。

路线与代价

评测问题样本策略可以支持不能支持
系统会怎样失败?难例、对抗例、边界例失败发现与诊断线上发生率
修复是否消除已知失败?固定复现任务变更前后回归未覆盖能力
某类任务表现是否稳定?预定义分层抽样与多 trial给定分布上的估计分布外结论
版本是否允许发布?风险加权回归套件发布决策产品整体价值

失败发现集需要快速吸收新问题,因此可能变化;发生率测量要求抽样与环境稳定。把二者混在同一总分里,会让分数变化既可能来自系统,也可能来自题目集合本身。

为避免把“决策用途”和“资产类型”混为一谈,本文区分四类资产:

资产目的冻结程度可估计线上发生率连接 Gate
Incident corpus保存原始、可能不可复现的失败线索不冻结否否
Capability suite探索可复现边界与新能力任务运行时固定,集合可演进否默认否
Estimation cohort在预定义生产抽样上估计发生率严格冻结抽样、环境与权重是另行定义
Regression suite保护确认不变量与修复严格版本化默认否是

Regression suite 不是天然具有代表性的 estimation cohort。只有额外定义生产抽样框、权重和更新政策后,才可以用于发生率估计。

案例决策

新发现但无法稳定复现的“引用行号错位”先留在 incident corpus。形成固定 commit、确定性引用 grader 和最小复现后,任务进入 capability suite;只有确认这是需要长期保护的不变量、grader 稳定后,才选择代表任务进入 regression suite。

四类评测资产矩阵
四类评测资产矩阵

章节图|Incident、Capability、Estimation 与 Regression 支持不同决策,不能借用彼此的声明。

待验证

项目是否拥有足够稳定的任务分布来估计发生率,需要数据审计。本文不使用公共 Benchmark 得分替代项目基线,也不给出通用样本量。

保守默认

先建立 incident corpus 与小型 capability suite,不用回归集推断线上发生率。

升级信号

需要回答“某类生产请求的失败率是多少”时,单独建立 versioned estimation cohort;需要阻止已确认修复回退时,才进入 regression。

3. 把失败改写为可复现 EvalTaskSpec

失效问题

一条自然语言 prompt 很少足以复现 Agent 失败。相同问题在不同仓库 commit、工具 schema、网络状态、模型版本或批准状态下,实际上是不同任务。

可核验事实与样本观察

[公开事实] SkillsBench 的 task set 通过稳定 digest 标识集合,并在 public readiness 流程中检查任务定义、revision 和 digest,源码见 sources/skillsbench/skillsbench_agentbeats/task_sets.py:75-125,146-171 与 sources/skillsbench/skillsbench_agentbeats/public_readiness.py:19-35,161-211,237-247。skillsbench

[公开事实] Gorilla BFCL 的 evaluator 对 model ID、prompt 与 ground truth 进行对齐,源码见 sources/gorilla-bfcl/berkeley-function-call-leaderboard/bfcl_eval/eval_checker/eval_runner.py:36-69。bfcl

[样本观察] 这些实现共同说明:任务身份、集合身份和结果对齐都需要稳定标识,而不能只靠展示名称或自然语言 prompt。

路线与代价

一个最小任务规范至少回答:

字段组问题
schema/identity使用哪个规范版本?这是哪个任务与 revision?
initial state开始时文件、服务和批准状态是什么?
goal什么终态算成功?
allowed actionsAgent 可以调用什么、访问什么?
forbidden effects哪些动作即使结果正确也不能发生?
environment时间、时区、网络、服务和初始状态如何冻结?
execution profilesystem build、Prompt、模型、runner、工具和重试策略分别是什么版本?
terminationtimeout、最大步数和提前终止怎样处理?
artifacts哪些原始日志、制品和回执必须保留?

任务定义与单次运行记录必须拆开。本文使用三层指纹:

task_digest =
  SHA-256(canonical_json(task contract + fixture + environment contract))

execution_digest =
  SHA-256(canonical_json(system build + prompt + model + runner + tools))

eval_case_digest =
  SHA-256(task_digest + execution_digest + grader_set_digest)

canonical_json 的字段顺序、空值处理、数值和字符串编码必须由 spec_schema_version 固定。run_id、attempt_id、开始时间、实际 trace URI 和实际 artifact URI 只属于 TrialRecord,不能进入 task_digest。否则每跑一次就会产生“新任务”,旧结果失去可比性。

冻结越完整,可复现性越强,但 fixture 维护成本越高。完全使用真实互联网和真实发布服务,环境接近生产,却会引入不可控变化和副作用;完全 mock 又可能错过协议差异。工程目标不是冻结宇宙,而是让所有会改变任务含义、系统行为或评分结果的变量都有身份。

案例决策

[案例决策] 离线任务固定:

  • 五个本地仓库的 commit;
  • 两份官方文档快照;
  • research_plan 与 required repository manifest;
  • 初始 source_records、evidence_pack、article_draft 与 review_decision 状态;
  • 一个 versioned approval service;
  • 一个 fake publish service;
  • 网络关闭;
  • UTC 测试时钟与显式时区;
  • system build、Prompt 内容 hash、模型 provider/name/API/采样参数/seed;
  • runner commit、container digest、adapter 和工具 schema 版本;
  • retry、concurrency、timeout 与最大步数;
  • initial state digest、task digest、execution digest 与 grader set digest。

真实发布动作不进入回归环境。fake publish service 仍完整实现 effect key、request hash、timeout、receipt 和重复调用检查。

评测任务的三层指纹
评测任务的三层指纹

章节图|任务、执行与评测案例使用独立 digest,TrialRecord 保留三层身份。

待验证

哪些外部依赖必须使用真实 staging、哪些可以 mock,需要按故障风险验证。任务 fixture 的刷新周期和兼容政策也没有通用答案。

保守默认

先冻结能改变成功判定的文件、状态、服务协议、Prompt 与工具版本,并把每次运行产生的 ID 和 URI 留在 TrialRecord。

升级信号

当无法解释两个结果差异来自系统变更还是环境漂移时,补充缺失的 digest、时钟、网络、service version、runner 或并发字段;不要用更长的任务描述替代指纹。

4. 分层验收:结果、硬约束与轨迹不能互相替代

失效问题

一个 Agent 可能完成目标,却走过禁止路径;也可能路径与参考轨迹不同,但结果完全正确。把结果、过程和安全压成一个 grader,会同时制造误报与漏报。

可核验事实与样本观察

[公开事实] helloagents 的 BFCL evaluator 根据调用类型使用 AST 或 execution 路径,并输出 sample 级结果,源码见 sources/helloagents-evaluation/hello_agents/evaluation/benchmarks/bfcl/evaluator.py:17-34,152-207。helloagents-eval

[公开事实] Gorilla BFCL 在多轮评测中将 force-terminated case 作为失败处理,源码见 sources/gorilla-bfcl/berkeley-function-call-leaderboard/bfcl_eval/eval_checker/eval_runner.py:166-215;模型 handler 将 raw model result 与 evaluator output 分开保存,见 sources/gorilla-bfcl/berkeley-function-call-leaderboard/bfcl_eval/model_handler/base_handler.py:768-805。bfcl

[样本观察] 这些机制支持“不同验收责任可以分开实现”,但不证明 AST、执行或某条固定轨迹适合本文任务。

路线与代价

本文采用三层验收:

层主要问题合适 grader是否可阻断
Outcome制品与环境终态是否完成deterministic、execution通常是
Hard constraints是否越权、泄漏、重复或未批准操作deterministic、policy checker、human是
Trajectory diagnosis为什么成功或失败,哪里浪费或脆弱trace rule、model grader、human默认否

结果层不要求固定工具顺序;轨迹层也不能用“路径看起来好”覆盖缺失终态。硬约束必须保持独立,因为平均分会稀释一次高损失失败。

分层验收与发布门禁
分层验收与发布门禁

图 2|Outcome、Hard Constraint 和 Trajectory Diagnosis 分别回答完成、安全与原因;证据不完整或外部效果未知时,评测先进入 blocked,而不是勉强计算总分。

案例中的失败需要一张明确的覆盖矩阵。每个失败至少有一个 primary grader、一个可定位证据指针和一个 gate effect:

失败Primary grader权威证据Blocking 结果Gate effect
required repository 缺失artifact-completeness / outcomeArtifactManifest.source_records、required manifesttask_fail阻断关键回归
路径、commit、行号或内容不匹配source-integrity / outcomesource_records、evidence_packtask_fail阻断关键回归
revision/content/destination 未获批准approval-publish-match / hardreview_decision、publish request/receipthard_constraint_fail立即阻断
访问未授权仓库resource-scope / hardtool call、authorization 与 tracehard_constraint_fail立即阻断
secret 泄露secret-exposure / hardartifact scan、tool payload、人工复核hard_constraint_fail立即阻断
外部效果未知effect-reconciliation / evidenceeffect key 查询、service eventambiguous_external_effect阻断至对账
同一 effect 多次 committedeffect-cardinality / hard按 effect key 聚合的 receiptshard_constraint_fail立即阻断
trace 或必需制品缺失evidence-completeness / evidenceArtifactManifest 与 required assertionsmissing_required_evidence阻断至补齐或判无效

案例决策

[案例决策]

  • Outcome:research_plan、source_records、evidence_pack、article_draft、review_decision、publish_receipt 存在且断言通过;引用可解析;published revision 与 content hash 正确;receipt committed。
  • Hard constraints:未批准发布、访问禁止仓库、泄露 secret、同一 effect 两次 committed 均为 hard fail。
  • Trajectory:重复读取、无效搜索、上下文膨胀、工具错误恢复和来源选择只用于诊断。

一条不同于参考轨迹、但满足终态与硬约束的路径仍可通过。

轨迹规则有三个状态:

diagnostic_only
  -> guardrail_candidate
  -> blocking_constraint
规则状态进入条件门禁作用退出或升级
diagnostic_only能观测到模式,但失败关联尚未确认不阻断重复出现且形成可检验风险假设后进入候选
guardrail_candidate有 owner、规则版本、观察窗口和影子运行数据默认不阻断误报高或关联消失则撤销;完成风险与误报评估后申请升级
blocking_constraint与真实失败稳定相关、误报可接受、policy owner 批准、grader 已版本化独立阻断风险边界变化时重新评审,不靠调低总分权重退出

升级后,规则进入 hard-constraint 覆盖矩阵,不再由诊断分数间接影响门禁。

失败与 Grader 覆盖矩阵
失败与 Grader 覆盖矩阵

章节图|每类失败都绑定 Primary Grader、权威证据与明确 Gate Effect。

待验证

哪些轨迹模式应升级为硬约束,取决于风险。固定工具顺序在某些合规流程中可能必要,在开放研究任务中则可能过拟合。

保守默认

先用 outcome 与 hard constraint 判定任务,用 trajectory 解释原因;未知和缺失证据单独 blocked。

升级信号

同一轨迹模式跨任务稳定导致高损失失败,且规则误报、owner、版本与证据都已明确后,才将它升级为 guardrail 或 blocking constraint。

5. 组合并校准 Grader

失效问题

确定性规则覆盖不了所有开放文本质量,LLM judge 又会受 rubric、模型和提示变化影响。单一 grader 无法同时提供低成本、语义覆盖和高可信阻断。

可核验事实与样本观察

[公开事实] helloagents 的 GAIA evaluator 提供答案归一化和多种比较路径,源码见 sources/helloagents-evaluation/hello_agents/evaluation/benchmarks/gaia/evaluator.py:59-224;同一仓库还提供 LLM judge,见 sources/helloagents-evaluation/hello_agents/evaluation/benchmarks/data_generation/llm_judge.py:14-78。helloagents-eval

[公开事实] OpenAI 官方评测最佳实践强调清晰 rubric、任务代表性和持续迭代;trace grading 将评分对象扩展到 Agent 轨迹。Anthropic 的 Agent eval 实践也区分任务、grader 与真实失败回流。openai-evalsanthropic-evals

路线与代价

Grader适合主要风险
Deterministic文件、hash、schema、权限、精确终态语义覆盖有限
Execution代码、工具调用、环境动作环境成本与不稳定
Model论证完整性、开放文本、复杂证据偏差、漂移、提示敏感
Human高风险、模糊边界、校准成本、速度、一致性

模型 grader 上线前需要一个版本化的校准记录,而不只是“与人工看起来一致”。最小字段包括:

校准字段作用
label_set_digest、sample_count固定人工标签集与样本规模
sampling_frame、failure_class_strata说明样本如何抽取,避免只测容易案例
annotation_guide_version固定标注协议
annotator_count、inter_rater_agreement暴露人工本身的分歧
calibration_split、holdout_split防止在同一标签上调 rubric 又报告效果
grader_prompt_hash、model、parameters固定自动 grader 实现
metrics_by_class、uncertainty按 failure class 报 precision/recall 与不确定性
abstain_policy、human_review_route无法可靠判断时升级人工
recalibrate_onPrompt、model、rubric、标签分布或环境变化后的触发器

这里的 precision、recall、置信区间和接受阈值都是项目参数,本文标为 [待验证]。如果人工标注者之间都无法在某一类别上达成稳定协议,模型 grader 不应独立阻断该类别。

案例决策

[案例决策] 文件、引用、commit、hash、approval 与 receipt 由 deterministic grader 阻断。文章是否把工程建议写成公开事实,由带 rubric 的 model grader 初筛;其结果只进入人工评审队列,不独立发布。

若 model grader 与人工在“事实/建议混淆”上持续分歧,先修 rubric 或降级适用范围,不提高模型分数阈值来掩盖问题。

Grader 校准阶梯
Grader 校准阶梯

章节图|Grader 的门禁责任随标签、holdout、分层指标与版本化校准提高。

待验证

模型 grader 的 precision、recall、可接受分歧率和复校准周期只能由本项目标签集决定。本文没有运行该校准,因此不声称它可以替代人工评审。

保守默认

能确定性验证的条件不交给模型 grader;未完成 holdout 校准的模型 grader只做诊断或分流。

升级信号

人工评审成为稳定瓶颈,且已有分层标签集、复审路径、abstain 策略和漂移监控时,再扩大模型 grader 的自动化责任。

6. 多次 Trial:先分清任务失败与无效运行

失效问题

Agent 是非确定系统。一次 pass 不代表稳定能力,一次 fail 也可能来自 fixture、网络、grader 或 Runtime 故障。若所有非 pass 都记成模型失败,结果不可归因;若 invalid 被静默删除,又会高估系统。

可核验事实与样本观察

[公开事实] promptfoo 的 evaluator 支持重复运行同一测试,源码见 sources/promptfoo/src/evaluator.ts:2665-2684,并在执行路径中区分 runtime error 与 assertion failure,见 sources/promptfoo/src/evaluator.ts:1340-1415,3431-3448。promptfoo

[公开事实] SkillsBench 的 adapter 在 timeout 时可将结果标记为 score_eligible=false,并记录基础设施失败类型,源码见 sources/skillsbench/skillsbench_agentbeats/adapters.py:265-301。skillsbench

路线与代价

每个 trial 必须有且只有一个 primary classification,并可以附带多个 secondary labels。primary 按下列优先级决定:

hard_constraint_fail
  > ambiguous_external_effect
  > missing_required_evidence
  > grader_invalid
  > infrastructure_invalid
  > agent_error
  > runtime_error
  > task_fail
  > task_pass
Primary classification含义发布解释
hard_constraint_fail已有证据确认禁止副作用或高风险违规立即阻断,不参与平均
ambiguous_external_effect请求已发出,但外部效果无法确认阻断并 reconcile 或人工处置
missing_required_evidence缺 trace、receipt、hard grader 结果或必需制品阻断,不能推定 pass
grader_invalidgrader 崩溃、schema 不兼容或校准失效评测结论无效
infrastructure_invalidfixture、服务、网络或测试环境损坏保留记录,修复后按政策重跑
agent_errorAgent 自身解析、规划或调用错误作为系统失败单独报告
runtime_errorRuntime、checkpoint 或状态机错误作为系统失败单独报告
task_fail证据完整,且确认终态未满足计入任务失败
task_passrequired evidence 完整,Outcome 与 Hard Constraint 均通过才能进入 pass

ambiguous_external_effect 不是基础设施 invalid。发布请求发出后超时,即使测试适配器也异常,除非能够证明外部服务没有接收请求,否则必须先按 effect key 对账。

重复运行增加成本,也可能制造重跑偏置。重跑政策需要在执行前固定:

  1. 所有首轮和 invalid trial 永久保留,不能用重跑结果覆盖。
  2. 为每类 invalid 定义允许重跑的前提、最大次数和 owner。
  3. 同时报告首次结果、invalid rate、重跑次数和重跑后结果。
  4. 不只对失败配置或失败样本选择性重跑;比较对象使用相同政策。
  5. 以 task 为主要统计单位,trial 用于描述波动和失败类别。
  6. 已确认 hard fail 不通过“再跑一次成功”解除,只能修复系统并产生新 build 的新证据。

案例决策

[案例决策] 文章生成允许多个 trial;fake publish service 固定。任何一次未批准发布或重复 committed effect 都是 hard fail,不因其他 trial 通过而被平均掉。基础设施 timeout 只有在证明 publish adapter 没有接收 request 时才标 invalid;外部效果未知属于 ambiguous_external_effect,不是 infrastructure invalid。

Trial Primary Classification 决策板
Trial Primary Classification 决策板

章节图|Trial 先按优先级分类,再决定能否进入统计、重跑与发布门禁。

待验证

重复次数、置信区间、随机种子和接受阈值取决于任务波动与错误成本。本文不提供“跑 N 次即可证明稳定”的通用常数。

保守默认

先保存全部 trial 和失败类别,再决定是否重跑;没有 required evidence 就不计算 pass。

升级信号

当系统波动已经影响版本决策时,再引入分层重复、区间估计或顺序检验,并预先冻结停止规则与任务级聚合方法。

7. Capability Suite 与 Regression Suite 不能互相替代

失效问题

一个持续吸收新难例的套件适合探索,却不适合稳定纵向比较;一个严格冻结的回归集适合门禁,却会逐渐遗漏新能力边界。二者若混为一体,任务变化会被误读为系统变化。

可核验事实与样本观察

[公开事实] SkillsBench 的 task-set digest 与 public readiness 流程说明,任务集合本身可以拥有 revision、完整性检查和发布状态,源码见 sources/skillsbench/skillsbench_agentbeats/task_sets.py:75-125,146-171 与 sources/skillsbench/skillsbench_agentbeats/public_readiness.py:161-211,237-247。skillsbench 这不等于其项目使用本文的 capability/regression 术语,但为“评测集合是版本化资产”提供了直接实现证据。

路线与代价

属性Capability SuiteRegression Suite
目标发现边界和验证新能力保护已确认能力与失败修复
任务变化快,允许重写慢,变更需版本与审查
Grader可探索,允许人工较多稳定、已校准、可重复
发布作用默认不直接阻断可以连接 GatePolicy
退出条件被替换、失去代表性不变量失效或由新版任务替代

任务进入 regression suite 前应满足:

  1. 失败或能力需求已经确认;
  2. fixture 可重复;
  3. 成功终态与禁止副作用可判定;
  4. grader 已校准;
  5. task、data、grader 和环境有版本;
  6. 失败 owner 与处理政策明确。

Incident corpus 与 estimation cohort 不走这条晋升路线。前者允许保留尚不可复现的线索;后者由稳定生产抽样框、权重和更新政策定义。一个 capability task 即使长期存在,也不会自动变成发生率样本;一个 regression task 即使经常失败,也不会自动代表线上分布。

案例决策

[案例决策] 来源遗漏、引用失效、批准 revision/content hash 错配和重复发布进入 regression suite。新的仓库类型、超长文档、多语言来源和开放写作风格留在 capability suite,直到不变量稳定。

任务不会因为“长期都通过”自动删除。删除需要说明风险消失、产品不再支持,或由新任务等价覆盖。

Capability 到 Regression 的晋升护栏
Capability 到 Regression 的晋升护栏

章节图|Capability 只有通过六道证据护栏,才晋升为持续守护的 Regression。

待验证

套件规模、刷新节奏和 representative sampling 需要按项目变化速度确定。回归集越大,成本越高;过度精简又会失去失败覆盖。

保守默认

新任务先进入 capability suite;只有确认不变量、fixture、grader、owner 和版本都稳定后,才复制或晋升到 regression suite。

升级信号

需要估计线上发生率时建立独立 estimation cohort;需要阻止已修复失败回退时连接 regression 与 GatePolicy,不用同一集合兼任所有职责。

8. GatePolicy:门禁按风险与失败类别,不按一个总分

失效问题

一个 95 分的系统仍可能发生一次未批准发布。若门禁只看总分,高损失失败会被大量低风险 pass 稀释;若任何细小波动都阻断,又会让团队绕过评测。

可核验事实与样本观察

[公开事实] OpenAI 的 Agent eval 指南将可复现评测与持续改进连接起来,trace grading 支持对具体决策和工具路径评分。openai-evals 这些资料支持持续执行和细粒度诊断,但不能替当前项目定义风险阈值。

路线与代价

风险层示例门禁方式
零容忍硬约束越权访问、未批准发布、重复不可逆动作任一确认失败即阻断
关键回归来源完整、引用可定位、恢复不重复提交按 task 或 failure class 对比基线
质量趋势论证质量、冗余、执行效率观察区间加人工判断
探索能力新仓库、新工具、新任务默认不阻断稳定发布

门禁必须先判断证据是否足以形成结论,再计算结果。本文使用以下优先级:

hard_constraint_fail
  -> ambiguous_external_effect
  -> missing_required_evidence
  -> grader_invalid
  -> infrastructure_invalid
  -> agent_error
  -> runtime_error
  -> task_fail
  -> task_pass

含义不是“取最差分数”,而是更高优先级状态先决定发布解释:

  • hard_constraint_fail:release blocked;
  • ambiguous_external_effect、missing_required_evidence、grader_invalid、infrastructure_invalid:decision blocked,先对账、补证据或修复评测;
  • agent_error、runtime_error、task_fail:在关键回归中判 release failed;
  • 只有所有 required task 都产生完整证据并满足 policy,才可能 release pass。

因此 zero_confirmed_failures 不是充分规则。没有确认失败,也可能只是没有 receipt、grader 没执行或 trace 已丢失。

每次门禁记录:

  • system build;
  • suite digest;
  • task 与 grader version;
  • trial records;
  • per-task、per-layer 和 failure-class 结果;
  • invalid 原因与重跑状态;
  • waiver、owner、适用 build 和过期时间;
  • release decision。

案例决策

[案例决策] 未批准发布、错误 destination、重复 committed effect 与越权仓库访问均为零容忍。来源完整、引用可定位和批准/发布一致性属于关键回归。文风和篇章节奏是质量信号,只进入人工评审。

普通 waiver 只允许覆盖 quality_signal 或明确标记的 noncritical_regression,并且只对指定 build 有效:

noncritical_regression 不能由执行团队临时重标。它必须由风险 owner 根据既有风险等级、影响范围、可逆性、可检测性和变更说明预先分类。保护权限、secret、人工批准、单次外部效果和 required evidence 的任务都不能归入 noncritical。

waivers:
  allowed_layers:
    - quality_signal
    - noncritical_regression
  forbidden_states:
    - hard_constraint_fail
    - ambiguous_external_effect
    - missing_required_evidence
    - grader_invalid
    - infrastructure_invalid
  require:
    - owner
    - reason
    - build_scope
    - expires_at

业务若确实要接受一项硬约束风险,需要独立、更高权限的 risk acceptance 流程,不能把它伪装成评测通过。本文案例不允许这种例外。也不能永久修改 grader 来“消除红灯”。

按风险和失败类别决策的 GatePolicy
按风险和失败类别决策的 GatePolicy

章节图|GatePolicy 先看风险与失败类别,再给出 release、hold 或 reject。

待验证

关键回归的接受区间、观察窗口和 waiver 时长需由风险 owner 决定。本文不把任一公共得分当作发布阈值。

保守默认

未知、缺证据和 grader/基础设施无效一律 fail closed;硬约束逐项判定,不进入总分。

升级信号

只有当关键回归积累了稳定基线、风险 owner 和变更成本证据后,才引入区间门、趋势门或有限 waiver;高损失约束继续独立阻断。

9. 把八个决策串成评测资产生命周期

八个决策最终形成一条闭环:

production incident or review finding
  -> minimal reproduction
  -> EvalTaskSpec
  -> versioned fixture
  -> layered GraderSpec
  -> human calibration
  -> repeated trials
  -> capability suite
  -> confirmed invariant
  -> regression suite
  -> GatePolicy
  -> release decision
  -> production monitoring and user feedback
  -> new incident

这条链有四个关键门:

  1. 不能复现的失败先保留 incident,不假装已经成为测试。
  2. 未校准 grader 可以探索,不直接阻断高风险发布。
  3. capability task 不因“很难”自动进入 regression。
  4. unknown、missing 和 invalid trial 必须先对账、补证据或修复评测,不能当 pass、fail 或静默删除。
评测资产生命周期
评测资产生命周期

图 3|Incident、Capability、Estimation 与 Regression 是不同资产;只有可复现、已校准且不变量稳定的任务进入持续门禁。

四类评测资产护照
四类评测资产护照

章节图|不同评测资产以不同证据资格进入各自用途,不能冒用声明。

公开 Benchmark、离线回归、staging 演练、生产监控、用户反馈和人工审查承担不同角色。离线 Eval 不替代线上观测;线上事故也要经过最小化和版本冻结,才能成为稳定资产。

10. Schema 是决策结果:推导最小评测制品

EvalTaskSpec

spec_schema_version: eval-task/v1
task:
  id: article-publish-approved-revision
  revision: 1
  task_digest: sha256:...
goal: publish_the_approved_article_revision
inputs:
  user_request_digest: sha256:...
  research_plan_id: plan-42
initial_state:
  digest: sha256:...
  repositories:
    - {id: repo-a, commit: "...", required: true}
    - {id: repo-b, commit: "...", required: true}
    - {id: repo-c, commit: "...", required: true}
    - {id: repo-d, commit: "...", required: true}
    - {id: repo-e, commit: "...", required: true}
  documents:
    - {id: docs-a, snapshot_digest: "..."}
    - {id: docs-b, snapshot_digest: "..."}
  article_draft: {id: article-42, revision: r7, content_hash: "..."}
  review_decision:
    {status: approved, revision: r7, content_hash: "...", destination: docs-site}
environment:
  clock: "2026-09-06T00:00:00Z"
  timezone: UTC
  network_policy: deny
  services:
    approval: {version: approval-fixture/v2, state_digest: "..."}
    publish: {version: fake-publish/v3, state_digest: "..."}
allowed_actions:
  - read_repository
  - write_artifact
  - request_review
  - publish
success_state:
  required_source_records: 5
  published_revision: r7
  published_content_hash: "..."
  receipt_status: committed
forbidden_effects:
  - access_unlisted_repository
  - publish_unapproved_revision
  - publish_more_than_once
execution_profile:
  system_build: build-...
  prompt:
    template_version: research-publish/v5
    content_hash: sha256:...
  model:
    provider: ...
    name: ...
    api_version: ...
    sampling: {temperature: ..., top_p: ...}
    seed_policy: fixed | recorded | unsupported
  runner:
    commit: ...
    container_digest: sha256:...
    adapter_version: ...
  tools:
    schema_digest: sha256:...
    service_versions: {...}
  retry_policy: {max_attempts: ..., eligible_states: [...]}
  concurrency: {max_workers: ..., scheduling_policy: ...}
termination:
  timeout_s: ...
  max_steps: ...
required_artifacts:
  logical:
    - research_plan
    - source_records
    - evidence_pack
    - article_draft
    - review_decision
    - publish_receipt
  evaluation:
    - trace
    - artifact_manifest
    - grader_results
digests:
  initial_state_digest: sha256:...
  task_digest: sha256:...
  execution_digest: sha256:...
  grader_set_digest: sha256:...
  eval_case_digest: sha256:...

task_digest 从任务契约、fixture 和 environment contract 的 canonical representation 计算;execution_digest 从 system、Prompt、模型、runner 和工具配置计算。digest 字段本身、run_id、时间戳和输出 URI 不参与自己的输入。若比较两个模型或两个 Prompt,任务 digest 可以相同,execution digest 必须不同。

ArtifactManifest 与 TrialRecord

ArtifactManifest 让“制品存在”升级为“制品身份、来源和断言可追踪”:

artifact_manifest:
  manifest_id: manifest-...
  task_digest: sha256:...
  trial_run_id: run-...
  artifacts:
    - kind: research_plan
      artifact_id: plan-42
      digest: sha256:...
      producer: runtime-step-2
      location: artifact://...
      assertion_refs: [required-repositories]
    - kind: source_records
      artifact_id: sources-42
      digest: sha256:...
      producer: runtime-step-8
      location: artifact://...
      assertion_refs: [source-integrity, required-repositories]
    - kind: evidence_pack
      artifact_id: evidence-42
      digest: sha256:...
      producer: runtime-step-9
      location: artifact://...
      assertion_refs: [evidence-lineage, source-integrity]
    - kind: article_draft
      artifact_id: draft-42-r7
      digest: sha256:...
      producer: runtime-step-12
      location: artifact://...
      assertion_refs: [approved-content-hash]
    - kind: review_decision
      artifact_id: review-42-r7
      digest: sha256:...
      producer: approval-fixture/v2
      location: artifact://...
      assertion_refs: [approved-revision, approved-destination]
    - kind: publish_receipt
      artifact_id: receipt-42
      digest: sha256:...
      producer: fake-publish/v3
      location: artifact://...
      assertion_refs: [effect-committed, effect-cardinality]

六类逻辑制品都需要 artifact_id、digest、producer、location 与 assertion refs。实际文件可以不同,但 grader 不应靠猜文件名建立关联。

TrialRecord 只保存某次执行产生的事实:

trial:
  trial_id: trial-...
  run_id: run-...
  attempt_id: attempt-...
  eval_case_digest: sha256:...
  started_at: ...
  completed_at: ...
  effective_seed: ...
  trace_uri: trace://...
  artifact_manifest_uri: artifact://manifest-...
  grader_result_uris: [...]
  primary_classification: task_pass
  secondary_labels: [...]
  external_effects:
    - {effect_key: ..., status: committed, external_ref: ...}
  rerun:
    reason: null
    parent_trial_id: null
    ordinal: 0

重跑创建新的 trial_id,通过 parent_trial_id 关联原 trial;它不会覆盖首轮记录。

分层 GraderSpec

grader_set:
  id: article-publish-graders
  version: 5
  digest: sha256:...
graders:
  - id: artifact-completeness
    version: 2
    layer: outcome
    type: deterministic
    evidence_required: [artifact_manifest, required_repository_manifest]
    produces: [task_pass, task_fail, missing_required_evidence]
    blocking: true
  - id: approval-publish-match
    version: 3
    layer: hard_constraint
    type: deterministic
    evidence_required: [review_decision, publish_request, publish_receipt]
    produces: [hard_constraint_fail, ambiguous_external_effect, pass]
    blocking: true
  - id: reasoning-evidence-discipline
    version: 4
    layer: trajectory_diagnosis
    type: model
    evidence_required: [article_draft, evidence_pack, trace]
    rule_state: diagnostic_only
    blocking: false
    calibration:
      label_set_digest: sha256:...
      sample_count: ...
      sampling_frame: ...
      failure_class_strata: [...]
      annotation_guide_version: ...
      annotator_count: ...
      inter_rater_agreement: ...
      calibration_split_digest: sha256:...
      holdout_split_digest: sha256:...
      metrics_by_class: {...}
      uncertainty: {...}
      abstain_policy: route_to_human
      recalibrate_on:
        - grader_prompt_changed
        - grader_model_changed
        - rubric_changed
        - label_distribution_shift

produces 限制 grader 可以给出的状态。Trajectory grader 不能产生 task_pass,更不能覆盖 hard-constraint 结果;它只有在完成规则升级流程后,才变成新的独立 blocking grader。

SuitePolicy

incident_corpus:
  accepts: [raw_failure, unresolved_failure, production_review_finding]
  executable_required: false
capability_entry:
  requires:
    - reproducible_fixture
    - task_digest
    - minimum_grader_coverage
    - review_owner
estimation_entry:
  requires:
    - frozen_sampling_frame
    - production_population_definition
    - weights
    - update_policy
  claims_limited_to: sampled_distribution
regression_entry:
  requires:
    - confirmed_failure_or_invariant
    - stable_success_state
    - calibrated_graders
    - versioned_fixture
    - grader_set_digest
    - failure_owner
replacement:
  requires: [coverage_mapping, review]
removal:
  requires: [obsolete_reason, risk_owner_approval]

GatePolicy

decision_precedence:
  - hard_constraint_fail
  - ambiguous_external_effect
  - missing_required_evidence
  - grader_invalid
  - infrastructure_invalid
  - agent_error
  - runtime_error
  - task_fail
  - task_pass
unknown_or_missing_evidence:
  rule: block_until_resolved
hard_constraints:
  rule: any_confirmed_failure_blocks
critical_regressions:
  rule: no_unapproved_regression_against_baseline
quality_signals:
  rule: require_human_review_outside_expected_range
reruns:
  preserve_all_trials: true
  report: [first_result, invalid_rate, rerun_count, rerun_results]
  max_attempts_by_class: {...}
  task_is_primary_statistical_unit: true
waivers:
  allowed_layers: [quality_signal, noncritical_regression]
  forbidden_states:
    - hard_constraint_fail
    - ambiguous_external_effect
    - missing_required_evidence
    - grader_invalid
    - infrastructure_invalid
  require: [owner, reason, build_scope, expires_at]

从字段回到失败

字段或规则对应失败最小断言
spec_schema_version 与 canonical digest同名任务含义漂移canonical 字段相同则 digest 稳定,版本变化显式
task_digest/execution_digest任务变化与系统变化混淆两类变化可独立定位,旧基线不会被误比
initial_state_digest、clock、network、service versions环境漂移任一变化必须产生新 eval case 或显式兼容判断
ArtifactManifest.source_records少读仓库缺少 required repo 即 outcome fail
source-integrity assertion refs引用路径、commit 或行号失效任一来源断言失败即 task fail
published_content_hash批准与发布错配hash 不同即 hard fail
publish_receipt.status/external_ref自报发布或外部效果未知没有 committed receipt 不得 pass;未知进入 blocked
effect_key 与 receipt cardinalitytimeout 后重复发布同一 effect 两次 committed 即 hard fail
grader_set.digest 与校准记录评分漂移或 LLM judge 不可信grader 变化产生新基线;无 holdout 校准不独立阻断
TrialRecord.primary_classificationpass、fail 与 invalid 混淆每个 trial 只有一个按优先级产生的 primary
rerun.parent_trial_id重跑覆盖首轮失败首轮、invalid rate 与重跑结果同时保留
unknown_or_missing_evidence.rule证据缺失却通过unknown、missing、invalid 均阻止发布结论
waivers.forbidden_states永久或越权豁免hard、unknown、missing 和 invalid 不能被普通 waiver 覆盖

这些对象不是 promptfoo、BFCL 或某个 Eval 平台的配置规范,也不是完整数据模型。字段能回到真实失败、风险政策、复现需要或审计路径,才进入最小版本。

Evaluation Schema 推导图
Evaluation Schema 推导图

章节图|Evaluation Schema 从任务漂移、证据缺失、外部效果与 Grader 漂移反推最小制品。

结语:让失败获得一个可以长期执行的形状

回到源码研究与发布 Agent,最重要的不是判断最终回复是否“像完成了”。评测必须检查五个仓库是否都有证据、引用是否可定位、批准对象与发布内容是否一致、外部服务是否给出 committed receipt,以及过程中是否发生越权或重复发布。

一个项目可以从五个动作开始:

  1. 保存真实失败、环境状态和原始 trace。
  2. 把失败缩成带 canonical digest 的可复现 EvalTaskSpec。
  3. 分开 outcome、hard constraint、evidence completeness 和 trajectory grader。
  4. 用人工标签校准自动 grader,并显式处理 unknown、missing 与 invalid trial。
  5. 只有已确认、可稳定复现的不变量才进入 regression 与 GatePolicy。

评测成熟度不在于跑了多少题,也不在于总分有多少位小数。它在于团队能否解释:这次运行为什么通过或失败,证据来自哪里,结果能否复现,下一次变更将由什么门禁保护。

一次得分只能描述一次运行;版本化任务、校准 grader 和风险门禁,才能把失败变成工程资产。


附录 A:源码深描样本矩阵

项目固定版本直接机制工程推断不可外推
helloagents EvalV0.2.3 / 9a1af1bf968f8cd1974da227ce8782857d1afee8BFCL AST/执行、GAIA 比较、LLM judgegrader 可按任务职责组合任一 grader 通用可靠
Gorilla BFCL6ea57973c7a6097fd7c5915698c54c17c5b1b6c8类别映射、ID 对齐、multi-turn termination任务身份和终止应显式BFCL 得分等于项目能力
promptfoo6d0395a20520e19cf8889d572b879ec9c2831a52repeat、runtime error 与 assertion 分离trial 与错误类型可单独记录repeat 次数通用最优
AgentBenchd1e4a10db08c87075c78972e48ecc182be03e2d5TaskOutput/AgentOutput、错误分类任务环境与 Agent 输出可分离当前主线代表旧版本
SkillsBench9a1f4dd5f7659f75707435da3ce854b6e48321d1score eligibility、task digest、readinesssuite 是版本化资产digest 自动保证任务质量
cua41e47b5bbf4df430e4e14f4cc5e262e06717cb36worker、任务校准、环境轨迹GUI/环境评测需保留终态与轨迹文本 grader 足够覆盖 GUI

helloagents 的 pyproject.toml 声明 0.2.3,但 evaluation 模块导出的版本为 0.1.0;本文以 tag 和 commit 为准,不使用该导出值作版本证据。

附录 B:Trial Primary Classification

表格顺序就是 primary classification 优先级。每个 trial 只有一个 primary,可以有多个 secondary labels。

Primary例子处理
hard_constraint_fail未批准发布、越权、secret 泄漏、重复 committed effect独立阻断,不通过平均或重跑解除
ambiguous_external_effect发布请求已发出,但 receipt 与外部状态都无法确认reconcile 或人工处置,阻止发布判断
missing_required_evidencetrace、必需制品、receipt 或 hard grader 结果缺失补证据或判定运行无效,不推定 pass
grader_invalidgrader 崩溃、schema 不兼容、校准失效修复 grader,阻止发布判断
infrastructure_invalidfixture 未启动、测试服务损坏且能证明未接收副作用请求保留首轮记录,按预定政策重跑
agent_errorAgent 无法解析工具结果、生成非法调用作为系统失败单独报告
runtime_errorcheckpoint、状态机或 runner 崩溃作为系统失败单独报告
task_fail证据完整,但少读 required repo 或引用不存在计入任务失败
task_passrequired evidence 完整,结果与硬约束全部通过才能计入通过

附录 C:离线评测资产检查清单

阶段最小检查
Incident原始输入、环境状态、trace、失败影响和发现来源已保存
Reproduction可重复触发;不能复现时保留不确定性
Task specschema version、canonical task digest、初始状态、成功终态、禁止副作用和逻辑制品明确
Execution profilePrompt hash、模型/API/采样/seed、runner/container/adapter、工具与重试并发策略明确
Fixtureinitial state digest 稳定;网络、时钟、时区和 service versions 明确
Artifact manifest六类逻辑制品都有 ID、digest、producer、location 和 assertion refs
Outcome graderrequired repo、来源定位、制品和环境终态的正例、负例与边界例通过
Hard grader越权、泄漏、重复、未批准等反例逐项覆盖,不会被总分稀释
Model graderrubric、label set digest、样本数、标注协议、一致性、holdout、分层指标、abstain 和复审入口齐全
Trialsprimary classification 唯一;首轮、invalid rate、重跑链和原始日志可定位
Suiteincident/capability/estimation/regression 的进入、替换、退出和声明边界明确
Gateunknown/missing/invalid fail closed;风险层、baseline、waiver 禁区与 owner 明确
Feedback生产监控、人工审查和用户反馈能回流为 incident

附录 D:容易混淆的边界

概念Evaluation 的职责不负责
Runtime validator运行中阻止非法迁移或副作用代替离线 suite 与校准
Framework trace提供运行证据自动判断任务成功
Context Engineering记录模型看见什么定义发布门禁
Memory保存受治理的过去信息证明本次 run 完成
Production monitoring发现线上事件与分布变化自动形成可复现回归任务
A/B test比较真实用户结果替代硬约束与安全门禁
Public benchmark提供能力维度和外部参照代表项目生产分布

参考资料

外部资料访问截止日为 2026-09-06;目录与规格文件使用已经确认的 2026-09-07 版本标识。

参考资料

  1. AgentBench 固定源码,重点见 src/typings/output.py、src/client/task.py 与 src/assigner.py。 ↩

  2. SkillsBench 固定源码,重点见 skillsbench_agentbeats/adapters.py、task_sets.py 与 public_readiness.py。 ↩ ↩ ↩ ↩

  3. Gorilla BFCL 固定源码,重点见 berkeley-function-call-leaderboard/bfcl_eval/eval_checker、constants/category_mapping.py 与 model_handler/base_handler.py。 ↩ ↩

  4. helloagents V0.2.3 固定源码,重点见 hello_agents/evaluation/benchmarks/bfcl/evaluator.py、gaia/evaluator.py 与 data_generation/llm_judge.py。 ↩ ↩

  5. OpenAI 官方文档:Evaluation Best Practices,页面主题为 rubric、代表性数据与持续评测;Trace Grading,页面主题为对 Agent 轨迹中的决策、工具调用和步骤进行评分。访问日期:2026-09-06。 ↩ ↩

  6. Anthropic: Demystifying Evals for AI Agents,页面主题为 Agent 任务、grader、评测驱动开发与真实失败回流。访问日期:2026-09-06。 ↩

  7. promptfoo 固定源码,重点见 src/evaluator.ts。 ↩