Hooks et skills : remettre du déterminisme dans un agent qui part en vrille
Pourquoi une consigne dans le prompt ne suffit pas, et comment bloquer mécaniquement les actions dangereuses d'un agent IA avec des hooks.
Tu as écrit dans ton prompt : « Ne supprime jamais de fichiers sans demander. » Trois heures plus tard, l’agent a supprimé un dossier.
Il n’a pas désobéi. Il a simplement traité ta phrase pour ce qu’elle est techniquement : un morceau de texte parmi des dizaines de milliers d’autres dans son contexte, sans statut particulier. Une consigne n’est pas une contrainte. Et cette distinction est la ligne qui sépare un agent utilisable d’un agent qu’on ne peut pas laisser tourner seul.
TL;DR
- Une instruction dans le prompt est une intention. Un hook est une garantie. Sur les règles critiques, seule la garantie compte.
- Trois hooks couvrent l’essentiel des incidents : blocage des actions destructrices, lecture obligatoire avant écriture, détection de boucle.
- Le hook ne dit pas seulement « non » : il renvoie à l’agent un message d’erreur exploitable, qui lui indique quoi faire à la place.
- Un hook mal calibré est pire que pas de hook : trop strict, il provoque exactement la boucle infinie qu’il devait empêcher.
Pourquoi une consigne dans le prompt ne tient pas
Trois mécanismes, indépendants les uns des autres, font qu’une règle écrite dans le prompt finit par être ignorée.
La dilution. Plus le contexte s’allonge, plus le poids relatif de chaque instruction diminue. Une règle écrite au tour 1 concurrence, au tour 40, des milliers de tokens de code, de sorties de commandes et de messages d’erreur. Sur un petit modèle, cette dégradation est particulièrement rapide ; sur un modèle frontière elle est plus lente, mais elle existe.
Le conflit d’instructions. « Ne supprime rien » et « répare le build cassé » peuvent entrer en contradiction quand le build est cassé par un dossier corrompu. Le modèle arbitre, et il ne t’a pas demandé ton avis.
L’interprétation. « Ne supprime jamais de fichiers » couvre-t-il un git checkout qui écrase des modifications locales ? Un npm install qui réécrit un fichier de verrouillage ? Le modèle tranche selon sa lecture, pas selon ton intention.
La conclusion est structurelle : tout ce qui doit être vrai à 100 % doit sortir du prompt et passer dans le code qui exécute les actions.
Qu’est-ce qu’un hook, concrètement ?
Un hook est un point de contrôle placé entre la décision de l’agent et son exécution. L’agent demande une action ; le hook l’inspecte ; il l’autorise, la refuse, ou la modifie.
La séquence :
- L’agent demande à exécuter une action (commande shell, écriture de fichier, appel d’outil).
- Le hook reçoit cette demande avant exécution.
- Il applique une règle déterministe, du code, pas un modèle.
- Il laisse passer, ou il refuse avec un message d’erreur destiné à l’agent.
Ce quatrième point est le plus important, et le plus souvent bâclé. Un hook qui refuse en silence produit un agent perdu. Un hook qui répond « suppression récursive interdite ; pour retirer un fichier, utilise la corbeille du projet » produit un agent qui corrige sa trajectoire tout seul.
Le hook est un contrat d’interface entre l’agent et l’environnement. Il ne rend pas l’agent plus intelligent : il rend son environnement plus sûr, ce qui n’est pas la même chose, et c’est bien plus fiable.
Les trois hooks qui règlent 80 % des incidents
Hook 1 : Blocage des actions destructrices
Ce qu’il fait : il refuse toute commande capable de détruire du travail non récupérable, suppression récursive, réinitialisation forcée d’un dépôt, écrasement d’un fichier de configuration sensible.
Pourquoi il est indispensable : c’est le seul type d’erreur qui n’est pas rattrapable. Un mauvais code se corrige. Un dossier supprimé, non.
Le piège : raisonner par liste noire. Interdire rm -rf est facile à contourner sans intention de nuire, une variable, un chemin relatif, un script intermédiaire, et la commande passe. La bonne approche est l’inverse : une liste blanche de ce qui est autorisé, en refusant tout le reste. C’est le principe classique de validation aux frontières, celui-là même que l’OWASP recommande pour toute entrée non fiable, et la sortie d’un modèle est, par définition, une entrée non fiable.
Le message de refus doit indiquer l’alternative, sans quoi l’agent va simplement reformuler la même commande jusqu’à trouver une variante qui passe.
Hook 2 : Lecture obligatoire avant écriture
Ce qu’il fait : il refuse toute modification d’un fichier qui n’a pas été lu dans le tour courant.
Pourquoi : un agent modifie souvent un fichier à partir de ce qu’il croit être son contenu, généralement ce qu’il a écrit lui-même plus tôt. Entre-temps, un autre processus, un formateur automatique ou un humain a pu le changer. La modification est alors appliquée sur une version qui n’existe plus, et le travail existant est écrasé silencieusement.
Le piège, et il est réel : ce hook est le plus susceptible de créer une boucle. Si l’agent ne comprend pas pourquoi il est bloqué, il retente la même écriture indéfiniment. Deux conditions pour l’éviter :
- Le message d’erreur nomme explicitement l’action attendue : « fichier non lu dans ce tour, lis-le avant de le modifier ».
- Une lecture partielle doit suffire à débloquer l’écriture de la portion concernée, sinon un gros fichier devient impossible à modifier.
Hook 3 : Détection de boucle
Ce qu’il fait : il compte les actions identiques consécutives et interrompt au-delà d’un seuil.
Pourquoi : un agent qui rencontre une erreur qu’il ne comprend pas répète. Sans information nouvelle dans son contexte, il n’a aucune raison de produire une réponse différente : c’est une propriété du mécanisme, pas un bug.
Ce qui doit se passer à l’interruption, et c’est la partie utile : ne pas se contenter de stopper, mais injecter de l’information nouvelle. Forcer une recherche documentaire sur le message d’erreur, ou remonter le problème à un humain. Une interruption sèche laisse l’agent dans le même état ; une interruption avec information nouvelle lui donne une chance de sortir de l’impasse.
Hooks et skills : deux outils, deux rôles
La confusion est fréquente, alors qu’ils répondent à des besoins opposés.
| Skill | Hook | |
|---|---|---|
| Nature | Information | Contrainte |
| Moment | Avant l’action, pour informer | Pendant l’action, pour autoriser |
| Fiabilité | Probabiliste (le modèle peut ne pas l’appliquer | Déterministe) le code s’exécute toujours |
| Bon usage | « Voici comment on structure un composant ici » | « Cette commande est interdite » |
| Mauvais usage | « Ne supprime jamais rien » | Encoder une préférence de style |
Une skill transmet une méthode, un contexte, une convention, les mécanismes de chargement à la demande sont décrits dans la documentation Anthropic sur les Agent Skills. Elle est puissante pour élever la qualité du travail, et inadaptée pour garantir une règle de sécurité.
La règle de partage : si l’infraction à la règle est rattrapable, c’est une skill. Si elle ne l’est pas, c’est un hook.
Cette séparation entre ce qui informe et ce qui contraint est exactement la même que celle qui structure une organisation d’agents pilotée par des boucles ITIL : la procédure guide, le contrôle bloque.
Le hook qui manque presque partout : la validation d’installation
Un agent qui décide d’installer une dépendance ne vérifie pas qu’elle existe vraiment. Il propose un nom plausible, et un nom plausible peut être un nom inventé, comme le montre l’affaire des packages NPM hallucinés adoptés par des centaines de dépôts.
Le hook correspondant est simple à écrire et résout définitivement le problème : avant toute installation, interroger le registre officiel. Le package existe-t-il ? Depuis quand ? Combien de téléchargements ? En dessous d’un seuil, on refuse et on remonte à l’humain.
C’est cinq lignes de code, et c’est la différence entre un agent qui peut installer des dépendances et un agent auquel on ne peut pas laisser cette permission.
Comment calibrer sans se bloquer
Un hook trop strict rend l’agent inutilisable ; trop laxiste, il ne sert à rien. La méthode qui fonctionne :
- Commence par observer sans bloquer. Journalise ce que le hook aurait refusé, pendant plusieurs sessions réelles. Tu découvriras des faux positifs auxquels tu n’aurais pas pensé.
- Active le blocage sur la règle la plus critique uniquement. Une seule à la fois.
- Mesure les boucles. Si un hook déclenche des répétitions, le problème est presque toujours son message d’erreur, pas sa règle.
- Traite les faux positifs par des exceptions nommées, pas en assouplissant la règle générale.
Checklist : équiper un agent de garde-fous
- Toute règle dont l’infraction est irréversible est implémentée en hook, pas en prompt.
- Le blocage des actions destructrices fonctionne par liste blanche, pas par liste noire.
- Chaque refus renvoie un message qui indique l’action alternative attendue.
- Un hook impose la lecture d’un fichier avant sa modification.
- Une lecture partielle suffit à débloquer la modification correspondante.
- Un compteur détecte les actions identiques répétées.
- L’interruption de boucle injecte une information nouvelle, elle ne se contente pas de stopper.
- Toute installation de dépendance est validée contre le registre officiel.
- Chaque hook a d’abord tourné en mode observation avant d’être activé.
FAQ
Les hooks ralentissent-ils l’agent ?
Marginalement en temps d’exécution, un contrôle de ce type se compte en millisecondes. En revanche, ils ralentissent bel et bien un agent mal calibré, en le forçant à relire des fichiers ou à reformuler des commandes. Ce ralentissement-là est un bon signal : il indique un message d’erreur peu clair ou une règle trop large, pas un problème de performance.
Faut-il des hooks avec un modèle frontière, ou seulement avec un petit modèle ?
Dans les deux cas, mais pour des raisons différentes. Un petit modèle a besoin de hooks pour ne pas dériver au quotidien. Un modèle frontière suit beaucoup mieux les consignes, mais il agit sur des périmètres plus larges et de façon plus autonome, l’incident est plus rare et son ampleur plus grande. La règle ne change pas : ce qui doit être vrai à 100 % ne se demande pas, il s’impose.
Comment gérer un hook qui bloque une action légitime ?
Par une exception nommée et documentée, jamais en désactivant la règle. Concrètement : une liste explicite de chemins ou de commandes autorisés, versionnée avec le projet et relue comme du code. Un hook qu’on désactive « juste pour cette fois » ne se réactive jamais, et c’est précisément la session où il aurait servi.
Peut-on remplacer les hooks par une simple demande de confirmation à l’humain ?
C’est complémentaire, pas équivalent. La confirmation humaine est adaptée aux actions rares et à fort impact : un déploiement, une suppression volontaire. Elle ne tient pas sur les actions fréquentes, un humain sollicité cent fois par heure valide sans lire, ce qui revient à ne rien contrôler. Les hooks traitent le flux courant, la confirmation traite l’exception.
Conclusion
La fiabilité d’un agent ne vient pas de la qualité de son prompt : elle vient de ce que son environnement l’autorise à faire.
Un prompt bien écrit améliore la qualité moyenne du travail. Il ne borne pas le pire cas. C’est le rôle des hooks, et cette borne conditionne tout le reste, parce que c’est elle qui détermine le degré d’autonomie qu’on peut raisonnablement accorder.
Commence par un seul hook : celui qui bloque ce que tu ne pourras pas récupérer. Fais-le tourner en observation une semaine. Tu sauras alors exactement quels autres écrire.
Cette approche est mise en œuvre en direct dans le live sur le développement avec un modèle local, où les hooks sont construits au fur et à mesure des blocages rencontrés.
À lire aussi
Architecture modulaire en silos : les contrats d'interface entre modules
Pourquoi l'IA casse ton code à mesure qu'il grossit, et comment des modules en silos avec contrats explicites règlent le problème à la racine.
RAG en entreprise : pourquoi ça casse dès qu'on dépasse trois documents
Le RAG global qui répond à tout est un mythe. Comment découper par silo métier, et dans quels cas il ne faut tout simplement pas faire de RAG.
Structurer ses agents IA avec ITIL : construire une Dream Team qui tient la route
Découvre comment appliquer les boucles ITIL (Incident, Problem, Change) pour orchestrer des agents IA fiables, autonomes et pilotables.