徹底解説· 5 分で読めます

エージェントのファンアウトと git worktree:衝突しない並列編集の仕組み

「並列化」は簡単に約束できても、安全にやるのは難しい。Muse Code の答えは、枯れた git の技術を正しく使い切ることでした。

#worktrees#parallel-agents#git#multi-agent

パターン:1 つの親と、書き込み可能な複数の子

Muse Code はシンプルなルールの上に成り立っています。1 つのジョブが複数の独立したタスクに分割できるとき、それらのタスクは自動的に別々のエージェントへとファンアウトされます。親エージェントがタスクごとに書き込み可能な子エージェントを 1 つずつ生成する仕組みです。特別な設定は不要で、「並列モード」を明示的に起動する必要もありません。仕事が十分に大きければ、分解とディスパッチはデフォルトの挙動として発動します。

すると当然、次の疑問が浮かびます。複数のエージェントが同じリポジトリに同時にコードを書き込めるなら、なぜマージコンフリクトやファイルの上書き合戦で崩壊しないのでしょうか?

Muse Code セッションのタスクテーブル:ブロック崩しゲームの 6 タスクのうち 4 つが完了、2 つが実行中。タスク 4 と 6 の分離されたワークツリーが /.muse/worktrees/ 配下でまだアクティブ

実際のファンアウトセッション:1 つのゲームに対して 6 タスク、4 つはマージ済み、2 つは実行中。それぞれが .muse/worktrees/ 配下の専用ワークツリーで動いており、メインのチェックアウトには一切手が触れられていません。

worktree:git ネイティブな分離のやり方

各子エージェントには専用の git worktree が割り当てられます。worktree とは、メインのコピーと履歴を共有しつつ、独自の作業ディレクトリと独自のブランチを持つ、リポジトリの別チェックアウトです。2 つの子エージェントが同じファイルをそれぞれの worktree で編集しても、作業途中の変更がお互いに見えることはありません。つまり構造的に、衝突は起こりようがないのです。

同じくらい重要なのは、あなたの作業コピーがクリーンなまま保たれるという点です。エディタで開いているディレクトリを、エージェントが書き換えることは決してありません。カーソルの下でファイルが勝手に動くことも、書きかけのエージェントの編集が diff に混入することもなく、エージェントの作業を破棄したければ worktree ごと捨てるだけで済みます。変更があなたのブランチに到達するのは、作業が完了しレビューを通過した後だけです。

なぜ単なるブランチやコンテナではないのか

普通のブランチは 1 つの作業ディレクトリを共有します。タスクの途中でブランチを切り替えれば、実行中のエージェントの足元から絨毯を引き抜くようなものです。コンテナやリポジトリのフルクローンでも実現はできますが、いかにも重い。オブジェクトストアの重複、遅いセットアップ、面倒なマージ。worktree はちょうどよい落としどころです。作成はほぼ一瞬、git のオブジェクトデータベースは共有され、子の完了ブランチのマージは普通の git 操作そのもの。信頼すべき独自の同期レイヤーも、デバッグすべきプロプライエタリな状態も存在しません。

6 機能を同時に、実演付きで

ローンチ時のデモはこの仕組みをフル活用していました。ゲーム開発の例では、Muse Code が 6 つのゲーム機能を同時に構築し、各エージェントが専用の worktree で作業して、すべてのブランチがクリーンにマージされました。これこそが実用上のリターンです。複数機能のスプリントにかかる実時間が、全タスクの合計ではなく、最も長い単一タスクの所要時間へと縮んでいくのです。

レシピで試す

エージェントのファンアウトは、Meta が cookbook レシピを提供している 3 つのパターンのうちの 1 つです。大きなジョブをサブエージェントに分割し、作業中の衝突を構造的に排除する。実行可能なバージョンはクックブックにあります。そして、ファンアウトされた作業こそ後から監査したくなるものです。各子エージェントの生成、ツール呼び出し、マージはすべてイベントログに記録されます。並列で起きたからといって、記録に残らないことは何一つありません。

続けて読む