Claude Media
Agent Teamsでサブエージェント定義をteammateに流用する

Agent Teamsでサブエージェント定義をteammateに流用する

security-reviewerのようなサブエージェント定義は、Agent Teamsのteammateとしてもそのまま起動できます。引き継がれる項目と引き継がれない項目、再開時の落とし穴を示します。

Agent Teamsでサブエージェント定義を流用するとは

.claude/agents/に置いたサブエージェント定義は、単一セッション内の委任だけでなくAgent Teamsのteammateとしても起動できます。役割を1回定義すれば、通常のサブエージェント呼び出しとteammateの両方で同じ定義を使い回せます。

ただし、定義に書いたフィールドがすべてteammateに効くわけではありません。tools・model・本文(body)は引き継がれ、skillsは引き継がれず、mcpServersは表示モードしだいです。「Skillが読み込まれない」「permissionModeを書いたのに効かない」という食い違いは、この区別を知らないと起きます。

有効化からスポーンまでの流れ

Agent Teamsは既定で無効です。CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSを1にしない限り、セッション開始時にチームは作られず、teammateのスポーンも提案されません。

手順

定義ファイルをteammateにするまで

  1. 1

    環境変数で有効化する

    settings.jsonのenvか、シェルの環境変数でCLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSを1にします。

  2. 2

    通常のサブエージェントとして定義する

    サブエージェントと同じ形式で書きます。teammate専用の書式はありません。

  3. 3

    スポーンのプロンプトで名指しする

    エージェントタイプ名を伝えます。

.claude/agents/security-reviewer.mdの定義ファイルの例です。

---
name: security-reviewer
description: 認証・認可まわりの差分を優先して確認するレビュー担当
tools: Read, Grep, Bash
model: sonnet
---
 
あなたはセキュリティレビュー専任のエージェントです。認証・認可に関わる差分を優先して確認し、
権限チェックの抜けや秘密情報のハードコードがないかを重点的に見てください。

スポーンの依頼文は次のとおりです。

security-reviewerエージェントタイプを使って、認証モジュールの監査を担当する
teammateを立ち上げて

Claude Codeは名指しされた定義を読み込み、teammateに適用できる部分だけを反映します。

Agent Teamsが有効なセッションでは、nameを付けてメインの会話から起動したサブエージェントが、サブエージェントではなくteammateとして立ち上がります。フォークと、呼び出し側でisolationを渡した場合は例外です。frontmatterにisolationを書いていても、この挙動は止まらず、teammateはメインセッションの作業ディレクトリで動きます。名前付きの委任を従来どおりサブエージェントとして走らせたいときは、CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSを0にします。

teammateに引き継がれる項目と引き継がれない項目

teammateに適用されうるのは、tools・model・本文(body)・skills・mcpServersの5つです。

フィールドteammateへの適用補足
toolsteammateへの適用適用される補足in-processのteammateにはSendMessageが自動追加され、Task系ツールのあるセッションではTaskCreate・TaskGet・TaskList・TaskUpdateも加わる。CronCreate・CronDelete・CronListは、toolsで絞り込んでもteammateに残る
modelteammateへの適用適用される補足スポーンプロンプトでモデルを指定していない場合に限る
本文(body)teammateへの適用適用される補足表示モードで異なる(次節)
skillsteammateへの適用適用されない補足teammateはプロジェクト・ユーザー設定のSkillsを読み込む
mcpServersteammateへの適用表示モードしだい補足表示モードで異なる(次節)

あるSkillの存在を前提にした役割定義は、通常のサブエージェントならskillsの指定どおり事前ロードされます。同じ定義をteammateにすると、そのSkillはロードされません。転用する前に、必要なSkillがプロジェクト側かユーザー側の設定にもあるかを見ておきます。

サブエージェントで使える他のフィールドは、teammateに適用される5項目に含まれません。hooks・disallowedTools・maxTurns・memory・effort・isolationがそうです。effortは定義ではなくリードの値が使われます。teammateはリードのeffort levelを引き継ぎます。

モデル選択でも定義のmodelフィールドが使われる

teammateのモデルは、次の優先順位で決まります。

  1. スポーンプロンプトでそのteammate向けに名指ししたモデル
  2. サブエージェント定義から起動した場合、その定義のmodel(inheritならリードのモデル)
  3. CLAUDE_CODE_SUBAGENT_MODEL環境変数(inherit以外のとき)
  4. リードの現在のモデル

定義のmodel: sonnetは、スポーンプロンプトでモデルを指定しなかったteammateにそのまま適用されます。CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1(v2.1.257以降)を設定すると、1番目と2番目が外れます。すべてのteammateのモデルがCLAUDE_CODE_SUBAGENT_MODEL(inherit以外のとき)か、リードのモデルで決まり、定義のmodelは使われません。v2.1.251より前は、CLAUDE_CODE_SUBAGENT_MODELが最優先でした。環境変数の詳細はCLAUDE_CODE_SUBAGENT_MODELの記事にあります。

旧設定のteammateDefaultModelはv2.1.234で削除され、残っている値は無視されます。モデルを変えたいteammateは、スポーンプロンプトで名指しします。

選ばれたモデルは、組織のavailableModels許可リストでも審査されます。opusのようなファミリーエイリアスが塞がれていると、Anthropic APIとClaude Platform on AWSでは、リストが許す同ファミリーの最新バージョンに置き換わります。プロバイダー固有のモデルIDを使う環境ではこの置き換えが働かず、他の許可外の値と同じくリードのモデルへフォールバックします。CLAUDE_CODE_SUBAGENT_MODELを設定している場合は、そちらが先に試されます。

定義を複数の組織や環境で使い回すなら、フォールバック先まで見ておくと、想定外のモデルでteammateが動く事態を避けられます。

in-processとsplit-paneで効く範囲が変わる

Agent Teamsのteammateは、in-process表示かsplit-pane表示かを選べます。同じ定義ファイルでも、この違いで実際に走るteammateの中身が変わります。

くらべる

表示モードで変わる定義の効き方

定義は補助

in-process

本文は既定のシステムプロンプトへの追記です。mcpServersは無視され、プロジェクト・ユーザー設定のMCPサーバーを使います。

定義が主導

split-pane

本文が既定のシステムプロンプトを置き換えます。mcpServersは定義の指定が効き、--agentで起動したセッションと同じルールで扱われます。SendMessageは追加されません。

表示モードに関わらず、teammateはCLAUDE.md・MCPサーバー・Skillsという通常セッションと同じプロジェクトコンテキストを読み込み、そこにスポーンプロンプトが加わります。リードの会話履歴は引き継がれません。リードが積み上げた文脈は、スポーンプロンプトで渡します。

in-processには、サブエージェントの定義側で注意が要る制約もあります。in-processのteammateが起動するサブエージェントは、フォアグラウンドで動きます。定義にbackground: trueを書いたサブエージェントをteammateから起動すると、エラーで拒否されます。

permissionModeは定義に書いても効かない

サブエージェント定義のpermissionModeは、通常の委任なら個体ごとにdefault・acceptEdits・planなどを固定できます。teammateには、この起動時指定に相当する仕組みがありません。teammateはリードのモードから出発します。

例外が1つあります。リードがdontAskモードのとき、teammateはそのモードを引き継ぎません。リードが--dangerously-skip-permissionsで動いていれば、teammateも全員同じ設定になります。スポーン後に個別のteammateのモードを変えることはできますが、スポーン時に個体別のモードを決める手段はありません。

plan modeのリードがスポーンしたteammateは、計画が固まるまで読み取り専用のplan modeで動きます。計画ができるとteammateはリードへ承認依頼を送り、リードのセッションは依頼が届いた時点で、リードが内容を確認せずに承認します。承認後も、teammateの編集やコマンドは通常の権限プロンプトを通ります。定義にpermissionMode: planを書くことの代替にはなりませんが、「read-onlyで始めさせる」意図はこの経路で実現できます。read-onlyなレビュー役を徹底したい場合の回避策は、Agent Teams権限モデルの記事で扱っています。

個体差を出したいなら通常のサブエージェント、チーム全体で確認方針を揃えたいならAgent Teamsという向き不向きが、ここに現れます。

どのスコープの定義が使えるか

サブエージェント定義は、どのスコープのものでもteammateの役割として名指しできます。

スコープ配置場所優先順位
組織全体(managed)配置場所managed settings経由で配布優先順位1(最高)
CLI定義配置場所--agentsフラグ(そのセッションのみ)優先順位2
プロジェクト配置場所.claude/agents/優先順位3
ユーザー配置場所~/.claude/agents/優先順位4
プラグイン配置場所プラグインのagents/ディレクトリ優先順位5(最低)

同名の定義が複数あると、優先順位の高い場所のものが使われます。組織で配布した役割定義も、teammateとして流用できます。

プラグインのサブエージェントは、セキュリティ上の理由でhooks・mcpServers・permissionModeが無視されます。teammateのmcpServersはもともとsplit-paneでしか効きません。プラグイン由来の定義でMCPをteammateに持たせたいなら、定義を.claude/agents/か~/.claude/agents/にコピーします。

--agentsの中身は、claude --helpではJSONオブジェクトとして説明されています(v2.1.287で確認)。

--agents <json-or-file>  JSON object defining custom agents, or with --print
                         the path to a file that holds one
                         (e.g. '{"reviewer": {"description": "Reviews code",
                         "prompt": "You are a code reviewer"}}')

built-inのサブエージェントも、teammateとして名指しできます。チーム構成ファイル(~/.claude/teams/{team-name}/config.json)のmembers配列には、各メンバーがスポーン時に名指しされたエージェントタイプが記録されます。入るのはbuilt-inタイプかサブエージェント定義で、名指しがなければ項目自体が省かれます。リード自身のタイプは常にteam-leadです。このファイルは実行時の状態(セッションIDやtmuxのペインID)を持つため、手で編集しても次の状態更新で上書きされます。再利用できる役割は、このファイルではなくサブエージェント定義で作ります。

再開したteammateで定義が戻らないとき

停止中のin-processのteammateへリードがメッセージを送ると、Claude Codeは同じセッションの中でteammateを呼び戻します。保存してあった会話を復元し、そのメッセージを次のプロンプトとして渡します。

このとき、.claude/agents/(または--add-dirしたディレクトリ)に置いた定義は、そのフォルダーを信頼済みにしている場合にだけ再適用されます。親フォルダーを信頼していても、条件を満たしません。未信頼のままだと、teammateは定義のtoolsも指示も持たず、全in-process teammateに加わるツールだけで戻ってきます。リードの結果には、次のような通知が付きます。

Its agent definition was not restored: the folder its definition file came from is not trusted (source: projectSettings), so the teammate is running with the team-essential tools and no custom instructions. To restore it, the user needs to run Claude Code in that folder once and accept the trust dialog (the --debug log names the folder); do not change trust settings on the user's behalf.

直し方は2通りです。

  • 通知が示すフォルダーでclaudeを一度起動し、信頼ダイアログを承認します。次に呼び戻すときから定義が再適用され、リードのセッションを再起動する必要はありません
  • ~/.claude.jsonで、--debugログが出力するprojects["<パス>"]のキーのhasTrustDialogAcceptedをtrueにします

/resumeと/rewindは、in-processのteammateを復元しません。再開後にリードが消えたteammateへ話しかけたら、新しいteammateのスポーンを依頼します。

まとめ

定義を通常のサブエージェントとteammateで両用するなら、skillsとpermissionModeに頼らない書き方にしておくのが分かれ目です。

この記事を共有:XはてブLinkedIn