えんがわ寿司のイラスト

Claude Code のオーケストレーション機能であるエージェントチームを試してみた

Claude Code のエージェントチームを使用すると、複数の Claude Code インスタンスが連携して動作するようになります。この記事では、Claude Code のエージェントチーム機能を試し、どのように動作するかを探ってみます。

Claude Code のエージェントチームを使用すると、複数の Claude Code インスタンスが連携して動作するようになります。1 つのセッションがチームリーダーとして機能し、他のセッションにタスクを割り当てたり作業を調整したりします。チームメンバーは独立したコンテキストで動作し、それぞれのメンバーと直接やり取りできます。

従来のサブエージェント機能では、メインのエージェントがサブエージェントにタスクを委任する一方向の関係であり、サブエージェントはメインエージェントのみに結果を報告できました。一方エージェントチームでは、リーダーを介さずにメンバー同士もしくはユーザー自身と直接コミュニケーションを取ることができるという点で大きく異なります。

この記事では、Claude Code のエージェントチーム機能を試し、どのように動作するかを探ってみます。

エージェントチームを有効にする

2026 年 2 月時点では、エージェントチームは実験的な機能として提供されており、デフォルトは無効になっています。有効にするには環境変数 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS を有効にする必要があります。

~/.claude/settings.json ファイルに以下のように設定を追加します。

{
  "env": {
    "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
  }
}

またエージェントチームでは "in-process"Split Pane の 2 つの表示モードがサポートされています。in-process モードでは、1 つのターミナルですべてのエージェントメンバーが動作し、shift + 矢印キーでどのメンバーを表示してやり取りするかを切り替えます。

Split Pane モードでは、各エージェントメンバーがターミナルの分割ペインで動作し、ペインをクリックすることでやり取りするエージェントを切り替えます。複数のエージェントの動作を同時に監視したい場合に便利です。Split Pane モードを使用するには tmux もしくは it2 CLI を備えた iTerm2 ターミナルが必要です。デフォルトでは tmux もしくは iTerm2 が検出された場合に Split Pane モードが使用されます。

エージェントチームとタスクの作成

Claude Code のエージェントチームとして動作してもらうためには、プロンプトでエージェントチームを使用するように指示し、各メンバーの役割を定義します。例えば以下の例では Next.js でブログアプリケーションを作成するために、フロントエンドエンジニア, バックエンドエンジニア, データベーススペシャリスト, QA エンジニア, UI/UX デザイナーの 5 人のエージェントメンバーを定義しています。

エージェントチームを使用して、Next.js でブログアプリケーションを作成してください。以下の役割を持つ 5 人のエージェントメンバーがいます。
1. フロントエンドエンジニア: ユーザーインターフェースとクライアントサイドのロジックを担当します。
2. バックエンドエンジニア: サーバーサイドのロジックと API を担当します。
3. データベーススペシャリスト: データベース設計と管理を担当します。
4. QA エンジニア: テスト計画と品質保証を担当します。
5. UI/UX デザイナー: ユーザーエクスペリエンスとデザインを担当します。
各メンバーは自分の役割に基づいてタスクを実行し、必要に応じて他のメンバーとコミュニケーションを取ってください。

まずはじめに TaskCreate ツールを使用して、ブログアプリケーションを構築するために必要なタスクの一覧を作成します。このタスク一覧はすべてのチームメンバーに共有されます。タスクに依存関係があれば TaskUpdate ツールを使用して更新します。

続いて TeamCreate ツールを使用してエージェントチームを作成します。ここではバックエンドエンジニアが担当するタスクはデータベーススペシャリストが担当するタスク #2 が終了した後に開始すべきことが指定されていますね。

作成したタスクは ~/.claude/tasks/{team-name} ディレクトリに、チームは ~/.claude/teams/{team-name} ディレクトリに保存されます。

作成されたチームの一例を見てみましょう。今回の例では ~/.claude/teams/robust-popping-snowflake ディレクトリにチームが保存されています。

robust-popping-snowflake
├── config.json
└── inboxes
    ├── backend-engineer.json
    ├── database-specialist.json
    ├── db-specialist.json
    ├── frontend-engineer.json
    ├── qa-engineer.json
    ├── team-lead.json
    ├── ui-designer.json
    └── ui-ux-designer.json

config.json ファイルにはチーム全体の設定が含まれており、inboxes ディレクトリには各メンバーがどのようなメッセージのやり取りをしたかが保存されています。

config.json ファイルを見るとどのエージェントがリーダーなのか leadAgentId プロパティで指定されており、members の配列で各メンバーの役割が定義されていることがわかります。

{
  "name": "robust-popping-snowflake",
  "description": "Next.jsブログアプリケーション開発チーム",
  "createdAt": 1770444712078,
  "leadAgentId": "team-lead@robust-popping-snowflake",
  "leadSessionId": "xxxx-xxxx-xxxx-xxxx-xxxx",
  "members": [
    {
      "agentId": "team-lead@robust-popping-snowflake",
      "name": "team-lead",
      "agentType": "team-lead",
      "model": "claude-sonnet-4-5-20250929",
      "joinedAt": 1770444712078,
      "tmuxPaneId": "",
      "cwd": "/Users/xxx/sandbox/example-agent-team",
      "subscriptions": []
    },
    {
      "agentId": "ui-ux-designer@robust-popping-snowflake",
      "name": "ui-ux-designer",
      "agentType": "general-purpose",
      "model": "claude-opus-4-6",
      "prompt": "あなたはNext.jsブログアプリケーション開発チームのUI/UXデザイナーです。\n\nあなたの役割:\n- ユーザーエクスペリエンスとデザインを担当\n- デザインシステム、カラースキーム、タイポグラフィを定義\n- レスポンシブデザインとアクセシビリティを考慮\n- TailwindCSSを使用したモダンなデザインを提案\n\nまず、TaskListを確認して、タスク#1「UI/UXデザインの策定」をあなたのownerに設定してください。その後、ブログアプリケーションのデザイン仕様を作成してください。\n\nデザイン仕様には以下を含めてください:\n1. カラーパレットとテーマ\n2. タイポグラフィ設定\n3. 主要なページレイアウト(ホーム、記事一覧、記事詳細、投稿作成)\n4. コンポーネント設計\n\nデザイン仕様を作成したら、team-leadにメッセージを送って完了を報告してください。",
      "color": "blue",
      "planModeRequired": false,
      "joinedAt": 1770444739060,
      "tmuxPaneId": "%1",
      "cwd": "/Users/xxx/sandbox/example-agent-team",
      "subscriptions": [],
      "backendType": "tmux",
      "isActive": true
    }
    // 他のメンバー情報は省略
  ]
}

inboxes/frontend-engineer.json ファイルを見てみましょう。このファイルは配列形式で、フロントエンドエンジニアが受信したメッセージが時系列で保存されています。

最初のメッセージはチームリーダーから役割定義と、どのタスクを担当するかが指示されています(読みやすいように改行を追加)。

[
  {
    "from": "team-lead",
    "text": "あなたはNext.jsブログアプリケーション開発チームのフロントエンドエンジニアです。
      あなたの役割:
      - ユーザーインターフェースとクライアントサイドのロジックを担当
      - Reactコンポーネントとページの実装
      - 状態管理とデータフェッチング
      まず、TaskListを確認して、タスク#4「フロントエンド実装」をあなたのownerに設定してください。ただし、このタスクはタスク#1(UI/UXデザイン)とタスク#3(バックエンドAPI)に依存しているため、両方の完了を待ってください。
 
UI/UXデザインとバックエンドAPIが完了したら、以下を実装してください:
1. ブログ投稿一覧ページ
2. 投稿詳細ページ
3. 投稿作成/編集フォーム
4. レスポンシブナビゲーション
5. 再利用可能なコンポーネント
 
実装完了後、team-leadにメッセージを送って報告してください。",
    "timestamp": "2026-02-07T06:12:32.967Z",
    "read": true
  }
]

2 つ目のメッセージは type: "task_assignment" で自身が担当するタスクを割り当てたことを報告しています。リーダからの指示通りフロントエンド実装タスクである #4 を担当することになっていますね。

[
  {
    "from": "frontend-engineer",
    "text": "{\"type\":\"task_assignment\",\"taskId\":\"4\",\"subject\":\"フロントエンド実装\",\"description\":\"Reactコンポーネントとページを実装する。ブログ一覧、記事詳細、投稿作成/編集フォーム、レスポンシブデザインを含む。\",\"assignedBy\":\"frontend-engineer\",\"timestamp\":\"2026-02-07T06:12:41.725Z\"}",
    "timestamp": "2026-02-07T06:12:41.725Z",
    "color": "purple",
    "read": true
  }
]

~/.claude/tasks/robust-popping-snowflake ディレクトリも覗いて見ましょう。ここにはタスク一覧が JSON ファイルとして保存されています。

robust-popping-snowflake
├── .lock
├── 1.json
├── 2.json
├── 3.json
├── 4.json
└── 5.json

.lock ファイルはタスクの競合状態を防止するために使用されます。1.json ファイルを見てみましょう。タスク #1 は UI/UX デザインの策定タスクです。owner プロパティに ui-ux-designer が設定されており、このタスクが UI デザイナーに割り当てられていることがわかります。activeForm プロパティには現在のタスクの進行状況が記録されています。

{
  "id": "1",
  "subject": "UI/UXデザインの策定",
  "description": "ブログアプリケーションのデザインシステム、レイアウト、ユーザーフローを設計する。カラースキーム、タイポグラフィ、コンポーネント構造を定義する。",
  "activeForm": "UI/UXデザイン仕様を策定中",
  "status": "in_progress",
  "blocks": [],
  "blockedBy": [],
  "owner": "ui-designer"
}

バックエンドのタスク #3 を見てみましょう。blockedBy プロパティに 2 が設定されており、データベーススペシャリストが担当するタスク #2 が完了するまで開始できないことがわかります。また blocks プロパティはタスクの進行に関するブロック情報を格納するために使用され、フロントエンドとテストのタスクはバックエンドのタスクが完了するまで開始できないことがわかります。

{
  "id": "3",
  "subject": "バックエンドAPIの設計と実装",
  "description": "Next.js API Routesを使用したRESTful APIを実装する。\n- ブログ記事のCRUD操作エンドポイント\n- 記事一覧取得(ページネーション、フィルタリング)\n- 個別記事取得\n- データベース接続とクエリ実装\n- エラーハンドリングとバリデーション\n- APIドキュメントの作成\n\nデータベーススペシャリストの完了後に開始してください。",
  "activeForm": "バックエンドAPIを実装中",
  "status": "pending",
  "blocks": ["4", "5"],
  "blockedBy": ["2"]
}

チームメンバーにプラン承認を要求する

チームメンバーが実装に入る前にプランを立てることを要求できます。この場合各メンバーはリーダーから承認を得るまで読み取り専用の Plan モードで動作します。プラン承認を要求するにはプロンプトで以下のように指示します。

...
変更を加える前に、各メンバーがプランを立てて承認を得るようにしてください。

プラン承認を要求されたメンバーは mode: "plan" プロパティが設定された状態となっています。

{
  "subagent_type": "general-purpose",
  "team_name": "my-team",
  "name": "developer",
  "mode": "plan", // ← プラン承認を必須にする
  "prompt": "ユーザー認証機能を実装してください",
  "description": "認証機能の実装"
}

各メンバーがプランを立てた後、リーダーエージェントは承認もしくは拒否のいずれかで応答します。承認されたメンバーは通常モードに戻り、タスクの実行を開始できます。拒否された場合、メンバーはフィードバックに基づいてプランを修正し、再度承認を求める必要があります。

承認を拒否した場合には content プロパティにフィードバックが含まれます。

{
  "type": "plan_approval_response",
  "request_id": "abc-123",
  "recipient": "developer",
  "approve": false,
  "content": "エラーハンドリングを追加してください"
}

delegate モードでリーダーを調整役に専念させる

時折リーダーエージェントはチームメンバーを待つ代わりに自分自身でタスクの実装を開始する場合があります。リーダーエージェントにチームの調整のタスクのみを行わせたい場合には delegate モードを使用します。delegate モードではリーダーエージェントが作業の分割、タスク割り当て、結果の統合に焦点を当てるように、コードに直接触れることがなくなります。

delegate モードを有効にする場合はチームを開始した後に Shift + Tab キーを押してモードを切り替えます。

タスクの割り当てとチームメンバーの作業

共有タスクリストに基づいて TaskUpdate ツールで owner パラメータを設定することにより、各タスクを特定のチームメンバーに割り当てます。タスクの割当には以下の 2 つの方法があります。

  • リーダーエージェントがタスクをメンバーに割り当てる
  • メンバーが自身のタスクを完了した後、まだ未割り当てのタスクがあれば自分でタスクを選択して割り当てる

なおタスクを要求する際にはファイルロックを使用するため、同じタスクが複数のメンバーに割り当てられる競合状態を防止できます。またタスク番号が小さい順にタスクを割り当てられるように推奨されています。タスクは保留中, 進行中, 完了の 3 つの状態を持ち、タスクを割り当てられたチームメンバーはタスクを進行中に更新し、タスクが完了したら完了に更新します。さらに依存関係があるタスクは、依存するタスクが完了するまで開始できません。

タスクを割り当てられたチームメンバーは、自分の役割に基づいてタスクを実行し、必要に応じて他のメンバーとコミュニケーションを取ります。メンバーは SendMessage ツールを使用して他のメンバーやリーダーエージェントにメッセージを送信できます。現在のタスクが完了した場合、メンバーは TaskUpdate ツールを使用してタスクを完了に更新し、リーダーにアイドル状態であることを通知します。

実際の作業の様子は以下のようになります。バックエンドエンジニアがプランをリーダーに提出し、リーダーが承認していますね。テストエンジニアは対応可能なタスクがないため、リーダーからの指示があるまで待機しています。

チームのクリーンアップ

タスクが完了したら以下のプロンプトを使用してチームのシャットダウンをリクエストできます。

チームをクリーンアップしてください

リーダーエージェントはそれぞれのチームメンバーに SendMessage ツールで type: "shutdown_request" メッセージを送信することで、そのメンバーのシャットダウンをリクエストできます。メンバーは承認または拒否のいずれかで応答します。

すべてのタスクが完了したら、リーダーエージェントが自律的に判断してチームメンバーにシャットダウンをリクエストします。すべてのメンバーがシャットダウンを承認した場合、リーダーエージェントは TeamDelete ツールを使用してチーム全体をクリーンアップします。

プラクティス

エージェントチームを使用するとより複雑で大規模なプロジェクトを効率的に管理できますが、通常のセッションと比較して多くのトークンを消費します。新しい機能を追加するために複数の分野(フロントエンド、バックエンド、デザイン、テストなど)の専門知識が必要であったり、複雑なバグを調査する場合には多くのトークンを消費する価値があると言えます。ですが、単純なルーティーンタスクや簡単なコードベースの質問には過剰な場合があります。エージェントチームを使用すべきタスクを慎重に評価し、コストと利点を比較検討してください。

タスクのサイズも考慮する必要があります。タスクのサイズが小さすぎる場合は、エージェントチームの調整のオーバーヘッドが大きくなりすぎてしまいますし、逆に大きすぎる場合はメンバーが長時間同じタスクに取り組むことになり、他のメンバーが待機状態になってしまいます。チームメンバー1 人あたり 5~6 個のタスクを割り当てることで、全員の生産性を維持し誰かが行き詰まった場合にリーダーが他のメンバーにタスクを再割り当てできるようになります。

コンテキストの管理の観点でも通常のセッションと比較して注意が必要です。各メンバーは独立したコンテキストで動作し、リーダーエージェントとの会話履歴は共有されません。チームメンバー間で情報を共有する方法は SendMessage ツールを使用したメッセージのやり取りと共有タスクリストのみです。CLAUDE.md や MCP サーバー、スキルなどのプロジェクト固有のコンテキストは常に読み込まれるため、このあたりのドキュメント整備がより重要になるでしょう。

ファイルの競合を避けるようにエージェントチームを設計することも重要です。この記事ではブログアプリケーションを構築するために UI/UX デザイナーとフロントエンドエンジニアを別々のメンバーとして定義しましたが、両者が layout.tsx を同時に編集しようとした結果余分なコンフリクト作業が発生してしまいました。UI/UX デザイナーはデザイン仕様の作成に集中し、フロントエンドエンジニアは実装に集中するように役割を分離することで、このような競合を避けることができます。

エージェントチームのメンバーがコマンドの実行の承認を求める場合、リーダーエージェントに承認を求めた後にリーダーエージェントはさらにユーザーからの承認を求めます。ユーザーによる承認作業は 1 度に 1 回ずつしか行えないため、複数のエージェントから同時に承認要求が来るとボトルネックになってしまいます。権限設定をあらかじめ設定しておくことで、エージェントチームのメンバーがユーザーの承認を待たずに実行できるコマンドの一覧を見直しておくことをお勧めします。

まとめ

  • Claude Code のエージェントチーム機能を使用すると、複数の Claude Code インスタンスが連携して動作するようになる
  • エージェントチームはリーダーエージェントと複数のメンバーエージェントで構成され、各メンバーは独立したコンテキストで動作する
  • チームリーダーはタスクの割り当て、進捗の監視、メンバー間の調整を担当する
  • 各メンバーは自分の役割に基づいてタスクを実行し、必要に応じて他のメンバーとコミュニケーションを取る
  • タスクの割り当てはリーダーエージェントが明示的に行うか、タスクを完了したメンバーが自分で選択して割り当てることができる
  • プラン承認モードを使用して、各メンバーが作業を開始する前にプランを立てて承認を得ることができる
  • delegate モードを使用して、リーダーエージェントがタスクの調整に専念し、コードに直接触れないようにできる
  • タスクが完了したら、リーダーエージェントがチームメンバーにシャットダウンをリクエストし、すべてのメンバーが承認した場合にチーム全体をクリーンアップする
  • エージェントチームを使用する際には、トークン消費、コンテキスト管理、ファイル競合、承認ボトルネックなどの点に注意が必要

参考

記事の理解度チェック

以下の問題に答えて、記事の理解を深めましょう。

エージェントチームと従来のサブエージェント機能の最も大きな違いは何か?

  • メンバー同士がリーダーを介さずに直接コミュニケーションを取れる

    正解!

    従来のサブエージェントはメインエージェントのみに結果を報告する一方向の関係でしたが、エージェントチームではメンバー同士やユーザーと直接やり取りできます。

  • サブエージェントよりも多くのメンバーを追加できる

    もう一度考えてみましょう

  • サブエージェントよりもトークンの消費量が少ない

    もう一度考えてみましょう

  • メンバーがリーダーのコンテキストを共有できる

    もう一度考えてみましょう

    各メンバーは独立したコンテキストで動作し、リーダーエージェントとの会話履歴は共有されません。

エージェントチームの `delegate` モードの役割として正しいものはどれか?

  • リーダーエージェントがコードに直接触れず、タスクの調整に専念する

    正解!

    delegate モードではリーダーエージェントが作業の分割、タスク割り当て、結果の統合に焦点を当て、コードに直接触れることがなくなります。

  • メンバーエージェントがリーダーの承認なしにタスクを実行できる

    もう一度考えてみましょう

    delegate モードはリーダーの動作を制限するもので、メンバーの権限を変更するものではありません。

  • タスクの依存関係を自動的に解決する

    もう一度考えてみましょう

    タスクの依存関係の管理は delegate モードとは関係ありません。

  • チームメンバーを自動的にシャットダウンする

    もう一度考えてみましょう

    シャットダウンは shutdown_request メッセージで行います。delegate モードとは無関係です。