Retour au blog

Claude Code en mode programmable : automatiser avec le SDK Agent

$date: |read: 8 min|cat: SDK & API
claude-codetutoriel
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 :

OutilCe qu'il faitCas d'usage
ReadLire un fichierAnalyse de code
WriteCréer un fichierGénération de code
EditModifier un fichier existantCorrection de bugs
BashExécuter une commande terminalTests, git, scripts
GlobChercher des fichiers par patternNavigation dans le codebase
GrepChercher dans le contenu des fichiersRecherche de code
WebSearchRechercher sur le webDocumentation, actualités
WebFetchRécupérer le contenu d'une page webScraping, API

#Modes de permission

Le SDK propose trois modes pour contrôler le niveau d'autonomie de l'agent :

ModeComportementQuand l'utiliser
acceptEditsApprouve les modifications de fichiers automatiquementDéveloppement de confiance
bypassPermissionsExécute tout sans demanderPipelines CI/CD
defaultUtilise un callback canUseTool pour chaque actionFlux 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èreCLI (flag -p)SDK Agent
InstallationDéjà installé avec Claude CodePackage à installer séparément
LangagesBash / tout langage via shellPython et TypeScript natifs
ComplexitéUne ligne de commandeCode async avec boucle de messages
Sortie structuréeJSON via --output-formatObjets natifs typés
CallbacksNonOui (hooks, permissions, approbation)
Sous-agentsNonOui (AgentDefinition)
Cas d'usage idéalScripts, CI/CD, tâches ponctuellesApplications, 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.