Skip to main content
你在 Experiment、评估组和评估用例上都写了 .before(),又给 Agent 配了安装步骤。真正跑起来之前,你想确认这些步骤最终按什么顺序执行、每一步的参数是什么,而不是等 Sandbox 建好、装了五分钟依赖之后才发现顺序不对。 exp --dry 告诉你会跑哪些评估、多少次。niceeval debug 更进一步:它列出某一条评估在 Sandbox 里的完整准备、安装、执行和收尾步骤,不创建任何 Sandbox,也不调用模型。

选定一个 Experiment 和一条评估用例

debug 一次只看一个 Experiment 下的一条评估用例:
两个参数都必须只命中一个。精确 ID 优先;前缀命中多个时,CLI 会列出候选并停止,你从中复制完整 ID 再运行一次。 评估用例只能从这个 Experiment 已经选中的范围里找。选中评估组里的一条时,计划不会把同组其它评估用例加进来,但仍会显示评估组贡献的准备步骤。

按顺序读计划

输出用分层的框展示:最外层是 Experiment,往里依次是每个 Attempt 和它的各个生命周期步骤。每个 sandbox.before 步骤会显示:
  • 这一步由谁声明(owner)和它的 ID(action);
  • 它最终的执行序号,以及属于哪条评估用例;
  • 你填写的 changeFrequency 数值、它从哪里来、对应哪个 preset;
  • 它依赖哪些步骤、为什么排在这个位置,以及它在哪一层执行(occurrence,当前固定为 attempt);
  • Provider 能不能缓存这一步,以及运行时还没有检查的缓存状态;
  • 这一步能否从缓存恢复(cache.state 的 declared、cumulative、providerCoverage 和 barrier)。
execution order 是真实运行时的顺序,不是你在代码里写下的顺序。排序规则是:依赖总是先执行;几个步骤都可以执行时,changeFrequency 数值小的先执行;数值也相同时,按声明者和声明先后决定。所以评估组里很少变化的步骤,可以排在 Experiment 里经常变化的步骤前面。

判断哪些步骤能从缓存恢复

  • declared 是这一步自己声明会改变的状态。
  • cumulative 包含它和它之前所有准备步骤会改变的状态。
  • providerCoverage 说明 Provider 实际能恢复的范围。
  • barrier 不是 none 时,输出还会给出 barrierActionId,指出第一个无法缓存的步骤。原因可能是它的状态声明是默认的 all、是 opaque,或者 Provider 不支持。这一步和它之后的所有步骤都会真实执行。

确认命令和参数

写死的命令步骤会显示命令的形状。普通的 callback 标为 OPAQUE,因为它只能在运行时执行,debug 看不到里面做了什么。 环境变量只显示变量名和摘要,stdin 只显示摘要和字节数。凭据值、stdin 原文和不安全的远端地址不会出现在终端或 JSON 输出里。

让工具读取计划

JSON 和终端输出是同一份计划,只是去掉了框线。每个步骤带 declarationOrder、executionOrder、changeFrequency、dependencies、occurrence 和 cache。 cache.state 总会给出 declared、cumulative、providerCoverage、barrier,有 barrier 时再给出 barrierActionId;能确定的步骤还会给出 cache.prefixIdentity。debug 不读取运行时的缓存,所以 cache.lookup 与 cache.runtime.finalKey 总是 not-probed,cache.runtime.status 总是 pending。 debug 只接受 --json。预算、重跑、并发这些运行参数对它不适用。

它不会创建任何资源

debug 不运行 before callback、test、after、ensure 或 Provider 的收尾函数,也不创建 Run、锁、Sandbox 或构建任务,不写入结果文件。 它会加载你的 Experiment 定义并执行 evals 选择函数。Provider 在规划时也可能读取本地文件、调用只读 CLI 或查询远端服务,所以仍然只在可信项目里运行它。 要确认跑哪些题、每题跑几次,用运行前确认跑哪些、跑几次。真实运行失败后需要进入现场时,用保留 Sandbox 现场排查问题。