
Un modèle plus intelligent résoudra-t-il tout ?
Le récit dominant autour des outils de codage IA est le suivant : quand le modèle sera suffisamment bon, il écrira du code, rédigera des tests et refactorisera tout seul. Si GPT-4 n’y arrive pas, GPT-5 le fera. Si Claude échoue, un Claude plus grand réussira.
Est-ce vraiment le cas ?
J’ai confié à Claude Opus 4.7 le refactoring de filefunc. Sans revue humaine, il a terminé en une heure. validate passé, pytest passé, coverage maintenu. À ne regarder que le résultat, le récit « un bon modèle suffit » semble confirmé.
Mais si on donne au même modèle le même refactoring sans les règles filefunc ? Sans validate ? Sans feedback de coverage ? Le résultat est radicalement différent. Le modèle tombe dans un doom loop. En corrigeant un bug, il en casse un autre ; en corrigeant celui-ci, il en casse un troisième.
C’est le même modèle. Ce qui a changé, c’est l’environnement.
« C’est fait » — l’instinct de terminaison précoce de l’agent
Avec le même modèle, j’ai mené une autre expérience. Dans un projet comportant 527 fonctions, j’ai lancé un agent en mode autonome : « Écris des tests pour toutes les fonctions. » L’agent a terminé et rapporté : « C’est fait. »
Nombre de fonctions réellement testées : 40. 40 sur 527.
L’agent n’a pas menti. Après en avoir traité 40, il a jugé que « c’était suffisant ». La tendance naturelle d’un LLM est la terminaison précoce optimiste. Face à une fonction difficile, il la saute, en traite quelques autres, puis conclut : « le reste suit le même pattern, c’est bon. »
Après avoir imposé une boucle via un outil CLI :
Agent autonome : 40 / 527 (7.6%) — l'agent déclare « terminé »
CLI loop : 527 / 527 (100%) — la machine déclare « encore 487 à traiter »
Même modèle. Même projet. La différence : qui décide que c’est « fini ».
L’environnement façonne le modèle
Les deux expériences pointent vers la même conclusion. Si Opus 4.7 a terminé, ce n’est pas parce que le modèle est intelligent. C’est parce que la specification surface était machine-checkable.
filefunc validate → La structure du code respecte-t-elle les règles ?
pytest → Le comportement existant est-il préservé ?
coverage → Quelles branches sont manquantes ?
Ces trois outils renvoyaient un feedback immédiat à chaque modification. Le modèle recevait le résultat, corrigeait, recevait à nouveau, corrigeait à nouveau. Un self-correcting loop.
Le point essentiel :
C’est la topologie du feedback, et non le QI du modèle, qui détermine le résultat.
Les LLM excellent en génération mais sont faibles en garantie de correctness. Toutefois, en présence d’un deterministic verifier, la performance se stabilise radicalement. lint, typecheck, test, coverage — tout cela devient le gradient signal qui corrige la sortie du modèle.
« Quand le modèle sera assez intelligent, tout sera résolu » est une thèse fausse. Plus exactement : « Quand le feedback sera assez rapide, le modèle actuel suffira. »
broad exploration vs local correction
La force des LLM n’est pas le broad exploration mais le local correction.
« Écris les tests de ce projet » — c’est du broad exploration. Le LLM perd le cap.
« line 41 n’est pas couverte » — c’est du local correction. Le LLM écrit précisément un test couvrant cette ligne.
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. La simple ligne « line 41 not covered » joue le rôle de gradient signal. Ce feedback guide les corrections du LLM dans la bonne direction.
Symbolic Feedback Loop
Une structure unique traverse toutes ces observations.
Le LLM génère → un outil déterministe juge → le résultat est renvoyé au LLM → répétition
J’appelle cela le Symbolic Feedback Loop.
Le courant dominant de l’industrie aujourd’hui est le LLM Feedback Loop. L’IA vérifie l’IA. Un homme ivre demande à son ami ivre : « Je suis bourré ? » Les deux sont stochastiques — les erreurs s’accumulent.
Le Symbolic Feedback Loop est différent. pytest n’hallucine pas. go test ne s’enivre pas. La mesure du coverage ne ment pas. La vérification de spécification ne dérive pas.
Cette structure fonctionne dans les domaines où la correctness peut être jugée mécaniquement — code, tests, spécifications, types. L’élégance d’une conception d’API ou le naturel d’une UX échappent encore aux outils symboliques. Repousser cette frontière est le prochain défi. Je crois qu’il existe un chemin pour amener le langage naturel lui aussi dans un périmètre verifiable.
Rendre le modèle plus intelligent est moins efficace que rendre le feedback renvoyé au modèle plus précis.
La délégation des décisions
Il est évident qu’on ne peut pas déléguer les décisions à l’IA. Cependant, tout vérifier et tout décider soi-même est un travail éprouvant. Certaines décisions répétitives et formalisables peuvent être confiées à des outils symboliques en lieu et place de l’humain.
« Ce test couvre-t-il toutes les branches ? » — inutile qu’un humain relise. L’outil de coverage tranche. « Ce code respecte-t-il les règles de structure ? » — inutile qu’un humain fasse la revue. validate tranche. « Reste-t-il des fonctions non traitées ? » — inutile qu’un humain compte. Le CLI le déclare.
Les décisions qu’on ne peut pas déléguer à l’IA, on peut les déléguer aux outils symboliques. Parce que ce n’est pas de la probabilité, mais du déterminisme. C’est la raison d’être du Symbolic Feedback Loop.
Il est plus important de poser les rails que de rendre le train plus rapide.
Beaucoup construisent des trains. Ceux qui posent les rails sont encore rares.