最近、界隈で大きな話題になった「Bunが11日間で53万行のZigコードをRustに書き換えた」という事例。ピーク時には64のClaude Code(AIエージェント)が並列稼働し、API費用換算で約16.5万ドルが投下されました。
この驚異的なプロジェクトの品質を担保したのは、言語に依存しない6万個以上のテスト(約138万回の expect() 呼び出し)という「神託(Oracle)」のようなテストスイートでした。
筆者は普段、LLMエージェントの「記憶層(Memory Layer)」を開発しているのですが、この事例のアーキテクチャを読み解く中で、ある技術的なボトルネックに釘付けになりました。
それは、「64並列で動くエージェントのうち、1体が今まさに発見した『未知のバグや仕様』は、どうやって残りの63体に同期されたのか?」という点です。
結論から言うと、システム的な同期メカニズムはなく、「人間のインテグレーターが人力で仕様書を更新し続ける」という力技で解決されていました。
本記事では、この事例から見えてきた「並列AIエージェントにおける知識同期の課題」と、それをシステムとしてどう実装・解決すべきかについて考察します。
⏳ TL;DR
- Bunの事例は「事前資料(PORTING.md)」+「テストによる自動検証」+「実行中の仕様書の継続的アップデート」で成功した。
- しかし、実行中の知識共有(仕様書アップデート)は、人間が11日間張り付いて異常を検知・追記し続けという属人的な運用だった。
- 仕組みがないと、64並列のエージェントは「同じ罠に63回ハマり、同じ試行錯誤コストを63回分API代として消費する」ことになる(AIは文句を言わないため隠蔽される)。
- 解決策は、エージェントの「発見」をメタデータ付きのJSONLで共有ストレージに即時書き込み、頻出するものを機械的に抽出してプロンプト(仕様書)に昇格させるアーキテクチャの導入である。
1. Bun事例のアーキテクチャ:テストは「神託」、仕様書は「テコ」
Bunの書き換えプロセスにおける基本ユニットは「1人の実装者 + 2人の敵対的レビュアー + 1人の修正者」でした。
彼らの優れた点は、人間のコードレビューを放棄し、完全な正当性確認をテストスイートに委ねたことです。
そして、運用上最も強力だったレバレッジが「問題が起きたら、個別コードではなく仕様書(PORTING.md)を修正する」というアプローチです。
-
事象: 並列エージェントたちが
git stashの衝突で互いのワークスペースを壊し始めた。 - 対策: 仕様書に「commit以外のgit操作禁止」と追記する。
たった1箇所(プロンプトのコンテキスト)を書き換えるだけで、その後の64体全てのエージェントの行動が修正されます。見事なプロンプトエンジニアリングと運用です。
しかし、ここにシステム上の空白地帯があります。「誰がその仕様書を直すのか?」です。
2. 並列化の落とし穴:「発見」コストの多重支払い
このプロジェクトでの知識の流動ルートを整理すると、以下のようになります。
| ルート | 内容 | 処理の主体 |
|---|---|---|
| ① 事前知識 | 変換パターン(PORTING.md)、ライフタイム表 | 事前生成 + 人間 |
| ② ルール更新 | stash禁止などの運用ルール追加 | 人間がログを監視して追記 |
| ③ 発見の同期 | 実行中に遭遇した「未定義の罠」の共有 | 仕組みなし |
致命的なのは「③ 発見の同期」が存在しなかった点です。
例えば、開始30時間後に Agent #23 が「Zig特有のセマンティクスによる罠」を踏み抜き、40分かけて回避策を発見したとします。
しかしこの発見は、Agent #23のローカルコンテキスト内に留まり、タスク終了と共に揮発します。結果として、Agent #24から#64までが全員同じ罠を踏み、それぞれ40分かけて同じ解決策を再発見することになります。
人間であれば「さっき俺がハマったエラーなんだけど〜」とSlackで共有されますが、エージェントは文句を言いません。
10体のエージェントがハマれば400分(約6.7時間分)のコンピュートリソースとトークンが、「同じ知識の再購入」に静かに消えていきます。
これが、人間の気合い(11日間連続の監視)なしでは並列エージェントシステムがスケールしなくなる根本原因です。
3. 「知識のバス」をシステムとして実装するアプローチ
この課題を解決するためには、エージェントのコンテキスト内で生まれた「発見(Discovery)」を抽出し、他のエージェントに分配するパイプライン(知識のバス)が必要です。
具体的には、以下の3つのコンポーネントを実装します。
Step 1. 「発見」を構造化して共有ストレージに即時追記
タスク完了時のサマリーではなく、「罠を脱出した直後」にその知見を構造化ログとして書き出させます。Tool Calling(Function Calling)等を用いて、以下のスキーマでJSONLストレージに追記します。
{
"ts": "2026-07-13T04:10:00Z",
"agent_id": "worker-23",
"task_target": "port/fs-watcher",
"kind": "discovery",
"what": "Zigのdeferは、特定のシナリオでRustのDropと解放順序が逆になる",
"evidence": "fs_watcher.zig:214の移植でwatch-close.test.tsが連続3回失敗 → Drop順序を明示的に調整して解決",
"cost_minutes": 40
}
実装のポイント:
-
evidence(証拠)とcost_minutes(解決に要した時間)をSchemaの必須プロパティ(required)にします。 - コストが小さいもの、根拠がない「ハルシネーションの可能性が高い知見」はノイズになるため弾くための指標になります。
Step 2. システムプロンプトへの「読み書き」の強制
エージェントの不変のシステムプロンプトに、以下のワークフローを組み込みます。
- [Read] タスク着手時、対象ファイルパスやタスク概要をクエリとして、共有ストレージから類似する発見をベクトル検索(Top-K)してコンテキストに含める。
- [Write] 事前資料(PORTING.md)に記載のない仕様やバグに遭遇し、それを解決した場合は、必ず指定のToolを使ってストレージに記録する。
※ストレージの全量読み込みはコンテキストウィンドウを圧迫し、パスポート情報の肥大化を招くため、必ずRAG(検索ベース)で絞り込みます。
Step 3. 頻度ベースでの「仕様書(プロンプト)への昇格」
蓄積されたログのうち、「別々のエージェントから2回以上同じような発見が記録されたもの」を機械的にクラスタリングし、「仕様書への追記候補」として人間に通知します。
人間の役割は「64体のログを11日間監視し続けること」から、「システムが通知してきた仕様変更のプルリク(候補)をレビューし、Approveすること」に変わります。
劇薬であるシステムプロンプトの更新権限は人間に残しつつ、監視と収集のコストを機械にオフロードするアーキテクチャです。
4. なぜ「事前に完璧なPORTING.mdを作る」だけではダメなのか?
Bunの事例(Zig→Rustの変換)は、正解が「言語仕様」という外部に存在していたため、事前知識(PORTING.md)の構築が非常に有効に機能しました。
しかし、以下のようなユースケースでは事前準備アプローチは破綻します。
- レガシーシステムのマイグレーション: 実行して初めてわかる隠し仕様や負債が多い。
- 外部APIを利用した開発: ドキュメント化されていないRate Limitや暗黙の制約がある。
- 長期運用される自律型エージェント: 11日間の短期決戦ではなく、月単位でエージェントが稼働し、モデルのバージョンアップも挟まるような場合。コンテキストの永続化が必須になる。
5. まとめ:並列エージェント導入時のチェックリスト
複数エージェントを並列稼働させるシステムを設計する際、インフラのスケールアウトと同じくらい「状態(知識)の同期」の設計が重要になります。
実装前のチェックリストとして以下を活用してみてください。
- 個別のエージェントが実行中に得た「発見」が、他のエージェントに伝播するシステム上のルートが存在するか?
- その発見は「誰が・どこで・何を・どんな証拠で・どれだけのコストをかけて」見つけたか、構造化されて保存されるか?
- 共有ストレージからノイズを弾き、重要な知見だけをシステムプロンプト(仕様書)にフィードバックする抽出プロセスがあるか?
- 「絶対的なルール(システムプロンプト)」と「エージェントの動的な経験ログ(RAG対象)」の保存領域が明確に分離されているか?
Bunの事例は、並列エージェントの圧倒的なポテンシャルを示しました。しかし、コンピュートリソースの並列化が容易になった今、次の技術的チャレンジは「分散したLLMのコンテキスト間で、いかに効率よく状態(暗黙知)を同期させるか」に移りつつあると感じています。
エージェントの記憶管理やアーキテクチャ設計について、皆さんの現場での知見や「こういうアプローチをとっている」というアイデアがあれば、ぜひコメントで教えてください!