Virtual Embryo Challenge更新于 10-03 20:13(北京时间) / 每 5 分钟更新

← 工作原理 · 原文件 notes/architecture/13_records.md(Markdown 源文件已渲染;链接到其他文档的会跳转,指向源码的只显示路径)

13 实验记录、溯源与消融协议(G27)

用户要求(2026-10-01):一切都能通过 git 追溯;消融要有重复、要有事先写清楚的「改进」定义;所有轨迹(对话、文件、权重)都要记下来,而且分门别类,不混在一起。

本文件回答三件事:每类记录放在哪、什么格式、留多久;一个 run 怎么追溯到代码;消融怎么做、怎么判定。

1. 四类轨迹 + 两张总账

类别记的是什么位置格式谁写保留
(a) run 内轨迹Agent 在一次 run 里的全部对话、计划、代码、打分run 目录(Spark:~/vec/runs/{formal,test}/<run_id>/,虚拟机:agent/runs/<run_id>/;按 run id 查找见 agent/paths.py)JSONL、SQLite、git bundleharness / 控制器自动写run 目录永久保留;节点 work/ 与预测文件在节点结束后清理(G23)
(b) 操作日志人对 run 做过的每个动作<run_dir>/operator_log.jsonl(G23 起);更早的 run 是 OPERATOR_NOTES.mdJSONLharness 每个子命令自动写跟 run 目录走,打进证据包
(c) 开发日志每个 G 任务做了什么、为什么notes/reports/dev/;拍板在 notes/changelogs/decisions.tsvMarkdown、TSVClaude(审查子 agent 报告后)git 永久
(d) 官网提交交了哪份预测、拿了多少分notes/changelogs/submissions.tsvTSV,只追加scripts/record_submission.pygit 永久
运行登记表每个 run 的目的、假设、代码版本、配置、结果、官网分notes/changelogs/runs.tsvTSV,只追加harness launch / package、record_submission(Part B);python -m agent.records backfillgit 永久
迭代报告每个 run / 每次提交的中文复盘notes/reports/runs/<date>_<run_id>.mdMarkdown报告 Agent(G28)git 永久

分开的原则:(a) 是 Agent 自己的东西,只在 run 目录里,锁定后人不读中间结果;(b) 是人的动作,和 (a) 物理上分文件,证据包里也分文件;(c) 是开发期(锁定前)的工程记录,只在主仓库 notes/,永远不进 Agent 上下文;(d) 和登记表是结果台账,只追加不改写。四类之间只用 run_id、G 编号、ledger 行号互相引用,不复制内容。

2. (a) run 内轨迹

搜索模式(mode: search)一个 run 目录里:

路径内容
nodes/<id>/{researcher,engineer,analyst,reviewer}.jsonl每个节点、每个角色一份 LLM 会话轨迹(opencode JSON 事件流);同名 .stderr 是 CLI 错误输出
nodes/<id>/PLAN.json、ANALYSIS.json、METHOD.md、DELTA.md、analysis/diff.patchResearcher 计划、Analyst 结论、方法说明、与父节点的分数差、代码改动
nodes/<id>/exec*、promo_seed*、final_*执行 / 复测 / 终选的结果文件(大文件在节点结束后清理,保留日志和 json)
archive.sqlite搜索树:节点、分数、各把尺子、事件(晋级、终选)
programs.git每个节点的程序是一次 commit;证据包里是 programs.bundle
research_log.jsonl文献检索服务(lit-search,G17)的每次查询
scoring_log.jsonl打分服务的每次调用(谁、哪道题、哪半真值、分数)
egress_log.jsonl出网代理的每次连接(只放行 LLM 域名)
controller.log、service.log、heartbeat.json控制器与服务日志
config.lock.json、run_meta.json锁(配置、代码哈希、评分器指纹、模型 id)与运行状态
final/SELECTION.md控制器写的终选说明(无人工输入)
evidence/打包证据:MANIFEST.json、trajectories_index.json、lineage_trajectories.tar.gz(胜者祖先链上全部节点的轨迹,含跨 run 接续导入的)、各日志副本

单 Agent 模式(mode: agent):trajectory.jsonl(整段会话)、prompts/、workspace/(含 Agent 自己的 git、experiments.tsv、final/SELECTION.md)、evidence/。

保留:run 目录不删。磁盘紧张时只删节点 work/ 和预测 .h5ad(G23 已实现,日志与轨迹保留)。正式提交时按 prepare_submission.py 选证据子集(单文件 ≤ 200 MB,全队 600 MB 上限);没上传的部分仍在 run 目录。

3. (b) 操作日志

  • G23 起,harness.py 每个作用于 run 的子命令(launch、resume、package、verify 等)都往 <run_dir>/operator_log.jsonl 追加一行:时间、argv、主机、用户、pid、systemd 单元。
  • 人工动作若改动了 run 受保护的文件,run 标记 tainted(G23;G29 改为写入时登记哈希的只追加台账)。
  • 更早的 run(run1)用手写 OPERATOR_NOTES.md。
  • 操作日志和 Agent 轨迹不在同一文件;证据包里各自一份。

4. (c) 开发日志

  • 每个 G 任务验收后,Claude 把子 agent 的最终报告整理成 notes/reports/dev/<YYYY-MM-DD>_<G-id>.md(日期 = 验收日),写清:做了什么、验收结果、遗留问题、提交 commit、对应 decisions 行。
  • G1–G29 的补录只做索引(一行一个任务,链到任务书、commit、decisions 行),见 reports/dev/README.md。
  • 拍板(为什么、否决了什么)仍只写 decisions.tsv;开发日志只引用行号,不重复。
  • 开发日志在主仓库 notes/,run 的沙箱读不到主仓库 notes/(G1、G4 的隔离验收项),所以不会进 Agent 上下文。

5. (d) 官网提交与运行登记表

提交账本 submissions.tsv:上传时一行,出分时再追加一行 score_of=<上传行号>,不改旧行(G8)。

运行登记表 runs.tsv(G27,列见 agent/records/README.md):

何时谁写status
launch 写完锁之后harness.py(Part B,调用 append_start)started
package 打完证据之后harness.py(Part B,append_end)ended:<state>:带节点数、最好排序分、胜者在每把尺子上的分
官网出分record_submission.py --score(Part B,append_score)official:<上传行号>
G27 之前的 runpython -m agent.records backfill --sparkbackfill:<state>;目的写「[回填] + 配置文件开头注释」
  • 配置文件必须有 purpose:(这次 run 为了什么)和 hypothesis:(预期结果);可选 ablation_of:(基线 run_id 或消融组名,如 G21)和 changed_factor:(这一臂改了什么)。缺字段的可提交 run,launch 拒绝启动(Part B 调 check_config)。
  • 只追加、不改写;更正就追加新行。一个 run 的当前状态 = 按文件顺序把它的各行叠起来(后写的非空格子覆盖前面的;官网分按题目收集)。
  • Spark 克隆上 harness 写的是 Spark 那份 runs.tsv;VM 上用 python -m agent.records merge --ssh spark:vec/2026_virtual_embryo/notes/changelogs/runs.tsv 合并后再提交(逐行去重)。

看板「实验登记」页直接读这张表(每 5 分钟)。

6. git 溯源(计划:Part B + G29)

  1. 可提交 run 的 launch 在锁定的 commit 上建附注 tag run/<run_id>(VM 仓库建,sync_spark.sh 推到 Spark 裸仓库);锁里记 git_commit 与 git_tag,登记表同步记两列。
  2. Spark 克隆必须和锁定 commit 一致,否则 launch 拒绝(不再允许「VM 上改了、Spark 上跑的是另一版」)。
  3. G29:launch 时为每个 run 建只读的代码检出(锁定 commit 的完整副本),run 期间读 prompts、ideas、knowledge、代码都从这份检出读,sync_spark.sh 更新主克隆不再影响在跑的 run。
  4. dirty(有未提交改动)的 run 不可提交;登记表 git_commit 后缀 +dirty。
  5. 追溯路径:官网分 → submissions.tsv 行 → run_id → runs.tsv(commit、tag、config 哈希)→ git show run/<run_id> → 锁里的文件哈希逐一可核。

G27 之前的 run 没有 tag,用锁里的 harness_git_sha 追溯(backfill 已写入 git_commit)。

7. 模型权重(计划:Part B,建在 G29 的 ARTIFACTS.json 上)

  • 候选程序可以在 solution/ 或节点工作目录写训练好的权重;G29 要求 >20 MB 的权重在 solution/ARTIFACTS.json 里声明(路径、sha256)。
  • 保留:晋级复测的前 5 名、最终胜者及其整条祖先链的权重,复制到 <run_dir>/weights/<node_id>/,旁边一份清单(文件、大小、sha256、产出节点、框架)。
  • 每个 run 设上限(配置 weights.cap_gb,默认 20 GB);超了先删最早的非祖先链权重。
  • 证据包只放清单(小于阈值的权重才放本体);权重本体留在 run 目录。

8. 消融协议

定义:一次消融 = 只改一个因素(changed_factor),其他配置、种子集合、预算都相同;每一臂 ≥ 3 次重复 run(不同 search_seed,各臂用同一组 seed)。各臂在登记表里用同一个 ablation_of(基线 run_id 或组名)连起来。

流程:

  1. 写配置:每个 run 都有 purpose、hypothesis、ablation_of、changed_factor(G21 的 12 个配置已按此生成)。
  2. 看结果之前把判定规则写进 decisions.tsv(预注册),之后不改。
  3. 跑完、提交、记分后:python scripts/ablation.py summary <组名或 run_id…> [--by changed_factor] [--metric all]。
  4. 把输出结论写进 decisions.tsv 新行,引用登记表行。

「改进」的事先定义(agent/records/stats.py):A 臂比 B 臂有改进,当且仅当

  • 每臂 n ≥ 3(否则输出「样本不足」,不下结论);
  • 均值差 mean(A) − mean(B) 大于噪声阈值 T:T1 题 2 分、T2 题 1 分(本地尺子单次打分噪声,k014 / agent/prompts/analyst_spec.md;T3 未测,暂按 1 分);
  • 均值差的 bootstrap 95% 置信区间不含 0(两臂各自有放回重抽,10000 次,百分位区间,随机种子 0,可复现)。

均值差够大但区间含 0 → 「未确立」;均值差 ≤ T → 「不超过噪声」。官网分和每把本地尺子都单独算一遍(--metric all)。

本地尺子可信度:全部已提交点(登记表里有官网分的 run)上,每把尺子分与官网分的 Spearman ρ(处理并列名次),bootstrap 95% CI(重抽 1000 对);不到 3 个点不计算。这是 G21 判定规则 ② 要的数。

G21 的预注册判定(decisions.tsv 第 74 行,脚本对 ablation_of = G21 的 run 自动套用):① 12 小时 run 的目标 = 官网均分最高的臂;前两臂均分差 < 1 分时,选本地尺子标准差平均更小的那臂;③ 所有臂官网均分都 < 50 → 不开 12 小时 run,先回到方法与尺子问题。

9. 保留期汇总

东西保留
run 目录(轨迹、存档、日志、锁、证据)永久(磁盘紧张时只删节点 work/ 与预测文件)
权重晋级前 5 + 胜者 + 祖先链,单 run ≤ 20 GB(Part B)
runs.tsv、submissions.tsv、decisions.tsv、experiments.tsvgit,永久,只追加
notes/reports/(runs/、reviews/、dev/)git,永久
run/<run_id> tag永久,不删不移
看板缓存(~/vec/dashboard/)可随时重建,不算记录