Hooks (pre/post tool use)
Intercepter les actions de l'agent avec du code déterministe. PreToolUse, PostToolUse, et l'articulation hooks vs CLAUDE.md.
Les hooks : intercepter les actions de l’agent
Claude Code permet de déclarer des hooks — des scripts qui s’exécutent automatiquement à des moments précis du cycle agentique. Le principe : au lieu de compter sur l’agent pour se discipliner (lancer les tests, vérifier le linting), on câble ces vérifications dans l’infrastructure.
Point clé : Un hook n’est pas un prompt. C’est du code déterministe qui s’exécute côté runtime, hors du contrôle du LLM. L’agent ne peut pas décider de l’ignorer.
Les cinq types de hooks
| Type | Déclencheur | Cas d’usage typique |
|---|---|---|
PreToolUse | Avant chaque appel d’outil | Bloquer un rm -rf, valider un path |
PostToolUse | Après chaque appel d’outil | Lancer les tests après une édition, audit log |
SessionStart | Au démarrage d’une session | Charger un dump de contexte, afficher un rappel |
UserPromptSubmit | À chaque message utilisateur | Enrichir le prompt, injecter des métadonnées |
Stop | Quand l’agent termine sa réponse | Résumé de session, nettoyage temporaire |
Déclaration et mécanique
Les hooks sont déclarés dans .claude/settings.json (au niveau projet) ou ~/.claude/settings.json (global). Chaque hook est un objet qui spécifie le type d’événement, un matcher optionnel (filtrer par outil), et la commande à exécuter.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "dotnet test --no-build -q"
}
],
"PreToolUse": [
{
"matcher": "Bash",
"command": "python3 .claude/validate-command.py"
}
]
}
}
Flux d’exécution
Le hook reçoit le payload de l’outil (nom, paramètres) sur stdin en JSON. Il peut :
- Laisser passer (exit code 0, pas de sortie spéciale) — l’action continue normalement.
- Bloquer (exit code non-zéro pour PreToolUse) — l’appel d’outil est annulé et l’agent reçoit le message d’erreur.
- Modifier (écrire un JSON modifié sur stdout) — le payload est transformé avant exécution.
Point clé : Un
PreToolUsequi échoue empêche l’action. UnPostToolUsequi échoue signale un problème mais l’action a déjà eu lieu. Cette asymétrie est fondamentale.
Hooks vs instructions dans CLAUDE.md
Écrire dans CLAUDE.md « lance les tests après chaque modification » est une suggestion au LLM. Il peut l’oublier, surtout en fin de session longue (context rot). Un hook PostToolUse est une garantie : le script s’exécute quoi qu’il arrive.
Piège courant : Doubler un hook par une instruction CLAUDE.md identique. Résultat : les tests tournent deux fois (une fois par le hook, une fois par l’agent qui obéit à l’instruction). Choisir l’un ou l’autre, pas les deux.
Quand utiliser quoi
| Besoin | Hook | CLAUDE.md |
|---|---|---|
| Lancer les tests après édition | PostToolUse (fiable) | Redondant, risque de doublon |
| Bloquer des commandes dangereuses | PreToolUse (le seul choix sûr) | Non fiable |
| Conventions de nommage | Pas adapté | Instruction naturelle |
| Workflow multi-étapes | Pas adapté | Slash command + instructions |
Règle simple : Tout ce qui doit être garanti passe par un hook. Tout ce qui est un guidage qualitatif reste dans CLAUDE.md.