SpyBara
Go Premium

agent-sdk/subagents.md 2026-09-27 23:59 UTC to 2026-09-28 22:01 UTC

This page contains 4 additions and 4 deletions.

2026
Wed 9 22:58 Sat 12 03:02 Fri 18 23:58 Tue 22 23:59 Mon 28 22:59

Subagents im SDK

Definieren und rufen Sie Subagents auf, um den Kontext zu isolieren, Aufgaben parallel auszuführen und spezialisierte Anweisungen in Ihren Claude Agent SDK-Anwendungen anzuwenden.

Subagents sind separate Agent-Instanzen, die Ihr Hauptagent spawnen kann, um fokussierte Teilaufgaben zu bewältigen. Verwenden Sie sie, um den Kontext zu isolieren, mehrere Analysen parallel auszuführen und spezialisierte Anweisungen anzuwenden, ohne das Prompt des Hauptagents zu erweitern.

Übersicht

Sie können Subagenten auf drei Arten erstellen:

  • Programmgesteuert: Verwenden Sie den Parameter agents in Ihren query()-Optionen. Siehe die Referenzen für TypeScript und Python
  • Dateisystem-basiert: Definieren Sie Agenten als Markdown-Dateien in .claude/agents/-Verzeichnissen. Siehe Subagenten als Dateien definieren
  • Integriert allgemein einsetzbar: Claude kann den integrierten general-purpose-Subagenten jederzeit über das Agent-Tool aufrufen, ohne dass Sie etwas definieren müssen

Dieser Leitfaden konzentriert sich auf den programmgesteuerten Ansatz, der für SDK-Anwendungen empfohlen wird.

Vorteile der Verwendung von Subagenten

Da Subagenten separate Agenten-Instanzen sind, bietet die Delegierung von Aufgaben an sie vier Vorteile:

  • Kontext-Isolation: Jeder Subagent läuft in seiner eigenen Konversation, die neu beginnt, es sei denn, der Subagent ist ein Fork. In jedem Fall bleiben zwischenzeitliche Tool-Aufrufe und Ergebnisse innerhalb des Subagenten; nur seine abschließende Nachricht kehrt zum übergeordneten Agenten zurück. Ein research-assistant-Subagent kann Dutzende von Dateien durchsuchen, ohne dass sich dieser Inhalt in der Hauptkonversation ansammelt. Der übergeordnete Agent erhält eine prägnante Zusammenfassung, nicht jede Datei, die der Subagent gelesen hat. Siehe What subagents inherit für genau das, was sich im Kontext des Subagenten befindet.
  • Parallelisierung: Mehrere Subagenten können gleichzeitig ausgeführt werden, sodass unabhängige Teilaufgaben in der Zeit des langsamsten statt in der Summe aller abgeschlossen werden. Während einer Code-Überprüfung können Sie style-checker-, security-scanner- und test-coverage-Subagenten gleichzeitig statt nacheinander ausführen.
  • Spezialisierte Anweisungen und Wissen: Jeder Subagent kann eine maßgeschneiderte System-Eingabeaufforderung mit spezifischer Expertise, Best Practices und Einschränkungen haben. Ein database-migration-Subagent kann detailliertes Wissen über SQL-Best-Practices, Rollback-Strategien und Datenintegritätsprüfungen haben, die in den Anweisungen des Hauptagenten unnötiges Rauschen wären.
  • Tool-Einschränkungen: Subagenten können auf bestimmte Tools beschränkt werden, was das Risiko unbeabsichtigter Aktionen verringert. Ein doc-reviewer-Subagent könnte nur Zugriff auf Read- und Grep-Tools haben, um sicherzustellen, dass er analysieren, aber niemals versehentlich Ihre Dokumentationsdateien ändern kann.

Subagenten erstellen

Definieren Sie Subagenten direkt in Ihrem Code mit dem Parameter agents. Claude ruft Subagenten über das Tool Agent auf.

Die meisten Beispiele auf dieser Seite geben nur das Endergebnis aus. Um zu bestätigen, dass Claude an einen Subagenten delegiert hat, anstatt direkt zu antworten, siehe Subagenten-Aufruf erkennen.

Dieses Beispiel erstellt zwei Subagenten: einen Code-Reviewer mit Lesezugriff und einen Test-Runner, der Befehle ausführen kann.

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(
# Auto-approve these tools
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-Konfiguration

Feld Typ Erforderlich Beschreibung
description string Ja Natürlichsprachige Beschreibung, wann dieser Agent verwendet werden soll
prompt string Ja Der System-Prompt des Agenten, der seine Rolle und sein Verhalten definiert
tools string[] Nein Array von zulässigen Tool-Namen. Falls weggelassen, erbt jeden für Subagenten verfügbaren Tool
disallowedTools string[] Nein Array von Tool-Namen, die aus dem Tool-Set des Agenten entfernt werden sollen. MCP-Server-Level-Muster werden ebenfalls akzeptiert: mcp__server oder mcp__server__* entfernt jeden Tool von diesem Server, und mcp__* entfernt jeden MCP-Tool von jedem Server
model string Nein Modell-Override für diesen Agent. Akzeptiert einen Alias wie 'fable', 'opus', 'sonnet', 'haiku', 'inherit', oder eine vollständige Modell-ID. 'inherit' verwendet das Hauptmodell. Wenn Sie es weglassen, wählt Claude Code das Modell in der Subagenten-Modellreihenfolge
skills string[] Nein Liste von Skill-Namen, die beim Start in den Kontext des Agenten vorgeladen werden sollen. Nicht aufgelistete Skills bleiben über das Skill-Tool aufrufbar
memory 'user' | 'project' | 'local' Nein Speicherquelle für diesen Agent
mcpServers (string | object)[] Nein MCP-Server, die diesem Agent zur Verfügung stehen, nach Name oder Inline-Konfiguration
initialPrompt string Nein Wird automatisch als erste Benutzer-Runde eingereicht, wenn dieser Agent als Haupt-Thread-Agent läuft. Wird ignoriert, wenn der Agent als Subagent aufgerufen wird
maxTurns number Nein Maximale Anzahl von Agent-Runden, bevor der Agent stoppt. Wenn der Agent das Limit erreicht, gibt Claude Code seine Ausgabe als teilweise markiert zurück, und Sie können den Agent fortsetzen, um fortzufahren. Die teilweise Markierung erfordert Claude Code v2.1.246 oder später
background boolean Nein Führen Sie diesen Agent als nicht-blockierende Hintergrund-Aufgabe aus, wenn er aufgerufen wird
omitClaudeMd boolean Nein Führen Sie diesen Agent ohne die Benutzer-, Projekt- und lokalen CLAUDE.md-Dateien aus, wenn er als Subagent läuft; verwaltete Richtliniendateien werden weiterhin geladen. Wird ignoriert, wenn der Agent als Haupt-Thread-Agent läuft. Erfordert TypeScript Agent SDK v0.3.271 oder später. Das Python SDK AgentDefinition hat dieses Feld nicht
effort 'low' | 'medium' | 'high' | 'xhigh' | 'max' | number Nein Reasoning-Aufwandsstufe für diesen Agent
permissionMode PermissionMode Nein Berechtigungsmodus für die Tool-Ausführung innerhalb dieses Agenten. Die Subagenten-Vererbungsregeln entscheiden, wann er angewendet wird

Im Python SDK behalten mehrteilige Feldnamen wie disallowedTools und mcpServers ihre camelCase-Schreibweise, um dem Wire-Format zu entsprechen, anstatt Pythons snake_case-Konvention zu folgen. Siehe die AgentDefinition-Referenz für Details.

Subagenten laufen standardmäßig im Hintergrund. Ein Agent-Tool-Aufruf, der die run_in_background-Eingabe weglässt, startet einen Hintergrund-Subagenten, und Claude setzt run_in_background: false, wenn es das Ergebnis benötigt, bevor es fortfährt. Setzen Sie das Feld background auf true, um die Hintergrund-Ausführung für einen bestimmten Agent zu erzwingen, unabhängig davon, was Claude anfordert. Vor Claude Code v2.1.198 wurde der Hintergrund-Standard schrittweise eingeführt, und ein Agent-Tool-Aufruf, der run_in_background wegließ, konnte den Subagenten synchron ausführen.

Subagenten können auch ihre eigenen Subagenten spawnen. Um zu begrenzen, wie tief diese Verschachtelung geht, wie viele Subagenten gleichzeitig laufen und wie viel eine Abfrage ausgibt, siehe Subagenten-Tiefe, Parallelität und Ausgaben begrenzen.

Dateisystem-basierte Definition (Alternative)

Sie können Subagenten auch als Markdown-Dateien in .claude/agents/-Verzeichnissen definieren. Siehe die Claude Code Subagenten-Dokumentation für Details zu diesem Ansatz. Programmatisch definierte Agenten haben Vorrang vor dateisystem-basierten Agenten mit demselben Namen.

Was Subagenten erben

Sofern der Subagent kein Fork ist, startet sein Kontextfenster neu, ohne übergeordnete Konversation, ist aber nicht leer. Der einzige Inhalt, den Sie vom übergeordneten Agent zum Subagenten übergeben, ist die Prompt-Zeichenkette des Agent-Tools. Fügen Sie daher alle Dateipfade, Fehlermeldungen oder Entscheidungen, die der Subagent benötigt, direkt in diese Prompt ein.

Ein Subagent, der das SendMessage-Tool hat, startet mit einer Liste der anderen benannten Agenten, die in der Sitzung ausgeführt werden, sodass er weiß, an welche Namen er Nachrichten senden kann. Claude Code fügt die Liste automatisch beim ersten Durchgang des Subagenten hinzu. Ein Fork erhält die Liste nicht, da er stattdessen die übergeordnete Konversation erbt.

Ein Subagent erbt auch die Konfiguration des erweiterten Denkens der Hauptsitzung.

Die folgende Tabelle zeigt, welche Inhalte der Kontext eines Nicht-Fork-Subagenten enthält und was er nicht enthält.

Der Subagent erhält Der Subagent erhält nicht
Seinen eigenen System-Prompt (AgentDefinition.prompt) und den Prompt des Agent-Tools Die Konversationshistorie oder Tool-Ergebnisse des übergeordneten Agenten
Projekt CLAUDE.md (geladen über settingSources), sofern der Agent nicht omitClaudeMd setzt Vorgeladene Skill-Inhalte, sofern nicht in AgentDefinition.skills aufgelistet
Tool-Definitionen (geerbt vom übergeordneten Agent oder die Teilmenge in tools, gefiltert für Hintergrund-Läufe) Der System-Prompt des übergeordneten Agenten

Ein API-Fehler, der den Subagenten vorzeitig beendet, wie z. B. eine Ratenbegrenzung, wird niemals als sein Ergebnis bereitgestellt. Siehe API-Fehler in Subagenten für das Vordergrund- und Hintergrundverhalten.

Subagenten aufrufen

Automatischer Aufruf

Claude entscheidet automatisch, wann Subagenten basierend auf der Aufgabe und der description jedes Subagenten aufgerufen werden. Wenn Sie beispielsweise einen performance-optimizer-Subagenten 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 Subagenten zuordnen kann.

Expliziter Aufruf

Um sicherzustellen, dass Claude einen bestimmten Subagenten verwendet, erwähnen Sie ihn namentlich in Ihrem Prompt:

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

Dies umgeht das automatische Matching und ruft den benannten Subagenten direkt auf.

Dynamische Agent-Konfiguration

Sie können Agent-Definitionen dynamisch basierend auf Laufzeitbedingungen erstellen. Dieses Beispiel erstellt einen Security-Reviewer mit verschiedenen Strenge-Ebenen 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", "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())

Subagent-Aufrufe erkennen

Claude ruft Subagents über das Agent-Tool auf. Um zu erkennen, wenn ein Subagent aufgerufen wird, suchen Sie nach tool_use-Blöcken, bei denen name gleich "Agent" ist. Nachrichten aus dem Kontext eines Subagents enthalten ein parent_tool_use_id-Feld.

Die Nachrichtenstruktur unterscheidet sich zwischen SDKs. In Python greifen Sie direkt über message.content auf Inhaltsblöcke zu. In TypeScript umhüllt SDKAssistantMessage die Claude-API-Nachricht, daher greifen Sie über message.message.content auf Inhalte zu.

Dieses Beispiel durchläuft gestreamte Nachrichten und protokolliert, wenn ein Subagent aufgerufen wird und wenn nachfolgende Nachrichten aus dem Ausführungskontext dieses Subagents stammen.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ToolUseBlock


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 isinstance(block, ToolUseBlock) 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())

Subagenten fortsetzen

Sie können einen Subagenten fortsetzen, um dort weiterzumachen, wo er aufgehört hat, anstatt von vorne zu beginnen. Ein fortgesetzter Subagent behält seine vollständige Gesprächshistorie bei, einschließlich aller vorherigen Tool-Aufrufe, Ergebnisse und Überlegungen.

Wenn ein Subagent sein maxTurns-Limit erreicht, markiert Claude Code die Ausgabe im Agent-Tool-Ergebnis als teilweise, damit Claude weiß, dass die Ausführung unvollständig ist.

Wenn ein Subagent abgeschlossen ist, enthält das Agent-Tool-Ergebnis einen Textblock mit agentId: <id>. Die integrierten Explore- und Plan-Agenten sind einmalig und geben keine agentId zurück. Verwenden Sie daher einen benutzerdefinierten Agenten oder general-purpose, wenn Sie fortsetzen müssen. Um einen Subagenten programmgesteuert fortzusetzen:

  1. Erfassen Sie die Sitzungs-ID: Extrahieren Sie session_id aus Nachrichten während der ersten Abfrage
  2. Extrahieren Sie die Agent-ID: Analysieren Sie agentId aus dem Agent-Tool-Ergebnis-Text
  3. Setzen Sie die Sitzung fort: Übergeben Sie resume: sessionId in den Optionen der zweiten Abfrage, und fügen Sie die Agent-ID in Ihrem Prompt ein. Jeder query()-Aufruf startet standardmäßig eine neue Sitzung, und Sie müssen dieselbe Sitzung fortsetzen, um auf das Transkript des Subagenten zuzugreifen.

Das folgende Beispiel definiert einen benutzerdefinierten endpoint-finder-Agenten. Die erste Abfrage führt ihn aus und erfasst die Sitzungs-ID und Agent-ID aus dem Agent-Tool-Ergebnis. Dann setzt die zweite Abfrage die Sitzung fort, um eine Folgefrage zu stellen, die Kontext aus der ersten Analyse erfordert.

import asyncio
import re
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ToolResultBlock

AGENTS = {
"endpoint-finder": AgentDefinition(
description="Locates and catalogs API endpoints in a codebase.",
prompt="You find and document API endpoints. Report each endpoint's path, method, and handler.",
tools=["Read", "Grep", "Glob"],
)
}


def extract_agent_id(block: ToolResultBlock) -> str | None:
"""Extract agentId from an Agent tool result's text content."""
parts = block.content if isinstance(block.content, list) else [{"text": block.content}]
for part in parts:
if match := re.search(r"agentId:\s*([\w-]+)", part.get("text") or ""):
return match.group(1)
return None


async def main():
agent_id = None
session_id = None

# First invocation - run the endpoint-finder subagent
try:
async for message in query(
prompt="Use the endpoint-finder agent to find all API endpoints in this codebase",
options=ClaudeAgentOptions(allowed_tools=["Read", "Grep", "Glob", "Agent"], agents=AGENTS),
):
# Capture session_id from ResultMessage (needed to resume this session)
if hasattr(message, "session_id"):
session_id = message.session_id
# Search tool results for the agentId trailer
for block in getattr(message, "content", None) or []:
if isinstance(block, ToolResultBlock):
agent_id = extract_agent_id(block) or agent_id
# Print the final result
if hasattr(message, "result"):
print(message.result)
except Exception as error:
# A single-shot query() raises after yielding an error result,
# so session_id and agent_id have already been captured by the loop above.
print(f"Session ended with an error: {error}")

# Second invocation - resume and ask follow-up
if agent_id and session_id:
async for message in query(
prompt=f"Resume agent {agent_id} and list the top 3 most complex endpoints",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"], agents=AGENTS, resume=session_id
),
):
if hasattr(message, "result"):
print(message.result)
else:
print("No agentId found in the first query, so there is no subagent to resume.")


asyncio.run(main())

Subagenten-Transkripte werden in separaten Dateien gespeichert und bleiben unabhängig vom Hauptgespräch erhalten. Siehe Subagenten in Claude Code fortsetzen für das Komprimierungsverhalten und den cleanupPeriodDays-Bereinigungszeitraum.

Werkzeugbeschränkungen

Verwenden Sie das Feld tools, um zu begrenzen, was ein Subagent tun kann:

  • tools weglassen: Der Subagent erhält jedes Werkzeug, das für Subagenten verfügbar ist
  • Werkzeuge auflisten: Der Subagent erhält nur diese. Ein Code-Reviewer, der niemals Dateien bearbeiten sollte, erhält beispielsweise ["Read", "Grep", "Glob"]

Ein Werkzeug, das Sie weglassen, ist überhaupt nicht in der Sitzung des Subagenten vorhanden: Claude arbeitet ohne es, ohne Berechtigungsaufforderung oder Fehler.

Dieses Beispiel erstellt einen schreibgeschützten Analyse-Agent, der Code untersuchen kann, 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", "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())

Häufige Werkzeugkombinationen

Anwendungsfall Werkzeuge Beschreibung
Schreibgeschützte Analyse Read, Grep, Glob Kann Code untersuchen, aber nicht ändern oder ausführen
Testausfü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 Werkzeuge Erbt die für Subagenten verfügbaren Werkzeuge (Feld tools weglassen)

Tiefe, Parallelität und Ausgaben von Subagenten begrenzen

Claude entscheidet selbst, wann ein Subagent erzeugt werden soll und wie viele erzeugt werden sollen. Jeder Subagent stellt seine eigenen API-Anfragen, die zur total_cost_usd der Abfrage zählen, und ein Subagent kann seine eigenen Subagenten erzeugen, sodass ein Prompt zu einem Baum von Agenten wachsen kann.

Sie können dieses Wachstum auf drei Arten begrenzen: wie tief Subagenten verschachtelt sind, wie viele gleichzeitig ausgeführt werden und wie viel die gesamte Abfrage kostet. Legen Sie die Tiefe- und Parallelitätslimits als Umgebungsvariablen über die env-Option fest, und das Ausgabenlimit als Abfrageoption:

Limit Festlegen mit Standard Was Claude Code beim Limit tut
Tiefe CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH 3 Ebenen von Subagenten unter Ihrem Hauptagenten. 1 verhindert, dass Ihre Subagenten ihre eigenen erzeugen Lässt einen Subagenten in der untersten Ebene unfähig sein zu erzeugen, sodass er seine delegierte Arbeit selbst erledigt. Siehe verschachtelte Subagenten
Parallelität CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS 20 Subagenten, die gleichzeitig ausgeführt werden, zählen jeden Subagenten, den Claude mit dem Agent-Tool erzeugt Weigert sich, einen weiteren Subagenten zu erzeugen, gibt Concurrent subagent limit reached zurück, bis die laufende Anzahl unter das Limit fällt. Sitzungen mit aktivem ultracode werden nie abgelehnt. Siehe das Parallelitätslimit für Subagenten
Ausgaben maxBudgetUsd in TypeScript, max_budget_usd in Python Kein Limit. Zählt die Ausgaben des Aufrufs selbst, einschließlich Subagenten-Anfragen Erzwingt die Obergrenze auf drei Arten: weigert sich, mehr Subagenten zu erzeugen, gibt Budget limit reached zurück, stoppt Hintergrund-Subagenten, die noch ausgeführt werden, und beendet die Abfrage mit dem Ergebnis-Subtyp error_max_budget_usd. Wie sich die Obergrenzen über eine Sitzung hinweg verhalten, finden Sie unter Durchläufe und Budget

Die beiden SDKs behandeln die env-Option unterschiedlich: Das TypeScript SDK ersetzt die Subprocess-Umgebung damit, daher verteilen Sie process.env darin, um Variablen wie PATH zu behalten, während das Python SDK es in die geerbte Umgebung zusammenführt. Dieses Beispiel deaktiviert Verschachtelung, erlaubt höchstens fünf Subagenten gleichzeitig und stoppt die Abfrage, sobald die geschätzten Ausgaben $5 erreichen:

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def main():
try:
async for message in query(
prompt="Audit every service in this repo for unhandled promise rejections",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"],
# env is merged on top of the inherited environment
env={
"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "1",
"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS": "5",
},
max_budget_usd=5.0,
),
):
if isinstance(message, ResultMessage):
print(f"{message.subtype}: ${message.total_cost_usd}")
except Exception as error:
# A single-shot query() raises after yielding an error result,
# so the budget-capped result has already been printed above.
print(f"Session ended with an error: {error}")


asyncio.run(main())

Was Sie sehen, hängt davon ab, welches Limit, falls vorhanden, die Abfrage erreicht:

  • Unter der Ausgabenbegrenzung: Sie sehen success und die geschätzten Kosten.
  • Bei der Ausgabenbegrenzung: Sie sehen error_max_budget_usd mit Kosten bei oder über 5, und dann wird Ihr Fehlerhandler ausgeführt.
  • Bei der Parallelitätsbegrenzung: Sie sehen einen tool_result-Block im Nachrichtenstrom mit Concurrent subagent limit reached. Claude erhält denselben Block als Ergebnis des Agent-Tools.

Opus 5 mit Subagenten ausführen

Claude Opus 5 delegiert bereitwilliger an Subagenten als frühere Modelle, daher sind die Tiefe-, Parallelitäts- und Ausgabenlimits am wichtigsten bei Abfragen, die Opus 5 ausführen. Der Opus 5-Prompting-Leitfaden enthält eine Delegationsanweisung, die Sie zu jedem Prompt hinzufügen können. Ob Claude Code eine eigene Anweisung hinzufügt, hängt davon ab, welche System-Prompt Sie verwenden:

  • claude_code-Voreinstellung: Wenn das Modell Opus 5 ist, fügt Claude Code eine Zeile zu seinem System-Prompt hinzu, die Claude mitteilt, das Agent-Tool nicht aufzurufen, es sei denn, es wird danach gefragt. Das Agent-Tool bleibt verfügbar.
  • Ein benutzerdefinierter Prompt oder kein systemPrompt: Claude Code erstellt seinen System-Prompt nicht, daher fehlt diese Zeile. Fügen Sie die Delegationsanweisung aus dem Prompting-Leitfaden zu Ihrem eigenen Prompt hinzu.

Jede Anweisung lenkt nur Claude, daher legen Sie auch die Limits fest. Claude Code erzwingt sie, wie auch immer Claude delegiert.

Skalierung mit dynamischen Workflows

Subagenten funktionieren gut für einige delegierte Aufgaben pro Turn. Für Läufe, die Dutzende bis Hunderte von Agenten koordinieren, verwenden Sie das Workflow-Tool, das die Orchestrierung in ein Skript verlagert, das die Laufzeit außerhalb des Konversationskontexts ausführt. Siehe dynamische Workflows für die Unterschiede zwischen Workflows und Turn-für-Turn-Subagenten-Delegation.

Das Workflow-Tool ist im TypeScript Agent SDK v0.3.149 und später verfügbar. Fügen Sie Workflow in allowedTools ein, um Workflow-Läufe automatisch zu genehmigen. Die Tool-Input- und Output-Schemas sind in der TypeScript-Referenz aufgelistet.

Fehlerbehebung

Claude delegiert nicht an Subagenten

Wenn Claude Aufgaben direkt abschließt, anstatt an Ihren Subagenten zu delegieren:

  • Verwenden Sie explizites Prompting: Erwähnen Sie den Subagenten nach Name in Ihrem Prompt, zum Beispiel „Verwenden Sie den Code-Reviewer-Agent, um das Authentifizierungsmodul zu überprüfen"
  • Schreiben Sie eine klare Beschreibung: Erklären Sie genau, wann der Subagent verwendet werden sollte, damit Claude Aufgaben angemessen zuordnen kann

Dateisystem-basierte Agenten werden nicht geladen

Claude Code überwacht ~/.claude/agents/ und .claude/agents/ und erkennt eine neue oder bearbeitete Agent-Datei innerhalb weniger Sekunden, ohne dass ein Neustart erforderlich ist. Wenn eine Definition nie angezeigt wird, arbeiten Sie diese Ursachen durch:

  • Neues agents-Verzeichnis: Der Watcher deckt nur Verzeichnisse ab, die beim Start der Session vorhanden waren, daher benötigt die erste Datei in einem neuen Verzeichnis einen Session-Neustart. Dies ist die häufigste Ursache.
  • Ungültiges Frontmatter oder doppelter name: Überprüfen Sie die YAML der Datei und ob ein vorhandener Agent bereits den name verwendet.
  • --disable-slash-commands: Sessions, die mit diesem Flag gestartet wurden, überwachen diese Verzeichnisse nicht und benötigen immer einen Neustart, um neue Dateien zu laden.
  • Eine Datei unter einem hinzugefügten Verzeichnis: Claude Code lädt .claude/agents/ aus Verzeichnissen, die mit der add_dirs-Option (Python) oder additionalDirectories-Option (TypeScript) oder der CLI-Option --add-dir oder /add-dir hinzugefügt wurden, überwacht sie aber nicht, daher benötigt eine neue oder bearbeitete Datei dort einen Session-Neustart.
  • Ein programmatischer Agent mit demselben Namen: agents, die an query() übergeben werden, überschreiben einen Dateisystem-Agent mit demselben Namen.

Für das Dateiformat siehe wie man Subagenten-Dateien schreibt.

  • Claude Code Subagenten: umfassende Subagenten-Dokumentation einschließlich dateisystem-basierter Definitionen
  • Dynamische Workflows: Orchestrieren Sie viele Subagenten aus einem Skript für Jobs, die zu groß für eine Konversation sind
  • SDK-Übersicht: Erste Schritte mit dem Claude Agent SDK