Skip to main content
一批评估用例共用同一套重工具链时,你通常同时需要两件事:不要为每道题重复创建 Sandbox,也不要为了复用而把整批任务都降成串行。defineEvalGroup() 把兼容的评估用例 划入同一个物理复用边界。同组真实派发的 Attempt 稳定串行并复用一台 Sandbox;不同组和 未分组的评估用例仍可使用其它并发位。 评估组只安排本轮需要真实运行的 Attempt。已经沿用的结果不会进入组内 Sandbox, --rerunattempts 和首过即停仍按 Experiment 的既有规则工作。

先选对复用方式

同一个 Experiment 不能同时选中评估组并声明 sandboxReuse: true。评估组已经拥有自己的 复用边界;两者同时出现会在 Provider 创建 Sandbox 前报 eval-group-sandbox-reuse-conflict

第 1 步:把组文件放在成员旁边

eval-group.ts 放进 evals/ 下的具名目录。目录路径就是评估组 ID:
NiceEval 只发现 evals/**/eval-group.ts。不要把文件写成 *.eval-group.ts,也不要放在 evals/eval-group.ts;后者没有可用的组 ID。

第 2 步:用工厂返回对象声明成员

每个成员照常默认导出 defineEval()defineScoreEval() 的返回值。组文件导入这些返回值, 再把兼容成员列入同一个闭合集合:
evals 必须非空。它只接受工厂实际返回的对象,不接受评估用例 ID、目录前缀、globtagselector。NiceEval 也不会自动收集同目录文件;成员增删和顺序变化都会明确出现在 eval-group.ts 的 diff 中。 evals 数组只声明成员,不声明业务顺序。Runner 始终按规范化 Eval ID 稳定排序;只调整 数组位置不会改变调度行为或组指纹。需要“先构建、后查询”这类结果依赖时,把两个步骤放进 同一条 Eval。Eval Group 的业务排序 API 还没有实现。 onUnavailable 是必填策略。"stop-group" 在物理 Sandbox 无法创建、重置或准备时停止 该组后续派发;"replace-sandbox" 会先退休当前实例,并让下一条 slot 尝试建立替代实例。 省略策略会在加载 eval-group.ts 时直接报错,避免运行器替作者猜测失败后的成本与副作用。 一条评估用例最多属于一个组,同一组也不能重复列出同一条。Experiment 与 CLI 仍负责筛选 评估用例;选中 workflow/02-query 不会自动把 workflow/01-index 拉进本轮运行。

第 3 步:让 Experiment 提供可复用的 Sandbox

大多数项目由 Experiment 选择 Provider 和 template,评估组只负责拥有复用队列:
这里不要写 sandboxReuse: truemaxConcurrency: 4 是整个 Experiment 的上限,不会让 同组同时跑四条;它允许其它评估组或未分组评估用例使用剩余并发位。 评估组只支持 Sandbox 型 Agent 和支持复用的 Provider。Direct Agent 与 localSandbox() 不能运行评估组。

第 4 步:先检查组 ID 和选择结果

先用 --dry 确认选择结果,不会创建 Sandbox:
上面的最小项目会显示:
确认两条选中 Eval 都显示相同的组 ID 后再运行:
当前调度器按规范化 Eval ID 排列成员;attempts 大于 1 时,同一成员的各次 Attempt 连续 进入组内泳道,再进入下一个成员。这只是稳定的调度规则,不是跨 Eval 的数据依赖契约。 首过即停或结果沿用没有实际派发的槽位会直接跳过。

把公共准备放到评估组

一次 Sandbox 规划可以同时接收 Experiment、评估组和评估用例三层声明,但三层中只能有 一层提供 template。常见分工如下: 评估组可以提供自己的 SandboxLayer
组内生命周期与 Agent Context 都能读取 ctx.evalGroup.idctx.evalGroup.definitionHash。公共函数也可能服务未分组评估,所以类型把 evalGroup 保留为可选字段。需要在 workdir 外隔离缓存或服务命名空间时,先检查字段是否存在,再使用 组 ID 派生键。 成员不能提供 template,也不能声明 .setup().teardown()。把实例级生命周期移到 评估组或 Experiment;成员只保留不含 template 与生命周期、仅声明 .prepare()SandboxLayer

不要把评估组当成任务依赖图

每条 Attempt 之间,NiceEval 会把 workdir 重置到公共准备完成时的状态。前一道题写进 workdir 的文件不会成为后一道题的输入;$HOME/tmp、全局安装和后台进程则可能保留。 无法接受这些残留时,不要复用 Sandbox。 评估组也不会保证前一道题一定执行。结果沿用、CLI 过滤、预算耗尽和中断都可能让成员不进入 本轮 Sandbox。后一项必须读取前一项文件时,把两个步骤写进同一条评估用例;只有共享状态本来 就在 workdir 外,而且每条评估用例都能独立得到有效判定时,才把它们放进同一组复用。

常见错误

接着看

  • 用 Plugin 复用完整评估条件——把组、实验或成员需要的声明组合成 显式 occurrence,同时保留评估组的 Docker Sandbox 复用边界。
  • 复用 Sandbox——整批普通评估用例适合使用 sandboxReuse: true 时的生命周期和残留边界。
  • 调好并发——评估组怎样与全局、Experiment 并发上限一起工作。
  • Sandbox Provider 配置——选择 template、设置寿命并编写 SandboxLayer
  • 重跑与沿用——哪些 Attempt 会进入本轮组内队列。