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
詳細
デュエリング・オートリサーチ・ループ
2つのレーンが同じ目標に並行して取り組み、同じ指標を競います。デフォルトでは、古典的/アルゴリズム的なレーンとML/学習ベースのレーンで競います(レーン名はユーザーが指定します)。各レーンは roles/TrackAgent.md に沿って、分析を優先した独自の反復を自分のレーン内に限定して進めます。毎ラウンド、両レーンは共有の duel_log.md スコアボードに結果を記録し、レーンの境界を越えてアイデアを借りることもできます。ただし、各レーンは自分のレーン内で作業します。フィードバック信号は、共有評価における共有の <metric> です。古典的なレーンが勝てば、それが正当な結果です。レーンはコードの配置場所を混在させられます。codebase レーンは既存のリポジトリファイルを編集し、sandbox レーンは独自のコードを作成します。また、評価の同等性を確認するゲートによって、スコアを比較可能に保ちます。
あなたはオーケストレーターです。各ラウンドで両方のレーンを進め、スコアボードを更新し、両レーンが誠実に取り組むようにしてください。ループの実行開始後は、許可を求めるために中断しないでください。
使用するタイミング
1つの指標をめぐって、実質的に異なる2つのアプローチを競わせ、同じ評価に照らして両者の妥当性を保つ場合に使用します。たとえば、古典的手法と学習ベースの手法、2つのモデルファミリー、2つのクエリ戦略の比較です。デフォルトでは、両方のレーンを並行して起動し、スコアボードを通じてレーン間でアイデアを借りられるようにします。レーンの改善が行き詰まった場合は、レーン内でより大胆な変更を促すか、ログから新しいアイデアを借りるよう促してください。単一のアプローチを調整する場合(単一レーンのループを使用します)や、完成済みの2つのものを一度だけ比較する場合には使用しません。
登場する役割(すべてこのフォルダー内):
roles/TrackAgent.md— レーンごとに1つずつ起動する、レーン担当のリサーチャーです。
セットアップ
バインディングを対話形式で解決します。作業ディレクトリに loop.run.yaml がある場合は読み込み、値を1行で確認して、ループに進みます。ない場合は、Claude Code(AskUserQuestion ツールが利用可能な場合)では各バインディングのもっともらしい値を推定して推奨オプションとして提示します。それ以外のホストでは、それぞれを引用符付きのプレーンテキストの質問として尋ねます。その後、loop.run.yaml(形式は examples/run.example.yaml)を書き込み、ほかのファイルを作成する前に値を確認します。
ホストは 並列起動するか、機能を縮退させるか も決定します。Claude Code ではレーンごとに実際の Agent を起動し、2つのレーンを 並列で 実行します。それ以外の場合は、roles/TrackAgent.md をインラインで採用し、レーンを順次実行します。
共有バインディング(両方のレーンで同一。誠実さの基準となるもの):
| バインディング | 意味 | デフォルト | 推定方法 |
|---|---|---|---|
<metric> | 両方のレーンが競う単一の指標。対決のグラウンドトゥルース | — | 尋ねます。実行ログを調べ、出力されたスコアを探します |
<metric_direction> | minimize または maximize | — | 指標の性質(損失か精度か)から判断します |
<gate> | 実行予算の単位:time または epochs | epochs | 成果物のランナー |
<budget> | 1回の実行あたりのエポック数(または gate: time の場合は分数) | 5 | — |
<sandbox_root> | スナップショット、台帳、対決ログの保存先 | ./sandbox | — |
<iter_strategy> | snapshots または branches(スナップショットを推奨。1つのブランチで2レーンを動かす方法がもっともシンプルです) | snapshots | — |
レーンごとのバインディング(レーンは2つで、デフォルト名は 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を実行します。2つのcodebaseレーンのeditable_filesは、互いに 重複してはいけません。sandbox— 実装は存在せず、リポジトリにも追加しません。レーンはentryを使って<sandbox_root>/<lane>/iter<N>/内にコードを 作成して実行します。
既存モデルが1つあるリポジトリでの典型的な対決: 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 レーンの反復ディレクトリには、その反復で使うレーンの 実際のコード が保存されます。維持された反復は、次の反復の開始点として引き継がれます。
ループ(対決)
各ラウンドで、両方のレーンが1イテレーションずつ進みます。Claude Codeでは、2つのTrackAgentを並列で起動します(1ターンでAgentを2回呼び出します)。それ以外の場合は、レーンA、次にレーンBの順でインライン実行します。1つのトラックは、そのレーン内に限定して分析を最初に行う1イテレーションです。実施するのはroles/TrackAgent.mdに記載された8つのステップです。ラウンド1は各レーンのベースラインです(codebaseレーンは変更を加えず、sandboxレーンは初期実装をiter1/に作成します)。各ラウンドでレーンごとに変更は1つだけとし、各メトリクスの差分をその変更に帰属できるようにします。
このチェックリストをコピーし、各ラウンドで項目にチェックを入れてください。
- 状態 — ラウンドNを記録し、
duel_log.md(両レーンの最新投稿とスコアボード)を読みます。 - 各レーンを進める — 各レーンのレーンバインディングと、共有の
<metric>/<metric_direction>/<gate>/<budget>、およびduel_log.mdを渡して、レーンごとにTrackAgent(roles/TrackAgent.md)を実行します。 - 投稿を記録 — 各レーンは、そのラウンドの記録を
duel_log.mdに追記します(最良の<metric>、重要な発見を1つ、行き詰まった点があればその内容、もう一方のレーンが取り入れられるアイデアを1つ)。 - スコアボード —
## Scoreboardを更新します。各レーンの最良の<metric>と現在のリーダー(<metric_direction>に基づく)を記載します。任意で、次のラウンド向けのレーン間共有の提案を1つ示します。 - 続行 — 次のラウンドに進みます。続けるかどうかを尋ねるために中断してはいけません。
レーンごとに起動するか、インライン実行に切り替えます。 ホストが対応している場合は、レーンごとに独立したTrackAgentを実際に起動します(Claude Codeでは、レーンごとにAgentを1つ起動し、並列処理のため両方を1ターンで起動します)。それ以外の場合は、roles/TrackAgent.mdの内容をインラインで適用し、レーンを順番に実行します。各TrackAgentは自身のレーン内に限定され、イテレーションの要約をオーケストレーターに返します。
台帳
台帳は2種類あります。各レーンの実験を記録する**レーンごとの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>を最適化します。それ以外の条件で比較してはいけません。評価やメトリクスを変更しないでください。これらは対決の公正さを保つ共有のグラウンドトゥルースです。 - 各メトリクスの差分をその変更に帰属できるよう、各ラウンドでレーンごとに変更は1つだけにします。
- 新しいパッケージをインストールしたり、プロジェクトにない依存関係を追加したりしないでください。ヘルパーコードは標準ライブラリのみを使用します。
- 各実行の出力はそのレーンの実行ログにリダイレクトします。
teeは使用しないでください。サンドボックスは自己完結させ、../で外部に出てはいけません。 - 方針を尋ねるためにループを中断しないでください。一度開始したら、手動で中断されるまで両方のレーンのイテレーションを続け、最終的な勝者ではなく現在のリーダーを報告してください。