Claude Codeで11人編成のマルチエージェント開発チームを構築した話
目次
はじめに
普段、個人で複数のWebアプリを開発している。それぞれ別のリポジトリで別の技術スタックで、並行して進めている。
Claude Codeを導入して開発速度は上がった。が、3プロジェクト並行で回し始めたら、1セッションでは回らなくなった。設計しながらレビューして、テストも書いて、仕様確認もして——結果、中途半端に全部進んで、どれも完成しない。人間のマルチタスクと同じ罠にAIもハマった。
「じゃあ、AIにもチームを組ませればいいのでは」と思い、tmuxベースのマルチエージェント開発チームを構築した。
最初に言っておくと、個人開発に11人チームは明らかにやりすぎだ。友人に話したら笑われた。でも「やりすぎた結果見えたもの」が予想以上に面白かったので、試行錯誤の過程も含めて共有したい。
最初は3人チームだった
いきなり11人にしたわけではない。最初はPM・TL・Engineerの3人構成で始めた。
これでも1セッションよりはマシだったが、すぐに問題が見えた。TLがコードレビューをしつつ仕様の妥当性も判断するのは荷が重い。「技術的にはOKだけど、そもそもこの仕様って正しいんだっけ?」という問いにTL1人で答えるのは無理がある。
次にBL(ビジネスリード)を追加して4人にした。仕様面のレビューが分離されて品質は上がったが、今度はUIの問題が出てきた。Engineerが「とりあえず動くUI」を作って、後から「これ使いにくい」となってやり直す。結局、UIの専門家がいないと画面設計の手戻りが止まらない。
そんな感じで「必要に迫られて1人ずつ増やした」結果が11人だ。最初からこの構成を計画していたわけではない。
現在のチーム構成
tmuxの1セッションが1プロジェクトに対応し、Window/Paneで役割を分離している。
tmux session: {project-name}
├── Window: pm (1 pane)
│ └── PM — 全体統括・進捗管理・承認
├── Window: lead (3 panes)
│ ├── TL — 技術統括・アーキテクチャ・コードレビュー
│ ├── BL — 要件定義・仕様検証・ビジネスロジック確認
│ └── UI Lead — UI/UX設計統括・デザインチーム管理
├── Window: ui (2 panes)
│ ├── UI Designer — 画面デザイン・コンポーネント設計
│ └── UX Architect — 情報設計・ユーザーフロー設計
└── Window: dev (5 panes)
├── Engineer ×3 — 実装担当
├── Tester — テストインフラ・UT/IT作成
└── QA — E2Eテスト・探索的テスト・品質保証
設計判断のポイント
- PMは作業しない。計画・承認・進捗管理のみ。最初はPMにも軽い実装をやらせていたが、「自分が書いたコードの設計変更を承認する」というバイアスが生まれたのでやめた
- TLとBLの分離。ここは3人チーム時代の反省から。技術的正しさと仕様的正しさは別の脳が必要
- テスターとQAの分離。ユニットテストを書く人と、E2Eで壊しにいく人では、マインドセットが真逆。同じエージェントにやらせると「自分が書いたテストが通るように壊す」という本末転倒が起きた
各エージェントは team.yaml で自分の役割を認識する。
# team.yaml(抜粋)
members:
- role: tl
window: lead
pane: 0
responsibilities:
- 技術統括・アーキテクチャ設計
- コードレビュー
- 技術的意思決定
reports_to: pm
reviews: [bl] # BLと相互レビュー通信プロトコル:カオスとの戦い
11人が自由にしゃべり始めたらどうなるか。試しにルーティングルールなしで走らせてみたことがある。
5分後にはカオスだった。EngineerがPMに直接「この仕様おかしくないですか」と送り、PMが「TLに聞いて」と返し、TLが「それBL案件では」と返す。その間にもう1人のEngineerが別の質問をPMに投げていて、PMのコンテキストは仕様相談で埋まり、肝心の進捗管理ができなくなった。ダッシュボードを見たら、11人中8人が「誰かの返答待ち」で止まっていた。
このとき悟った。自由なコミュニケーションは生産的なコミュニケーションとは違う。人間の組織にルーティングルールがある理由を、身をもって理解した瞬間だった。
tmux直接通信(通知のみ)
# TLからEngineer(pane 0)へ通知
tmux send-keys -t {session}:dev.0 \
"設計書あり: /tmp/shared/{session}/mailbox/eng0-design.md" C-m「ファイル置いたから読んで」程度の短い通知だけに使う。
ファイルベースMailbox(本文)
/tmp/shared/{project}/mailbox/{recipient}-{topic}.md
設計書、レビュー結果、詳細な指示——実質的なコミュニケーションはすべてMarkdownファイル経由。
最初はtmux send-keysで全部送っていた。が、長いメッセージを送ると受信側のコンテキストウィンドウを一気に食う。あるとき、TLに設計書を丸ごと送り込んだら、それだけでコンテキストの1/4を消費してしまい、その後のレビューがスカスカになった。それ以降、本文はファイル経由に統一した。
副次的に、全てのやりとりがMarkdownファイルとして残るので監査証跡にもなる。「なぜこの設計判断をしたか」を後から追えるのは、実際にデバッグで何度か助けられた。
ルーティングルール
| 用件 | 送信元 | 宛先 |
|---|---|---|
| 開発作業指示 | TL | dev |
| 仕様不明点 | dev | BL |
| 技術質問 | dev | TL |
| レビュー依頼 | dev | TL |
| デザインハンドオフ | UI Designer | Engineer |
| エスカレーション | TL/BL | PM |
PMはEngineerに直接指示しない。必ずTLを経由する。人間の組織では当たり前だが、AI相手だと「PMから直接言った方が早くない?」と思いがち。実際にやると、TLが把握していない実装が進行して後からコンフリクトするので、遠回りに見えてもルーティングを守った方が結果的に速い。
Gate System:勝手に先に進ませない仕組み
マルチエージェントで一番困ったのは「設計レビューが終わってないのにEngineerが実装を始めている」問題だ。
最初にこれが起きたのはあるプロジェクトの認証機能で、BLが仕様レビュー中なのにEngineer2が「待ち時間がもったいない」とばかりに実装を始めていた。結果、BLが「この認証フローは要件と違う」とNGを出した時点で、すでに3ファイル200行が書かれていた。全部書き直し。正直、あのときは「なんで先に始めてるんだよ」と画面に向かって声が出た。
2回目は設計のレビュー中に別機能の実装が走った。3回目はテスト仕様が確定する前にテストコードが書かれた。3回目でさすがに仕組みで止めないと無理だと悟り、gate.shを書いた。約800行のBashスクリプトで、フェーズ制御を強制する。
2つのモード
Feature Mode(単機能開発):
調査 → 設計 → 実装 → レビュー → テスト
System Mode(システム全体開発):
[システムフェーズ]
調査 → アーキテクチャ設計 → 計画
[フィーチャーフェーズ] ※依存関係あり、並列実行可能
各機能: 設計 → 実装 → レビュー
[仕上げフェーズ]
結合テスト → E2Eテスト
System Modeでは機能間の依存関係も管理する。「ユーザー管理」が「認証」に依存しているなら、認証が完了するまでユーザー管理の設計には入れない。
使い方
# プロジェクト初期化
gate.sh init $SESSION feature
# フェーズの流れ
gate.sh check $SESSION "設計" # 前提条件を検証(NGなら作業禁止)
gate.sh start $SESSION "設計" # フェーズ開始を記録
gate.sh review $SESSION "設計" bl ok # BLレビューOK
gate.sh review $SESSION "設計" tl ok # TLレビューOK
gate.sh approve $SESSION "設計" # PM承認
gate.sh complete $SESSION "設計" # フェーズ完了 → 次へ状態は /tmp/shared/{project}/workflow-state.json で管理される。複数エージェントが同時にフェーズを更新しようとする競合を避けるため、jqで一時ファイルに書き出してから mv でアトミックに置き換える。直接編集は禁止。
痛い目を見て追加したルール
レビュアー ≠ 実施者。 最初はこの制約を入れていなかった。TLが自分で書いたアーキテクチャ設計を自分でレビューOKにして、結果、大きな見落としがそのまま実装まで行ったことがある。
NG 2回でPM介入。 TLとBLがレビューで延々と往復する現象が発生した。「技術的にはこうすべき」「仕様的にはこうあるべき」が噛み合わず5往復。以降、2回NGが出たらPMが最終判断を下すルールにした。
git pre-commit hookとの連携。 gate.shの状態をpre-commit hookで参照し、フェーズが「実装」で開始済みでない場合はcommitをブロックする。これで「設計フェーズなのにこっそりコード書いてた」が物理的に不可能になった。
リアルタイム監視ダッシュボード
Gate Systemで「勝手に進む」問題は解決した。次の問題は「今何が起きているか分からない」だった。
tmuxのウィンドウを順番に覗いていくのは11人×3プロジェクトだと現実的ではない。ある日、あるプロジェクトのEngineerが許可待ちで30分止まっていたことに気づかず、その間TLもBLも「Engineer待ち」でIDLEだった。人間がボトルネックになっていたのに、それに気づく手段がなかった。
この経験からagent-status.sh(173行)でターミナルTUIを作った。
Agent Status Dashboard
━━━ project-a (19m) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
● pm Screen and document output tests
○ tl —
○ bl —
● engineer3 engineer3
━━━ project-b (10h 40m) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
◆ pm [許可待ち] Project retrospective
● tl Set up Biome linting with Husky pre-c...
● bl Review demo HTML specifications
○ ui_lead —
2 sessions | 22 agents | 1 perm | 1 working | 6 done | 14 idle
Claude Codeの状態をどう外部判定するか
公式APIがないので、かなり泥臭いハックになった。
Claude Codeはtmuxのpane_titleにスピナー文字を表示する。処理中はブレイユ文字(U+2800-28FF)が回り、完了すると✳に変わる。これをxxd -pでバイト列に変換し、e2 a0〜e2 a3の範囲かどうかで処理中/完了を判定している。
# pane_titleの先頭バイトをhexで取得
hex=$(echo -n "$title_char" | xxd -p | head -c6)
# ブレイユ文字範囲なら処理中正直、Claude Codeのバージョンアップでスピナー表示が変わったら壊れる。脆い実装だとは分かっているが、他に方法がなかった。実用上は今のところ安定している。
一番役に立っているのはPERM(許可待ち)の検出で、tmux capture-paneで最終10行を取得し、"Allow", "Deny", "Permission" 等のキーワードを探す。--dangerously-skip-permissionsを使わない運用だと、人間の承認待ちでエージェントが止まるので、これがないと「気づいたら30分間6人が止まっていた」ということが起きる(実際に起きた)。
Manager層:プロジェクト横断の統括
ここまでが1プロジェクト内の話。3プロジェクト並行となると、さらに上位の調整が必要になる。
最初はManagerなしで3つのtmuxセッションを手動で切り替えていた。「プロジェクトAの設計レビューして」「次はプロジェクトBのPMに指示出して」とセッション間を行き来する。15分ごとにコンテキストが切り替わり、各プロジェクトの状態を自分の頭で管理していた。正直、これが一番つらかった。
そこでManager層を追加した。
~/workspace/manager/ # Manager(全プロジェクト統括)
~/workspace/develop/ # 各プロジェクトの開発チーム
Managerは各プロジェクトのPMにのみ通信する。開発メンバーへの直接通信は禁止。ここでもルーティングの原則は同じだ。
# ManagerからPMへ指示
tmux send-keys -t project-a:pm.0 \
"指示あり: /tmp/shared/manager/mailbox/project-a-sprint-plan.md" C-mManagerの仕事は、各プロジェクトのPMから上がってくる進捗報告を集約し、リソース配分を調整すること。「プロジェクトCの認証機能が遅れているから、プロジェクトAは今日のところはIDLEで」みたいな判断をする。人間がやっていたプロジェクト間の切り替えコストをManagerが吸収してくれるので、だいぶ楽になった。
現在、以下の3プロジェクトをこの体制で並行運用している。
- プロジェクトA: 業務管理システム(Feature Mode)
- プロジェクトB: コンテンツ共有アプリ(Feature Mode)
- プロジェクトC: 審査システム(System Mode、8フィーチャー並行開発)
コストの話:正直に書く
一番聞かれるので先に答えておく。11エージェント並列はレートリミットとの戦いだ。
Claude Code Maxプラン(月額$200)を使っている。Proプラン($20)の5倍のレートリミットがあるが、11人が一斉に動くとそれでも上限に当たることがある。特にOpusモデルでTL/BLが大きなファイルを読み込むレビューフェーズは消費が激しい。体感として、3プロジェクト全員稼働だと数時間でレートリミットに達する日もあった。
実用的には、全員を同時に動かす必要はない。Feature Modeなら同時稼働は3〜5人程度で、残りはIDLE。System Modeの並列フィーチャー開発時に最大稼働になるが、それも一時的。常に11人がフル回転しているわけではない。
節約のために地味だが効果のある工夫をしている。
- Readツールでoffset/limitを必ず指定。800行のファイルを全部読ませるのと、変更対象の30行だけ読ませるのではトークン消費が全然違う
- サブエージェントには行範囲つきで指示。「src/router.ts見て」ではなく「src/router.ts:30-50を見て」
- レビューはgit diffのみ。変更されてないファイルの再読み込みは禁止
- コミットは1論理変更ずつ。巨大なdiffをレビューさせるとそれだけでコンテキストが埋まる
月額$200が高いか安いかは人それぞれだが、個人開発でこの体制を維持するなら必要経費だと割り切っている。3プロジェクトを人間のフリーランスに頼んだら桁が3つ違う。
実際に運用して得られたもの
品質:別視点のレビューは本当に効く
あるプロジェクトの登録機能で、TLが「実装OK、LGTM」とレビューしたものをBLが差し戻したことがあった。理由は「ステータス遷移が要件定義と違う」。TLは技術面(バリデーション、型安全性、エラーハンドリング)を見ていて、ビジネスロジックの妥当性は視野に入っていなかった。
別の機能では、UIデザイナーがFigmaで作ったデザインをEngineerが実装した後、UI Leadが「この画面遷移だとユーザーが迷う」とUX観点で差し戻した。技術的にもデザイン的にも正しいが、ユーザー体験としてNGというケース。1人では絶対に気づけない。
こういう「別視点からの差し戻し」が月に数回発生する。毎回「分離しておいてよかった」と思う。
想定外だったのは、BLとTLの設計レビューのやりとり自体が設計ドキュメントとして機能し始めたこと。mailboxに残ったレビューの往復を後から読むと、「なぜこの設計にしたか」「どの案を棄却したか」が全部残っている。意図して作った仕組みではないが、結果的に一番役に立っている副産物かもしれない。
プロセス:もどかしいけど手戻りよりマシ
Gate Systemで手戻りが体感で7割減った。「設計が固まってないのに実装を始めて全部やり直し」がなくなった。
代わりに「設計レビュー待ちでEngineerが暇」という時間が発生する。もどかしい。でも、200行書き直すよりレビュー待ちの30分の方がずっとマシ。これは人間のチーム開発でも同じで、「プロセスが遅く感じる」のは正しく機能している証拠でもある。
運用:ダッシュボードは生命線
22エージェントを1画面で見られるようにしたことで、運用の質が変わった。特にPERM待ちの検出。以前は「なんか進捗ないな」と思って各ペインを巡回して「あ、3人許可待ちだった」と気づくまでに15分かかっていた。今はダッシュボードの赤◆を見れば1秒で分かる。
残っている課題
ターミナルの視認性はまだ課題で、個別ペインの中身を見たいときはダッシュボードでは不十分。通信レイテンシもファイルベース通信の宿命で、数秒〜数十秒のラグがある。リアルタイムな議論には向かない。
コンテキストウィンドウの消費も悩みどころで、長時間稼働するとTL/BLのコンテキストが埋まる。定期的にセッションをリフレッシュする運用でカバーしているが、もう少しスマートな方法がないか模索中。
--dangerously-skip-permissions は実用上ほぼ必須になっている。11人が毎回許可を求めてきたら、人間がボタンを押す作業だけで午前中が終わる。名前の通りdangerousではあるが、代替手段がない現状ではトレードオフとして受け入れている。
始めるならどこから
「面白そうだけど、いきなり11人は無理」という人向けに、段階的な導入パスを書いておく。
Step 1: 3人チーム(PM + TL + Engineer) 最小構成。PMが計画と承認、TLがレビュー、Engineerが実装。これだけでも「セルフレビューの限界」は突破できる。自分が最初にやったのもこの構成で、初日から「別人にレビューしてもらう」効果を実感した。tmuxのセットアップは以下の通り。
# 最小3人チームの起動例
tmux new-session -d -s myproject -n pm
tmux new-window -t myproject -n lead
tmux new-window -t myproject -n dev
mkdir -p /tmp/shared/myproject/mailbox
# 各paneでClaude Codeを起動し、CLAUDE.mdで役割を認識させるStep 2: +BL(4人) 仕様の妥当性チェックが必要になったら追加。自分の場合、TLが「技術OK」と言ったものをBLが「仕様NG」で差し戻すケースが出始めて「これは分けないとまずい」と感じた。leadウィンドウにpaneを1つ足すだけ。
Step 3: +Tester(5人) 実装者がテストも書くと、テストが実装に寄り添いすぎる。独立したTesterを入れるとテストの観点が変わる。
Step 4: UI Designer + UI Lead(7人) UIの手戻りが目立ち始めたら。フロントエンドがあるプロジェクトでは特に効果が大きい。
Step 5〜: 必要に応じて QA、UX Architect、Engineer追加は、プロジェクトの複雑さ次第。必要を感じてから増やす。「多分必要」で増やすと遊休エージェントが出るだけ。
gate.shは3人構成でも使える。むしろ少人数のうちにワークフロー制御を入れておくと、人数が増えたときにスムーズ。
まとめ
一番印象に残っているのは、ルーティングルールなしで11人を走らせた日のことだ。5分で8人が待ち状態になり、「ああ、組織のルールって飾りじゃなかったんだ」と本気で思った。
この体制を作って運用してみて分かったのは、AIエージェントのオーケストレーションに必要な知識は、新しい技術ではなくて昔からある組織論だということ。役割の分離、指揮系統の設計、プロセスの強制、状態の可視化。どれも人間の組織で長年かけて磨かれてきたプラクティスで、それがAI相手でもそのまま通用した。
逆に言えば、AIだから特別なことをする必要はなかった。レビュアーと実施者を分ける、PMは手を動かさない、指揮系統を飛ばさない——全部、人間のチームでも言われることだ。違いがあるとすれば、AIはルールを明文化しないと本当に守らない、という点くらい。人間なら「空気を読んで」できることも、AIには team.yaml と gate.sh で明示的に書かないといけない。
この体制が正解かは分からない。Claude Codeのアップデートで壊れるかもしれないし、もっとスマートなやり方が出てくるかもしれない。でも、「AIに組織で働いてもらう」という実験を通じて、人間の組織設計の理由が身体感覚として分かったことは、個人的には一番の収穫だった。
関連記事
- 技術
Claude Codeマルチエージェントのリアルタイム監視ダッシュボードを作った
Claude Codeをtmuxで11人編成のマルチエージェントとして運用する中で生まれた「誰が何をしているか分からない」課題を、173行のBashスクリプトによるターミナルTUIダッシュボードで解決した設計と実装の記録。
ClaudeAIマルチエージェント - 技術
Webカメラだけで物理マウスを捨てる - NonMouseをM2 Mac + Python 3.14で再起動して自分用にチューニングした話
Webカメラと手のランドマーク検出でマウスを動かすOSS「NonMouse」を、M2 Mac + Python 3.14で動かすまでの依存再構築・Tasks API移行・TUI化と、押下トグル操作や加速カーブのチューニングを実装ベースで記録。
Python - 技術
React入門 - コンポーネント、JSX、Props、Stateの基本
Reactの基礎であるコンポーネント、JSX、Props、Stateを初心者向けに解説。宣言的UIの考え方、TypeScriptでの型定義、State更新の落とし穴、よくあるエラーと解決策、Todoアプリの実践例まで、つまずきポイントを押さえながら学べます。
ReactTypeScriptJavaScript
