SpyBara
Go Premium

agent-sdk/subagents.md 2026-06-16 21:57 UTC to 2026-06-17 17:02 UTC

87 added, 75 removed.

2026
Sat 27 01:01 Fri 26 23:00 Thu 25 23:58 Wed 24 22:02 Tue 23 22:00 Mon 22 23:59 Fri 19 22:58 Thu 18 22:00 Wed 17 17:02 Tue 16 21:57 Mon 15 23:02 Sat 13 21:59 Fri 12 22:00 Thu 11 23:01 Wed 10 23:57 Tue 9 06:34 Mon 8 06:52 Sat 6 06:24 Fri 5 06:45 Thu 4 06:52 Wed 3 06:53 Tue 2 06:51

Sous-agents dans le SDK

Définissez et invoquez des sous-agents pour isoler le contexte, exécuter des tâches en parallèle et appliquer des instructions spécialisées dans vos applications Claude Agent SDK.

Les sous-agents sont des instances d'agent distinctes que votre agent principal peut créer pour gérer des sous-tâches ciblées. Utilisez les sous-agents pour isoler le contexte des sous-tâches ciblées, exécuter plusieurs analyses en parallèle et appliquer des instructions spécialisées sans surcharger l'invite du principal agent.

Ce guide explique comment définir et utiliser les sous-agents dans le SDK en utilisant le paramètre agents.

Aperçu

Vous pouvez créer des sous-agents de trois façons :

  • Par programmation : utilisez le paramètre agents dans vos options query() (TypeScript, Python)
  • Basé sur le système de fichiers : définissez les agents comme des fichiers markdown dans les répertoires .claude/agents/ (voir définir les sous-agents comme fichiers)
  • Général intégré : Claude peut invoquer le sous-agent general-purpose intégré à tout moment via l'outil Agent sans que vous ayez besoin de rien définir

Ce guide se concentre sur l'approche programmatique, qui est recommandée pour les applications SDK.

Lorsque vous définissez des sous-agents, Claude détermine s'il faut les invoquer en fonction du champ description de chaque sous-agent. Écrivez des descriptions claires qui expliquent quand le sous-agent doit être utilisé, et Claude délèguera automatiquement les tâches appropriées. Vous pouvez également demander explicitement un sous-agent par son nom dans votre invite (par exemple, « Utilisez l'agent code-reviewer pour... »).

Avantages de l'utilisation des sous-agents

Isolation du contexte

Chaque sous-agent s'exécute dans sa propre conversation nouvelle. Les appels d'outils intermédiaires et les résultats restent à l'intérieur du sous-agent ; seul son message final revient au parent. Voir Ce que les sous-agents héritent pour savoir exactement ce qui se trouve dans le contexte du sous-agent.

Exemple : un sous-agent research-assistant peut explorer des dizaines de fichiers sans que le contenu de ces fichiers s'accumule dans la conversation principale. Le parent reçoit un résumé concis, pas chaque fichier que le sous-agent a lu.

Parallélisation

Plusieurs sous-agents peuvent s'exécuter simultanément, de sorte que les sous-tâches indépendantes se terminent dans le temps du plus lent plutôt que la somme de tous.

Exemple : lors d'une révision de code, vous pouvez exécuter les sous-agents style-checker, security-scanner et test-coverage simultanément au lieu de séquentiellement.

Instructions et connaissances spécialisées

Chaque sous-agent peut avoir des invites système adaptées avec une expertise spécifique, des meilleures pratiques et des contraintes.

Exemple : un sous-agent database-migration peut avoir des connaissances détaillées sur les meilleures pratiques SQL, les stratégies de restauration et les vérifications d'intégrité des données qui seraient du bruit inutile dans les instructions du principal agent.

Restrictions d'outils

Les sous-agents peuvent être limités à des outils spécifiques, réduisant le risque d'actions involontaires.

Exemple : un sous-agent doc-reviewer pourrait n'avoir accès qu'aux outils Read et Grep, garantissant qu'il peut analyser mais ne peut jamais modifier accidentellement vos fichiers de documentation.

Création de sous-agents

Définissez les sous-agents directement dans votre code en utilisant le paramètre agents. Cet exemple crée deux sous-agents : un examinateur de code avec accès en lecture seule et un exécuteur de tests qui peut exécuter des commandes. Claude invoque les sous-agents via l'outil Agent, donc incluez Agent dans allowedTools pour approuver automatiquement les invocations de sous-agents sans invite de permission.

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, including Agent 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())

Configuration AgentDefinition

Champ Type Requis Description
description string Oui Description en langage naturel de quand utiliser cet agent
prompt string Oui L'invite système de l'agent définissant son rôle et son comportement
tools string[] Non Tableau des noms d'outils autorisés. S'il est omis, hérite de tous les outils
disallowedTools string[] Non Tableau des noms d'outils à supprimer de l'ensemble d'outils de l'agent. Les modèles au niveau du serveur MCP sont également acceptés : mcp__server ou mcp__server__* supprime tous les outils de ce serveur, et mcp__* supprime tous les outils MCP de n'importe quel serveur
model string Non Remplacement du modèle pour cet agent. Accepte un alias tel que 'fable', 'opus', 'sonnet', 'haiku', 'inherit', ou un ID de modèle complet. Par défaut le modèle principal s'il est omis
skills string[] Non Liste des noms de compétences à précharger dans le contexte de l'agent au démarrage. Les compétences non listées restent invocables via l'outil Skill
memory 'user' | 'project' | 'local' Non Source de mémoire pour cet agent
mcpServers (string | object)[] Non Serveurs MCP disponibles pour cet agent, par nom ou configuration en ligne
initialPrompt string Non Soumis automatiquement comme premier tour utilisateur lorsque cet agent s'exécute en tant qu'agent de thread principal. Ignoré lorsque l'agent est invoqué en tant que sous-agent
maxTurns number Non Nombre maximum de tours d'agent avant que l'agent s'arrête
background boolean Non Exécuter cet agent comme une tâche de fond non bloquante lorsqu'il est invoqué
effort 'low' | 'medium' | 'high' | 'xhigh' | 'max' | number Non Niveau d'effort de raisonnement pour cet agent
permissionMode PermissionMode Non Mode de permission pour l'exécution des outils au sein de cet agent

Dans le SDK Python, ces noms de champs utilisent camelCase pour correspondre au format de transmission. Voir la référence AgentDefinition pour plus de détails.

Définition basée sur le système de fichiers (alternative)

Vous pouvez également définir les sous-agents comme des fichiers markdown dans les répertoires .claude/agents/. Voir la documentation des sous-agents Claude Code pour plus de détails sur cette approche. Les agents définis par programmation ont la priorité sur les agents basés sur le système de fichiers portant le même nom.

Ce que les sous-agents héritent

La fenêtre de contexte d'un sous-agent commence fraîche (pas de conversation parent) mais n'est pas vide. Le seul canal du parent au sous-agent est la chaîne d'invite de l'outil Agent, donc incluez tous les chemins de fichiers, messages d'erreur ou décisions dont le sous-agent a besoin directement dans cette invite.

Le sous-agent reçoit Le sous-agent ne reçoit pas
Sa propre invite système (AgentDefinition.prompt) et l'invite de l'outil Agent L'historique de conversation du parent ou les résultats des outils
Le CLAUDE.md du projet (chargé via settingSources) Le contenu des compétences préchargées, sauf s'il est listé dans AgentDefinition.skills
Les définitions d'outils (héritées du parent, ou le sous-ensemble dans tools) L'invite système du parent

Invocation des sous-agents

Invocation automatique

Claude décide automatiquement quand invoquer les sous-agents en fonction de la tâche et de la description de chaque sous-agent. Par exemple, si vous définissez un sous-agent performance-optimizer avec la description « Spécialiste de l'optimisation des performances pour l'optimisation des requêtes », Claude l'invoquera lorsque votre invite mentionne l'optimisation des requêtes.

Écrivez des descriptions claires et spécifiques pour que Claude puisse faire correspondre les tâches au bon sous-agent.

Invocation explicite

Pour garantir que Claude utilise un sous-agent spécifique, mentionnez-le par son nom dans votre invite :

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

Cela contourne la correspondance automatique et invoque directement le sous-agent nommé.

Configuration d'agent dynamique

Vous pouvez créer des définitions d'agent dynamiquement en fonction des conditions d'exécution. Cet exemple crée un examinateur de sécurité avec différents niveaux de rigueur, en utilisant un modèle plus puissant pour les révisions strictes.

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())

Détection de l'invocation de sous-agents

Les sous-agents sont invoqués via l'outil Agent. Pour détecter quand un sous-agent est invoqué, vérifiez les blocs tool_usename est "Agent". Les messages provenant du contexte d'un sous-agent incluent un champ parent_tool_use_id.

La structure du message diffère entre les SDK. En Python, les blocs de contenu sont accessibles directement via message.content. En TypeScript, SDKAssistantMessage enveloppe le message de l'API Claude, donc le contenu est accessible via message.message.content.

Cet exemple itère à travers les messages en continu, enregistrant quand un sous-agent est invoqué et quand les messages suivants proviennent du contexte d'exécution de ce sous-agent.

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())

Reprise des sous-agents

Les sous-agents peuvent être repris pour continuer là où ils se sont arrêtés. Les sous-agents repris conservent leur historique de conversation complet, y compris tous les appels d'outils précédents, les résultats et le raisonnement. Le sous-agent reprend exactement là où il s'est arrêté plutôt que de recommencer à zéro.

Lorsqu'un sous-agent se termine, le résultat de l'outil Agent inclut un bloc de texte contenant agentId: <id>. Les agents intégrés Explore et Plan sont ponctuels et ne retournent pas d'agentId, donc utilisez un agent personnalisé ou general-purpose lorsque vous avez besoin de reprendre. Pour reprendre un sous-agent par programmation :

  1. Capturez l'ID de session : Extrayez session_id des messages lors de la première requête
  2. Extrayez l'ID d'agent : Analysez agentId du texte du résultat de l'outil Agent
  3. Reprenez la session : Passez resume: sessionId dans les options de la deuxième requête, et incluez l'ID d'agent dans votre invite

L'exemple ci-dessous définit un agent personnalisé endpoint-finder. La première requête l'exécute et capture l'ID de session et l'ID d'agent du résultat de l'outil Agent, puis la deuxième requête reprend la session pour poser une question de suivi qui nécessite le contexte de la première analyse.

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
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)

# 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)


asyncio.run(main())

Les transcriptions des sous-agents persistent indépendamment de la conversation principale :

  • Compaction de la conversation principale : Lorsque la conversation principale se compacte, les transcriptions des sous-agents ne sont pas affectées. Elles sont stockées dans des fichiers séparés.
  • Persistance de la session : Les transcriptions des sous-agents persistent au sein de leur session. Vous pouvez reprendre un sous-agent après avoir redémarré Claude Code en reprenant la même session.
  • Nettoyage automatique : Les transcriptions sont nettoyées en fonction du paramètre cleanupPeriodDays (par défaut : 30 jours).

Restrictions d'outils

Les sous-agents peuvent avoir un accès aux outils restreint via le champ tools :

  • Omettez le champ : l'agent hérite de tous les outils disponibles (par défaut)
  • Spécifiez les outils : l'agent ne peut utiliser que les outils listés

Cet exemple crée un agent d'analyse en lecture seule qui peut examiner le code mais ne peut pas modifier les fichiers ou exécuter des commandes.

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())

Combinaisons d'outils courantes

Cas d'usage Outils Description
Analyse en lecture seule Read, Grep, Glob Peut examiner le code mais pas modifier ou exécuter
Exécution de tests Bash, Read, Grep Peut exécuter des commandes et analyser la sortie
Modification de code Read, Edit, Write, Grep, Glob Accès complet en lecture/écriture sans exécution de commandes
Accès complet Tous les outils Hérite de tous les outils du parent (omettez le champ tools)

Augmenter l'échelle avec des flux de travail dynamiques

Les sous-agents fonctionnent bien pour quelques tâches déléguées par tour. Pour les exécutions qui coordonnent des dizaines à des centaines d'agents, utilisez l'outil Workflow, qui déplace l'orchestration dans un script que le runtime exécute en dehors du contexte de conversation. Voir flux de travail dynamiques pour savoir comment les flux de travail diffèrent de la délégation de sous-agents tour par tour.

L'outil Workflow est disponible dans le TypeScript Agent SDK v0.3.149 et versions ultérieures. Incluez Workflow dans allowedTools pour approuver automatiquement les exécutions de flux de travail. Les schémas d'entrée et de sortie de l'outil sont listés dans la référence TypeScript.

Dépannage

Claude ne délègue pas aux sous-agents

Si Claude complète les tâches directement au lieu de déléguer à votre sous-agent :

  1. Vérifiez que les invocations d'Agent sont approuvées : incluez Agent dans allowedTools pour approuver automatiquement les appels de sous-agent. Sans cela, les invocations d'Agent passent par votre callback canUseTool ou, en mode dontAsk, sont refusées
  2. Utilisez des invites explicites : mentionnez le sous-agent par son nom dans votre invite (par exemple, « Utilisez l'agent code-reviewer pour... »)
  3. Écrivez une description claire : expliquez exactement quand le sous-agent doit être utilisé pour que Claude puisse faire correspondre les tâches de manière appropriée

Les agents basés sur le système de fichiers ne se chargent pas

Les agents définis dans .claude/agents/ sont chargés au démarrage uniquement. Si vous créez un nouveau fichier d'agent pendant que Claude Code s'exécute, redémarrez la session pour le charger.

Windows : échecs d'invite longue

Sur Windows, les sous-agents avec des invites très longues peuvent échouer en raison des limites de longueur de ligne de commande (8191 caractères). Gardez les invites concises ou utilisez des agents basés sur le système de fichiers pour les instructions complexes.

  • Sous-agents Claude Code : documentation complète des sous-agents incluant les définitions basées sur le système de fichiers
  • Flux de travail dynamiques : orchestrez de nombreux sous-agents à partir d'un script pour les tâches trop importantes pour une seule conversation
  • Aperçu du SDK : prise en main du Claude Agent SDK