メインコンテンツへスキップ
モジュール 2:マルチエージェント 3 / 6
中級 Session 9 エージェントチーム コミュニケーション

エージェントチームとコミュニケーション

TeammateManager と JSONL メッセージバスがどのようにマルチエージェントのコラボレーションを実現するかを探る。

2026年3月20日 20 分で読む

学ぶこと

サブエージェント(セッション4)は、個々のサブタスクに対するコンテキスト分離の問題を解決します。しかし、持続的で継続的なコラボレーションが必要な場合はどうでしょうか?あるエージェントがコードを書き、別のエージェントがそれをレビューし、両者が多くのターンにわたってそれぞれのコンテキストを維持する必要がある場合は?

ここでエージェントチームが登場します — 複数の Claude Code インスタンスが並行して動作し、それぞれが独自のコンテキストウィンドウを持ち、共有メッセージバスを通じて通信します。

このセッションが終わるまでに、以下のことを理解できるようになります:

  • エージェントチームがサブエージェントとどう異なるか
  • TeammateManager 調整レイヤー
  • JSONL メッセージバスによるエージェント間通信の仕組み
  • チームトポロジー:名前、役割、メッセージングパターン
  • 一般的なマルチエージェントワークフローの実用的な構成

問題

サブエージェントは強力ですが一時的です。スポーンし、タスクを実行し、結果を返し、消えます。そのコンテキストは破棄されます。これは一回限りの調査や探索には最適ですが、継続的なコラボレーションには対応できません:

Subagent Limitation:

  Turn 1: Spawn reviewer agent → reviews code → result → context gone
  Turn 2: Spawn reviewer agent → has no memory of Turn 1 review
  Turn 3: Spawn reviewer agent → starts from scratch again

  Each review is isolated. The reviewer can't track
  whether its previous feedback was addressed.

また、スケールが大きくなるとコンテキスト汚染の問題も発生します。複雑な機能を構築している場合、実装者のコンテキストはコードで埋まり、レビューのフィードバックがその上に蓄積されます。最終的に、単一のコンテキストウィンドウでは実装の詳細とレビュー履歴の両方を保持できなくなります。

必要なのは、互いに通信できる独立したコンテキストを持つ永続的なエージェントです:

Agent Teams:

  ┌─────────────────┐     ┌─────────────────┐
  │  Implementer    │     │  Reviewer        │
  │  (own context)  │◄───►│  (own context)   │
  │                 │     │                  │
  │  Remembers all  │     │  Remembers all   │
  │  code written   │     │  review feedback │
  └─────────────────┘     └─────────────────┘
         │                        │
         └──────────┬─────────────┘

            ┌───────▼────────┐
            │  JSONL Message │
            │  Bus (shared)  │
            └────────────────┘

仕組み

エージェントチームの有効化

エージェントチームは環境変数で有効化する実験的な機能です:

export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1

有効化されると、Claude Code セッション内でキーボードショートカットを使用してチームメイトを作成できます:

ショートカットアクション
Shift+Up / Shift+Downチームメイトの選択
Shift+Tabデリゲートモード(チームメイトにタスクを送信)
Ctrl+T全チームメイトのタスクリストを表示

各チームメイトは、独自のターミナル、独自のコンテキストウィンドウ、独自の会話履歴を持つ別の Claude Code プロセスとして動作します。

TeammateManager

TeammateManager は、セッション内のすべてのアクティブなチームメイトを追跡する調整レイヤーです。誰がアクティブか、その役割、通信チャネルのレジストリを維持します:

┌──────────────────────────────────────────────────┐
│                TeammateManager                    │
│                                                   │
│  Registry:                                        │
│  ┌─────────────────────────────────────────┐     │
│  │  Name: "implementer"                    │     │
│  │  Role: "Write and modify source code"   │     │
│  │  Status: active                         │     │
│  │  Context: [independent message array]   │     │
│  ├─────────────────────────────────────────┤     │
│  │  Name: "reviewer"                       │     │
│  │  Role: "Review code and suggest fixes"  │     │
│  │  Status: active                         │     │
│  │  Context: [independent message array]   │     │
│  ├─────────────────────────────────────────┤     │
│  │  Name: "tester"                         │     │
│  │  Role: "Write and run tests"            │     │
│  │  Status: active                         │     │
│  │  Context: [independent message array]   │     │
│  └─────────────────────────────────────────┘     │
│                                                   │
│  Message Bus: ~/.claude/teams/session-xyz.jsonl   │
│                                                   │
└──────────────────────────────────────────────────┘

レジストリ内の各チームメイトは以下を持ちます:

  • Name — メッセージのアドレス指定に使用される一意の識別子
  • Role — チームメイトの動作を形成する説明
  • Status — チームメイトがアクティブ、アイドル、または完了かどうか
  • Context — 独立したメッセージ配列(チームメイト独自の会話)

JSONL メッセージバス

チームメイトはファイルベースの JSONL メッセージバスを通じて通信します。各メッセージは共有ファイルに追加される1行の JSON です:

Communication Flow:

  Implementer                    Reviewer
  ┌──────────┐                  ┌──────────┐
  │ writes   │    message.jsonl │ reads     │
  │ code     │───────────────►  │ message   │
  │          │                  │ reviews   │
  │ reads    │  ◄───────────────│ sends     │
  │ feedback │    message.jsonl │ feedback  │
  └──────────┘                  └──────────┘

バス上のメッセージは以下のようになります:

{"from": "implementer", "to": "reviewer", "type": "request", "content": "I've finished the auth middleware in src/middleware/auth.ts. Please review for security issues.", "timestamp": "2026-03-20T10:15:30Z"}
{"from": "reviewer", "to": "implementer", "type": "response", "content": "Found 2 issues: (1) JWT secret is hardcoded on line 15, use env var. (2) No rate limiting on login endpoint.", "timestamp": "2026-03-20T10:16:45Z"}
{"from": "implementer", "to": "reviewer", "type": "request", "content": "Fixed both issues. JWT secret now from process.env.JWT_SECRET, added rate-limiter-flexible on /login. Ready for re-review.", "timestamp": "2026-03-20T10:18:20Z"}

なぜ JSONL なのか?ネットワークベースの通信に対していくつかの利点があります:

  • 追記専用 — 複数のエージェントが同時に書き込んでも競合しない
  • 永続的 — エージェントが再起動してもメッセージが残る
  • 検査可能 — ファイルを読んで完全な通信履歴を確認できる
  • シンプル — サーバー不要、ポート不要、ネットワーク不要 — ただのファイル

SendMessage ツール

チームメイトは SendMessage ツールを使用して通信します:

{
  "type": "tool_use",
  "name": "SendMessage",
  "input": {
    "to": "reviewer",
    "content": "The auth middleware is ready for review. Key files: src/middleware/auth.ts, src/routes/auth.ts"
  }
}

受信側のチームメイトは、次のターンでシステム通知としてメッセージを確認します。これはバックグラウンドタスクの完了が報告される方法(セッション8)と似ています。

スケールでのコンテキスト分離

エージェントチームの単一エージェントに対する根本的な利点はコンテキスト分離です。比較してみましょう:

Single Agent (200K context):
  ┌──────────────────────────────────────────────┐
  │  System prompt          ~3K tokens           │
  │  Implementation code    ~50K tokens          │
  │  Review feedback        ~20K tokens          │
  │  Test output            ~15K tokens          │
  │  Documentation          ~10K tokens          │
  │  ─────────────────────────────────────       │
  │  Total: ~98K tokens     (49% capacity)       │
  │  All competing for the same context window   │
  └──────────────────────────────────────────────┘

Agent Team (200K x 3 contexts):
  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
  │  Implementer    │  │  Reviewer        │  │  Tester          │
  │  ~53K tokens    │  │  ~23K tokens     │  │  ~18K tokens     │
  │  (27% capacity) │  │  (12% capacity)  │  │  (9% capacity)   │
  │                 │  │                  │  │                  │
  │  Deep code      │  │  Deep review     │  │  Deep test       │
  │  context        │  │  context         │  │  context         │
  └─────────────────┘  └─────────────────┘  └─────────────────┘
  Total: 600K tokens available, each domain has room to breathe

各チームメイトは他のメンバーを圧迫することなく、自分の担当領域を深く掘り下げることができます。レビュアーは、実装者のコード用の利用可能なコンテキストを減らすことなく、広範なレビュー履歴を保持できます。

キーインサイト

チームは各エージェントに独自のコンテキストウィンドウを与え、サブエージェントよりも大きなスケールでコンテキスト汚染の問題を解決します。 サブエージェントはステートレスです — スポーンし、実行し、消えます。チームメイトはステートフルです — 多くのターンにわたって永続し、ドメイン知識を蓄積し、継続的な対話を行います。

これは実際のエンジニアリングチームの働き方を反映しています。コードレビュアーは、次のプルリクエストのレビューを依頼されたときに以前のレビューを忘れません。QA エンジニアは、今週のビルドをテストするときに先週見つけたバグを覚えています。永続的なコンテキストにより、蓄積された専門知識が可能になります。

JSONL メッセージバスは、これを機能させる接着剤です。これがなければ、チームメイトは孤立したサイロになります。これがあることで、各メンバーが自分の一貫したコンテキストを維持しながら専門的な視点を提供する協力的なチームが形成されます。

ネットワークプロトコルではなくファイルベースのメッセージング(JSONL)を使用するという設計選択は意図的です。ファイルはシンプルで、デバッグしやすく、インフラストラクチャを必要としません。メッセージバスを cat して、エージェントが互いに何を言っているかを正確に確認できます。この透明性は信頼にとって重要です — エージェント間で何が起きているかを常に把握できます。

実践例

実装者 + レビュアーチームの構成

機能開発ワークフローのための2エージェントチームの構成方法:

Terminal 1 — Implementer:
  $ export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
  $ claude
  > I'm the implementer. I'll write the code for the
    notification system.

Terminal 2 — Reviewer:
  $ export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
  $ claude
  > I'm the reviewer. I'll review code that the implementer
    produces and provide security and quality feedback.

両方が動作すると、ワークフローは以下のようになります:

Implementer                         Reviewer
────────────                        ────────────
Writes notification model
  └── src/models/notification.ts

Sends: "Model ready for review"
                          ────────►
                                    Reviews model
                                    Sends: "Add index on
                                    userId for query perf"
                          ◄────────

Adds index, continues to
write API endpoints
  └── src/routes/notifications.ts

Sends: "Endpoints ready"
                          ────────►
                                    Reviews endpoints
                                    Sends: "LGTM, but add
                                    pagination to GET /list"
                          ◄────────

Adds pagination, marks
feature complete

3エージェントチーム:実装、レビュー、テスト

より大きな機能には、テストエージェントを追加します:

Team Configuration:

  Implementer                Reviewer                 Tester
  ┌─────────────┐           ┌─────────────┐          ┌─────────────┐
  │ Writes code │──message──│ Reviews code │          │ Writes tests│
  │             │           │ for quality  │          │ Runs tests  │
  │             │◄─feedback─│ and security │          │             │
  │             │           └─────────────┘          │             │
  │             │──────────message────────────────── │             │
  │             │◄─────────test results──────────────│             │
  └─────────────┘                                    └─────────────┘

  Workflow:
  1. Implementer writes feature code
  2. Reviewer reviews it (in parallel with step 3)
  3. Tester writes test cases based on the feature spec
  4. Implementer addresses review feedback
  5. Tester runs tests against the updated code
  6. All agents converge: code + reviews + green tests

コミュニケーションパターン

エージェントチームのコミュニケーションには3つのパターンが支配的です:

1. リクエスト-レスポンス(最も一般的):

Implementer → Reviewer: "Please review src/auth.ts"
Reviewer → Implementer: "Found 2 issues: ..."

2. ブロードキャスト(全員に告知):

Implementer → All: "Breaking change: renamed User to Account
in all models. Update your references."

3. デリゲート(タスクの割り当て):

Implementer → Tester: "Write unit tests for the new
  notification model. Cover: create, read, mark-as-read,
  delete. Expected file: src/models/notification.test.ts"

チームとサブエージェントの使い分け

基準サブエージェントエージェントチーム
タスクの期間短い、一回限り持続的、マルチターン
コンテキストの必要性使用後に破棄ターンをまたいで永続
コミュニケーション結果を一度だけ返す継続的な対話
セットアップコストゼロ(自動)明示的なセットアップが必要
典型的な用途探索、調査実装、レビュー
エージェント数1-3の一時的なもの2-4の永続的なもの
コンテキストウィンドウ親 + 一時的な子すべて独立、すべて永続

経験則:タスクが「X を見つけて報告する」であればサブエージェントを使用。タスクが「今後30分間、一緒に X に取り組む」であればチームメイトを使用。

チームコミュニケーションのデバッグ

メッセージバスはプレーンな JSONL ファイルなので、検査できます:

# See all messages between agents
cat ~/.claude/teams/session-xyz.jsonl | python3 -m json.tool

# Filter messages from a specific agent
grep '"from": "reviewer"' ~/.claude/teams/session-xyz.jsonl

# Count messages per agent
grep -o '"from": "[^"]*"' ~/.claude/teams/session-xyz.jsonl | sort | uniq -c

この透明性により、エージェントが何を議論しているかを常に監査でき、ミスコミュニケーションを早期に発見し、チームがどのように連携したかを理解できます。

変更点

単一エージェントエージェントチーム
すべてに1つのコンテキストウィンドウチームメイトごとに独立したコンテキスト
混在する関心事でコンテキストが埋まる各エージェントが自分の領域に集中
永続的なコラボレーションなしチームメイトが継続的な対話を維持
レビューにはレビュー + コードコンテキストの読み込みが必要レビュアーにレビュー履歴専用のコンテキスト
逐次的:書く、次にレビュー、次にテスト並列:実装者がコーディング中にレビュアーとテスターが作業
コードに対する1つの視点複数の専門的な視点

次のセッション

これでマルチエージェントの核心概念のまとめとなります。セッション10ではチームプロトコルを探ります。エージェントチームを予測可能かつスケールで効果的にする構造化されたコミュニケーションパターンと規約について学びます。