Subagents sind separate Agent-Instanzen, die Ihr Hauptagent spawnen kann, um fokussierte Teilaufgaben zu bewältigen. Verwenden Sie Subagents, um den Kontext für fokussierte Teilaufgaben zu isolieren, mehrere Analysen parallel auszuführen und spezialisierte Anweisungen anzuwenden, ohne den Prompt des Hauptagents zu überlasten.
Dieser Leitfaden erklärt, wie Sie Subagents im SDK mit dem Parameter agents definieren und verwenden.
Sie können Subagents auf drei Arten erstellen:
agents in Ihren query()-Optionen (TypeScript, Python).claude/agents/-Verzeichnissen (siehe Subagents als Dateien definieren)general-purpose-Subagent jederzeit über das Task-Tool aufrufen, ohne dass Sie etwas definieren müssenDieser Leitfaden konzentriert sich auf den programmatischen Ansatz, der für SDK-Anwendungen empfohlen wird.
Wenn Sie Subagents definieren, entscheidet Claude basierend auf dem Feld description jedes Subagents, ob er ihn aufrufen soll. Schreiben Sie klare Beschreibungen, die erklären, wann der Subagent verwendet werden sollte, und Claude wird automatisch geeignete Aufgaben delegieren. Sie können einen Subagent auch explizit nach Name in Ihrem Prompt anfordern (z. B. „Verwenden Sie den Code-Reviewer-Agent, um...").
Subagents verwalten einen separaten Kontext vom Hauptagent, was Informationsüberflutung verhindert und Interaktionen fokussiert hält. Diese Isolierung stellt sicher, dass spezialisierte Aufgaben den Hauptkonversationskontext nicht mit irrelevanten Details verschmutzen.
Beispiel: Ein research-assistant-Subagent kann Dutzende von Dateien und Dokumentationsseiten durchsuchen, ohne die Hauptkonversation mit allen zwischenzeitlichen Suchergebnissen zu überlasten, und gibt nur die relevanten Erkenntnisse zurück.
Mehrere Subagents können gleichzeitig ausgeführt werden und beschleunigen komplexe Workflows dramatisch.
Beispiel: Während einer Code-Überprüfung können Sie style-checker-, security-scanner- und test-coverage-Subagents gleichzeitig ausführen und die Überprüfungszeit von Minuten auf Sekunden reduzieren.
Jeder Subagent kann maßgeschneiderte System-Prompts mit spezifischer Expertise, Best Practices und Einschränkungen haben.
Beispiel: Ein database-migration-Subagent kann detailliertes Wissen über SQL-Best-Practices, Rollback-Strategien und Datenintegritätsprüfungen haben, die in den Anweisungen des Hauptagents unnötiger Lärm wären.
Subagents können auf bestimmte Tools beschränkt werden, was das Risiko unbeabsichtigter Aktionen reduziert.
Beispiel: Ein doc-reviewer-Subagent könnte nur Zugriff auf Read- und Grep-Tools haben, um sicherzustellen, dass er Dokumentationsdateien analysieren, aber niemals versehentlich ändern kann.
Definieren Sie Subagents direkt in Ihrem Code mit dem Parameter agents. Dieses Beispiel erstellt zwei Subagents: einen Code-Reviewer mit Nur-Lese-Zugriff und einen Test-Runner, der Befehle ausführen kann. Das Task-Tool muss in allowedTools enthalten sein, da Claude Subagents über das Task-Tool aufruft.
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())| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
description | string | Ja | Natürlichsprachige Beschreibung, wann dieser Agent verwendet werden soll |
prompt | string | Ja | Der System-Prompt des Agents, der seine Rolle und sein Verhalten definiert |
tools | string[] | Nein | Array von zulässigen Tool-Namen. Falls weggelassen, erbt alle Tools |
model | 'sonnet' | 'opus' | 'haiku' | 'inherit' | Nein | Modell-Override für diesen Agent. Standardmäßig das Hauptmodell, falls weggelassen |
Subagents können keine eigenen Subagents spawnen. Fügen Sie Task nicht in das tools-Array eines Subagents ein.
Sie können Subagents auch als Markdown-Dateien in .claude/agents/-Verzeichnissen definieren. Weitere Informationen zu diesem Ansatz finden Sie in der Claude Code Subagents-Dokumentation. Programmatisch definierte Agents haben Vorrang vor dateisystem-basierten Agents mit demselben Namen.
Auch ohne benutzerdefinierte Subagents kann Claude den integrierten general-purpose-Subagent spawnen, wenn Task in Ihren allowedTools enthalten ist. Dies ist nützlich, um Recherche- oder Explorationsaufgaben zu delegieren, ohne spezialisierte Agents zu erstellen.
Claude entscheidet automatisch, wann Subagents basierend auf der Aufgabe und der description jedes Subagents aufgerufen werden. Wenn Sie beispielsweise einen performance-optimizer-Subagent mit der Beschreibung „Performance-Optimierungsspezialist für Query-Tuning" definieren, wird Claude ihn aufrufen, wenn Ihr Prompt die Optimierung von Queries erwähnt.
Schreiben Sie klare, spezifische Beschreibungen, damit Claude Aufgaben dem richtigen Subagent zuordnen kann.
Um sicherzustellen, dass Claude einen bestimmten Subagent verwendet, erwähnen Sie ihn nach Name in Ihrem Prompt:
"Use the code-reviewer agent to check the authentication module"Dies umgeht automatisches Matching und ruft direkt den benannten Subagent auf.
Sie können Agent-Definitionen dynamisch basierend auf Laufzeitbedingungen erstellen. Dieses Beispiel erstellt einen Security-Reviewer mit verschiedenen Strenge-Leveln und verwendet ein leistungsfähigeres Modell für strenge Überprüfungen.
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())Subagents werden über das Task-Tool aufgerufen. Um zu erkennen, wann ein Subagent aufgerufen wird, suchen Sie nach tool_use-Blöcken mit name: "Task". Nachrichten aus dem Kontext eines Subagents enthalten ein Feld parent_tool_use_id.
Dieses Beispiel durchläuft gestreamte Nachrichten und protokolliert, wenn ein Subagent aufgerufen wird und wenn nachfolgende Nachrichten aus dem Ausführungskontext dieses Subagents stammen.
Die Nachrichtenstruktur unterscheidet sich zwischen SDKs. In Python werden Inhaltsblöcke direkt über message.content aufgerufen. In TypeScript umhüllt SDKAssistantMessage die Claude API-Nachricht, daher wird auf den Inhalt über message.message.content zugegriffen.
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())Subagents können fortgesetzt werden, um dort fortzufahren, wo sie aufgehört haben. Fortgesetzte Subagents behalten ihre vollständige Konversationshistorie, einschließlich aller vorherigen Tool-Aufrufe, Ergebnisse und Überlegungen. Der Subagent setzt genau dort an, wo er gestoppt hat, anstatt von vorne zu beginnen.
Wenn ein Subagent abgeschlossen ist, erhält Claude seine Agent-ID im Task-Tool-Ergebnis. Um einen Subagent programmatisch fortzusetzen:
session_id aus Nachrichten während der ersten AbfrageagentId aus dem Nachrichteninhaltresume: sessionId in den Optionen der zweiten Abfrage und fügen Sie die Agent-ID in Ihren Prompt einSie müssen dieselbe Session fortsetzen, um auf das Transkript des Subagents zuzugreifen. Jeder query()-Aufruf startet standardmäßig eine neue Session, daher übergeben Sie resume: sessionId, um in derselben Session fortzufahren.
Wenn Sie einen benutzerdefinierten Agent verwenden (nicht einen integrierten), müssen Sie auch dieselbe Agent-Definition im Parameter agents für beide Abfragen übergeben.
Das folgende Beispiel demonstriert diesen Ablauf: Die erste Abfrage führt einen Subagent aus und erfasst die Session-ID und Agent-ID, dann setzt die zweite Abfrage die Session fort, um eine Folgefrage zu stellen, die Kontext aus der ersten Analyse erfordert.
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);
}
}Subagent-Transkripte bleiben unabhängig von der Hauptkonversation bestehen:
cleanupPeriodDays bereinigt (Standard: 30 Tage).Subagents können eingeschränkten Tool-Zugriff über das Feld tools haben:
Dieses Beispiel erstellt einen schreibgeschützten Analyse-Agent, der Code untersuchen, aber keine Dateien ändern oder Befehle ausführen kann.
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())| Anwendungsfall | Tools | Beschreibung |
|---|---|---|
| Schreibgeschützte Analyse | Read, Grep, Glob | Kann Code untersuchen, aber nicht ändern oder ausführen |
| Test-Ausführung | Bash, Read, Grep | Kann Befehle ausführen und Ausgabe analysieren |
| Code-Änderung | Read, Edit, Write, Grep, Glob | Vollständiger Lese-/Schreibzugriff ohne Befehlsausführung |
| Vollständiger Zugriff | Alle Tools | Erbt alle Tools vom übergeordneten Element (Feld tools weglassen) |
Wenn Claude Aufgaben direkt abschließt, anstatt an Ihren Subagent zu delegieren:
allowedTools enthalten seinAgents, die in .claude/agents/ definiert sind, werden nur beim Start geladen. Wenn Sie eine neue Agent-Datei erstellen, während Claude Code ausgeführt wird, starten Sie die Session neu, um sie zu laden.
Unter Windows können Subagents mit sehr langen Prompts aufgrund von Befehlszeilenlängenbeschränkungen (8191 Zeichen) fehlschlagen. Halten Sie Prompts prägnant oder verwenden Sie dateisystem-basierte Agents für komplexe Anweisungen.
Was this page helpful?