SpyBara
Go Premium

agent-sdk/subagents.md 2026-05-07 22:59 UTC to 2026-05-08 22:00 UTC

601 added, 0 removed.

2026
Sun 31 06:39 Sat 30 06:23 Fri 29 06:38 Thu 28 06:37 Wed 27 06:42 Tue 26 06:33 Sun 24 06:25 Sat 23 06:18 Fri 22 06:33 Thu 21 06:36 Wed 20 06:35 Tue 19 06:34 Mon 18 23:59 Sun 17 01:01 Fri 15 22:58 Thu 14 17:02 Wed 13 23:01 Tue 12 22:57 Mon 11 23:00 Sun 10 23:03 Sat 9 04:57 Fri 8 22:00 Thu 7 22:59 Tue 5 23:00 Mon 4 22:58 Sat 2 18:14 Fri 1 18:19

SDK のサブエージェント

サブエージェントを定義して呼び出し、コンテキストを分離し、タスクを並列実行し、Claude Agent SDK アプリケーションで特殊な指示を適用します。

サブエージェントは、メインエージェントが生成できる個別のエージェントインスタンスで、焦点を絞ったサブタスクを処理します。 サブエージェントを使用して、焦点を絞ったサブタスクのコンテキストを分離し、複数の分析を並列実行し、メインエージェントのプロンプトを肥大化させずに特殊な指示を適用します。

このガイドでは、agents パラメータを使用して SDK でサブエージェントを定義および使用する方法について説明します。

概要

サブエージェントは 3 つの方法で作成できます。

  • プログラム的に: query() オプションの agents パラメータを使用します(TypeScriptPython
  • ファイルシステムベース: .claude/agents/ ディレクトリ内のマークダウンファイルとしてエージェントを定義します(ファイルとしてサブエージェントを定義するを参照)
  • 組み込みの汎用: Claude は、何も定義することなく、Agent ツールを介して組み込みの general-purpose サブエージェントをいつでも呼び出すことができます

このガイドでは、SDK アプリケーションに推奨されるプログラム的なアプローチに焦点を当てています。

サブエージェントを定義する場合、Claude は各サブエージェントの description フィールドに基づいて、それらを呼び出すかどうかを判断します。サブエージェントをいつ使用すべきかを説明する明確な説明を書いてください。Claude は自動的に適切なタスクを委譲します。プロンプトでサブエージェントを名前で明示的にリクエストすることもできます(例えば、「code-reviewer エージェントを使用して...」)。

サブエージェントを使用する利点

コンテキスト分離

各サブエージェントは独自の新しい会話で実行されます。中間的なツール呼び出しと結果はサブエージェント内に留まり、最終メッセージだけが親に返されます。サブエージェントが継承するものを参照して、サブエージェントのコンテキストに正確に何が含まれているかを確認してください。

例: research-assistant サブエージェントは、そのコンテンツがメイン会話に蓄積されることなく、数十のファイルを探索できます。親は、サブエージェントが読んだすべてのファイルではなく、簡潔なサマリーを受け取ります。

並列化

複数のサブエージェントを同時に実行でき、複雑なワークフローを劇的に高速化します。

例: コードレビュー中に、style-checkersecurity-scannertest-coverage サブエージェントを同時に実行でき、レビュー時間を数分から数秒に短縮できます。

特殊な指示と知識

各サブエージェントは、特定の専門知識、ベストプラクティス、制約を備えたカスタマイズされたシステムプロンプトを持つことができます。

例: database-migration サブエージェントは、SQL ベストプラクティス、ロールバック戦略、データ整合性チェックに関する詳細な知識を持つことができます。これらはメインエージェントの指示では不要なノイズになります。

ツール制限

サブエージェントは特定のツールに制限でき、意図しないアクションのリスクを軽減します。

例: doc-reviewer サブエージェントは Read と Grep ツールのみにアクセスでき、ドキュメントファイルを分析できますが、誤って変更することはありません。

サブエージェントの作成

プログラム的な定義(推奨)

agents パラメータを使用してコード内でサブエージェントを直接定義します。この例では、読み取り専用アクセスを持つコードレビュアーとコマンドを実行できるテストランナーの 2 つのサブエージェントを作成します。Claude がサブエージェントを Agent ツール経由で呼び出すため、Agent ツールを allowedTools に含める必要があります。

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


async def main():
async for message in query(
prompt="Review the authentication module for security issues",
options=ClaudeAgentOptions(
# Agent tool is required for subagent invocation
allowed_tools=["Read", "Grep", "Glob", "Agent"],
agents={
"code-reviewer": AgentDefinition(
# description tells Claude when to use this subagent
description="Expert code review specialist. Use for quality, security, and maintainability reviews.",
# prompt defines the subagent's behavior and expertise
prompt="""You are a code review specialist with expertise in security, performance, and best practices.

When reviewing code:
- Identify security vulnerabilities
- Check for performance issues
- Verify adherence to coding standards
- Suggest specific improvements

Be thorough but concise in your feedback.""",
# tools restricts what the subagent can do (read-only here)
tools=["Read", "Grep", "Glob"],
# model overrides the default model for this subagent
model="sonnet",
),
"test-runner": AgentDefinition(
description="Runs and analyzes test suites. Use for test execution and coverage analysis.",
prompt="""You are a test execution specialist. Run tests and provide clear analysis of results.

Focus on:
- Running test commands
- Analyzing test output
- Identifying failing tests
- Suggesting fixes for failures""",
# Bash access lets this subagent run test commands
tools=["Bash", "Read", "Grep"],
),
},
),
):
if hasattr(message, "result"):
print(message.result)


asyncio.run(main())

AgentDefinition 設定

フィールド 必須 説明
description string はい このエージェントをいつ使用するかについての自然言語説明
prompt string はい エージェントの役割と動作を定義するシステムプロンプト
tools string[] いいえ 許可されたツール名の配列。省略した場合、すべてのツールを継承します
disallowedTools string[] いいえ エージェントのツールセットから削除するツール名の配列
model string いいえ このエージェントのモデルオーバーライド。'sonnet''opus''haiku''inherit' などのエイリアス、または完全なモデル ID を受け入れます。省略した場合、メインモデルがデフォルトになります
skills string[] いいえ スタートアップ時にエージェントのコンテキストにプリロードするスキル名のリスト。リストされていないスキルは Skill ツール経由で呼び出し可能なままです
memory 'user' | 'project' | 'local' いいえ このエージェントのメモリソース
mcpServers (string | object)[] いいえ このエージェントが利用可能な MCP サーバー(名前またはインライン設定)
maxTurns number いいえ エージェントが停止する前の最大 agentic ターン数
background boolean いいえ 呼び出されたときにこのエージェントをノンブロッキングバックグラウンドタスクとして実行します
effort 'low' | 'medium' | 'high' | 'xhigh' | 'max' | number いいえ このエージェントの推論努力レベル
permissionMode PermissionMode いいえ このエージェント内のツール実行のパーミッションモード

Python SDK では、これらのフィールド名は wire フォーマットに一致するように camelCase を使用します。詳細については、AgentDefinition リファレンスを参照してください。

ファイルシステムベースの定義(代替)

.claude/agents/ ディレクトリ内のマークダウンファイルとしてサブエージェントを定義することもできます。このアプローチの詳細については、Claude Code サブエージェントドキュメントを参照してください。プログラム的に定義されたエージェントは、同じ名前のファイルシステムベースのエージェントより優先されます。

サブエージェントが継承するもの

サブエージェントのコンテキストウィンドウは新しく開始されます(親の会話なし)が、空ではありません。親からサブエージェントへの唯一のチャネルは Agent ツールのプロンプト文字列なので、サブエージェントが必要とするファイルパス、エラーメッセージ、または決定をそのプロンプトに直接含めてください。

サブエージェントが受け取るもの サブエージェントが受け取らないもの
独自のシステムプロンプト(AgentDefinition.prompt)と Agent ツールのプロンプト 親の会話履歴またはツール結果
プロジェクト CLAUDE.md(settingSources 経由でロード) プリロードされたスキルコンテンツ(AgentDefinition.skills にリストされている場合を除く)
ツール定義(親から継承、または tools のサブセット) 親のシステムプロンプト

サブエージェントの呼び出し

自動呼び出し

Claude は、タスクと各サブエージェントの description に基づいて、サブエージェントをいつ呼び出すかを自動的に決定します。例えば、説明が「クエリチューニング用のパフォーマンス最適化スペシャリスト」である performance-optimizer サブエージェントを定義した場合、プロンプトでクエリの最適化について言及すると、Claude はそれを呼び出します。

Claude がタスクを正しいサブエージェントにマッチングできるように、明確で具体的な説明を書いてください。

明示的な呼び出し

Claude が特定のサブエージェントを使用することを保証するには、プロンプトで名前を言及してください。

"Use the code-reviewer agent to check the authentication module"

これは自動マッチングをバイパスし、名前付きサブエージェントを直接呼び出します。

動的エージェント設定

実行時の条件に基づいて、エージェント定義を動的に作成できます。この例では、異なる厳密性レベルを持つセキュリティレビュアーを作成し、厳密なレビューにはより強力なモデルを使用します。

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


# Factory function that returns an AgentDefinition
# This pattern lets you customize agents based on runtime conditions
def create_security_agent(security_level: str) -> AgentDefinition:
is_strict = security_level == "strict"
return AgentDefinition(
description="Security code reviewer",
# Customize the prompt based on strictness level
prompt=f"You are a {'strict' if is_strict else 'balanced'} security reviewer...",
tools=["Read", "Grep", "Glob"],
# Key insight: use a more capable model for high-stakes reviews
model="opus" if is_strict else "sonnet",
)


async def main():
# The agent is created at query time, so each request can use different settings
async for message in query(
prompt="Review this PR for security issues",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"],
agents={
# Call the factory with your desired configuration
"security-reviewer": create_security_agent("strict")
},
),
):
if hasattr(message, "result"):
print(message.result)


asyncio.run(main())

サブエージェント呼び出しの検出

サブエージェントは Agent ツール経由で呼び出されます。サブエージェントが呼び出されたときを検出するには、name"Agent" である tool_use ブロックをチェックしてください。サブエージェントのコンテキスト内からのメッセージには parent_tool_use_id フィールドが含まれます。

この例は、ストリーミングされたメッセージを反復処理し、サブエージェントが呼び出されたときと、その後のメッセージがそのサブエージェントの実行コンテキスト内から発信されたときをログに記録します。

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


async def main():
async for message in query(
prompt="Use the code-reviewer agent to review this codebase",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep", "Agent"],
agents={
"code-reviewer": AgentDefinition(
description="Expert code reviewer.",
prompt="Analyze code quality and suggest improvements.",
tools=["Read", "Glob", "Grep"],
)
},
),
):
# Check for subagent invocation. Match both names: older SDK
# versions emitted "Task", current versions emit "Agent".
if hasattr(message, "content") and message.content:
for block in message.content:
if getattr(block, "type", None) == "tool_use" and block.name in (
"Task",
"Agent",
):
print(f"Subagent invoked: {block.input.get('subagent_type')}")

# Check if this message is from within a subagent's context
if hasattr(message, "parent_tool_use_id") and message.parent_tool_use_id:
print("  (running inside subagent)")

if hasattr(message, "result"):
print(message.result)


asyncio.run(main())

サブエージェントの再開

サブエージェントを再開して、中断したところから続行できます。再開されたサブエージェントは、以前のすべてのツール呼び出し、結果、推論を含む完全な会話履歴を保持します。サブエージェントは新しく開始するのではなく、停止したところから正確に再開します。

サブエージェントが完了すると、Claude は Agent ツール結果でエージェント ID を受け取ります。サブエージェントをプログラム的に再開するには:

  1. セッション ID をキャプチャする: 最初のクエリ中にメッセージから session_id を抽出します
  2. エージェント ID を抽出する: メッセージコンテンツから agentId を解析します
  3. セッションを再開する: 2 番目のクエリのオプションで resume: sessionId を渡し、プロンプトにエージェント ID を含めます

以下の例は、このフローを示しています。最初のクエリはサブエージェントを実行してセッション ID とエージェント ID をキャプチャし、2 番目のクエリはセッションを再開して、最初の分析からのコンテキストが必要なフォローアップ質問をします。

import { query, type SDKMessage } from "@anthropic-ai/claude-agent-sdk";

// Helper to extract agentId from message content
// Stringify to avoid traversing different block types (TextBlock, ToolResultBlock, etc.)
function extractAgentId(message: SDKMessage): string | undefined {
if (!("message" in message)) return undefined;
// Stringify the content so we can search it without traversing nested blocks
const content = JSON.stringify(message.message.content);
const match = content.match(/agentId:\s*([a-f0-9-]+)/);
return match?.[1];
}

let agentId: string | undefined;
let sessionId: string | undefined;

// First invocation - use the Explore agent to find API endpoints
for await (const message of query({
prompt: "Use the Explore agent to find all API endpoints in this codebase",
options: { allowedTools: ["Read", "Grep", "Glob", "Agent"] }
})) {
// Capture session_id from ResultMessage (needed to resume this session)
if ("session_id" in message) sessionId = message.session_id;
// Search message content for the agentId (appears in Agent tool results)
const extractedId = extractAgentId(message);
if (extractedId) agentId = extractedId;
// Print the final result
if ("result" in message) console.log(message.result);
}

// Second invocation - resume and ask follow-up
if (agentId && sessionId) {
for await (const message of query({
prompt: `Resume agent ${agentId} and list the top 3 most complex endpoints`,
options: { allowedTools: ["Read", "Grep", "Glob", "Agent"], resume: sessionId }
})) {
if ("result" in message) console.log(message.result);
}
}

サブエージェントのトランスクリプトはメイン会話とは独立して永続化されます。

  • メイン会話の圧縮: メイン会話が圧縮されると、サブエージェントのトランスクリプトは影響を受けません。これらは別のファイルに保存されます。
  • セッション永続化: サブエージェントのトランスクリプトはセッション内で永続化されます。同じセッションを再開することで、Claude Code を再起動した後にサブエージェントを再開できます。
  • 自動クリーンアップ: トランスクリプトは cleanupPeriodDays 設定に基づいてクリーンアップされます(デフォルト:30 日)。

ツール制限

サブエージェントは tools フィールド経由で制限されたツールアクセスを持つことができます。

  • フィールドを省略: エージェントは利用可能なすべてのツールを継承します(デフォルト)
  • ツールを指定: エージェントはリストされたツールのみを使用できます

この例では、コードを検査できるが、ファイルを変更したりコマンドを実行したりできない読み取り専用分析エージェントを作成します。

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


async def main():
async for message in query(
prompt="Analyze the architecture of this codebase",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"],
agents={
"code-analyzer": AgentDefinition(
description="Static code analysis and architecture review",
prompt="""You are a code architecture analyst. Analyze code structure,
identify patterns, and suggest improvements without making changes.""",
# Read-only tools: no Edit, Write, or Bash access
tools=["Read", "Grep", "Glob"],
)
},
),
):
if hasattr(message, "result"):
print(message.result)


asyncio.run(main())

一般的なツール組み合わせ

ユースケース ツール 説明
読み取り専用分析 ReadGrepGlob コードを検査できますが、変更または実行はできません
テスト実行 BashReadGrep コマンドを実行し、出力を分析できます
コード変更 ReadEditWriteGrepGlob コマンド実行なしで完全な読み取り/書き込みアクセス
完全アクセス すべてのツール 親からすべてのツールを継承します(tools フィールドを省略)

トラブルシューティング

Claude がサブエージェントに委譲していない

Claude がサブエージェントに委譲する代わりにタスクを直接完了する場合:

  1. Agent ツールを含める: サブエージェントは Agent ツール経由で呼び出されるため、allowedTools に含める必要があります
  2. 明示的なプロンプトを使用する: プロンプトでサブエージェントを名前で言及します(例えば、「code-reviewer エージェントを使用して...」)
  3. 明確な説明を書く: サブエージェントをいつ使用すべきかを正確に説明し、Claude がタスクを適切にマッチングできるようにします

ファイルシステムベースのエージェントが読み込まれていない

.claude/agents/ で定義されたエージェントはスタートアップ時にのみ読み込まれます。Claude Code の実行中に新しいエージェントファイルを作成した場合、セッションを再起動して読み込んでください。

Windows:長いプロンプトの失敗

Windows では、非常に長いプロンプトを持つサブエージェントは、コマンドライン長の制限(8191 文字)により失敗する場合があります。プロンプトを簡潔に保つか、複雑な指示にはファイルシステムベースのエージェントを使用してください。

関連ドキュメント