Annexes · Claude
Aide-mémoire Agent SDK
Démarrages rapides du Claude Agent SDK en Python et TypeScript, options, hooks, subagents, serveurs MCP, modes de permission, événements de streaming et patterns headless.
Le Claude Agent SDK (claude-agent-sdk, renommé depuis « Claude Code SDK ») expose de façon programmatique le harnais d’agent de Claude Code : la boucle agentique, les outils, les hooks, les permissions, les subagents et les serveurs MCP. Vous l’hébergez — à opposer aux Managed Agents, où Anthropic héberge la boucle et le sandbox.
Quand recourir au SDK
Choisissez l’Agent SDK quand vous devez contrôler le runtime, le réseau, la localité des données ou le harnais lui-même. Choisissez les Managed Agents pour une charge opérationnelle minimale. Choisissez une simple boucle Messages API quand vous n’avez pas besoin de la machinerie fichiers/outils de Claude Code.
Installation
pip install claude-agent-sdk # Pythonnpm install @anthropic-ai/claude-agent-sdk # TypeScriptDémarrage rapide
import anyiofrom claude_agent_sdk import query, ClaudeAgentOptions
async def main(): options = ClaudeAgentOptions( model="claude-opus-5", system_prompt="You are a precise refactoring assistant.", allowed_tools=["Read", "Edit", "Bash"], permission_mode="acceptEdits", cwd="/repo", ) async for message in query(prompt="Rename getUserName to getUsername repo-wide, then run tests.", options=options): print(message)
anyio.run(main)import { query } from '@anthropic-ai/claude-agent-sdk';
for await (const message of query({ prompt: 'Rename getUserName to getUsername repo-wide, then run tests.', options: { model: 'claude-opus-5', systemPrompt: 'You are a precise refactoring assistant.', allowedTools: ['Read', 'Edit', 'Bash'], permissionMode: 'acceptEdits', cwd: '/repo', },})) { console.log(message);}Options
| Option (Py / TS) | Objet |
|---|---|
model | ID de modèle (claude-opus-5, claude-sonnet-5, …) |
system_prompt / systemPrompt | Instructions de base ; peut s’ajouter au prompt intégré de Claude Code |
allowed_tools / allowedTools | Allowlist d’outils (Read, Edit, Bash, Grep, …) |
disallowed_tools / disallowedTools | Refus explicites |
permission_mode / permissionMode | default | acceptEdits | plan | bypassPermissions |
cwd | Répertoire de travail |
mcp_servers / mcpServers | Configs de serveurs MCP disponibles pour l’agent |
hooks | Handlers de cycle de vie (voir ci-dessous) |
agents | Définitions de subagents |
setting_sources / settingSources | Charger ou non CLAUDE.md/les settings depuis le disque |
max_turns / maxTurns | Plafond de sécurité sur les tours agentiques (pas l’arrêt principal) |
env | Variables d’environnement pour l’exécution des outils |
max_turns est un garde-fou, pas un arrêt
max_turns est un filet de sécurité contre l’emballement. La véritable terminaison de la boucle reste stop_reason: end_turn. Utiliser un plafond de tours comme arrêt principal est l’anti-pattern 2.
Modes de permission
| Mode | Comportement | Usage |
|---|---|---|
default | Demander selon les règles de permission | Interactif, prudent |
acceptEdits | Auto-accepter les éditions de fichiers, demander pour le shell | Boucles d’édition de confiance |
plan | Lecture seule ; produire un plan, n’exécuter rien | Relecture avant d’agir |
bypassPermissions | Aucune invite | CI sandboxé uniquement |
Callback de permission programmatique
Contrôle fin au-delà des listes allow/deny — décidez par appel :
async def can_use_tool(tool_name, tool_input, context): if tool_name == "Bash" and "rm -rf" in tool_input.get("command", ""): return {"behavior": "deny", "message": "destructive command blocked"} if tool_name == "Edit" and tool_input.get("file_path", "").endswith(".env"): return {"behavior": "deny", "message": "secrets are read-only"} return {"behavior": "allow"}
options = ClaudeAgentOptions(can_use_tool=can_use_tool, allowed_tools=["Read", "Edit", "Bash"])const options = { allowedTools: ['Read', 'Edit', 'Bash'], canUseTool: async (toolName: string, input: Record<string, unknown>) => { if (toolName === 'Bash' && String(input.command).includes('rm -rf')) return { behavior: 'deny', message: 'destructive command blocked' }; return { behavior: 'allow' }; },};Hooks
Mêmes événements de cycle de vie que Claude Code (PreToolUse, PostToolUse, UserPromptSubmit, Stop, SessionStart, SubagentStop, PreCompact, Notification), enregistrés dans le code. Un hook PreToolUse renvoyant une décision de refus bloque l’outil — le mécanisme d’application déterministe.
async def block_destructive(input_data, tool_use_id, context): cmd = input_data.get("tool_input", {}).get("command", "") if any(bad in cmd for bad in ("rm -rf", "git push --force", "drop table")): return {"decision": "block", "reason": "destructive command"} return {}
options = ClaudeAgentOptions( hooks={"PreToolUse": [{"matcher": "Bash", "hooks": [block_destructive]}]})Subagents
Définissez des agents délégués avec un contexte isolé, leurs propres outils et modèle :
options = ClaudeAgentOptions( agents={ "security-reviewer": { "description": "Reviews diffs for injection, secrets, authz. Use after auth edits.", "prompt": "Report findings only: file:line, severity, fix. Do not edit.", "tools": ["Read", "Grep", "Glob"], "model": "claude-sonnet-5", } })Les subagents ne reçoivent que ce que le parent transmet ; ne présumez jamais d’un héritage. Utilisez un modèle moins cher pour le travail délégué mécanique.
Serveurs MCP
options = ClaudeAgentOptions( mcp_servers={ "orders": {"command": "python", "args": ["orders_server.py"]}, # stdio "linear": {"type": "http", "url": "https://mcp.linear.app/mcp"}, # remote }, allowed_tools=["mcp__orders__get_order", "mcp__linear__list_issues"])Les outils MCP sont dans l’espace de noms mcp__<server>__<tool> ; mettez-les explicitement en allowlist.
Événements de streaming
query() produit un flux de messages typés reflétant le flux SSE : un message system d’init, des messages assistant (blocs text/tool_use), des messages user (tool_result), et un message result final portant stop_reason, usage et le coût.
async for message in query(prompt="…", options=options): if message.type == "assistant": for block in message.content: if block.type == "text": print(block.text, end="") elif message.type == "result": print(message.stop_reason, message.usage, message.total_cost_usd)Branchez sur le stop_reason du message result, pas sur le parsing du texte assistant.
Patterns headless
| Pattern | Comment |
|---|---|
| Job batch en un coup | query() une fois, lire le message result, sortir en non-zéro sur échec |
| Barrière CI | permission_mode="plan" ou une allowlist serrée ; parser result pour pass/fail |
| Fan-out sur des unités | Lancez N sessions SDK (une par fichier/module), chacune dans son propre worktree, agrégez |
| Service longue durée | Persistez le stockage du memory tool ; utilisez le context editing pour borner les tokens |
| Contrôle des coûts | Modèle moins cher pour les subagents ; plafonner max_turns ; journaliser total_cost_usd |
# CI gate sketchimport sysasync def review(): async for m in query(prompt="Review the diff for security issues; output PASS or FAIL.", options=ClaudeAgentOptions(permission_mode="plan", allowed_tools=["Read", "Grep", "Bash(git diff:*)"])): if m.type == "result": sys.exit(0 if "PASS" in (m.result or "") else 1)Agent SDK vs Managed Agents vs boucle Messages API
| Boucle Messages API | Agent SDK | Managed Agents | |
|---|---|---|---|
| Vous écrivez la boucle | ✓ | Harnais fourni | Non (hébergé) |
| Outils fichiers / machinerie Claude Code | Non | ✓ | ✓ |
| Hooks / subagents / modes de permission | À construire soi-même | ✓ | Configurés |
| Contrôle runtime/réseau/données | Complet | Complet | Limité |
| Charge d’exploitation | Faible (juste l’API) | Vous hébergez le harnais | Minimale |
| Choisir quand | Boucle d’outils simple | Besoin du harnais, auto-hébergé | Moins d’ops |
Idées reçues courantes
| Idée reçue | Réalité | Pourquoi cela compte à l’examen |
|---|---|---|
| « L’Agent SDK est hébergé par Anthropic » | Vous l’hébergez ; les Managed Agents sont hébergés | Distracteur de confusion d’hébergement |
« max_turns est la façon dont la boucle s’arrête » | C’est un plafond de sécurité ; stop_reason arrête la boucle | Anti-pattern de plafond d’itérations |
« bypassPermissions convient par commodité » | CI sandboxé uniquement | Distracteur d’agence excessive |
| « Les subagents voient tout le contexte du parent » | Seulement ce qui est transmis explicitement | Distracteur de perte de contexte silencieuse |
| « Appliquer les règles dans le prompt système » | Utilisez les hooks / callbacks de permission | Anti-pattern du prompt-comme-application |
| « Charger tous les outils MCP » | Allowlistez les outils avec espace de noms ; gardez la liste petite | Anti-pattern de trop d’outils |
Analyse de scénario
Une équipe plateforme veut un agent CI auto-hébergé qui relit les PR pour des problèmes de sécurité, ne doit jamais éditer de fichiers, doit s’exécuter dans leur VPC (localité des données), et doit faire échouer le build sur un constat.
- Auto-hébergé + localité des données dans le VPC → Agent SDK, pas Managed Agents (qui est hébergé). Une boucle Messages API impliquerait de reconstruire le harnais.
- Ne doit jamais éditer →
permission_mode="plan"(lecture seule) et une allowlist d’outils sansEdit/Write. - Focus sécurité → un subagent
security-reviewersurclaude-sonnet-5(moins cher, suffisant), outilsRead,Grep,Bash(git diff:*). - Application → un refus
PreToolUsepour toute écriture, déterministe, pas une phrase de prompt. - Faire échouer le build → parser le message
result;sys.exit(1)sur un constat. - Sécurité coût/boucle → plafonner
max_turns; journalisertotal_cost_usd; toujours brancher surstop_reason.
Alternatives rejetées : Managed Agents (viole la localité des données), bypassPermissions (agence excessive), appliquer la lecture seule via le prompt système (prompt-comme-application), et utiliser un plafond de tours comme signal de complétion (anti-pattern de plafond d’itérations).
Points clés à retenir
- L’Agent SDK est auto-hébergé ; les Managed Agents sont hébergés par Anthropic ; choisissez selon le contrôle runtime/données vs la charge d’ops.
- La terminaison de boucle est
stop_reason;max_turnsn’est qu’un garde-fou contre l’emballement. - Appliquez les règles avec les hooks /
can_use_tool, jamais avec du texte de prompt. - Les subagents ne reçoivent que le contexte transmis explicitement ; donnez-leur leur propre modèle (souvent moins cher) et une allowlist d’outils serrée.
- Les outils MCP sont
mcp__server__tool; allowlistez-les et gardez l’ensemble petit. bypassPermissionsest réservé au CI sandboxé.
Dernière mise à jour le 18 sept. 2026