本文へスキップ
ウェブエンジニア問題集
第7章

複数のAIエージェントを同時に走らせるときに壊れるもの

約9分
この章の目次開く

エージェントが速いと分かると、次に考えるのは同じことです。3つ同時に走らせれば3倍になるのでは。

半分は当たっています。ただし何も考えずに並べると、壊れるものがあります。しかも壊れ方が分かりにくく、症状から原因にたどり着けないことが多い。この章では、何が壊れるのかを構造で押さえます。

学習者学習者

ターミナルを3つ開いて、同じプロジェクトで3つ動かせばいいんじゃないの?

同じディレクトリで複数動かすと衝突する

いちばん素直なやり方が、いちばん先に壊れます。同じ作業ディレクトリで複数のエージェントを動かすと、同じファイルを同時に編集して互いの変更を上書きします。

これを避ける標準的な手段が git worktree です。公式ドキュメントの説明では、worktreeとは独自のファイルとブランチを持つ別の作業ディレクトリで、リポジトリの履歴とリモートは元のチェックアウトと共有します。それぞれのセッションを別のworktreeで動かせば、一方の編集が他方のファイルに触れることはありません。

分岐する道

ここまでは広く知られています。問題はこの先です。

worktreeが隔離するもの、しないもの

worktreeは作業ディレクトリを分けますが、すべてを分けるわけではありません。公式が明示している共有物と、そもそも範囲外のものを並べます。

分類具体例
隔離される作業ファイル、チェックアウトしているブランチ
共有される(公式明記)リポジトリの .git ディレクトリ、プロジェクトスコープのプラグイン、権限の承認
そもそも範囲外ポート、データベース、ビルド成果物の出力先、キャッシュ、生成ファイル

真ん中の権限の承認は知っておく価値があります。worktreeの中で「今後は聞かない」を選ぶと、その許可ルールはメインチェックアウト側の設定ファイルに保存され、リポジトリ全体とすべてのworktreeに効きます。worktreeを消しても残ります。隔離されているつもりで許可を出すと、範囲は隔離されていません。

そして実務で本当に効いてくるのが、いちばん下の行です。

worktreeは作業ディレクトリを分けますが、ディレクトリの外にある共有状態は分けません。

実例 — 共有の生成物が壊れる

抽象的なので、実際に起きた例を挙げます。このサイトのリポジトリで起きた事故です。

コンテンツをビルドするツールが、リポジトリ直下の1つのディレクトリに約10MBのJSONを生成します。このツールはロックも一時ファイルも使わず、生成先へ直接書き込みます。

複数のセッションが同時に開発サーバーを立てると、2つのプロセスが同じファイルへ同時に書き込み、JSONが壊れます。結果として全ページが500エラーになります。

同じ構造の事故は、あちこちにあります。

  • 同じポートで開発サーバーを立てて、後から起動したほうが別ポートに逃げる(そして参照先がずれる)
  • 同じ開発用データベースにマイグレーションを同時に流す
  • 共有のキャッシュディレクトリを同時に書き換える
  • 同じ生成ファイル(型定義、APIクライアント、スナップショット)を同時に再生成する
並列にする前に、「このプロジェクトで、作業ディレクトリの外に書き込むものは何か」を洗い出します。

新しいチェックアウトは空である

もう1つ、公式が明記している実務的な性質があります。worktreeは新しいチェックアウトなので、Git管理外のファイルは存在しません。.env も、インストール済みの依存も、ビルド済みの成果物もありません。

つまり、worktreeを作るたびに開発環境の初期化が要ります。依存をインストールし、環境変数を用意する。ここを自動化しないと、並列化のたびに手作業が増えて、結局遅くなります。

Git管理外のファイルを新しいworktreeへ自動コピーする仕組みは用意されていますが、シークレットの章で触れたとおり、秘密の複製がworktreeの数だけ増える点は意識してください。

後片付けが要る

公式の挙動として、対話的なセッションを終了するとき、worktreeに作業が残っていなければ自動で削除され、残っていれば確認を求められます。

ただし非対話モードで走らせた場合は終了時の確認がないため、worktreeは片付けられません。スクリプトで大量に並列実行すると、worktreeが溜まり続けます。定期的な掃除の仕組みはありますが、作業が残っているものは保護されるので、手で消す判断が必要になる場面はあります。

並列度の上限を決めるのは人間

技術的な問題を全部解決しても、まだ天井があります。人間側です。

導入から3か月後に社内アンケートを取った12名規模のチームの報告では、66.7%が並列作業の増加による認知の負荷を課題に挙げました。疲労の増加が42%、ストレスの増加が25%。同じ調査で83%が生産性の向上を実感しているので、効果と負荷が同時に増えています。

急いでいる人

さらに2つ、上限として効くものがあります。

  • レビューの章で扱う、人間が1回に見られる差分量の上限(1回400行・60分が目安)
  • コストの章で扱う、複数エージェント構成は標準的なセッションの約7倍のトークンを使うという公式の目安
並列度の上限を決めるのは、マシンでもエージェントでもなく、レビューできる人間の数です。

並列にしてよいもの、いけないもの

判断の目安です。

並列にしてよい並列にしてはいけない
触るファイルが重ならない同じファイル・同じモジュールを触る
生成物の出力先が分かれている同じ生成ファイルを作り直す
片方の結果を他方が使わない前の結果を前提にした続きの作業
それぞれ独立に検証できるまとめてからでないと検証できない
先生先生

並列にする前に「担当範囲」と「触ってはいけないもの」を先に決める。人間のチーム開発と同じだよ。

よくあるハマりどころ

同じディレクトリで複数動かす。 最も基本的な失敗です。worktreeで分けます。

共有状態を見落とす。 worktreeで安心してしまい、ポートや生成物の競合に気づかない。症状から原因が遠いので、時間を溶かします。

依存のあるタスクを並列にする。 互いの前提を壊し合い、両方が失敗します。

後片付けをしない。 特に非対話モードでは自動で片付きません。

人間の処理能力を超えて並べる。 レビューが詰まり、疲労が上がり、品質のばらつきが放置されます。

worktree内の許可設定が隔離されていると思う。 権限の承認はリポジトリ全体に効きます。

ちゃんと使うためのポイント

  • 同じディレクトリでの並列は壊れる。worktreeで作業ディレクトリを分ける
  • worktreeが隔離するのはファイルとブランチだけ。.git・プラグイン・権限の承認は共有される
  • 本当に危ないのは作業ディレクトリの外にある共有状態(ポート・DB・生成物・キャッシュ)
  • 並列にする前に、外に書き込むものを洗い出す
  • worktreeは空のチェックアウト。初期化の自動化が要る
  • 非対話実行は後片付けされない
  • 並列度の上限はレビューできる人間の数で決まる

次の章では、並列に走らせたエージェントを「見張らずに済ませる」方法を扱います。並べただけで張り付いていては、負荷が増えるだけになります。

参考リンク