内置 sandbox agents
claude-code
运行 Anthropic Claude Code CLI,需要
ANTHROPIC_API_KEY。codex
运行 OpenAI Codex CLI,需要
CODEX_API_KEY。bub
运行 bub coding agent,鉴权遵循 bub CLI 自身约定。
运行内置 agent
在 Eval 或 Experiment 上设置sandbox,选择 NiceEval 在哪里创建隔离环境:
没有对应的 CLI flag,也没有项目级默认 provider。Eval 与 Experiment 都没贡献 template-bearing layer 时,link planning 会在创建任何 Sandbox 前失败。
NICEEVAL_CLAUDE_CODE_E2B_TEMPLATE,Bub 用 NICEEVAL_BUB_E2B_TEMPLATE。常量的值是完整、版本固定的引用,版本跟着模板里那个 Agent 的版本走,你不用跟踪它。添加系统包、二进制或模型缓存的步骤见 Sandbox Provider · 从官方基线继续构建以提速。
内置 agent 从 niceeval/adapter 导出的是工厂函数。需要配置鉴权、代理、MCP 或 GitHub skill 时,把这些写进工厂参数。模型仍然写在 experiment 的 model 字段,sandbox provider 仍然写在 sandbox 字段:
agent 环境变量
工作流程
test(t) 中。agent 执行阶段只能看到你已经写进 sandbox 的文件。
t.sandbox.fileChanged() 等归因断言只评 agent 在 t.send() 期间改动的文件:NiceEval 在每次 t.send() 前后记录一次工作区状态,把中间的变化记在 agent 名下。你上传的起始文件、t.send() 之后写入的验证材料都不会混进来,所以 fileChanged("src/app.ts") 只在 agent 真的动过这个文件时通过。
文件改动的采集条件
NiceEval 在 Sandbox 里另开一本私有 Git 仓库,每次t.send() 前后各记一次工作区状态,中间的变化就是 agent 改的。要让这份记录采得到,下面几条要成立:
- Sandbox 里有
git和 POSIX shell。 内置 provider 的默认镜像都带,自定义镜像要自己确认。被测项目自己是不是 Git 仓库不影响采集:这本账放在 workdir 之外的私有路径,不碰你的.git,agent 也看不到它。 - 文件写在 workdir 里。 采集范围就是
sandbox.workdir。写文件时省略targetDir/cwd,需要绝对路径就读sandbox.workdir,不要硬编码/workspace——写到 workdir 之外的文件 agent 看不见,也采不到。 - workdir 根下没有第二个 Git 仓库。 被测 checkout 直接放在 workdir 根。workdir 里出现 submodule 或另一个 clone 进来的仓库时,这一步直接报执行错误并列出路径,因为那个仓库里的普通文件改动会从记录里静默消失。确实不参与评分的仓库用
diff.ignore整体排除。 - 改动发生在
t.send()期间。 最后一次t.send()之后写入的文件算你的验证材料,不进这份记录。
.git、node_modules、__pycache__、Python 虚拟环境、常见构建产物和包管理器缓存默认排除。否则,环境准备中的一次 npm install 就可能产生几万个文件。要调整就写评估用例的 diff 字段:
/ 的匹配任意深度的同名项,带 / 的从 workdir 根匹配,末尾 / 表示目录。项目自己的 .gitignore 不参与判断,被项目忽略的文件照常记录。清单在第一次记账时冻结,agent 事后改 .gitignore 影响不了它。
单个 t.send() 窗口最多采 10,000 个路径、64 MiB 内容。超了这一步直接报执行错误,不会伪装成「一个文件都没改」让文件断言假通过。
生命周期(.setup() / .teardown())挂在 experiment sandbox 字段的 spec 上,用来做”按实验变化的环境准备”——装某个实验专属的二进制、预热、跨 attempt 载入和回存状态。它写下的文件属于环境,不会被算进 agent 产出的 diff。写法和规则见 Sandbox provider · 生命周期。
自定义 sandbox agent
createNpmCliInstaller 会在宿主机准备 npm 包,再把它送入 Sandbox。Sandbox 里不需要安装 Node.js 或 npm。完整步骤见为自定义 Sandbox Agent 安装 CLI。
setup、每次 send 和 teardown 都拿到各自作用域的反馈方法:
ctx.progress({ message, current?, total? })更新当前短期状态,适合安装 CLI、运行 Turn、读取 transcript。不要逐 token 或逐 JSONL frame 调用。ctx.diagnostic({ code, level, message, data?, dedupeKey? })保存协议退化、transcript 缺失和清理问题。它会进入终端永久事件,并作为 channel event 随 Attempt 提交进 Record。- 无法继续运行时抛出异常。runner 会把发生阶段、错误码、message、cause 和 stack 写入诊断通道,并在
niceeval.verdict通道形成erroredVerdict。
console.log/error 或写 process.stdout/stderr。它们会打散 Human dashboard,也会破坏 CI 日志顺序。
运行中看到 Sandbox 或 Adapter 错误时,终端会给出 Attempt locator:
niceeval show --run <runId> --page attempt-5TB8167MXJ30SYZCNAVRHPQ4D2 可查看结构化错误、diagnostics 和已完成的生命周期阶段。该页面读取 timing 通道,包含排队、Sandbox 启动、setup/teardown hook 里的 shell、Agent CLI 安装与启动命令、每轮 send、可关联的 OTel model/tool 与收尾。它可直接看出错误或超时发生在哪一层,以及之前的时间花在哪里。
树超过 80 个细节节点时会保留失败、慢点和首尾样本,并提示省略数量。需要逐节点审计时,从同一 Sample 的页面索引选择完整 timing route;execution route 以事件为骨架查看 agent 做了什么,有 OTel 时只把时间贴到能唯一关联的事件旁。Sandbox 创建失败可能发生在 telemetry 建立前,所以错误回顾不依赖 trace。