Conception + Révision de boucle
Prémisse. Un LLM est un système feed-forward : prompt en entrée → jetons en sortie, sans capacité intrinsèque à « orienter vers l'objectif » au fil des tours. Pour le faire se comporter comme un système orienté objectif, on l'entoure d'une boucle de rétroaction. Cette compétence vous aide à écrire cette boucle correctement et à la réviser pour qu'elle ne dérape pas.
Quand l'utiliser / ne pas l'utiliser
À utiliser quand :
- Vous souhaitez confier une tâche répétitive à un agent qui l'exécute en boucle (écrire→tester, tester→corriger, corriger→vérifier…).
- Vous avez déjà une boucle et craignez qu'elle tourne en rond, triche, ou exécute une réponse erronée jusqu'au bout.
Ne pas l'utiliser pour :
- Une tâche unique → faites-la simplement, pas besoin de boucle.
- Un simple minuteur / sondage → utilisez
/loop; pas de conception nécessaire. - Comment câbler l'architecture de la boucle (pipelines → DAGs, reprise après incident) → c'est la couche mécanisme ; voir
autonomous-loops/continuous-agent-loop. Cette compétence couvre uniquement « l'objectif est-il bon, et la boucle dérapera-t-elle » — elle ne réexplique pas le mécanisme.
Prémisse fondamentale : deux niveaux de rétroaction
| Niveau | Qui le possède | Ce qu'il fait |
|---|---|---|
| Exécution (bas) | machine / agent | Mesure « à quel point on est loin de l'objectif concret » et le réduit à zéro. La machine est forte ici. |
| Jugement (haut) | humain | Décide « cet objectif lui-même est-il bon, doit-il changer, doit-on s'arrêter ». La machine ne peut pas sortir de sa propre boucle pour remettre l'objectif en question. |
Un thermostat peut renvoyer « à quel point on est loin de 26 °C », mais quand vous avez de la fièvre et voulez 28 °C, il ne peut pas juger si 26 est la bonne cible — il se contente de tendre vers 26. « Quelle valeur choisir aujourd'hui » est toujours la décision humaine. Confier le jugement / la validation / le dernier interrupteur à la machine = supprimer la rétroaction de haut niveau = elle sprinte, vite et fort, vers un objectif que personne n'a remis en question → résultat erroné.
Action 1 — Écrire une boucle (5 étapes)
Étape 0 · D'abord, soustrayez : devriez-vous même la construire ? (4 conditions, un seul échec = veto)
① la tâche se répète au moins une fois par semaine ② la vérification peut être automatisée ③ le budget en jetons peut la supporter ④ l'agent dispose d'outils qui s'exécutent réellement et voient le résultat.
Un seul échec → ne construisez pas de boucle ; faites-le manuellement ou autrement.
Ce qui arrête la plupart des gens n'est pas « puis-je écrire une boucle », c'est « mon dépôt mérite-t-il une boucle ». Un dépôt qui mérite une boucle a une base de réconciliation (échantillon de référence / total amont) + des tests + un outil de vérification automatique. Un dépôt qui ne mérite pas une boucle ne fera qu'amplifier ses erreurs avec une.
Étape 1 · Définir un objectif décidable par une machine (la partie difficile — la boucle vit ou meurt ici)
Toute la boucle repose sur la capacité du comparateur à répondre à « est-ce fini ? ». Le comparateur ne peut fonctionner que si votre condition de sortie peut être jugée oui/non par une machine.
- Mauvais : vague (« améliore-le », « rédige-le mieux ») → le comparateur ne peut pas juger → soit il ne termine jamais (bloqué à réessayer), soit il devine (passe/bloque au hasard).
- Bon : décidable (« les 96 tests unitaires sont verts ET une liste de modifications est produite », « les champs du module-02 sont remplis, pytest réussit, la logique métier est inchangée ») → une seule vérification ; la boucle converge proprement.
Cadre en cinq points pour l'objectif :
- Le critère de fin est vérifiable par une machine.
- Les conditions limites sont définies en même temps que le critère de fin (« ce qu'il NE DOIT PAS faire ») — anti-Goodhart ; des limites manquantes = une licence pour tricher.
- Possède une solution de repli en cas d'échec — limite de tentatives N + escalation vers un humain quand dépassée.
- L'objectif est structuré en couches.
- Préférer la réconciliation à la simple assertion pour le critère de fin — ancrer à un fait externe (échantillon de référence / total amont / rapprochement financier / chiffres du back-office) avant vos propres assertions. « Tous les tests passent » peut être manipulé (assouplir les assertions, simuler des mocks, avaler les exceptions) ; « différence par rapport à la référence < 0,01 » ne peut pas.
Auto-vérification : lisez l'objectif à quelqu'un qui ne connaît pas le domaine — peut-il exécuter une commande et dire si c'est terminé ? Si non, ce n'est pas assez décidable. Recommencez.
Étape 2 · Choisir le type de boucle
| Votre tâche | Type de boucle (cybernétique) | Comment elle s'arrête |
|---|---|---|
| A un test de « fini » clair (écrire jusqu'à fini / un lot d'images traitées) | servo (boucle fermée de type /goal) | s'arrête en atteignant l'objectif |
| Pas de point final, doit maintenir un état (alerte de stock / vérification de santé planifiée) | régulateur (thermostat de type /loop) | ne s'arrête jamais ; agit uniquement lors d'un changement (zone morte élimine le bruit) |
| Échantillonnage périodique, arrêt sur condition (surveiller une PR jusqu'à ce que la CI soit verte) | régulateur avec sortie | s'arrête quand la condition de sortie est satisfaite |
| Doit « garantir que quelque chose arrive à l'heure » | envelopper le tout dans /schedule | déclenché par cron |
Règle empirique : test de « fini » clair → servo ; doit maintenir, pas de point final → régulateur ; doit « arriver à l'heure » → envelopper un régulateur dans une planification.
Étape 3 · Choisir un squelette
Type maintenance (entretenir quelque chose qui existe) → répartition par document. La boucle n'est pas « exécuter une vérification fixe sur un minuteur », c'est « lire un document sur un minuteur, et ne déclencher que lorsque le document a changé ». Le document est la file de tâches + la machine d'état + l'interface humaine. Trois disciplines : ① la colonne problème est en écriture humaine uniquement, la colonne résultat est en écriture boucle uniquement, l'état avance dans un sens et ne recule jamais ; ② le code de sortie est définitif (si le script dit exit 1, le script gagne) ; ③ l'état n'avance que jusqu'à « en attente de vérification » — la cellule « terminé » est basculée par un humain uniquement. La boucle est l'ouvrière, pas l'officier d'acceptation.
Type greenfield (construire à partir de zéro) → planifier / construire / juger, trois rôles.
| Rôle | Fait | Clé |
|---|---|---|
| Planifier | décomposer l'objectif en un cahier des charges + conditions d'acceptation décidables | l'acceptation doit pouvoir être jugée par script |
| Construire | écrire selon le cahier des charges | ne doit pas modifier les conditions d'acceptation |
| Juger | exécuter l'acceptation de manière indépendante ; réussite → arrêt, échec → renvoyer la raison de l'échec à Construire | indépendant + déterministe |
Trois règles d'airain (miser sur le juge) : ① le juge doit être indépendant — pas le même agent que Construire (corriger ses propres devoirs les gonfle toujours) ; ② règles déterministes — pytest / diff de réconciliation / vérification de type / diff, jamais « a l'air correct » ; ③ Construire ne peut pas modifier les conditions d'acceptation pour réussir. Trois tentatives échouées → escalade vers un humain.
Étape 4 · Ajouter de l'amortissement (contre l'oscillation / l'emballement)
Limite de tentatives, arrêt dur, l'humain bascule le dernier interrupteur = amortissement. Un retour négatif sans amortissement oscille (la boucle de Ralph-Wiggum : tourner sur place, brûler des jetons).
Étape 5 · Déployer en trois étapes (ne passez pas en automatique complet le premier jour)
① Exécutez-la une fois manuellement (vous oblige à préciser exactement « comment le juge décide ») → ② consolidez en une compétence / sous-agents Claude Code (un Claude principal boucle, dispatche planification/construction/jugement) → ③ accrochez-la à cron pour l'automatisation complète.
Action 2 — Réviser une boucle (liste de contrôle = cinq modes de défaillance)
Faites passer la boucle en revue ligne par ligne. Un seul hit = cette boucle va mal fonctionner ; renvoyez-la. Ces cinq sont de l'expérience négative (pièges) — valent plus que des règles positives.
| # | Mode de défaillance (comment ça casse) | Question de révision (un hit = rouge) | Anticorps |
|---|---|---|---|
| 1 | L'objectif est une généralité correcte → tourne en rond, brûle de l'argent | La condition de sortie peut-elle être jugée oui/non par une machine ? Ou est-ce « gérez-le bien / améliorez-le » ? | Remplacer par une condition de résultat décidable (Action 1·Étape 1) |
| 2 | La « vérification » est écrite comme « vérifier si ça a l'air correct » → l'agent dit avec confiance que c'est bon et s'arrête | Le juge est-il l'accusé lui-même ? La vérification repose-t-elle sur « l'air correct » ou sur des règles déterministes ? | Réconciliation + règles de code de sortie + juge indépendant |
| 3 | (pire) Seule condition de garde : « tous les tests passent » → l'agent supprime les tests | Y a-t-il une limite (« ce qu'il NE DOIT PAS faire ») ? Ou seulement un critère de fin ? | Critère de fin + limite ensemble (l'anticorps de Goodhart) |
| 4 | Compte sur l'agent pour demander en cours de route → il ne le fera pas ; il exécute la mauvaise réponse jusqu'au bout | Y a-t-il un point du type « clarifier uniquement à l'exécution » ? | Précharger toute clarification ; la régler une fois avant le lancement |
| 5 | CLAUDE.md gonflé + mémoire obsolète → plus la boucle tourne vite, plus elle fait d'erreurs | Les docs/mémoires dont elle dépend sont-ils à jour ? Qui les maintient ? | Mémoire en couches + vérification automatique périodique |
Plus trois lignes rouges (en violer une = interdit d'être automatique) :
- Garder le jugement avec l'humain. L'acceptation / la cellule « terminé » est basculée par un humain ; la boucle n'est pas l'officier d'acceptation.
- La responsabilité ne se transfère pas. Tout ce dont l'échec est inacceptable (fusionner la mauvaise PR / publier la mauvaise chose / allouer l'argent de travers) → ne pas déléguer l'autorité automatiquement.
- Avertissement contre-intuitif. Plus une boucle est « auto-améliorante / qui réécrit ses propres règles », plus elle nécessite une révision humaine stricte (pour voir en quoi elle a réécrit les règles) — pas moins. La machine est trop rapide pour être interceptée après coup, donc le jugement humain doit se situer avant l'action (une porte verrouillée), pas comme un correctif a posteriori.
Exemple concret — révision d'une boucle de « maintenance nocturne des tests verts »
Vous voulez une boucle qui s'exécute chaque nuit et corrige les tests qui échouent.
- Objectif naïf : « faire passer tous les tests. » → L'auto-vérification de l'étape 1 échoue : c'est l'appât du mode de défaillance #3.
- Objectif décidable (corrigé) : « tous les tests sont verts ET aucun fichier de test n'est supprimé ou affaibli ET la couverture n'a pas baissé ET une liste de modifications est produite. » Limite désormais définie en même temps que le critère de fin.
- Type : servo avec une limite de 3 tentatives (Étape 2 + Étape 4).
- Squelette : planification/construction/jugement — le juge est la CI exécutée indépendamment, jamais l'agent correcteur (Étape 3).
Appliquez maintenant la liste de contrôle de révision, et elle détecte ce que la version naïve aurait manqué :
- Hit #3 → le « tous les tests passent » naïf permet à l'agent de supprimer un test qui échoue pour « gagner. » Corrigé par la limite « aucun fichier de test supprimé/affaibli. »
- Hit #2 → si l'agent correcteur jugeait aussi sa propre correction, il se validerait lui-même. Corrigé par « juge = CI indépendante, déterministe. »
- Hit #4 → si une correction est ambiguë, l'agent ne s'arrêtera pas pour demander à 2 h du matin ; il soumettra une supposition. Corrigé par le préchargement : les corrections ambiguës sont laissées à l'humain, pas devinées.
- Ligne rouge → la boucle ouvre une PR mais ne la fusionne pas automatiquement ; l'humain bascule le dernier interrupteur (la responsabilité ne se transfère pas).
La boucle naïve et la boucle révisée diffèrent par quatre lignes de contrainte — et c'est la différence entre « vous réveiller avec une suite de tests supprimée » et « vous réveiller avec une PR propre. »
Conclusion en une phrase
La partie difficile de l'écriture d'une boucle n'est pas « puis-je écrire une boucle », c'est définir un objectif qu'une machine peut réconcilier — décidable, borné, basé sur la réconciliation. Le contrôleur doit être déterministe et externe ; gardez le jugement et la norme avec l'humain ; le système tend vers l'entropie, donc entretenez-le. Une boucle ne récompense que celui qui a déjà réfléchi à l'avance. Comptez sur elle pour penser pour vous, et elle pensera volontiers de travers, avec vous, à grande échelle.
Parenté : la rétroaction à deux niveaux de Wiener (The Human Use of Human Beings, 1950) pour la séparation jugement/exécution et les lignes rouges ; le modèle planification/construction/jugement d'Anatoli (Loops explained) et d'Addy (Loop Engineering). Couche mécanisme (comment câbler l'architecture de la boucle) : voir
autonomous-loops/continuous-agent-loop. Cette compétence ne réimplémente pas le mécanisme ; elle couvre uniquement la définition de l'objectif et la prévention de l'emballement.