exp
跑实验并记录 provenance:先写假设和成功判据,跑时记录 git hash、完整 resolved config 和 seed,跑完把结论写回 research-log.md 并标 [AI-DRAFT] 与 [source: run_id]。任何要跑训练/评测/对比的场景都走这里。
SKILL.md.claude/skills/exp/SKILL.md
GitHub跑实验并记录 provenance
实验:$ARGUMENTS
为什么
allowed-tools里是完整的Bash:本 skill 要真的启动训练/评测,长任务还要后台跑、 查日志,命令形态事先不可枚举。allowed-tools是「本轮免批准的范围」,不构成硬限制, 收窄它只会让每一步都卡权限确认,并不会真的挡住什么。真正的护栏在.claude/hooks/protect_paths.py和下面的硬约束里。
第 1 步 跑之前:先写判据
先写判据再跑,是这个 skill 存在的全部理由。 先跑再解释,人一定会把任何结果讲成故事。
run_id 格式固定 YYYYMMDD-<slug>(slug 小写英文加短横线),例如 20260722-attn-cache-seed1。
在 research-log.md 末尾追加一节(此时实验还没开始)。字段顺序照抄,不要改名:
## 2026-07-22 run_id: 20260722-<slug>
- 假设: <一句话,可证伪。例:把 lr 降到 1e-4 能让 loss 在 5k step 内不再发散>
- 成功判据: <具体数值/条件。例:step 5000 时 train_loss < 2.0 且无 NaN>
- 失败判据: <什么结果算假设被证伪>
- 对照: <baseline 是哪个 run_id;没有就写「无对照,仅探索」>
- git hash: <跑之前留空,第 2 步填>
- 结果: <跑完填>
- 结论: <跑完填>
判据写不出具体数字,就说明这个实验还没想清楚——先想清楚再跑。
第 2 步 跑之前:检查可复现性
git status --short
git rev-parse HEAD
工作区不干净(git status 有输出)时,先警告用户:
工作区有未提交改动,本次结果将无法复现(跑的代码和任何 commit 都不对应)。 建议先 commit 再跑。要继续吗?
用户坚持就继续,但必须在 run 记录里标 dirty: true 并列出脏文件。
第 3 步 跑:把 provenance 落到输出目录
产物目录一律是 experiments/(不要用 results/ runs/ outputs/),每个 run 一个独立目录
experiments/<run_id>/。
只写新建的 run 目录,绝不修改已有 run。 protect_paths.py 对 experiments/** 的规则是
「文件已存在才阻断,新建放行」,所以往新 run 目录里落 provenance 是允许的;一旦你去写一个
已经存在的文件,hook 会直接 exit 2 挡下来——那不是配置错误,那是你走错了路,换个新 run_id。
跑之前先往新目录里写:
git rev-parse HEAD的结果,以及是否 dirty- 完整的 resolved config —— 展开之后的最终配置内容,不是 config 文件路径, 也不是命令行片段。路径会随代码变,展开后的配置才是这次真正跑的东西。
- seed(所有相关的:数据、初始化、框架全局)
- 完整启动命令
- 环境:
python3 --version,关键库版本
然后启动。长任务用后台运行并说明怎么看日志,不要傻等。
第 4 步 跑完:派 result-analyst 读日志,再写结论
派 result-analyst subagent 去读日志和输出文件,不要自己读。 训练日志动辄几千行,
拉进主 context 就再也清不掉了;而且它是 fresh eyes,不知道你希望看到什么结果。
派给它的 prompt 要写明:run 目录路径、成功判据原文、要对比的 baseline run_id(如果有)。
要求它回报:指标名 = 值 + 每个数字来自哪个文件,以及判据逐条「达成 / 未达成」。
拿到它的回报后,把结论补进 research-log.md 里本次那一节(只补自己这节的空字段,
不碰任何别的条目):
- git hash: <hash>(dirty: false;dirty 时列出脏文件)
- 结果: <指标名 = 值,出处 experiments/<run_id>/metrics.json>
- 结论: [AI-DRAFT] <假设成立 / 被证伪 / 判据外的意外现象> [source: 20260722-<slug>]
然后提示用户:
以上结论标的是
[AI-DRAFT]。你人工核过原始输出之后,把它改成[HUMAN-VERIFIED]。
硬约束(违反即本次实验作废)
- 不得口算或估算任何指标。 不许从日志里心算平均值、不许目测曲线报数字、 不许把「大概 0.85」写成 0.85。
- 不得报告没有落盘文件支撑的数值。 每个数字要能指到
experiments/<run_id>/下的某个文件。 - 不得修改或删除
research-log.md里已有的条目,只能 append。写错了就新增一条更正, 注明更正的是哪条。 - 不得复用别的 run 的输出目录。 覆盖等于毁掉那次实验的证据。
- 不得在工作区脏的情况下静默开跑,必须先警告。
- 不得把
[AI-DRAFT]自行升级成[HUMAN-VERIFIED]。 只有用户能升。
需要一个还没有的指标时怎么办(合法路径)
不要绕过约束 1 自己算。正确做法:
- 写一个脚本来算,放
explorations/(沙箱目录,随便试)。 - 脚本要能从
experiments/<run_id>/的产物读入、把结果写成文件。 - 脚本进版本控制(
git add),这样这个数字以后可以被重新算一遍。 - 跑脚本,报告它输出的文件里的数字。
脚本稳定下来、要反复用了,再从 explorations/ 提升为正式脚本。
experiments/ 里已有的东西是只读的(新 run 目录可以建、可以落 provenance),
任何时候都不要往里手写数字——数字只能由脚本产生。