ブログに戻る

13体のAIエージェントでソフトウェアを出荷している。実際の様子がこれだ

これが今のターミナルだ。

13エージェントtmuxセッション

13体のClaude Codeエージェント。それぞれ独自のtmuxペインで、同じコードベースで作業している。実験ではない。見せびらかしでもない。毎日ソフトウェアを出荷している方法がこれだ。

プロジェクトはBeadbox。AIコーディングエージェントをモニタリングするリアルタイムダッシュボードだ。モニタリング対象のエージェントフリート自体がBeadboxを構築している。エージェントがコードを書き、テストし、レビューし、パッケージングし、出荷する。自分はコーディネートする。

2〜3体以上のエージェントを動かしていて、全員が何をしているか把握する方法を模索しているなら、数ヶ月のイテレーションを経てたどり着いた形がこれだ。

編成

すべてのエージェントにCLAUDE.mdファイルがあり、アイデンティティ、担当範囲、担当外の範囲、他のエージェントとのコミュニケーション方法が定義されている。汎用的な「何でもやる」アシスタントではない。それぞれが狭い職務と明確な境界を持つ。

グループ エージェント 担当範囲
コーディネーション super, pm, owner 作業ディスパッチ、プロダクト仕様、ビジネス優先度
エンジニアリング eng1, eng2, arch 実装、システム設計、テストスイート
品質 qa1, qa2 独立した検証、リリースゲート
オペレーション ops, shipper プラットフォームテスト、ビルド、リリース実行
グロース growth, pmm, pmm2 アナリティクス、ポジショニング、パブリックコンテンツ

キーワードは境界だ。eng2はイシューをクローズできない。qa1はコードを書かない。pmmはアプリのソースに触れない。superは作業をディスパッチするが実装しない。境界が存在する理由は、境界がないとエージェントがドリフトするからだ。リファクタリング不要なコードをリファクタリングして「手伝おう」とし、検証されていないイシューをクローズし、資格のないアーキテクチャ決定を下す。

すべてのCLAUDE.mdはアイデンティティの段落と境界セクションから始まる。eng2のものを簡略化した例:

## Identity
Engineer for Beadbox. You implement features, fix bugs, and write tests.
You own implementation quality: the code you write is correct, tested,
and matches the spec.

## Boundary with QA
QA validates your work independently. You provide QA with executable
verification steps. If your DONE comment doesn't let QA verify without
reading source code, it's incomplete.

このパターンはスケールする。3体のエージェントから始めたとき、1つの緩いプロンプトを共有できた。13体では、明示的なロールとプロトコルがコーディネーションとカオスの分かれ目だ。

コーディネーションレイヤー

3つのツールがフリートを束ねている。

beads はオープンソースのGitネイティブイシュートラッカーで、まさにこのワークフローのために構築された。すべてのタスクは「bead」であり、ステータス、優先度、依存関係、コメントスレッドを持つ。エージェントはbdというCLIを通じて同じローカルデータベースを読み書きする。

bd update bb-viet --claim --actor eng2   # eng2がバグを担当
bd show bb-viet                           # 仕様全体 + コメントを確認
bd comments add bb-viet --author eng2 "PLAN: ..."  # eng2がプランを投稿

gn / gp / ga はtmuxメッセージングツールだ。gnは別のエージェントのペインにメッセージを送る。gpは別のエージェントの最近の出力を覗く(中断せずに)。gaは緊急でないメッセージをキューに入れる。

gn -c -w eng2 "[from super] You have work: bb-viet. P2."  # ディスパッチ
gp eng2 -n 40                                               # 進捗確認
ga -w super "[from eng2] bb-viet complete. Pushed abc123."  # 報告

CLAUDE.mdプロトコル がエスカレーションパス、コミュニケーションフォーマット、完了基準を定義する。すべてのエージェントが知っている: beadを担当し、コーディング前にプランをコメントし、プッシュ前にテストを実行し、検証ステップ付きでDONEをコメントし、QA待ちにマークし、superに報告する。

superは5〜10分ごとにパトロールループを実行する: 各アクティブエージェントの出力を覗き、beadのステータスを確認し、パイプラインが停滞していないか検証する。プロダクションのオンコールローテーションのようなものだが、サービスがAIエージェントで、インシデントが「eng2が20分間不審に静かだ」というものだ。

ある日の実際

2026年2月下旬の水曜日に実際に起きたこと。

午前9:14 - GitHubユーザーericinfinsがIssue #2を開く: Beadboxをリモートのdoltサーバーに接続できない。アプリはローカル接続のみサポート。ownerがそれを見てsuperにフラグを立てる。

午前9:30 - superが作業をディスパッチ。archが接続認証フロー(TLSトグル、ユーザー名/パスワードフィールド、環境変数の受け渡し)を設計。pmが受け入れ基準付きの仕様を書く。engがピックアップして実装開始。

その間、並行して:

PMがリリーステスト中に発見した2つのバグを登録。1つは外観上のもの: ヘッダーバッジが最終ビルドで"v0.10.0"ではなく"v0.10.0-rc.7"と表示される。もう1つはプラットフォーム固有: スクリーンショット自動化ツールがARM64 Macで空の帯を返す。Apple SiliconがTauriのWebViewをMetal合成でレンダリングし、バッキングストアが空になるため。

opsがスクリーンショットバグの根本原因を突き止める。修正はエレガント: キャプチャ後に画像の高さが不審に小さい(800pxであるべきウィンドウに対して50px未満)かチェックし、座標ベースのスクリーンキャプチャにフォールバックする。

growthがPostHogデータを取得し、IP相関分析を実行。発見: Reddit広告は96クリックで帰属可能なリテンションユーザーはゼロ。GitHub READMEトラフィックは15.8%でコンバージョン。まさにこの記事はその分析の結果として存在する。

eng1archのActivity Dashboard設計でブロック解除され、クロスフィルターの状態管理とユーティリティ関数の構築を開始。687テストがパス。

qa1がヘッダーバッジの修正を検証: テストサーバーを立ち上げ、ブラウザ自動化でバッジが正しくレンダリングされることを確認し、665ユニットテストがパスすることをチェックし、PASSをマーク。

午後2:45 - shipperがリリース候補PRをマージし、v0.10.0タグをプッシュし、プロモートワークフローをトリガー。CIが5プラットフォーム(macOS ARM、macOS Intel、Linux AppImage、Linux .deb、Windows .exe)のアーティファクトをビルド。shipperが各アーティファクトを検証し、両リポジトリのリリースノートを更新し、ウェブサイトを再デプロイし、Homebrew caskを更新。

午後3:12 - ownerがGitHub Issue #2に返信:

Good news: v0.10.0 just shipped with full Dolt server auth support. Update and you should be unblocked.

午前にバグが報告され、午後には修正が出荷された。そしてその間、次の機能が設計され、別のバグの根本原因が分析され、アナリティクスが解析され、QAが独立して別の修正を検証していた。

それは13体のエージェントが速いからではない。13体のエージェントが並列だからだ。

うまくいかないこと

「こんなAIセットアップを使っています」系の記事がたいてい省く部分だ。

高並行時にレートリミットにぶつかる。 13体のエージェントがすべて同じAPIアカウントで動いていると、トークンを急速に消費する。この日は、supereng1eng2が同時にレートリミット上限に達した。全員が停止。待つしかない。オフィスの全員が同時にプリンターを使おうとするAI版だが、プリンターは1ページごとに課金され、1分あたりのページ数に上限がある。

QAが作業を差し戻す。 これは設計通りだが、サイクルが増える。QAがビルドをリジェクトした。エンジニアの「DONE」コメントに検証ステップが含まれていなかった。修正は動いていたが、QAがソースコードを読まずに確認できなかった。engに差し戻し、完了コメントを書き直し、QAに再戻し、再検証。5分で済むはずのことに20分かかった。プロトコルが摩擦を生むが、その摩擦は耐荷重性だ。QAをショートカットするたびに、何かがプロダクションで壊れた。

コンテキストウィンドウが埋まる。 エージェントはセッション中にコンテキストを蓄積する。superには、コンテキスト使用率65%で「作業を保存しろ」ディレクティブを送るプロトコルがある。そのタイミングを逃すと、エージェントは自分が何をしていたか見失う。

エージェントがスタックする。 エージェントがエラーループにハマり、同じ失敗するコマンドをリトライし続けることがある。superのパトロールループがこれをキャッチするが、十分な頻度でチェックしている場合に限る。礼儀正しく沈黙の中で失敗し続けるエージェントに30分を失ったことがある。

コーディネーションのオーバーヘッドは現実だ。 CLAUDE.mdファイル、ディスパッチプロトコル、パトロールループ、beadコメント、完了レポート。2体のエージェントのセットアップなら過剰だ。13体では最小限の構造だ。非公式なコーディネーションが機能しなくなり、明示的なプロトコルがないと何が起きているか把握できなくなるクロスオーバーポイントが、約5体のあたりにある。

学んだこと

専門化が汎用化に勝る。 13体のフォーカスされたエージェントは3体の「フルスタック」エージェントを上回る。qa1が検証のみでコードを書かないとき、engが見逃したものを毎回キャッチする。archが設計のみで実装しないとき、実装を楽にするために仕様をショートカットする誘惑がないため、設計がクリーンになる。

独立したQAは譲れない。 QAは独自のリポジトリクローンを持つ。プッシュされたコードをテストし、ワーキングツリーではない。エンジニアの自己申告を信用しない。遅く感じるかもしれない。毎回のリリースでバグをキャッチしている。

可視性がないとフリートはドリフトする。 5体以上のエージェントでは、tmuxペインを切り替えて頭の中でbd listを実行するだけでは状態を追えない。依存関係ツリー、どのエージェントが何に取り組んでいるか、どのbeadがブロックされているかを表示するダッシュボードが必要だ。これがBeadboxを構築した理由だ。

再帰ループが重要だ。 エージェントがBeadboxを構築する。BeadboxがエージェントをモニタリングするBeadboxにバグが生じると、他のすべてのバグをキャッチしたのと同じQAプロセスでフリートがそれをキャッチする。ツールが改善されるのは、最も使うチームがそれを作るチームだからだ。これは天才的か、史上最も精巧なピタゴラスイッチかのどちらかだと自覚している。出荷された機能は前者を示唆し、トークンの請求書は後者を示唆している。

スタック

自分でも試したいなら、必要なものはこれだ:

  • beads: オープンソースのGitネイティブイシュートラッカー。コーディネーションの背骨。すべてのエージェントがこれを読み書きする。
  • Claude Code: エージェントランタイム。各エージェントはtmuxペイン内のClaude Codeセッションで、独自のCLAUDE.mdアイデンティティファイルを持つ。
  • tmux + gn/gp/ga: エージェントを並べて実行するためのターミナルマルチプレクサ。メッセージングツールにより、共有メモリなしでエージェント間通信が可能。
  • Beadbox: フリートが何をしているかを表示するリアルタイムビジュアルダッシュボード。今読んでいるのがこれだ。

13体すべてのエージェントを最初から必要としない。2人のエンジニアと1体のQAエージェントをbeadsでコーディネートすれば、1人の開発者が何を出荷できるかについての考え方が変わる。

次に来るもの

現在のセットアップで最大のギャップは、3つの質問に一目で答えられないことだ。どのエージェントがアクティブで、アイドルで、スタックしているのか?パイプラインのどこに作業が溜まっているのか?そして、自分が気にしているエージェントやステージでフィルタリングして、直近で何が起きたのか?

今はパトロールループと大量のgpコマンドが必要だ。だからBeadboxに直接コーディネーションダッシュボードを構築している。上部にエージェントステータスストリップ、beadsがどこに蓄積しているかを示すパイプラインフロー、そしてエージェントやパイプラインステージをクリックすると他のすべてが連動してフィルタリングされるクロスフィルタードイベントフィード。3つのレイヤーはすべて同じリアルタイムデータソースを共有している。3つともライブで更新される。

Activity Dashboard preview

13体のエージェントが今まさにこれを構築している。出荷されたら書く。

自分で試してみる

まず beads を連携レイヤーとして導入。ビジュアルな管理が必要になったら Beadbox を追加。

ベータ期間中は無料。アカウント不要。データはローカルに保存されます。

Share