关于 dueling-autoresearch
用于机器学习实验的双路线自动研究技能,让两种不同方法围绕同一指标并行迭代。它通过共享评估集、记分板和每轮单项改动来比较结果,并支持代码库与沙盒路线。
主要功能
- 01两条路线围绕同一指标竞赛
- 02共享评估与结果记分板
- 03代码库或沙盒式路线
- 04每轮单项改动与实验记录
- 05根据运行环境并行或顺序执行
适用场景
- 01比较经典算法与学习型方法
- 02在同一留出集上测试两种策略
- 03让两条研究路线交换思路
- 04追踪实验结果与当前领先路线
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gaasher/ agent-loop-skills --skill dueling-autoresearch安装后在 Claude Code 中输入/dueling-autoresearch确认已加载。
附带文件examples/run.example.yamlroles/TrackAgent.md
详细介绍
对决式 Autoresearch 循环
两条赛道并行处理同一个目标,并角逐同一项指标——默认分别采用经典/算法方案和 ML/学习式方案(赛道名称由用户指定)。每条赛道都通过 roles/TrackAgent.md 独立执行分析优先的迭代,仅限于自己的赛道。每轮两条赛道都会将结果发布到共享的 duel_log.md 记分板上,并可跨越赛道边界借鉴思路——但各自始终留在自己的赛道中。反馈信号是基于共享评估得出的共享 <metric>:如果经典赛道胜出,那就是真实结果。赛道支持混合代码位置——codebase 赛道会编辑现有仓库文件,sandbox 赛道会编写自己的代码——并设有评估一致性关卡,确保分数可比较。
你是协调者:每一轮推进两条赛道、更新记分板,并确保双方如实报告。循环启动后,不要暂停等待许可。
适用场景
当你希望针对一项指标,让两种真正不同的方案展开竞赛,并通过同一评估确保结果可靠时,请使用此方法,例如经典方案与学习式方案、两类模型或两种查询策略。默认同时启动两条赛道,并让记分板推动跨赛道借鉴思路;如果某条赛道陷入停滞,就推动它在本赛道内进行更激进的改动,或从日志中借鉴新思路。不适用于调整单一方案(请使用单赛道循环),也不适用于对两个已完成的方案进行一次性比较。
参与角色(均在此文件夹中):
roles/TrackAgent.md— 每条赛道对应的研究者,每条赛道实例化一次。
设置
通过交互方式确定绑定项。如果工作目录中存在 loop.run.yaml,则加载该文件,用一行确认其中的值,然后跳转到循环。否则:在 Claude Code 中(有 AskUserQuestion 工具可用),推断每个绑定项可能的值,并将其作为推荐选项呈现;在其他宿主中,则针对每项提出带引号的纯文本问题。随后写入 loop.run.yaml(格式:
examples/run.example.yaml),并在创建任何其他文件前确认这些值。
宿主还决定采用启动或降级策略:在 Claude Code 中,为每条赛道启动一个真正的 Agent,让两条赛道并行运行;在其他宿主中,则内联采用 roles/TrackAgent.md,并让赛道按顺序运行。
共享绑定项(两条赛道相同——诚实性基准):
| 绑定项 | 含义 | 默认值 | 推断方式 |
|---|---|---|---|
<metric> | 两条赛道竞逐的唯一指标;对决的真实依据 | — | 提出问题;扫描运行日志,查找打印出的分数 |
<metric_direction> | minimize 或 maximize | — | 根据指标性质判断(损失值还是准确率) |
<gate> | 运行预算单位:time 或 epochs | epochs | 根据产物的运行器确定 |
<budget> | 每次运行的轮数(若 gate: time,则为分钟数) | 5 | — |
<sandbox_root> | 快照、账本和对决日志的存放位置 | ./sandbox | — |
<iter_strategy> | snapshots 或 branches(推荐使用 snapshots——两条赛道共用一个分支最简单) | snapshots | — |
各赛道绑定项(两条赛道,默认名称为 classical 和 learned)。每条赛道都有一个 code_location,用于决定它需要哪些其他字段——绝不要向代码库添加代码:
| 字段 | 含义 | 适用条件 |
|---|---|---|
name | 赛道名称 | 始终需要 |
code_location | codebase 或 sandbox | 始终需要 |
run_cmd | 要运行的现有入口点,例如 python train.py | 若为 codebase |
editable_files | 此赛道可以编辑的现有仓库文件 | 若为 codebase |
entry | 从 <sandbox_root>/<lane>/iter<N>/ 内运行的命令,例如 python run.py | 若为 sandbox |
codebase——赛道对应现有代码:编辑其editable_files并运行run_cmd。两条codebase赛道的editable_files必须互不重叠。sandbox——不存在实现代码,且不会向仓库添加任何代码:赛道通过entry在<sandbox_root>/<lane>/iter<N>/内编写并运行自己的代码。
一个仓库中只有一个现有模型时的典型对决: learned 赛道采用
codebase(编辑model.py/config.yaml,运行train.py);classical 赛道采用sandbox(在<sandbox_root>/classical/iter<N>/下编写自己的代码)。不会向代码库添加任何内容,但 classical 赛道仍会进行构建和迭代。
评估一致性门槛(诚实性基准)。 开始前,确认两条赛道都针对同一留出集,以相同方式计算并报告 <metric>,以确保分数可比较——说明每条赛道如何输出该指标(例如,两条赛道都在运行日志中打印 <metric>:)。如果不一致,先修正;否则对决毫无意义。如果 gate: time,则为每条赛道编写一个 run_with_timeout.sh 包装脚本(timeout $(( <budget> * 60 )) <entry-or-run_cmd> "$@")。
初始化沙箱(确认后):
<sandbox_root>/
├── duel_log.md ← shared channel + scoreboard (## Scoreboard, ## Round log; headers only)
├── <laneA>/results.tsv ← lane A ledger, header only
└── <laneB>/results.tsv ← lane B ledger, header only
每条赛道每次迭代的工作内容都存放在 <sandbox_root>/<lane>/iter<N>/(analysis/、results/、
运行日志)。codebase 赛道的迭代目录还会保存 code_snapshot/(用于回退的变更前副本);sandbox 赛道的迭代目录则保存该赛道本次迭代的实际代码(保留的迭代会作为下一次迭代的起始点)。
循环(对决)
每个轮次都会让两条赛道各推进一次迭代。在 Claude Code 中,并行启动两个 TrackAgent(一个回合,调用两次 Agent);否则,先内联运行赛道 A,再运行赛道 B。一个赛道的迭代是在该赛道内完成的一次分析优先迭代,包含 roles/TrackAgent.md 中的 8 个步骤。第 1 轮是每条赛道的基线(codebase 赛道保持原样;sandbox 赛道在 iter1/ 中编写初始实现)。每条赛道每轮只做一项更改,这样每个指标变化都可归因。
复制此清单,并在每轮勾选:
- 状态 — 记录第 N 轮;阅读
duel_log.md(两条赛道最新的帖子和记分板)。 - 推进各赛道 — 为每条赛道运行一个 TrackAgent(
roles/TrackAgent.md),并提供该赛道的绑定信息、共享的<metric>/<metric_direction>/<gate>/<budget>以及duel_log.md。 - 记录帖子 — 每条赛道都在
duel_log.md中追加本轮条目(最佳<metric>、一项关键发现、任何失败方向,以及一个其他赛道可以借鉴的想法)。 - 记分板 — 更新
## Scoreboard:列出每条赛道的最佳<metric>和当前领先者(依据<metric_direction>);也可以标出一项供下一轮借鉴的跨赛道建议。 - 继续 — 进入下一轮;绝不暂停并询问是否继续。
每条赛道都要启动,否则降级处理。 在宿主支持的情况下,为每条赛道启动一个真正隔离的 TrackAgent(Claude Code:每条赛道启动一个 Agent,并在同一回合并行启动)。否则,内联采用 roles/TrackAgent.md 并按顺序运行各赛道。每个 TrackAgent 都只能在自己的赛道内操作,并向编排器返回其迭代摘要。
记录表
两种记录表:每条赛道各自的实验记录 results.tsv,以及共享的 duel_log.md 记分板和每轮帖子。
每条赛道的 <sandbox_root>/<lane>/results.tsv(以制表符分隔,自由文本中不得使用逗号):
iter <metric> status analysis_summary description
1 0.6320 keep baseline; classical features, logistic head baseline
2 0.6610 keep added HOG features; per-class gains on textured classes add HOG feature extractor
status ∈ {keep、discard、crash}(发生崩溃时,<metric> 为 0.000000)。
共享的 <sandbox_root>/duel_log.md — 记分板和每轮帖子:
## Scoreboard
round classical_best learned_best leader
1 0.6320 0.6480 learned
2 0.6610 0.7050 learned
## Round log
### Round 2
- **classical** — best 0.6610 (this iter 0.6610). Finding: HOG helps textured classes
(results/per_class.txt). Dead end: raw-pixel kNN plateaus. Borrow: learned's augmentation
could expand classical's training set.
- **learned** — best 0.7050. Finding: BN fixed conv2 saturation. Dead end: dropout hurt at this
budget. Borrow: classical's HOG features as an aux input channel.
报告当前领先者(依据 <metric_direction>),不要宣布最终获胜者——落后的赛道仍有机会反超。不要跟踪 results.tsv、duel_log.md 和 iter*/(不要提交它们)。
约束
- 绝不向代码库添加代码。
codebase赛道只能编辑自己的<editable_files>;sandbox赛道只能在<sandbox_root>/<lane>/中操作。各赛道不得触碰对方的文件——其他所有文件都是评估的真实依据。 - 留在自己的赛道。 赛道可以借鉴想法,但绝不能转变为另一种方法——即使借鉴了学习型赛道的损失或目标设计,传统方法赛道仍须保持传统方法。
- 指标相同,评估相同。 两条赛道都要在相同的留出集上优化
<metric>,且采用相同的计算方式;否则绝不比较。不要修改评估流程或指标——它们是让这场对决保持公正的共同真实依据。 - 每条赛道每轮只做一项更改,这样每个指标变化都可归因。
- 不要安装新软件包,也不要添加项目所缺少的依赖;辅助代码只能使用标准库。
- 将每次运行的输出重定向到该赛道的运行日志;绝不使用
tee。沙盒必须自成一体——不得使用../跳出。 - 不要暂停循环以寻求指示;启动后,应持续让两条赛道迭代,直到被手动中断,并报告当前领先者,而不是宣布最终获胜者。