
« C’est fait »
J’ai demandé à un agent AI d’écrire les tests de 527 fonctions. L’agent a terminé son travail et a rendu son rapport :
« Terminé. »
En réalité, des tests avaient été écrits pour 40 fonctions.
Il n’a pas menti. Après 40 fonctions, il a simplement jugé que c’était suffisant. Face à une fonction difficile, il la saute, en traite quelques autres, puis conclut : « Le reste suit le même schéma, ça ira. »
Le LLM excelle à générer. Mais son évaluation de l’achèvement n’est pas fiable.
Le cliquet
La clé à cliquet possède des dents qui ne s’engagent que dans un sens. On tourne : ça avance. On relâche : ça s’arrête, mais ça ne recule jamais.
Le Ratchet Pattern applique ce mécanisme au contrôle d’un agent.
Élément 1 : vérification mécanique → PASS → suivant
Élément 2 : vérification mécanique → FAIL → nouvel essai (avec feedback)
Élément 2 : vérification mécanique → PASS → suivant
...
Élément N : PASS → terminé. Arrêt.
Trois règles :
- Ne montrer qu’un seul élément à la fois.
- Le suivant ne s’ouvre qu’après validation du précédent.
- Quand tout est validé, on s’arrête.
Implémentez ces règles dans un CLI, et l’agent n’a besoin de connaître qu’une seule commande : next. Le reste, c’est la machine qui décide.
L’agent s’arrête à 40, le cliquet va jusqu’à 527
Même modèle. Même projet. Mêmes 527 fonctions.
Agent autonome : 40 / 527 (7.6%) — l'agent a déclaré "terminé"
Ratchet CLI : 527 / 527 (100%) — la machine a déclaré "encore 487 à faire"
La différence ne tient pas à la performance du modèle. Elle tient à qui décide de la fin.
En mode autonome, c’est le LLM qui décide quand s’arrêter. Le LLM est optimiste. Après 40 éléments, il « sent » que c’est assez. Avec le cliquet, c’est la machine qui décide. La machine ne ressent rien. Elle déclare « pas encore » tant que le nombre d’éléments restants n’est pas zéro.
Définition en une phrase
Placer un agent probabiliste à l’intérieur d’une machine à états déterministe.
| Rôle | Responsable |
|---|---|
| Génération | LLM |
| Jugement | verifier |
| Gestion de la progression | ratchet |
Beaucoup de systèmes confient la génération, le jugement et la décision d’arrêt au LLM. Ratchet sépare ces responsabilités.
Cinq principes
1. La condition d’arrêt est mécanique
pass/fail. Pas « looks good ». go test passe : PASS. coverage à 100% : PASS. Aucune place pour le jugement subjectif.
2. Un PASS est immuable
Un élément validé ne se rouvre pas. On ne revient pas en arrière. Le nombre d’éléments restants décroît de façon monotone.
remaining_work(t+1) ≤ remaining_work(t)
Ce qui est fait aujourd’hui n’est pas défait demain. On ne va que vers l’avant. C’est la différence fondamentale avec un « agent 24 heures ». Un agent sans condition d’arrêt ajoute une abstraction aujourd’hui, la supprime demain, la rajoute après-demain. Le cliquet interdit ces oscillations.
3. Le LLM ne fait que générer
Générer du code, écrire des tests, proposer des corrections — voilà le rôle du LLM. Quoi corriger, est-ce validé, quelle est la suite, est-ce fini — tout cela, c’est la machine qui en décide. Le LLM n’est pas un planner, c’est un constrained generator.
4. On retire à l’agent le droit de décider de la fin
Quand c’est le LLM qui dit « c’est fait », on s’arrête à 40. Quand c’est la machine qui dit « c’est fait », on s’arrête à 527. La raison d’être du cliquet tient en cette seule ligne.
5. Le Verifier doit être déterministe
Tout ne peut pas servir de verifier.
| Peut l’être | Ne peut pas l’être |
|---|---|
go test | “looks cleaner” |
| mesure de coverage | “seems better” |
| AST validation | “more scalable” |
| schema diff | “clean architecture” |
Conditions d’un Verifier : deterministic, machine-checkable, resumable, localized feedback. Si l’une de ces quatre conditions n’est pas remplie, les dents du cliquet ne s’engagent pas.
Le feedback comme gradient signal
Si le cliquet ne renvoie que « pass/fail », le LLM corrige à l’aveugle. Plus le feedback est précis, plus la correction du LLM est exacte.
Feedback faible : "test échoué" → le LLM corrige sans direction
Feedback moyen : "coverage 65%" → le LLM renforce approximativement
Feedback fort : "line 41, 44, 70 non couvertes" → le LLM couvre exactement ces branches
Chiffres vérifiés sur un projet réel :
Sans feedback : 60-70% de coverage puis stagnation
Avec feedback : 100% atteint (pour les fonctions atteignables)
Même modèle. Une seule ligne — « line 41 not covered » — joue le rôle de gradient signal.
Plus la résolution du feedback augmente, plus la précision des corrections du LLM s’améliore, plus le nombre d’itérations diminue, plus le coût baisse.
L’agent meurt. La progression survit.
Un agent finit toujours par tomber. Limite de tokens, erreur réseau, coupure de session. Si le cliquet persiste l’état de progression, l’agent suivant reprend là où le précédent s’est arrêté.
Agent A : fonctions 1-200 traitées → arrêt
Agent B : next → reprise à partir de 201
Agent C : next → reprise à partir de 401
L’agent est jetable. La progression s’accumule.
Changez le Verifier, vous obtenez un autre outil
Le cliquet n’est lié à aucun vérificateur en particulier. Changez le vérificateur et vous obtenez un outil différent.
| Cliquet + vérificateur | Usage |
|---|---|
Cliquet + go test + coverage | Génération de tests par fonction |
| Cliquet + validator de règles structurelles | Refactoring de la structure du code |
| Cliquet + hurl pass/fail | Vérification d’endpoints API |
| Cliquet + vérification croisée de spécifications | Garantie de cohérence SSOT |
| Cliquet + Toulmin verdict | Application de règles personnalisées |
Le pattern est unique. Le vérificateur détermine le domaine.
Question
Combien d’éléments votre agent a-t-il traités avant de dire « c’est fait » ?
Était-ce vraiment fini ?
Qui a décidé de la fin — l’agent ou la machine ?
Article lié : La topologie du feedback compte plus que le QI du modèle — le fondement théorique du Ratchet Pattern. Pourquoi la structure du feedback importe plus que la performance du modèle.