Skip to main content
先把数据集记录转换为稳定的 TaskSpec,再明确哪些字段可以交给 Harness、哪些状态只能用于评测。

区分四种数据载体

Harness 可以读取整个 PreparedTask,包括其中的 ground_truth 和 metadata。不要未经筛选就复制 TaskSpec.metadata。 仅供评测使用的数据应留在 TaskSpec.ground_truth 或类型化 BenchmarkPlan 中,并把 PreparedTask.ground_truth 设为 None。这些对象仍处于 runtime 和结果审计范围内,因此不能保存凭证或其他禁止持久化的秘密材料。 只有可以随结果公开的参考答案,才能写入 RunResult.ground_truth。

定义公开配置

Benchmark 参数应使用 RuntimeBenchmarkConfig 和 config_field(),并在 __post_init__() 中尽早规范化类型:
不要在模块导入时下载数据、安装依赖或读取凭证。应通过显式加载器或依赖准备流程访问数据;如果版本、数据划分或访问条件不符合要求,请给出包含解决办法的错误信息。

加载确定性任务

load_tasks() 应固定上游版本并生成稳定的 task_id。下面的 metadata 只包含可以进入日志和执行输入的复现信息;答案单独放在 ground_truth 中:
继承的 select_tasks() 已提供 runtime 的通用任务选择逻辑。只有当前 Benchmark 的规则不同于普通 ID 过滤时,才需要覆盖该方法;无论采用哪种规则,都要保证返回顺序确定。

Harbor 任务与执行要求

通过 agentcompass.benchmarks.utils.harbor 中的 load_harbor_task(),可将 Harbor 任务目录转换成 TaskSpec。除了 network policy 和 resources,adapter 还映射以下执行要求: 显式独立的 verifier 环境通过 evaluation_environment_setup 提供独立的镜像、工作目录和构建超时基线:未填写的值不会继承 agent 的设置,显式空配置也保持独立。只有 None(没有声明独立基线)才继承解析后的运行环境设置,包括 Recipe 默认值。请求中的 EnvironmentSpec.setup 和 evaluation_setup 覆盖任务默认值;Provider 原生启动选择器不属于公共输入。工作目录、启动超时、环境变量和出站规则只接受通用字段;provider 原生别名会报错。 容器镜像的解析结果统一保存在 EnvironmentSpec.setup.image。Harbor 的 environment.docker_image 映射到任务 setup;Recipe 读取合并后的 plan setup,只在镜像缺失时向该字段补充默认值,不再读写 params["image"]。provider 仅在构建环境配置时将该字段转换为自身参数。请求入口拒绝旧参数 image 和 evaluation_image,必须直接配置 setup.image 和 evaluation_setup.image。配置示例: --env-params '{"setup": {"image": "registry.example/runner:v1"}}'。 fresh verifier 的网络遵循同样的独立规则:显式 verifier.environment 提供自己的基线,空表也使用独立的默认 public 网络;未声明 verifier 环境才继承 agent 基线。请求中的 evaluation_baseline_network_policy 优先于公共请求 baseline_network_policy,后者优先于任务的 verifier 基线。runtime 使用该基线启动 verifier,在评测时切换到 evaluation_network_policy,之后恢复基线,不会用其中一种策略静默替代另一种。可以用 --env-params '{"evaluation_baseline_network_policy": {"network_mode": "no-network"}}' 只覆盖 fresh verifier 的基线;该请求字段要求 fresh evaluation。 workdir 必须是环境内的 POSIX 绝对路径,用于 env.exec() 没有指定 cwd 的情况;显式 cwd 优先。它不会替换 Benchmark/Harness 显式指定的工作区。SWE-Marathon 使用统一的 workdir 作为工作区,未声明时依次回退到 Dockerfile 的 WORKDIR 和配置的工作区根目录。可以用 --env-params '{"setup": {"workdir": "/app"}}' 覆盖任务默认值。 这些是分别计时的阶段 deadline,不是整个 task 共用的 wall clock、单次工具调用超时或 sandbox 生命周期。任务字段为 None 表示未指定 deadline;指定秒数时必须是有限正数。adapter 只映射显式声明的超时,不引入 Harbor 的隐式默认值。映射构建超时不会让仅支持预构建镜像的 provider 自动获得构建 Dockerfile 的能力。 Benchmark 可用 BenchmarkPlan.run_timeout_seconds 和 evaluation_timeout_seconds 提供 task/Benchmark 默认值。Planner 先解析请求中的 execution.run_timeout_seconds 和 evaluation_timeout_seconds,再应用阶段倍率(run_timeout_multiplier 或 evaluation_timeout_multiplier)或公共 timeout_multiplier。阶段倍率替换公共倍率;缺省或 null 的覆盖值继承默认值。仅当 task/Benchmark 均未提供执行默认值时,才使用 Harness 回退预算。 最终 ExecutionPlan 同时提供 runtime 阶段 watchdog 和 Harness/评测器的原生超时控制值。Harness 的 execute_task()(或无 Harness Benchmark 的 run_task())与 evaluate() 分别计时,复用 Environment 和 fresh Environment 的规则一致;随后在关闭 session 前通过 collect_result() 回收已保存的 Harness 输出,使用 harness_result_timeout_seconds(默认 60 秒)。回收不得继续执行 agent,也不会清除原始执行错误;执行和评测倍率不影响回收预算。超时后 runtime 记录阶段错误,并尝试适用的产物采集和清理流程。取消协程本身不能确认远程进程已经停止。 产物准备使用独立的 artifact_collect_timeout_seconds deadline(默认 null);下载/恢复使用 artifact_limits.timeout_seconds(默认 600 秒)。通过 YAML 的 execution、SDK 的 execution_params 或 run 的 --execution-params 配置。这些预算不延长 sandbox TTL,也不覆盖整个运行的取消机制。 未映射的声明保存在 TaskSpec.load_warnings 中。runtime 在 select_tasks() 之后才打印这些警告,因此被排除的 sample 不产生告警。直接调用 loader 的代码可以自行检查此列表。真正未支持的声明仍会保留告警,不能仅因为原始 metadata 保存了字段,就将其标记为已映射。 environment 或 verifier.environment 下旧版 memory、storage 的容量字符串,只有被 Harbor 转换为对应的 MiB 资源字段时才视为已映射。旧字段与新字段冲突时仍会校验失败;被忽略的旧字段值仍保留未映射告警。 任务来源信息保存在 TaskSpec.metadata 中:顶层 source 映射到 metadata["source"],包含 task.version 的包信息映射到 metadata["task"]。显式任务声明优先于自由格式 metadata 表中的同名条目。包版本必须是非空字符串,不要求遵循语义化版本;旧版 Harbor 未定义此字段时,由 adapter 进行兼容校验。顶层旧字段 version 仍是 schema_version 的别名,不代表包版本。原始声明在 harbor_raw 中保持不变。 Recipe 应用后的最终 ExecutionPlan 是执行时的唯一来源。Harness 和 verifier 不再读取 task TOML、私有 timeout 字段或 metadata 中的 timeout。Recipe 必须修改 plan.run_timeout_seconds 和 plan.evaluation_timeout_seconds,再由 Planner 将运行超时映射到 Harness 原生字段。

任务环境变量

任务和环境的公共契约分别提供公共、运行阶段专用和评测阶段专用的变量:env_variables、run_env_variables 和 evaluation_env_variables。TaskSpec.evaluation_environment_env_variables 提供 fresh verifier 独立的启动变量基线:None 继承任务公共变量,显式映射则替换它们,空映射也不继承。Harbor 将生效的独立 verifier 环境中的 env 表映射到此字段,而不是仅用于命令的阶段变量。计划中保留 ${GRADER_KEY} 等引用,由 provider 在执行前从启动进程的环境中解析。只需 export 所选任务要求的 key;缺少必需引用时会在分配环境前报错,不打印变量值。同时支持 ${NAME:-default} 和字符串内嵌引用,不执行 shell 命令展开。 请求级配置按 key 覆盖任务默认值;请求中的阶段变量优先于公共变量,当前阶段变量优先于内部 env.exec(env=...) 默认值。不得覆盖的原生协议要求应通过 env.require_exec_env() 显式校验;冲突时只报告变量名,不打印值。agent 安装/执行和评测命令使用同时按 session 与异步上下文隔离的临时作用域,成功、失败或取消后均恢复。任务准备、结果回收、Harness 清理、产物生成命令与产物恢复只使用公共变量,不继承 agent 专属变量。provider 支持时,公共变量也会注入 sandbox 启动过程;阶段专用变量只用于命令,不进入镜像 entrypoint。这是注入契约,不是针对复用 sandbox 中残留进程或文件的安全隔离边界。host_process 仍继承宿主进程环境。 EnvironmentSpec.evaluation_environment_env_variables 是请求层的 fresh 启动变量覆盖入口,要求 evaluation_environment_mode="fresh"。它按 key 覆盖任务 verifier 基线和请求公共变量;执行评测命令时,请求的评测专用变量优先级更高。请求中缺省表示继承,空映射表示不增加覆盖;与任务中的显式映射不同,请求空映射不清空任务基线。 旧 Harness env 参数会报错,应迁移到 environment.run_env_variables。Harness 适配原生工具配置时从当前 Environment 作用域获取解析后的变量,不修改 RunRequest 或宿主 os.environ。直接运行在本地的 SDK 继续使用显式 SDK 配置;这些变量只注入经 Environment 执行的命令。 Harbor 的 solution.env 默认属于参考解。只有确认这些变量确实也是 agent 任务所需时,Benchmark 才应通过 solution_env_for_agent=True 显式启用映射;不能自动把参考解的密钥注入 agent。

提交产物与回放

TaskSpec.artifacts 是 Benchmark 或格式适配层提供的文件清单。collect_artifacts = true 的 Benchmark 始终包含主环境约定目录 /logs/artifacts/。Harbor 适配层在加载 task 格式时解析同一目录(包括 Harbor 中的空声明),并添加显式附加路径;原生 Benchmark 在规划时遵循相同规则。TaskSpec.artifacts = [] 或 execution.artifacts = [] 表示没有额外路径,并不关闭收集;只有 collect_artifacts = false 才会关闭收集。显式声明约定目录时使用该条目的排除配置。目标路径冲突时沿用 Harbor 的先到先保留规则并给出警告,公共 runtime 接收不重叠的清单。 Benchmark 声明提供收集默认值。execution.artifacts 指定时会替换 task 专用的额外路径,但收集型 Benchmark 的 /logs/artifacts/ 始终保留;未指定或为 null 时继承,[] 表示只收集该约定目录。execution.artifact_collect 独立覆盖命令,其中 [] 清空命令列表。runtime 使用解析后的列表;只有 collect_artifacts = false 才跳过收集。collect_artifacts 只是解析后计划中的只读值,不是 CLI、YAML 或 SDK 的执行参数。execution.save_artifacts 控制本地持久化:未指定或为 null 时,fresh 解析为 true,reuse/none 解析为 false。fresh 必须保存,显式设置 save_artifacts=false 会在创建环境前报错。reuse/none 关闭保存只跳过文件下载,仍执行声明的准备命令;仅开启保存不会增加收集路径。保存文件不会保留 sandbox,环境生命周期仍由 keep_environment 控制。答案、轨迹、日志及 Benchmark 专用评测输出不受影响。具备已分类推理快照及完整评分输入时,none/fresh 支持仅评测恢复;reuse 必须重新执行 attempt。 当产物路径依赖 Recipe 最终选定的 workspace 时,可覆盖 BaseBenchmark.resolve_artifacts(task, req, plan)。Planner 会在全部 Recipe 之后、最终规范化之前调用它;显式 execution.artifacts 仍具有最高优先级,并跳过 Benchmark 默认值。

覆盖产物路径和准备命令

execution.artifacts 和 execution.artifact_collect 分别覆盖 task/Recipe 的额外路径和命令。未指定或为 null 时继承对应声明;显式 artifact 列表会替换额外路径,但始终保留 /logs/artifacts,包括 [],此时只收集该目录。CLI 列表会替换对应的 YAML 列表;没有 task 专用默认声明的 Benchmark 也可以通过这些参数指定路径或命令,前提是它支持收集。Benchmark 类可以声明 collect_artifacts = False,此时显式覆盖任一列表(包括 [])都会在规划阶段报 unsupported;未指定或为 null 不算覆盖。该能力默认 True,不是 Benchmark params 或 execution 的 CLI 参数,Recipe 也不能重新启用。需要保留 task 专用条目再增加自定义条目时,应在替换列表中包含所需的原始条目。
source 是 agent sandbox 内的绝对路径,可以指向文件或目录。destination 相对于当前 attempt 的本地 artifacts/ 目录:上例 /app/submission 保存到 artifacts/submission/,排除 *.tmp;另一个文件保存为 artifacts/result.json。源路径不存在时会记录缺失状态,不会使收集失败。目标存储路径重叠会在执行前报错。fresh 评测将文件恢复到原始 source 路径。 只执行解析后的命令列表,按列表顺序完成后才下载文件;覆盖命令时不会自动先执行 Benchmark 的原始命令。CLI 命令使用 timeout_seconds,Harbor task.toml 使用 timeout_sec。准备和传输预算作用于解析后的列表。reuse/none 下 save_artifacts=false 仍执行命令;fresh 必须保存。示例命令生成演示文件,并替换 Benchmark 的原始命令列表。替换列表中应保留 verifier 所需的准备命令,否则可能无法生成评测所需的提交内容。 Recipe 可以调整解析后的路径。None 和 [] 表示没有解析后的路径,不再作为 Harbor 原始声明处理。调整后重新校验路径;关闭整条收集流程应使用 execution 开关。host_process 的绝对来源路径指向宿主文件系统。 默认目录是可选输出:来源不存在时记录为 missing,空目录成功下载后记录为 collected,内容字节数为零。两种情况都不会阻止评测或 checkpoint 创建;空目录会保留用于 fresh 恢复,缺失条目不会上传文件。权限错误、异常祖先路径、传输失败、超时和超限仍属于采集错误,不会伪装成无产物,既有失败处理保持不变。空采集本身不证明任务能够独立评测,回放仍需具备 verifier 要求的全部输入。 ArtifactSpec 位于 agentcompass.runtime.artifacts。字符串声明表示 sandbox 中的绝对源路径;对象声明还可指定产物存储区内的相对 destination 和 exclude 模式。默认目标路径是去掉源路径开头的斜杠。采集支持文件、二进制数据和目录,排除规则使用 GNU tar 模式;目标路径重叠、路径或链接越界、特殊文件以及非主服务声明都会显式报错。 runtime 先执行声明的收集命令(如果有)。关闭收集开关时跳过整条流程;否则没有命令就跳过准备,仍可收集已有文件。持久化开启时,在释放 agent 环境前复制选定的产物。二进制内容保存在结果目录的 artifacts/ 下,RunResult.artifacts.declared_artifacts 只记录相对路径、状态、大小和校验和。迁移运行结果时需要连同该目录一起保留。复用结果会先校验并复制引用的产物字节,再保存复用的 detail 或终态 attempt checkpoint;产物缺失或损坏时,该结果会重新运行。不同 run 的产物文件不会通过硬链接共享。源文件缺失或被完全排除时会记录状态,由 verifier 评分;传输错误和超限会让采集失败。 runtime 在 agent sandbox 中按顺序执行 ExecutionPlan.artifact_collect;没有命令就跳过准备,不调用 Benchmark 回退钩子。公共 download_artifacts() 在持久化开启且清单非空时负责打包、传输、校验和本地存储。解析后的空路径列表不会禁止声明命令执行。 Harbor 的 verifier.collect 映射到 TaskSpec.artifact_collect,由 Planner 复制,并在 Recipe 调整后再次校验。每条声明映射 command、timeout_sec → timeout_seconds(默认 60 秒)以及 service(默认 main)。命令使用 bash -c 按顺序执行,沿用运行阶段的网络策略,但只使用公共环境变量,发生在评测及环境释放之前;不注入 verifier 专属变量,变量引用在 sandbox 中展开,不在任务加载时展开。每条命令具有独立的有限正数超时,还受可选的收集阶段总 deadline 限制。暂不支持 sidecar 服务和命令级 user 覆盖,加载时会明确报错;未知命令字段也会明确报错。 仅关闭 save_artifacts 时,声明的命令仍会执行;也可以只指定路径而不声明命令。路径描述已有或预期的提交物,不描述如何生成它们。任务已提供 collect 命令时,会完全绕过 Benchmark 钩子。例如:
采集清单以 submission-*.manifest.json 的形式原子写入提交目录旁边。后续操作失败时,已成功校验的文件仍保留在磁盘中。ArtifactDownloadError.manifest 返回 complete=false 的部分记录,区分失败、取消和未采集条目;runtime 将其保留在 declared_artifacts 中,并在 telemetry 的 post_run_errors 中分别记录准备和传输错误,不覆盖原始运行错误。准备失败后仍尝试采集已有文件,但准备或传输失败都会阻止该次尝试进入评测及生成可续跑 checkpoint。显式取消继续向上传播,磁盘清单保留用于诊断。进度事件包含当前操作、已完成的字节和条目、已知的归档大小及剩余预算;provider 下载接口不提供连续的逐字节进度。 fresh evaluation 会先验证清单和校验和,再将产物恢复至原 sandbox 源路径,然后调用 evaluate()。目录恢复会替换目标目录的内容,清除旧文件和隐藏条目,但保留目录本身以兼容挂载工作区。恢复时先暂存完整产物,安装失败时尝试回滚;中断后保留恢复暂存区,直到环境清理。reuse evaluation 不会覆盖现场工作区。旧结果中的内联文本产物仍可兼容,但必须覆盖全部声明的输出。ExecutionPlan.artifact_limits 默认限制每次采集或恢复为 16 GiB、100,000 个文件系统条目、600 秒,Recipe 可以调整这些类型化限制。清理临时目录前,会等待本地文件操作完成或响应取消。 父路径先于子路径恢复,不受声明或 manifest 顺序影响,因此显式采集的子路径不会被父目录的排除规则覆盖。同一源路径存在不同排除规则时,fresh 计划会报错;同源副本的采集状态、内容和权限必须在上传前校验一致,相同副本只恢复一次。 同一个逻辑 attempt 重跑 agent 前,runtime 会将上一轮产物、结果和 checkpoint 归档到 retries/<id>/,并更新诊断记录中的产物引用。新的实际运行从空产物目录开始;仅恢复评测时保留已有输入。 DeepSWE v1.1 的锁定版本声明了 verifier.collect 命令,提取 base commit 到 HEAD 的差异,因此需要 agent 自行提交改动。runtime 不会自动提交或执行旧版 pre_artifacts.sh。公共下载器传输声明的 patch,SWE-Marathon 的目录声明使用同一套下载器。 Harbor adapter 只映射 Harbor 官方字段。SWE-Marathon 直接使用 load_harbor_task(),不支持其自定义的 verifier.type 和 grader.restore_paths。原始声明仍保留在任务 metadata 中,runtime 仅对选中的任务输出未映射字段告警。AgentCompass 不校验或执行这两个扩展:它们既不会选择 verifier 实现,也不会触发文件恢复。SWE-Marathon 的正常评测仍在复用的 agent 环境中执行 tests/test.sh。checkpoint 选择和评测续跑属于独立的 runtime 职责,不属于任务格式映射。 runtime.checkpoint 保存已分类的推理与准备输入快照、网络策略和产物完整性信息,支持 none/fresh 评测恢复;失败评分不能污染保存的输入。 v4 checkpoint 恢复 PreparedTask 和推理结果,包括 issues、轨迹与用量;每轮评分使用独立副本。driver 输入文件按保存的路径与摘要校验,缺失或发生变化时拒绝恢复。client/session 对象和未校验的远端媒体 URL 不能形成可恢复快照。旧版仅产物 checkpoint 仍可读取,但缺少跨 run 物化所需的已分类快照,可能需要重新执行;prepare_evaluation(task, req, plan) 保留为可支持的旧版 fresh checkpoint 的回退。详见评测 checkpoint。

为每次尝试建立类型化计划

如果评测状态需要结合配置和任务计算,请定义 BenchmarkPlan 子类,并在 build_plan() 中为当前尝试解析一次:
build_plan() 不应打开 Environment、调用 Model 或修改 RunRequest。初始 ExecutionPlan 建立后,Recipe 会按照自身契约调整计划,因此 Benchmark 文档不能假定 runtime 统一保证某种 Recipe 字段优先级。需要映射 provider 时,请在对应的 Recipe 集成中说明并测试字段保留规则。

准备执行输入

prepare_task() 可以在任务 Environment 中创建工作区或上传公开材料,但返回值只能包含执行阶段可见的内容:
需要创建文件或目录时,请使用传入的 EnvironmentSession,不要绕过 Environment 直接调用 provider SDK。重试时可能再次调用该方法,因此准备过程必须能够安全重复;否则,应在执行前明确清理自己创建的工作区。

注册与依赖

使用 @BENCHMARKS.register() 注册实现,并在 src/agentcompass/benchmarks/__init__.py 中导入模块:
在仓库根目录检查组件发现和参数结构:
框架运行所必需的依赖应加入默认项目依赖。只有某个 Benchmark 使用的 Python 驱动,应加入单独的可选依赖组并声明 DependencySpec。任务或验证器需要的 runtime 依赖,则应固定在对应的 Environment 中。注册成功只说明模块可以导入,不代表数据、凭证、验证器或真实运行已经验证通过。