7月17日、Hideaki Takahashiが「What I Learned from Reimplementing 40 Multi-Agent LLM Papers」と題した記事を公開した。マルチエージェントLLM論文40本を実際に再実装して得られた実践的な知見を10個にまとめたもので、「読んだことはあっても実装したことはない」エンジニアには特に刺さる内容だ。
著者はマルチエージェント実験用に自身が開発したh5i-pythonフレームワーク上で40本の論文を動作するスクリプトとして再実装し、その過程で見えてきたパターンと落とし穴を整理している。
結論:40本の論文は実質8つのパターンに収束する
最も刺さるメタ的な気づきから始めよう。40本を再実装した結果、独立した手法は実質8つのファミリーに集約されるというのが著者の結論だ。
「第2バッチの20本を選ぶ際、最も難しかったのは最初の20本にすでに含意されていない論文を見つけることだった」
8つのファミリーとは:refine loop(改善ループ)、sample-and-vote(サンプリングと多数決)、debate-with-a-visibility-function(可視性関数付きディベート)、judge panels(判定パネル)、generative fusion(生成的融合)、text-search-then-commit(テキスト探索後コミット)、staged pipelines(段階的パイプライン)、dynamic team management(動的チーム管理)。
製品を作る立場なら、これら8つのファミリーをパラメータ化して実装すれば、論文群の大部分をカバーできる。
ほとんどの論文は100行のcontrol flowだ
論文から評価セクションとフレームワーク宣伝を取り除くと、中央値的な貢献はループの形・プロンプトの規律・集約ルールの3点に帰着する。
例として挙げられているのが「More Agents Is All You Need(Li et al. 2024)」。手法の本質はN個の独立サンプルを取って多数決するだけで、実装はこれだけだ:
async def main(question: str) -> None:
# N個のエージェントを起動
forest = [
await c.hire(f"tree{i}", runtime="claude", model="claude-haiku-4-5")
for i in range(N_AGENTS)
]
# 手法の全体:N個の独立サンプルを取り、多数決する
samples = list(
await asyncio.gather(*(seat.ask(prompt, parse=parse_answer) for seat in forest))
)
winner, votes = majority(samples)
著者はこれを批判ではなく「小さいアルゴリズムが実際の効果を持つのは最高の形だ」と評価している。ただしこれ以降、新しいエージェント論文を読む際は「ループの形と集約ルールは何か」を先に探すようになったという。
独立性こそが最重要の不変条件
エンジニアとして最も実装上の失敗につながりやすい知見がこれだ。多くの論文が「サンプルの独立性」を暗黙の前提としているが、単一コンテキストのフレームワークではこれを簡単に破壊できる。
- Self-Consistencyの投票は、サンプルが互いを参照していたら意味をなさない
- CodeTの「dual execution agreement」は、実装を知らない状態で書かれたテストが必要
- Chain-of-Verificationのbest variant("factored")は、ドラフトを見ていないコンテキストで検証が必要
共有された会話履歴が1つあるだけで、5つの「独立サンプル」が5つの言い換えになってしまう。エージェント基盤を構築するなら、独立性をチェック可能な一級プロパティとして設計すべきだという。
5本の改善ループ論文は、フィードバックのソースが違うだけの同一構造
Self-Refine、Reflexion、CRITIC、Self-Debug、Constitutional AIは、「試みる→フィードバックに対して修正する」という同じ2ステップループで、フィードバックのソースだけが異なる。
| 手法 | フィードバックのソース |
|---|---|
| Self-Refine | 同じモデル自身の批評 |
| Reflexion | 失敗シグナルに対するモデルの内省 |
| CRITIC | 外部ツールの出力 |
| Self-Debug | モデルが自身のコードを一行ずつ説明 |
| Constitutional AI | 書かれた原則に照らした批評 |
フィードバックをオブジェクトとして扱うと、この5本は「パラメータが1つ違う同一関数」になる。
特にSelf-Debugの「ラバーダック」手法が実装者として気になる点だ。修正前にモデルはコードが「意図通りに何をするか」ではなく「実際に何をするか」を説明しなければならない。エラーメッセージが全くない状態でも効果があると論文は報告しており、シグナルがどこに存在するかについての強い主張だと著者は評価している。
集約ルールは10行で、すべてを決める
多数決、信頼度重み付き投票(ReConcile)、判定者の平均(ChatEval)、pairwise比較の勝利数(LLM-Blender)——それぞれ約10行のコードだが、同じスケルトンを持つ論文間の実質的な差異はここにある。
実装上の注意点が2つ:
- Pairwise比較は絶対スコアより優れているが、各ペアを両方の順序で提示し、順序を入れ替えても勝つときだけ勝利とカウントしなければならない。ポジションバイアスは実在し、これが安価な対策だ
- 集約は通常のコードで実装し、プロンプトに入れるな。ユニットテストしたい部分だからだ
ディベート系論文は「誰が誰のメッセージを見るか」の関数一つに収まる
Multiagent debate、MAD、ReConcile、Exchange-of-Thoughtの違いは主に「ラウンド間で誰が誰のメッセージを見るか」だ。Exchange-of-Thought(EoT)はこれを明示的に4つのトポロジーで示しており、差異は1つの関数に収まる:
def visible_peers(topology: str, me: int, n: int) -> list[int]:
if topology == "memory": # バス型:全員
return [j for j in range(n) if j != me]
if topology == "report": # スター型:スポーク⇔ハブ
return [j for j in range(n) if j != me] if me == 0 else [0]
if topology == "relay": # リング型:前者のみ
return [(me - 1) % n]
if topology == "debate": # ツリー型:兄弟ペア、ルートは全員を聞く
return [j for j in range(n) if j != me] if me == 0 else [me % 2 + 1]
思考の探索は安く、試みの探索は高い
Tree of Thoughts、Graph of Thoughts、LATSはコスト面でのはしごを形成している。ToTとGoTはテキストを探索する——思考の提案とスコアリングは安いデータターンで、実装作業のコストは勝者プランのみが支払う。一方LATSは実際の試みを探索し、各ノードが実際の提出と実際のテスト実行を伴う。これは1ノードあたり桁違いに高コストだが、意見ではない報酬シグナルが得られる。
著者が提案する実践的なレシピ:テキスト上で広く探索し、実行時には絞り込む。方向性選択にToTスタイルの計画を使い、最終候補にのみLATSスタイルのループを適用する。
すべての40本分のスクリプトはリポジトリのexamples/papers/以下に収録されており、各スクリプトは自己完結型で安価なモデルを固定している。
詳細はWhat I Learned from Reimplementing 40 Multi-Agent LLM Papersを参照していただきたい。