サブエージェントは、メインエージェントが集中的なサブタスクを処理するために生成できる個別のエージェントインスタンスです。 サブエージェントを使用して、集中的なサブタスクのためにコンテキストを分離し、複数の分析を並列実行し、メインエージェントのプロンプトを肥大化させることなく専門的な指示を適用できます。
このガイドでは、agents パラメータを使用してSDKでサブエージェントを定義・使用する方法を説明します。
サブエージェントは3つの方法で作成できます:
query() オプションの agents パラメータを使用(TypeScript、Python).claude/agents/ ディレクトリにマークダウンファイルとしてエージェントを定義(ファイルとしてのサブエージェント定義を参照)general-purpose サブエージェントを呼び出すことができますこのガイドでは、SDKアプリケーションに推奨されるプログラム的アプローチに焦点を当てます。
サブエージェントを定義すると、Claudeは各サブエージェントの description フィールドに基づいて呼び出すかどうかを判断します。サブエージェントをいつ使用すべきかを説明する明確な説明を記述すれば、Claudeは適切なタスクを自動的に委任します。プロンプトでサブエージェントを名前で明示的にリクエストすることもできます(例:「code-reviewerエージェントを使って...」)。
サブエージェントはメインエージェントとは別のコンテキストを維持し、情報過多を防ぎ、インタラクションを集中させます。この分離により、専門的なタスクが無関係な詳細でメインの会話コンテキストを汚染することがなくなります。
例: research-assistant サブエージェントは、メインの会話をすべての中間検索結果で散らかすことなく、数十のファイルやドキュメントページを探索し、関連する発見のみを返すことができます。
複数のサブエージェントを同時に実行でき、複雑なワークフローを劇的に高速化します。
例: コードレビュー中に、style-checker、security-scanner、test-coverage サブエージェントを同時に実行し、レビュー時間を数分から数秒に短縮できます。
各サブエージェントは、特定の専門知識、ベストプラクティス、制約を含むカスタマイズされたシステムプロンプトを持つことができます。
例: database-migration サブエージェントは、メインエージェントの指示では不要なノイズとなるSQLのベストプラクティス、ロールバック戦略、データ整合性チェックに関する詳細な知識を持つことができます。
サブエージェントを特定のツールに制限でき、意図しないアクションのリスクを軽減します。
例: doc-reviewer サブエージェントはReadとGrepツールのみにアクセスでき、ドキュメントファイルを分析はできても誤って変更することがないようにします。
agents パラメータを使用してコード内で直接サブエージェントを定義します。この例では、読み取り専用アクセスのコードレビューアーとコマンドを実行できるテストランナーの2つのサブエージェントを作成します。ClaudeはTaskツールを介してサブエージェントを呼び出すため、allowedTools に Task ツールを含める必要があります。
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(
# Task tool is required for subagent invocation
allowed_tools=["Read", "Grep", "Glob", "Task"],
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())| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
description | string | はい | このエージェントをいつ使用するかの自然言語による説明 |
prompt | string | はい | エージェントの役割と動作を定義するシステムプロンプト |
tools | string[] | いいえ | 許可されたツール名の配列。省略した場合、すべてのツールを継承 |
model | 'sonnet' | 'opus' | 'haiku' | 'inherit' | いいえ | このエージェントのモデルオーバーライド。省略した場合はメインモデルがデフォルト |
サブエージェントは独自のサブエージェントを生成できません。サブエージェントの tools 配列に Task を含めないでください。
.claude/agents/ ディレクトリにマークダウンファイルとしてサブエージェントを定義することもできます。このアプローチの詳細については、Claude Codeサブエージェントドキュメントを参照してください。プログラム的に定義されたエージェントは、同じ名前のファイルシステムベースのエージェントよりも優先されます。
カスタムサブエージェントを定義しなくても、allowedTools に Task が含まれていれば、Claudeは組み込みの general-purpose サブエージェントを生成できます。これは、専門的なエージェントを作成せずにリサーチや探索タスクを委任するのに便利です。
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", "Task"],
agents={
# Call the factory with your desired configuration
"security-reviewer": create_security_agent("strict")
}
)
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())サブエージェントはTaskツールを介して呼び出されます。サブエージェントがいつ呼び出されたかを検出するには、name: "Task" を持つ tool_use ブロックを確認します。サブエージェントのコンテキスト内からのメッセージには parent_tool_use_id フィールドが含まれます。
この例では、ストリーミングされたメッセージを反復処理し、サブエージェントが呼び出されたときと、後続のメッセージがそのサブエージェントの実行コンテキスト内から発信されたときにログを記録します。
メッセージ構造はSDK間で異なります。Pythonでは、コンテンツブロックは message.content を介して直接アクセスされます。TypeScriptでは、SDKAssistantMessage がClaude APIメッセージをラップするため、コンテンツは message.message.content を介してアクセスされます。
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", "Task"],
agents={
"code-reviewer": AgentDefinition(
description="Expert code reviewer.",
prompt="Analyze code quality and suggest improvements.",
tools=["Read", "Glob", "Grep"]
)
}
)
):
# Check for subagent invocation in message content
if hasattr(message, 'content') and message.content:
for block in message.content:
if getattr(block, 'type', None) == 'tool_use' and block.name == 'Task':
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はTaskツールの結果でそのエージェントIDを受け取ります。サブエージェントをプログラム的に再開するには:
session_id を抽出agentId を解析resume: sessionId を渡し、プロンプトにエージェントIDを含めるサブエージェントのトランスクリプトにアクセスするには、同じセッションを再開する必要があります。各 query() 呼び出しはデフォルトで新しいセッションを開始するため、同じセッションで続行するには resume: sessionId を渡してください。
カスタムエージェント(組み込みではないもの)を使用している場合は、両方のクエリで agents パラメータに同じエージェント定義を渡す必要もあります。
以下の例はこのフローを示しています:最初のクエリでサブエージェントを実行してセッション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', 'Task'] }
})) {
// 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 Task 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', 'Task'], resume: sessionId }
})) {
if ('result' in message) console.log(message.result);
}
}サブエージェントのトランスクリプトはメインの会話とは独立して永続化されます:
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", "Task"],
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())| ユースケース | ツール | 説明 |
|---|---|---|
| 読み取り専用分析 | Read, Grep, Glob | コードを調査できるが、変更や実行はできない |
| テスト実行 | Bash, Read, Grep | コマンドを実行して出力を分析できる |
| コード変更 | Read, Edit, Write, Grep, Glob | コマンド実行なしの完全な読み書きアクセス |
| フルアクセス | すべてのツール | 親からすべてのツールを継承(tools フィールドを省略) |
Claudeがサブエージェントに委任せずにタスクを直接完了する場合:
allowedTools に含める必要があります.claude/agents/ で定義されたエージェントは起動時にのみ読み込まれます。Claude Codeの実行中に新しいエージェントファイルを作成した場合は、セッションを再起動して読み込んでください。
Windowsでは、非常に長いプロンプトを持つサブエージェントがコマンドラインの長さ制限(8191文字)により失敗する場合があります。プロンプトを簡潔に保つか、複雑な指示にはファイルシステムベースのエージェントを使用してください。
Was this page helpful?