Claude Code en mode programmable : automatiser avec le SDK Agent
#Pourquoi utiliser Claude Code par programmation ?
Tu connais Claude Code en mode interactif : tu ouvres un terminal, tu tapes ta demande, Claude répond. C'est parfait pour le développement au quotidien. Mais certains scénarios nécessitent de l'automatisation :
- Lancer une review de code à chaque pull request dans ta CI
- Générer des commit messages depuis un script
- Intégrer Claude dans une application Python ou TypeScript
- Orchestrer plusieurs agents qui travaillent en parallèle
Pour ces cas, Claude Code propose deux approches : le flag -p (CLI) et le SDK Agent (Python/TypeScript). Les deux donnent accès aux mêmes outils, à la même boucle d'agent et à la même gestion du contexte que le mode interactif.
Le mode CLI avec -p s'appelait auparavant "mode headless" (sans interface). Le nom a changé, mais le comportement est identique.
#L'approche CLI : le flag -p
Le flag -p (ou --print) transforme Claude Code en commande non-interactive. Tu passes ton prompt en argument, Claude exécute la tâche et retourne le résultat sur stdout.
#Utilisation basique
# Poser une question sur ton codebase
claude -p "Que fait le module d'authentification ?"
# Corriger un bug avec accès aux outils
claude -p "Trouve et corrige le bug dans auth.py" --allowedTools "Read,Edit,Bash"
Le flag --allowedTools indique quels outils Claude peut utiliser sans demander de permission. Sans ce flag, Claude n'aura accès qu'à la lecture et devra demander confirmation pour chaque action.
#Sortie structurée avec JSON
Par défaut, -p retourne du texte brut. Pour intégrer la réponse dans un script, utilise --output-format json :
claude -p "Résume ce projet" --output-format json
La réponse inclut le résultat textuel dans le champ result, plus des métadonnées (ID de session, utilisation de tokens, etc.).
Pour aller plus loin, tu peux forcer la réponse à respecter un schéma JSON avec --json-schema :
claude -p "Extrais les noms de fonctions de auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'
Le résultat structuré se trouve dans le champ structured_output. Combine avec jq pour extraire exactement ce dont tu as besoin :
# Extraire le texte brut
claude -p "Résume ce projet" --output-format json | jq -r '.result'
# Extraire la sortie structurée
claude -p "Extrais les fonctions de auth.py" \
--output-format json \
--json-schema '...' \
| jq '.structured_output'
#Streaming en temps réel
Pour recevoir les tokens au fur et à mesure qu'ils sont générés, utilise --output-format stream-json :
claude -p "Écris un poème" --output-format stream-json --verbose --include-partial-messages
Chaque ligne est un objet JSON représentant un événement. Pour afficher uniquement le texte en streaming :
claude -p "Écris un poème" --output-format stream-json --verbose --include-partial-messages | \
jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
#Cas d'usage concrets avec la CLI
#Créer un commit automatiquement
claude -p "Regarde mes changements staged et crée un commit avec un message approprié" \
--allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"
Le flag --allowedTools utilise la syntaxe de règles de permission. L'espace suivi de * active la correspondance de préfixe : Bash(git diff *) autorise toute commande qui commence par git diff. L'espace avant * est important — sans lui, Bash(git diff*) correspondrait aussi à git diff-index.
#Review de sécurité sur une PR
gh pr diff "$PR_NUMBER" | claude -p \
--append-system-prompt "Tu es un ingénieur sécurité. Cherche les vulnérabilités." \
--output-format json
Le flag --append-system-prompt ajoute des instructions au prompt système par défaut de Claude Code. Tu peux aussi utiliser --system-prompt pour le remplacer complètement.
#Conversations multi-tours
Utilise --continue pour reprendre la conversation la plus récente, ou --resume avec un ID de session spécifique :
# Première requête
claude -p "Analyse ce codebase pour les problèmes de performance"
# Continuer la même conversation
claude -p "Concentre-toi maintenant sur les requêtes base de données" --continue
claude -p "Génère un résumé de tous les problèmes trouvés" --continue
Pour gérer plusieurs conversations en parallèle, capture l'ID de session :
session_id=$(claude -p "Démarre une review" --output-format json | jq -r '.session_id')
claude -p "Continue cette review" --resume "$session_id"
#Le SDK Agent : Python et TypeScript
Le flag -p couvre les besoins de scripting et de CI/CD. Mais pour une intégration poussée dans une application, le SDK Agent offre un contrôle programmatique complet avec des objets natifs, des callbacks et du streaming.
#Installation
# TypeScript
npm install @anthropic-ai/claude-agent-sdk
# Python (pip)
pip install claude-agent-sdk
# Python (uv)
uv add claude-agent-sdk
Configure ensuite ta clé API :
export ANTHROPIC_API_KEY=ta-cle-api
Le SDK supporte aussi Amazon Bedrock, Google Vertex AI et Microsoft Azure comme fournisseurs d'API.
#Premier agent
Voici un agent minimal qui trouve et corrige des bugs :
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Review utils.py pour les bugs. Corrige ce que tu trouves.",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Edit", "Glob"],
permission_mode="acceptEdits"
)
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Review utils.py pour les bugs. Corrige ce que tu trouves.",
options: {
allowedTools: ["Read", "Edit", "Glob"],
permissionMode: "acceptEdits"
}
})) {
if ("result" in message) console.log(message.result);
}
L'agent fait exactement ce que ferait Claude Code en mode interactif : il lit le fichier, identifie les problèmes, et applique les corrections. La différence, c'est que tout se passe sans intervention humaine.
#Outils disponibles
Le SDK donne accès aux mêmes outils que Claude Code :
| Outil | Ce qu'il fait | Cas d'usage |
|---|---|---|
| Read | Lire un fichier | Analyse de code |
| Write | Créer un fichier | Génération de code |
| Edit | Modifier un fichier existant | Correction de bugs |
| Bash | Exécuter une commande terminal | Tests, git, scripts |
| Glob | Chercher des fichiers par pattern | Navigation dans le codebase |
| Grep | Chercher dans le contenu des fichiers | Recherche de code |
| WebSearch | Rechercher sur le web | Documentation, actualités |
| WebFetch | Récupérer le contenu d'une page web | Scraping, API |
#Modes de permission
Le SDK propose trois modes pour contrôler le niveau d'autonomie de l'agent :
| Mode | Comportement | Quand l'utiliser |
|---|---|---|
| acceptEdits | Approuve les modifications de fichiers automatiquement | Développement de confiance |
| bypassPermissions | Exécute tout sans demander | Pipelines CI/CD |
| default | Utilise un callback canUseTool pour chaque action | Flux d'approbation personnalisé |
#Sessions multi-tours
Comme avec la CLI, tu peux maintenir le contexte entre plusieurs requêtes :
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
session_id = None
# Première requête : capturer l'ID de session
async for message in query(
prompt="Lis le module d'authentification",
options=ClaudeAgentOptions(allowed_tools=["Read", "Glob"])
):
if hasattr(message, 'subtype') and message.subtype == 'init':
session_id = message.session_id
# Reprendre avec le contexte complet
async for message in query(
prompt="Trouve tous les endroits qui l'appellent",
options=ClaudeAgentOptions(resume=session_id)
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
#Sous-agents spécialisés
Tu peux définir des agents avec des rôles précis que l'agent principal délègue :
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
async for message in query(
prompt="Utilise l'agent code-reviewer pour analyser ce codebase",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep", "Task"],
agents={
"code-reviewer": AgentDefinition(
description="Expert en review de code.",
prompt="Analyse la qualité du code et suggère des améliorations.",
tools=["Read", "Glob", "Grep"]
)
}
)
):
if hasattr(message, "result"):
print(message.result)
L'agent principal orchestre, les sous-agents exécutent. C'est le même pattern que les subagents dans Claude Code interactif, mais piloté par du code.
#CLI vs SDK : lequel choisir ?
| Critère | CLI (flag -p) | SDK Agent |
|---|---|---|
| Installation | Déjà installé avec Claude Code | Package à installer séparément |
| Langages | Bash / tout langage via shell | Python et TypeScript natifs |
| Complexité | Une ligne de commande | Code async avec boucle de messages |
| Sortie structurée | JSON via --output-format | Objets natifs typés |
| Callbacks | Non | Oui (hooks, permissions, approbation) |
| Sous-agents | Non | Oui (AgentDefinition) |
| Cas d'usage idéal | Scripts, CI/CD, tâches ponctuelles | Applications, orchestration complexe |
En pratique, beaucoup d'équipes utilisent les deux : la CLI pour les scripts rapides et la CI/CD, le SDK pour les applications en production.
#Récapitulatif
Claude Code n'est pas qu'un outil de terminal interactif. Avec le flag -p, tu peux l'intégrer dans n'importe quel script ou pipeline en une ligne. Avec le SDK Agent, tu construis des applications complètes qui orchestrent des agents autonomes.
Les points clés à retenir :
claude -p: mode non-interactif, parfait pour les scripts et la CI/CD--output-format json: sortie structurée pour l'intégration dans des pipelines--allowedTools: contrôle granulaire des permissions par outil- SDK Agent : même puissance que Claude Code, programmable en Python et TypeScript
- Sessions : maintiens le contexte entre plusieurs requêtes pour des workflows complexes
Pour explorer les exemples complets, consulte le dépôt de démos et la documentation officielle du SDK Agent.