Skip to main content
共享 runtime 负责单个请求内的任务执行,Orchestrator 负责多个命名请求之间的调度。修改生命周期时,先判断行为属于一次尝试、一个任务、一个请求,还是整次编排。 主要实现位于以下文件:

准备请求

UnifiedEvaluationRuntime.prepare 在任务工作协程启动前完成请求级工作:
  1. 预留新输出目录并初始化进度报告;
  2. 写入初始 run_info.json
  3. 执行尚未完成的依赖与组件兼容性预检;
  4. 调用 Benchmark.load_tasks,校验任务 ID,再调用 Benchmark.select_tasks
  5. 将可复用的正常明细文件放入新运行目录;
  6. 加载这些明细,并从待处理队列移除对应的任务 ID。
每个请求只加载和选择一次任务。Planner.planBenchmark.prepare_task 则属于尝试作用域,会在之后按需再次执行。

执行一次尝试

对于每个选中的任务,_run_attempts 会读取 RunRequest.execution.attempts,解析已注册 strategy,再由 AttemptScheduler 决定仍需执行哪些 attempt 索引。一次 attempt 的逻辑顺序如下: runtime 在打开 Environment 前构建并记录 ExecutionPlan。下一次语义尝试会重新构建计划,同一次尝试内的 runtime 重试则复用该计划。 Benchmark.prepare_task 接收原始 TaskSpec、已打开的任务 EnvironmentSession、完整请求与 plan.benchmark_plan,并返回 PreparedTask。普通 Harness 路径随后依次调整输入、启动 Harness 会话、切换运行网络策略、执行任务,并在嵌套的 finally 中关闭 Harness 会话。 对于 HarnessFreeBenchmark,请求使用占位 Harness ID none。runtime 不构造 Harness,而是在相同的网络策略边界下调用 HarnessFreeBenchmark.run_task。两条路径此时都只返回原始 RunResult,不会在推理阶段评分。 如果已经得到 RunResult,runtime 会在任务 Environment 仍存活且处于运行策略时调用 Benchmark.collect_artifacts。这是释放任务 Environment 前,最后一个可以读取 agent 所创建文件的共享生命周期方法;它可以附加或规范化产物,但不负责聚合请求指标。 ExecutionPlan.evaluation_environment_mode 决定 Benchmark.evaluate 收到的 Environment: Benchmark.evaluate 返回每次尝试的权威评分。评测完成后,analyze_task 按数据集、数据要求、配置和分析器系列选择符合条件的实现;分析失败会单独记录,不会覆盖 Benchmark 得分或原始失败信息。 这里的“保留”指 ExecutionSpec.keep_environment=True。它只跳过 Environment 关闭操作,不会改变传给评测器的会话。

区分语义尝试与 runtime 重试

两层循环解决不同问题: 重试预算在每次语义尝试开始时重置,并由该次尝试的全部可重试阶段共享。retry_pattern_list=None 时,任意非空错误都可匹配;列表只重试至少匹配一个正则表达式的错误,空列表不匹配任何错误。 失败位置决定重试作用域:
  • 准备、Environment、推理、产物或一般尝试失败时,使用新的任务 Environment 与同一计划重跑整个尝试;
  • 推理返回的错误符合重试条件时,也会重跑整个尝试;
  • reuse 评测失败会重跑整个尝试,因为评测器共享任务 Environment 的状态;
  • none 评测失败只使用同一个已准备任务与运行结果重试 Benchmark.evaluate
  • fresh 评测失败会重新打开评测 Environment,并使用同一个已准备任务与运行结果重试评测。
RunStore.save_retry_detail 将被丢弃尝试的诊断数据、重试序号、阶段、作用域、匹配模式和脱敏计划写到 details/ 之外,因此重试不会改变可计数的任务集合。重试耗尽后,runtime 会在结果中保留异常堆栈或返回的错误。 每个已评测结果都会按稳定的 attempt 索引写入 checkpoint。avg strategy 会完成所有已配置 attempts;pass strategy 可以在主观测第一次得到有效成功后停止。调度前会恢复已有的兼容 checkpoints,因此中断后的 k>1 任务只执行缺失 attempts。任务进入终态后,runtime 调用 RunStore.save_partial_result,随后删除内部 attempt checkpoints。

编排请求并施加限制

以上阶段都属于单个请求;跨请求调度由 Orchestrator 负责。Orchestrator._run_orchestration 启动三类协作任务:
  • _prepare_in_order 按声明顺序准备各请求;
  • task_concurrency_worker 通过同一个全局池执行任务;
  • _finalize_ready 在请求满足收尾条件后启动聚合。
准备阶段采用流水线。只有当更早且未终止的请求都已完成准备,并且它们的待处理任务总数小于工作协程数时,后续请求才开始准备。_select_state 按声明顺序选择第一个已准备且仍有待处理任务的请求:
这是有序优先级,不是完整请求之间的屏障。改成轮询或提前交错会改变用户可见的调度语义。请求自身没有待处理或活动任务,且更早的请求都已清空待处理队列后,才会开始收尾;收尾可以与其他活动任务重叠。为兼容直接调用 runtime,UnifiedEvaluationRuntime.execute 仍保留有界的 TaskExecutor 路径;公开的单请求辅助函数会先包装成 Orchestration,因此使用中央工作协程池。 AgentCompass 在不同职责层独立限制并发和外部服务压力: provider 容量或打开 QPS 为 0 时,会禁用相应限制。两类缓存都是进程全局的,并可跨事件循环安全使用;重跑整个尝试时会先释放再重新获取 provider 容量许可。任务并发不能代替 provider 容量,因为多个编排可能在同一进程中共享同一个 provider。 网络策略属于 ExecutionPlan,强制执行由 Environment provider 负责: BaseEnvironment.build_config 会校验 provider 是否支持请求的策略转换。不能动态切换的 provider 必须拒绝阶段策略不同于基线策略的计划,不能静默使用更宽松的访问范围。评测结束后,runtime 会先避免恢复基线策略的操作被取消,再进入正常清理路径。

清理并收尾

资源按照所有权从内到外释放:
Harness.close_sessionBenchmark.collect_artifacts 前执行,任务 Environment 在产物收集期间仍可用。驱动进程评测或全新 Environment 评测会先关闭任务 Environment,reuse 则保留它直到评测结束。Harness 或 Environment 释放失败会记录警告,避免覆盖原始任务失败;取消、KeyboardInterruptSystemExit 会继续抛出。 ExecutionSpec.keep_environment=True 只适用于显式保留或调试,不能用来掩盖清理失败。新增 provider 的 close 仍应具备幂等性,并正确处理部分初始化、失败和取消。具体测试要求见 Environment 验证与对齐 Orchestrator.execute 在开始计算编排截止时间前完成组件预检。超时或外层 asyncio 取消后,会依次锁定终态、取消准备与工作协程、在 cleanup_grace_seconds 内等待自身创建的异步任务和已跟踪线程、持久化未终止请求的终态,最后关闭日志与进度渲染器。第一次 CLI 中断请求这条协作清理路径,第二次中断会强制退出,因此清理代码不能依赖无限等待。 取消可能发生在任意 await。获取会话、进程、代理、客户端、后台任务或临时端点后,应立即安装清理逻辑,并继续抛出 asyncio.CancelledError 单个请求的待处理队列与活动任务清空后,UnifiedEvaluationRuntime.finalize 会按选中任务的顺序合并新旧记录,将指标聚合交给 Benchmark.aggregate_metrics,并写入摘要与可选的分析产物。返回值代表整个请求,而不是单次执行使用的 RunResult 继续阅读 结果与复用 了解部分结果、聚合产物与终态结构。