1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【徹底解説】autoresearch と Bilevel Autoresearch —— AIエージェントの「ループエンジニアリング」を最深部まで分解する

1
Posted at

「プロンプトを書く時代」から「ループを設計する時代」へ。
本記事では、Andrej Karpathy の OSS autoresearch(通称 Karpathy Loop)と、そのメタ版である論文 Bilevel Autoresearch: Meta-Autoresearching Itself(arXiv:2603.23420) を、アーキテクチャ・アルゴリズム・実験結果・実装パターン・限界まで一気に分解します。


0. TL;DR(3分で要点)

論点 結論
ループエンジニアリングとは 「1回の推論品質」ではなく「反復と行動の積み上げ」を設計する技術。Verifier / State / Stop条件 の3点セットが必須
autoresearch(Karpathy Loop) 630行・3ファイル・MIT。エージェントが train.py だけを書き換え、5分学習 → val_bpb で採点 → 良ければ commit / 悪ければ git reset「ラチェット(爪車)」 構造
実績 約700実験で20件の改善を採用、GPT-2品質までの学習時間を 2.02h → 1.80h(-11%)
Bilevel Autoresearch 内側ループ(タスク最適化)の上に外側ループ(探索メカニズム自体の最適化)を載せる二層構造
キモ 外側ループが探索メカニズムを Python コードとして生成し、実行時に注入する(プロンプト調整ではない)
効果 同一LLMのまま、val_bpb 改善量が -0.009 → -0.045(約5倍)
なぜ効く LLMの事前分布(priors)が作る決定論的な探索パターンを破壊し、避けていた方向(バッチサイズ「減少」)を強制探索させたから
実務への含意 自動で不合格を出せるゲート(Verifier)がある仕事なら、ML以外にも全部載る

1. なぜ「ループ」なのか:プロンプトの敗北ではなく降格

まず用語を整理します。

  • プロンプト(Prompt):1つの指示。次に何をするかはあなたが決める。
  • ループ(Loop):1つのゴール。モデルが計画し、実行し、自分の結果を検査し、繰り返す。反復はループが担う。
[Prompt]  You → Model → You → Model → You → ...   (人間が律速)
[Loop]    You → Goal → (Model ⇄ Verifier) × N → Artifact   (検証が律速)

ここで極めて重要な前提が一つあります。

ループがコストに見合うのは、仕事が「測定可能」なときだけ。

測れないものにループを回すと、エージェントは自分に同意し続けるだけの高価な独り言マシンになります。これが後述する「Verifier がすべて」という話の出発点です。

世代論として整理する

世代 中心テーマ 最適化対象
第1世代 Prompt Engineering 1回の推論品質
第2世代 RAG / Tool Use 外部知識・APIの接続
第3世代 Agentic Workflow 複数ステップの自動化
第4世代 Loop Engineering 長時間・多段・自己改善型の実行
第4.5世代 Bilevel(メタループ) ループの探索メカニズムそのもの

2. ループを成立させる3つの部品

どんなに派手なフレームワークを使っても、実際に機能するループはこの3つに還元されます。

2.1 Verifier(検証器)— 一番難しいのはここ

各試行を採点する仕組み。以下のいずれかであること。

  • テストがパスする / しない
  • 指標が動く(val_bpb、精度、レイテンシ、コスト…)
  • ビルドが通る / 通らない

Verifier が無いループは、ループではなく反復するチャットボットです。

💡 設計原則:Verifier はエージェントが触れない場所に置く。
これを守らないと、エージェントは「モデルを良くする」代わりに「テストを簡単にする」(= specification gaming)方向に最適化します。

2.2 State(状態)

何を試し、何が失敗し、何が残っているかの記録。小さなサイドファイル1枚で十分です。これがあるから、次の run は再開でき、ゼロから再スタートしなくて済みます。

2.3 Stop condition(停止条件)

暴走コストの防波堤。「ゴール達成」または「N回試行」で必ず止まる設計に。

for step in range(MAX_STEPS):        # 停止条件1:実験予算
    candidate = propose_change(current)
    score = train_and_eval(candidate)  # Verifier
    if score < best:                   # 改善したものだけ採用
        current, best = candidate, score
    if best <= TARGET:                 # 停止条件2:ゴール到達
        break

3. autoresearch 徹底解説 —— The Karpathy Loop

3.1 概要

  • 公開:2026年3月7日、MIT ライセンス
  • 規模:コアファイル3つ・約630行
  • 反響:公開直後にバイラル化し、GitHub スターは 9万近く
  • 中身:single-GPU 版に簡略化した nanochat の学習セットアップ

コンセプトは Karpathy 自身の言葉が最も端的です。

あなたはもはや Python ファイルを触らない。program.md という Markdown をプログラミングして、自律的な研究組織をセットアップする。

つまり、プログラミング対象がコードから「研究組織の運営規約」に移ったわけです。

3.2 三ファイル・アーキテクチャ(=契約構造)

ファイル 所有者 変更可否 役割
prepare.py 誰のものでもない 不変(人間もAIも触らない) データ準備・BPEトークナイザ(語彙8,192)・評価指標 val_bpb の定義。中立な審判
train.py エージェント 自由に書き換え可 630行。GPTアーキテクチャ、Muon+AdamW オプティマイザ、学習ループ。活性化関数の交換、Attention ヘッド再構成、LRスケジュール変更、重み初期化…何でもあり
program.md 人間 人間のみ編集 研究方針、避けるべき方向、実験の進め方

この分業が美しいのは、「評価器の不可侵性」がシステムの公平性を保証している点です。全実験が同じ物差しで測られるので、比較が成立します。

3.3 program.md に何を書くか

想像以上に具体的です。実際に含まれている要素:

  1. ベースライン指標のハードコードval_bpb: 0.997900peak VRAM: 45GB → 何を超えるべきかが明確

  2. 実験の実行コマンドと結果抽出方法

  3. 失敗時のハンドリング:typo は直して再実行 / 根本的に壊れたアイデアはスキップ / 10分超えたらkill

  4. システムを成立させる決定的な一行

    "NEVER STOP. Once the experiment loop has begun, do NOT pause to ask the human if you should continue."

  5. 設計哲学の制約

    "All else being equal, simpler is better. A small improvement that adds ugly complexity is not worth it."
    (複雑さを増すだけの微改善は採らない = 人間レビュアーが承認できる変更に誘導する)

🔑 ここが Loop Engineering の実体です。program.md は「プロンプト」ではなく ループ契約書(loop contract)。ゴール・スコープ・検証器・状態・停止条件・エスカレーション・予算を、エージェントが走り出す前に定義する文書です。

3.4 ラチェットループ(9ステップ)

「ラチェット(爪車)」という名前の由来は git 履歴にあります。成功した実験は commit として積まれ、失敗は revert される。コードベースは前にしか進めない。 検証済みの改善が一つずつ蓄積されていきます。

  • 1実験 = 5分固定 → 約12実験/時間 → 一晩で約100実験
  • 5分固定にすることで、「速く学習する変更」と「低く収束する変更」が同じ土俵で比較される

3.5 git と results.tsv が「研究メモリ」になる

results.tsv に記録されるもの:commit hash / val_bpb / GPUメモリ使用量 / pass-fail / 何を試したかの説明。

これは人間向けの監査証跡(朝起きて確認する)であると同時に、エージェント自身が次に何を試すかを較正するための長期記憶でもあります。序盤は広く(オプティマイザ設定を色々)、後半はデータが支持した方向へ絞り込んでいく挙動が観察されています。

構造的には進化的アルゴリズムに似ていますが、**集団(population)ではなく単一系統(single lineage)**を維持する点が違います。交叉や突然変異の代わりに、LLM が突然変異オペレータ(変更提案)と選択圧(過去結果に基づく試行選択)の両方を兼ねているわけです。

3.6 これは「ハイパーパラメータ探索」ではない

手法 探索空間 性質
Optuna / Ray Tune 事前定義したパラメータ空間 精密だが空間の外には出られない
AutoML / NAS 構造化アルゴリズムでアーキテクチャ探索 定義済み空間に制約される
AlphaEvolve (DeepMind) 進化的アプローチ+Gemini 強力だがクローズド
SWE-Agent / OpenHands / Aider 任意コード生成 experiment-evaluate-keep/revert サイクル向けに作られていない
autoresearch LLM が思いつける全て 数学的保証を捨て、LLMの一般知識に賭ける

3.7 実測結果

Run 実験数 採用された改善 結果
初回オーバーナイト(single GPU) 83 15 val_bpb: 1.000 → 0.975
拡張2日ラン(depth-12) 約700 約20 全て加算的、depth-24 モデルにも転移
プロダクション影響 GPT-2品質までの時間 2.02h → 1.80h(-11%)
コミュニティセッション 126 val_bpb: 0.9979 → 0.9697

見つかった具体例:

  • QK-Norm にスカラー乗数が欠けていた(Attention が全ヘッドに拡散しすぎていた)
  • Value Embeddings は正則化の恩恵を受ける
  • banded attention のチューニング、AdamW β パラメータ、weight decay スケジューリングでの改善

さらに Shopify CEO の Tobi Lütke が社内のクエリ拡張モデル(0.8Bパラメータ)に適用し、37実験で検証スコア +19% を翌日に報告しています。

Karpathy のまとめが刺さります:

客観指標があるなら、ボトルネックはあなただ。(人間は12回くらいの実験で疲れるが、ループは疲れない)

3.8 autoresearch の限界 —— 「創造性の天井」

ここを理解せずに導入すると必ず失望します。

(a) 局所探索に閉じる(ラチェットの副作用)

GitHub Issue #22 で指摘された構造問題。ラチェットは 「即座に val_bpb を改善する変更」しか受理しないため、エージェントは一歩下がってから大きく跳ぶことができません。人間の研究者が日常的にやる「一旦悪くなるが、その先で良くなる」という推論の余地がゼロなのです。

(b) RLHF 由来の「臆病さ」

Karpathy 自身が Hacker News で言及。オープンエンドな問題に対してエージェントは "cagy and scared"(及び腰でビクビクしている)。RLHF が安全で保守的な出力を報酬づけているため、大胆な実験より無難な選択に流れる。能力はあるが、そう振る舞うように作られていない。

(c) 5分固定ウィンドウのバイアス

短時間で価値が見える変更しか発見されない。長期ランでしか真価が出る変更は永遠に不可視のまま。

(d) 評価セットへの過学習リスク

同じ検証セットに対して100実験を回すと、一部の「改善」はその eval 固有のものかもしれない。prepare.py の不変性は公平性の保証であると同時に、システムの盲点でもある。

(e) 新規性の天井

「β を少し調整」「正則化を追加」といった真の改善は見つかるが、新しい Attention 機構を発明した報告は無い。方法論的な反復は自動化できたが、研究の方向性を定式化する創造的な部分はまだ人間の仕事です。

コミュニティでは、この天井が フレームワーク由来か、モデル由来か が議論されており、提案として「第2のエージェントが結果に基づいて program.md を書き換えるメタプロンプト最適化」「新規性を報酬する多様性指令」「局所解脱出のための定期リセット実験」などが挙がっていました。

この延長線上に現れたのが、次章の Bilevel Autoresearch です。


4. Bilevel Autoresearch 徹底解説 —— ループの上にループを載せる

論文:Bilevel Autoresearch: Meta-Autoresearching Itself(Yaonan Qu, Meng Lu / arXiv:2603.23420, 2026年3月24日投稿, 6月2日 v2 / AISC 2026)
コードEdwardOptimization/Bilevel-Autoresearch(MIT)

4.1 出発点となる問い

論文の問題設定は、身も蓋もないくらい明快です。

既存の autoresearch システムはすべて、人間がコードを読み、ボトルネックを特定し、新しいコードを書いて改善してきた。

  • Karpathy の single-track ループ
  • AutoResearchClaw(AIMing Lab)の multi-batch 並列探索
  • EvoScientist の永続的経験メモリ

LLM は、同じことを自律的にできるのか?

つまり 「autoresearch が研究の一形態なら、autoresearch を autoresearch できるはずだ」。これを文字通りに実行したのが本論文です。

4.2 中核となる欠陥:探索メカニズムは設計時に固定されている

既存の autoresearch:
  探索メカニズム(提案ロジック・受理規則・探索戦略)= 人間が設計時にハードコード
  ↓
  実行時に変えられるのは「パラメータの値」だけ
  ↓
  LLM の priors が作る決定論的な探索パスから抜け出せない

4.3 二層構造の定義

最適化するもの サイクル
内側ループ タスクの出力(ハイパーパラメータ等) propose → execute → evaluate → keep/discard
外側ループ 内側ループの動き方そのもの analyze trace → modify mechanisms → re-run

両レベルとも同じパターン(propose × evaluate × iterate)であり、同じLLMを使う。ここが論文の主張の核心です。

改善は「メタレベルに強いモデルを置いたから」ではなく、「二層アーキテクチャそのもの」から来ている。
(ただし外側ループは追加の推論予算と wall-clock を消費する)

4.4 実装は3レイヤー(設計はbilevel、実装は関心の分離)

論文/リポジトリでは、外側ループを責務で2つに割っています。

レイヤー 役割 変更対象 発火頻度
Level 1 内側ループ タスク出力(ハイパーパラメータ) 毎イテレーション
Level 1.5 外側ループ(config) 実行時の探索パラメータ(freeze/unfreeze、戦略シフト) 5イテレーションごと
Level 2 外側ループ(mechanism) 内側ループのコード構造(新しいPythonメカニズムを生成) 2サイクルごと
  • Level 1.5 = 戦術的調整:「WEIGHT_DECAY の探索はやめて LR に集中せよ」
  • Level 2 = 戦略的革新:「提案の反復を防ぐために Tabu Search メカニズムを発明せよ」

分離の理由は、Level 2 をパラメータ調整に気を取られずメカニズム発見に専念させるためです。

4.5 Level 2 の「4ラウンド研究セッション」

Level 2 が起動すると、4回の連続したLLM呼び出しで新しいPythonモジュールを生み出します。

厳密なバリデーションと動的インポートのプロトコルにより、壊れたコードは revert され、システムの整合性は保たれます

4.6 実験セットアップとアブレーション結果

条件:Karpathy の GPT 事前学習ベンチマーク(50Mパラメータ)、RTX 5090 32GB、300秒の学習予算、4グループ × 3回独立反復 × 30イテレーション、全レベルで同一LLM(DeepSeek)。ベースライン val_bpb ≈ 1.10

Group 構成 平均 Δval_bpb vs Group A
A Level 1(標準 autoresearch) -0.009 ± 0.002
B Level 1 + 1.5(探索configの調整) -0.006 ± 0.006 0.7×(改善せず)
C Level 1 + 1.5 + 2(フル) -0.045 ± 0.030
D Level 1 + 2(config調整なし) -0.034 ± 0.031 3.8×

※ より負の値が良い。

この表から読み取るべき3つのこと:

  1. Group B の失敗が最も雄弁。「パラメータレベルの調整(メカニズム変更なし)では信頼できる改善は得られない」。探索の多様性は増えたが、構造的な壁は破れなかった。
  2. Group D が Group A の3.8倍。つまり Level 2(メカニズム生成)だけで十分であり、性能の主ドライバーはメカニズム変更である。
  3. 標準偏差が大きい(±0.030)。3回中2回で大きな利得が出た形で、分散も大きい。ここは後述の限界に直結します。

4.7 Level 2 が自律的に発見したメカニズム一覧

人間はどのドメインを探索すべきかを一切指定していません。 各反復が独立に異なるドメインからメカニズムを発見しました。

メカニズム 由来ドメイン やっていること
Tabu Search Manager 組合せ最適化 最近探索したパラメータ領域への再訪を禁止
Multi-Scale Bandit Proposer オンライン学習 / 多腕バンディット パラメータ横断で探索と活用のバランスを取る
Systematic Orthogonal Exploration 実験計画法(DoE) 直交するパラメータ次元への探索を強制
GP Regressor(revert された) ベイズ最適化 val_bpb 予測の代理モデル(sklearn 未インストールで失敗)

6件中5件が one-shot のLLM呼び出しでバリデーションを通過。1件は外部依存の欠落で revert。

実際に生成されたコードの雰囲気:

# エージェントが生成したメカニズム:Tabu Search は LLM が失敗した提案を繰り返すのを防ぐ
class TabuSearchManager:
    def __init__(self, max_tabu_size=10):
        self._tabu_list = []  # 最近訪れたパラメータ領域

    def is_tabu(self, changes: dict) -> bool:
        """提案された変更が直近の試行と似すぎていないかチェック"""
        for tabu_entry in self._tabu_list:
            if self._similarity(changes, tabu_entry) > 0.8:
                return True  # この提案をブロックし、LLM に別の方向を強制する
        return False

4.8 なぜ Level 2 が勝つのか —— 事前分布の牢獄を壊す

これが本論文で最も面白い知見です。

Group A(外側ループなし)の挙動
WEIGHT_DECAY を試す → WINDOW_PATTERN を試す → そこから20イテレーション以上、同じ提案を繰り返して停滞。ほぼ決定論的な探索パス。

Level 2 のメカニズムが入った後
Tabu Search と Orthogonal Exploration がその周回を壊し、LLMを未踏の方向へ押し出した結果——

TOTAL_BATCH_SIZE を 2^19 から 2^17〜2^18 へ「減らす」と val_bpb が劇的に改善する。

Blackwell 世代の計算環境+固定時間予算という条件下では、バッチを小さくすることで同じ300秒でより多くのステップを回せるため大幅に有利だった。しかし LLM のデフォルト探索パスは 繰り返しバッチサイズを「増やす」方向を試し続け、最適な「減少」方向を完全に見落としていた。Group A も B もこの方向には一度も到達していません。

💡 教訓:LLM の priors は強力な事前知識であると同時に、系統的な盲点でもある。
メカニズムレベルの介入は「もっと頑張って探索する」ことではなく、**「LLMが構造的に避ける方向を強制的に踏ませる」**ことに価値がある。

4.9 究極目標:再帰的ブートストラップ(Recursive Bootstrapping)

リポジトリの README が示す野心的な射程:

Level 2 が Level 1 を加速するメカニズム(並列マルチエージェント討論、永続メモリ、Tabu Search 等)を発見したなら、その同じメカニズムを抽象化して Level 2 自身に逆適用できる
システムは「学び方」を学び、そのレッスンを自らのメタ学習プロセスに適用する。

論文 v2 の枠組みでは、メカニズムの担体(carrier)はコードだけではないとも述べられています。

メカニズムを符号化できるもの:
  コード / スキル / プロンプト / ワークフロー
  / 評価器 / ドメイン原理 / 世界モデルの仮定 / メモリスキーマ

つまり Claude Code の Skill、CLAUDE.md、評価ルーブリック、記憶スキーマも「外側ループが書き換えうる対象」 ということです。ここが実務者にとって一番の応用ポイントだと思います。

4.10 Bilevel Autoresearch の限界

論文とレビューが挙げている未解決事項:

カテゴリ 具体的な問題
統計的検出力 グループあたり n=3。分散が大きく、「5倍」の主張には n≥10 と信頼区間/検定が必要
計算コストの会計 Level 2 セッションは内側ループの反復を約6分削る。wall-clock / GPU時間で正規化した比較が未実施
一般化 単一ベンチマーク・単一ハードウェア。TOTAL_BATCH_SIZE の知見が RTX 5090 固有かどうか不明
ベースライン比較 Optuna / SMAC / ベイズ最適化 / 人間エキスパートとの比較が無い
受理基準のノイズ 「1回 val が下がったら採用」ではノイズを採用してしまう。ブートストラップや逐次検定が必要
コード注入の安全性 サンドボックス、リソース制限、権限管理が要る。検証が「import が通る」だけでは弱く、単体/結合テストが必要
specification gaming Level 2 が変更可能なファイルを厳密に制限しないと、検証ロジックや指標そのものを書き換えるリスク
依存管理 依存のホワイトリスト/ロックファイルが無いと sklearn 問題のような revert が起きる
サイレント故障 動的ロードの脆さ(過去に sys.modules バグ)。カナリアテストと監視が必要
プロンプト誘導バイアス Level 2 のプロンプトからドメインヒントを外した場合の感度が未測定

5. 3モードの比較(ここだけ覚えて帰ってもOK)

観点 One-shot prompt Karpathy Loop (autoresearch) Bilevel Autoresearch
あなたが定義するもの 各ステップ ゴール(1回だけ) ゴール(1回だけ)
反復する主体 あなた 内側エージェント 内側 + 外側エージェント
Verifier あなた(手動) prepare.pyval_bpb 同じ指標を2レベルで
State チャット履歴のみ 実験ログ(results.tsv + git) ログ + 注入されたコード
最適化対象 出力 出力 出力 + 探索メカニズム
人間の役割 エンジン program.md の著者 program.md の著者
報告された結果 まちまち 700実験 → 20改善、11%高速化 val_bpb 改善量が5倍
主なコスト 人間の時間 GPU時間 + API GPU時間 + メタ推論の追加予算

6. 実務ループを組む5つのビルディングブロック

現場のAIエンジニアリングチームは、動くループを次の5部品で組み立てています(Claude Code / Codex はこの5つを標準搭載)。

部品 役割 実装例
Automation(Heartbeat) スケジュール・イベント・トリガでループを起動 cron、Webhook、GitHub Actions
Skill プロジェクト知識を Markdown に保存し、毎回読ませる SKILL.mdprogram.mdCLAUDE.md
Sub-agents 書き手と評価者を分離(1モデルは自分に甘い) writer agent / reviewer agent
Connectors 実ツールの中で動く(課題管理、Slack、DB) MCP、API連携
Verifier 悪い仕事を却下するゲート テスト、ルーブリック、メトリクス

さらに、autoresearch から学ぶべき**隔離(Isolation)**の観点を追加すべきです。

  • Worktree Isolation:git worktree / コンテナ / サンドボックスで作業空間を隔離

  • Evaluator Isolation:評価器はエージェントの書き込み権限外に置く

  • Memory Isolation:リポジトリ README にある重要な制約——

    The evaluator must NEVER receive lesson memory. Lessons influence proposals, never judgments.
    (教訓メモリを評価器に渡してはならない。教訓は「提案」に影響してよいが、「判断」に影響してはならない)

    これは実務でも極めて重要です。「前回はこう直したから今回もOKだろう」という評価の汚染を構造的に防ぎます。


7. 今すぐ体験する:ワンプロンプト・ループ

Claude Code も Codex も無くても、ループの手触りは試せます。任意の高性能モデルに貼り付けてください。

You will work in a loop until the task meets the bar.

TASK: [作りたいものを厳密に記述]

SUCCESS CRITERIA (be strict):
- [基準1]
- [基準2]
- [基準3]

LOOP PROTOCOL, repeat every turn:
1. PLAN   - 次の一手を1つだけ宣言する
2. DO     - 成果物を作る/改善する
3. VERIFY - 各基準について 1-10 で自己採点する。正直に。
4. DECIDE - 全基準が 8 以上なら FINAL と出力して停止。
            そうでなければ ITERATING と出力し、最も低いスコアから直す。

RULES:
- 全基準が8以上になるまで完了と宣言しない
- 各パスは前回 VERIFY の最弱点を必ず修正すること
- 質問しない。妥当な仮定を置いて続行する
Begin.

ただしこれは「疑似ループ」です。 トリガはあなたであり、タブを閉じれば状態は消え、採点はモデルの自己申告(=甘い)。ここに Automation・State ファイル・独立した Verifier を足して初めて自律ループになります。


8. 自分のドメインに移植する設計チェックリスト

autoresearch の三ファイル契約(不変の評価器 / エージェントが書き換える実装 / 人間が書く方針)は、自動採点関数が定義できる領域であれば横展開できます。

8.1 適用可能性の判定

  • 自動で「不合格」を出せるゲートがあるか?(これが No なら、ループは不要)
  • 1試行が「分」オーダーで回るか?(時間単位だとフィードバックが遅すぎる)
  • 小規模で得た改善が、スケールアップ時に転移するか?
  • 評価セットは本番データに合わせて進化させられるか?(静的ベンチはすぐ飽和する)

8.2 ドメイン別の Verifier 設計例

領域 ループが回すもの Verifier
モデル開発 ハイパーパラメータ / アーキテクチャ val_bpb・精度・レイテンシ
ソフトウェア リファクタリング テスト・型チェック・ビルドが全部通る
コンテンツ 記事・提案書の書き直し ルーブリック各項目が閾値超え
データ基盤 パイプライン調整 スキーマ検査・データ品質チェック
検索/RAG チャンク戦略・リランカ nDCG・回答正解率・引用整合性
業務エージェント プロンプト/スキル/ツール構成 業務KPI・SLA達成率・エスカレーション率

8.3 安全設計(Bilevel を実務投入するなら必須)

  • エージェントが書き込めるファイルをホワイトリストで限定(評価器・メトリクス定義は絶対に含めない)
  • 生成コードはサンドボックス実行、リソース制限、ネットワーク/OS権限の分離
  • 検証は「import 成功」で終わらせず、単体テスト・結合テスト・振る舞いチェックまで
  • 依存ホワイトリスト / ロックファイル(sklearn 問題の再発防止)
  • 生成コード・プロンプト・シード・環境ハッシュをバージョン管理して再現性を担保
  • カナリアテストでサイレント revert / 劣化を検知
  • 予算上限(トークン・GPU時間・wall-clock)とヒューマンチェックポイント

9. よくある落とし穴 FAQ

Q1. Verifier が主観的な場合はどうする?
A. LLM-as-a-judge をルーブリック化し、判定用モデルには「教訓メモリ」を渡さない。加えて人間のスポットチェックを stop condition に組み込む。判定が揺れるなら、複数回サンプリングして多数決や統計的受理基準(ブートストラップ)を使う。

Q2. ラチェットの「局所解に嵌まる」問題は避けられる?
A. まさにこれが Bilevel の答えです。受理規則そのもの(=メカニズム)を書き換えられる層を上に置く。簡易版なら、Tabu リスト・定期リセット・多様性ボーナスを手で実装するだけでも効きます。

Q3. 外側ループのコストは見合う?
A. 論文でも未解決です。 Level 2 は内側の反復時間を削るので、GPU時間あたりの改善量で正規化した比較が必要。まずは「内側ループが明確に停滞した時だけ Level 2 を発火する」適応的スケジューリングから試すのが現実的です。

Q4. program.md は誰が書ける?
A. 自分でその研究をやったことがある人です。どの方向が試す価値があるか、「良い」とは何か、逓減が始まるのはいつかを知っている必要がある。エージェントが実行を担っても、研究アジェンダの判断は人間に残ります。

Q5. まず何から始めるべき?
A. ①測定可能なタスクを1つ選ぶ → ②評価器をエージェントの手の届かない場所に置く → ③状態ファイルと停止条件を書く → ④一晩回す → ⑤ログを読んで program.md を改訂。この⑤の改訂こそが、あなたが手動でやっている「外側ループ」です。 それを自動化したくなった時が、Bilevel の出番です。


10. まとめ

  1. ループは、仕事が測定可能なときだけコストに見合う。 Verifier・State・Stop条件の3点が揃って初めてループ。
  2. autoresearch の本質は630行のコードではなく「契約構造」。不変の評価器 / 書き換え可能な実装 / 人間が書く方針、という三権分立が公平な実験を保証する。
  3. ラチェットは前にしか進まないが、それゆえ局所解に嵌まる。 5分固定・即時改善のみ採用・RLHF由来の保守性が「創造性の天井」を作る。
  4. Bilevel Autoresearch は、その天井をメカニズムレベルで破る試み。 外側ループが探索機構をコードとして生成・注入し、同一LLMのまま5倍の改善を出した。
  5. 効いた理由は「LLMの事前分布が避ける方向を強制的に踏ませた」から。 バッチサイズ減少という盲点の発見がその象徴。
  6. ただし n=3・単一ベンチ・計算コスト未正規化。 「5倍」を鵜呑みにせず、方向性の証明として読むべき。
  7. メカニズムの担体はコードだけではない。 スキル、プロンプト、ワークフロー、評価器、メモリスキーマ——あなたのエージェント基盤の中で「将来の挙動を規定するもの」はすべて、外側ループの最適化対象になり得ます。

ループは思考を消さない。仕事を「設計」と「レビュー」へ移すだけです。


付録A. 最小実装:GPU無しで動く Bilevel ループ(約120行)

概念だけでは腹落ちしないので、GPUもLLM APIも無しで挙動を再現できる最小骨格を置いておきます。タスクは「ノイズのある関数を最小化する」ダミーですが、内側ループの決定論的停滞外側ループのメカニズム注入による脱出 という論文の核心的な現象は、そのまま再現されます。

"""
minimal_bilevel.py — Bilevel Autoresearch の最小骨格
実行: python minimal_bilevel.py
"""
import random, math, json, pathlib

# ── Verifier(不変。エージェントは絶対に触れない)────────────────
def evaluate(params: dict) -> float:
    """低いほど良い。最適解は batch=2^17 付近だが、
       "batch は大きいほど良い" という素朴な事前分布からは見えにくい谷にしてある。"""
    lr, batch = params["lr"], params["batch"]
    penalty = abs(math.log2(batch) - 17) * 0.03      # 17 が最適(=減らす方向)
    penalty += abs(math.log10(lr) + 3) * 0.02        # 1e-3 が最適
    return 1.10 + penalty + random.gauss(0, 0.001)   # ノイズ込み

# ── State(永続化。ここがあるから「再開」できる)──────────────
STATE = pathlib.Path("loop_state.json")
def load_state():
    return json.loads(STATE.read_text()) if STATE.exists() else {"history": [], "best": None}
def save_state(s): STATE.write_text(json.dumps(s, indent=2))

# ── 内側ループの提案器(= LLM の priors を模した決定論的バイアス)──
class NaiveProposer:
    """実際の LLM と同じく "batch は増やす方が良い" という偏見を持つ"""
    name = "naive"
    def propose(self, cur, history):
        if random.random() < 0.75:
            return {**cur, "batch": min(cur["batch"] * 2, 2**21)}   # ← 常に増やす偏見
        return {**cur, "lr": cur["lr"] * random.choice([0.5, 2.0])}

# ── Level 2 が「生成」するメカニズム(実際は LLM がコードを書く)──
class TabuProposer(NaiveProposer):
    """組合せ最適化ドメイン由来。直近試した領域への再訪を禁止し、
       priors が避ける方向(batch 減少)へ強制的に踏み出させる。"""
    name = "tabu"
    def __init__(self, size=8): self.tabu = []
    def propose(self, cur, history):
        for _ in range(20):
            c = super().propose(cur, history)
            if not any(self._sim(c, t) > 0.8 for t in self.tabu):
                self.tabu = (self.tabu + [c])[-8:]
                return c
        # 全部 tabu → priors が避けていた方向を強制探索
        return {**cur, "batch": max(cur["batch"] // 2, 2**14)}
    @staticmethod
    def _sim(a, b):
        return sum(1 for k in a if abs(math.log2(a[k]/b[k])) < 0.01) / len(a)

# ── 内側ループ(Level 1)ラチェット構造 ────────────────────
def inner_loop(proposer, state, n_iter=30, target=1.10):
    cur = state["best"] or {"lr": 1e-2, "batch": 2**19}
    best_score = evaluate(cur)
    for i in range(n_iter):                       # 停止条件1: 予算
        cand = proposer.propose(cur, state["history"])
        score = evaluate(cand)                    # Verifier
        keep = score < best_score                 # ラチェット: 改善時のみ採用
        state["history"].append(
            {"iter": i, "mech": proposer.name, "params": cand,
             "score": round(score, 4), "kept": keep})
        if keep:
            cur, best_score = cand, score         # commit 相当
        if best_score <= target:                  # 停止条件2: ゴール到達
            break
    state["best"] = cur
    return best_score, state

# ── 外側ループ(Level 2)停滞を検知してメカニズムを差し替える ──
def outer_loop(cycles=2):
    state, proposer = load_state(), NaiveProposer()
    for c in range(cycles):
        score, state = inner_loop(proposer, state)
        recent = state["history"][-15:]
        stalled = sum(h["kept"] for h in recent) <= 1     # ← トレース分析
        print(f"[cycle {c}] mech={proposer.name:5s} score={score:.4f} "
              f"batch=2^{int(math.log2(state['best']['batch']))} stalled={stalled}")
        if stalled and not isinstance(proposer, TabuProposer):
            print("  → 停滞を検知。Level 2 が新メカニズムを生成・注入します")
            proposer = TabuProposer()   # 実際は importlib で動的ロード
        save_state(state)
    return state

if __name__ == "__main__":
    random.seed(42)
    final = outer_loop()
    print("final:", final["best"], "", round(evaluate(final["best"]), 4))

実行するとこうなる

[cycle 0] mech=naive score=1.1602 batch=2^19 stalled=True
  → 停滞を検知。Level 2 が新メカニズムを生成・注入します
[cycle 1] mech=tabu  score=1.1027 batch=2^17 stalled=True
final: {'lr': 0.00125, 'batch': 131072} → 1.1025

seed=42 での実測値。Δscore は -0.0575 で、内側ループ単独の停滞点から大きく改善しています)

論文と同じ現象が起きていることに注目してください。

  1. naive(= Level 1 単独)は「batch は増やすもの」という事前分布に従って提案を続け、初期値 2^19 から一歩も改善できずに停滞する(30イテレーション中の採用がほぼゼロ)
  2. 外側ループがトレース(直近15件の採用率)から停滞を検知
  3. Tabu メカニズムが再訪を禁止し、全候補が tabu になった時点で priors が構造的に避けていた「batch を減らす」方向へ強制的に踏み出す
  4. 真の最適解 2^17(=131072) に到達し、score が 1.1602 → 1.1027 へ

これは論文の実験で観測された「LLM は TOTAL_BATCH_SIZE を増やす方向ばかり試し、最適だった減少方向を見落としていた」という現象の、完全な再現ミニチュアです。同じ提案器・同じ評価器のまま、探索メカニズムを差し替えただけで結果が変わる——これが Bilevel の主張そのものです。

これを本物にするには、以下を差し替えるだけです。

骨格 本番
evaluate() のダミー関数 実際の学習+val_bpb 測定(5分固定)
NaiveProposer LLM に train.pyresults.tsv を読ませて変更を提案させる
TabuProposer を手書き Level 2 が4ラウンドセッションで Python コードを生成し importlib で注入
stalled の単純判定 LLM によるトレース分析+ボトルネック特定
loop_state.json git 履歴 + results.tsv

⚠️ 本番化する際は、第8.3節の安全設計チェックリスト(書き込み先ホワイトリスト、サンドボックス、依存ロック、カナリアテスト)を必ず適用してください。特に evaluate() に相当するファイルをエージェントの書き込み対象に含めないことは絶対条件です。


付録B. 用語ミニ辞典

用語 意味
val_bpb validation bits-per-byte。検証データ1バイトあたりの情報量。低いほど良い言語モデル
ラチェット(ratchet) 爪車。前進のみ許し後退させない機構。ここでは「改善commitのみ蓄積、失敗はrevert」
Verifier エージェントの成果を自動採点し、不合格を出せるゲート。ループの心臓部
specification gaming 目的を達成する代わりに、評価そのものを歪めて高得点を取る挙動
priors(事前分布) LLMが学習から得た「こうするのが普通」という偏り。強力な知識であり同時に盲点
bilevel optimization 2つの入れ子になった最適化問題。外側の解が内側の問題定義を変える
importlib Pythonの動的インポート機構。実行中に新しいモジュールを読み込める
Tabu Search 組合せ最適化の手法。直近訪れた解を禁止リストに入れ循環を防ぐ
agentic engineering Karpathyの造語。「99%コードを書かず、エージェントを指揮し監督する」働き方

参考リンク

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?