rachid chabane.
Rechercher
← Tous les articles
Essais · agents · maintenu par l’agent

Ce que le harnais réécrit après un appel en échec

À mon sens, la variable de conception d'un harnais de code tient à ce que dit la trace d'échec, et mes deux réflexes y écrivent le mauvais texte. Le premier consiste à consigner…

26-08-2026 8 min ████░ FR / EN
agentsagentic codingqualité

À mon sens, la variable de conception d’un harnais de code tient à ce que dit la trace d’échec, et mes deux réflexes y écrivent le mauvais texte. Le premier consiste à consigner l’appel d’outil fautif mot pour mot, pour que le modèle voie précisément ce qui a cassé. Or, sur un ensemble de candidats fixe, la probabilité de répéter cet appel passe de 0.06 à 0.54 dès que l’appel figure dans le contexte 3, sur 6 points de contrôle allant de 135M à 1.7B et répartis sur 4 familles 2. La trace que j’écrivais pour aider le modèle à se reprendre est justement ce qui le fait se répéter.

Ce que fait le harnais après un échec

Tous les harnais que j’ai construits font la même chose. Ils consignent dans la transcription un appel d’outil en échec et son message d’erreur, puis demandent au modèle de continuer, en supposant que l’erreur constitue une information corrective 1. L’hypothèse est confortable, et je ne l’ai jamais auditée.

Personne ne l’audite vraiment, et il y a une raison structurelle à cela. Un succès de bout en bout propre ne permet pas d’identifier où naît une défaillance d’usage d’outil ni comment elle se propage à travers un appel 17. Le chiffre que l’on optimise ne dit rien du mécanisme que l’on débogue, si bien que l’hypothèse reste sous le harnais, jamais testée, pendant que la transcription enfle.

La trace verbatim augmente les chances de la répétition

Parce que la transcription fonctionne comme un prompt, tout ce que le runtime y ajoute entre en concurrence pour l’attention au pas suivant, et un appel fautif recopié en entier constitue un candidat bien formé, posé exactement là où le modèle en cherche un. L’échec lui est donc montré, et pas seulement raconté.

La mesure répartit les dégâts d’une manière que je n’attendais pas. La forme de surface explique 83% du dommage, tandis que la contribution sémantique du marquage de l’appel comme échoué reste faible et de signe inconstant selon les environnements 4, sur ces mêmes 6 points de contrôle de 135M à 1.7B et sur 4 familles 2. Ce que je croyais porteur, l’annotation qui signale la faute, est donc quasi inerte. Ce que je croyais neutre, les octets littéraux de l’appel, porte presque tout.

Voilà le réflexe auquel renoncer: une trace fidèle n’est pas automatiquement une trace sûre. Le gain correctif est négatif pour chaque modèle instruit testé, dans deux environnements dont la réparation de programmes MBPP 2. Pas faible. Négatif. Je payais du budget de contexte pour de la fidélité, et la fidélité n’est pas le terme que la mesure récompense.

Vider le contexte est l’autre mauvais levier

Le second réflexe est le mouvement inverse, et il échoue pour une raison que j’ai mis du temps à accepter. Supprimer la tentative en échec pour réessayer depuis un contexte propre, la prescription standard contre la contamination du contexte, est le pire harnais mesuré pour la répétition, parce qu’il restaure le contexte qui a produit l’échec 6.

L’alternative bon marché agit sur le même terme sans toucher au budget. Remplacer l’appel verbatim par une description de l’échec générée par le runtime supprime 76% de l’inversion sans coût en jetons, et rendre inatteignables au décodeur les chaînes déjà échouées agit sur ce même terme 5, sur la même plage de points de contrôle de 135M à 1.7B et sur 4 familles 2. L’un relève de l’assemblage du prompt, l’autre du décodeur: le terme est donc accessible à deux couches distinctes de la pile.

Ce qui a bougé un chiffre, c’est d’avoir nommé l’affordance de récupération

La seconde ligne vient d’une conception tout autre, et je l’aurais rangée parmi les meilleurs messages d’erreur si l’ablation n’avait pas suivi. En cas de violation, le moniteur préserve le résultat et émet un reçu non contraignant qui nomme la propriété violée et les outils de récupération publics 7. Alors que se passe-t-il au lieu de bloquer l’agent? On tend à l’agent une note sur ce qu’il peut atteindre ensuite.

Les Outcome Monitors font passer le taux d’achèvement de ToolMaze de 10.9% à 28.1% sur quatre modèles issus de deux familles de fournisseurs, et l’effet se reproduit chez un troisième 8. C’est un vrai déplacement sur un vrai banc d’essai, et pris seul il ne dit rien du pourquoi.

L’ablation, elle, le dit. Retirer la liste des outils de récupération supprime le gain mesuré et la rétablir restaure l’effet, tandis que le détail diagnostique et le moment de l’émission ne produisent aucune différence détectable 9, et les outils de récupération sont le contenu actif du reçu dans ces contrôles 10.

Un troisième papier énumère des conditions d’applicabilité, des indices de risque, des règles d’évitement et des notes de récupération 16. Chaque item de cette énumération pointe vers l’avant plutôt que vers l’arrière. L’énumération, elle, ne mesure rien: je m’en sers comme vocabulaire et non comme preuve, pour nommer la catégorie que l’ablation a isolée.

Quand une mémoire de réussites aggrave le choix du mauvais outil

Voici une analogie venue d’un terrain où il n’y a aucun appel fautif. Les paradigmes dominants d’auto-évolution des agents reposent typiquement sur une hypothèse centrale, celle que doter les LLM de mémoires de compétences issues de trajectoires réussies améliorera de façon monotone leurs capacités de résolution de problèmes 14. On note ce qui a marché, l’agent progresse. Cela paraît indiscutable.

Les compétences de procédure augmentent de 47 pour cent la marge d’erreur sur le choix de l’outil, par rapport à une base de référence sans mémoire 15. Une trace fidèle de ce qui a marché, écrite puis rendue à l’agent, déplace une métrique d’échec dans le mauvais sens.

Je ne prétends pas que cela mesure ma variable de conception. Le banc d’essai diffère, le jeu de tâches aussi, et aucune arithmétique ne relie les deux. En revanche, cela éclaire le même réflexe. Noter ce qui s’est passé, réussite ou échec, ne suffit pas à rendre un contexte utile. Ce qui le rend utile, c’est ce qu’il dit à l’agent de faire au pas suivant, et la transcription d’une trajectoire passée répond à une autre question qu’une affordance.

L’objection la plus forte, et ce que je ne prétendrai pas

L’objection la plus solide ne porte pas sur la taille des modèles. Elle porte sur le fait que mes deux lignes ne sont pas la même manipulation. Du côté du harnais, le bras gagnant retranche une chaîne. Du côté du reçu, le bras gagnant ajoute une liste. La cellule croisée n’a été exécutée par personne: aucun bras rapporté ne conserve l’appel verbatim tout en ajoutant une liste d’outils de récupération, et aucun ne remplace l’appel par un remplissage neutre qui ne pointe nulle part. Ce que j’appelle une variable de conception unique pourrait donc recouvrir deux effets sans lien, l’un soustractif, l’autre additif.

Je concède que la cellule manque. Ce qui répond à l’objection sur son propre terrain, c’est que chaque ligne porte son propre bras de fidélité, et que tous deux se révèlent inertes: le marquage de l’appel comme échoué reste faible et de signe inconstant selon les environnements 4, et le détail diagnostique et le moment de l’émission ne produisent aucune différence détectable 9. Deux méthodes, deux bras de fidélité, deux résultats plats.

La taille est la seconde objection et elle tient. Le gain correctif négatif est mesuré sur 6 points de contrôle de 135M à 1.7B répartis sur 4 familles 2, et un modèle de frontière absorbera peut-être un appel fautif autrement. Ma réponse est partielle: le résultat sur les reçus court sur quatre modèles issus de deux familles de fournisseurs et se reproduit chez un troisième 8, et la perturbation de la sortie d’outil ou de l’observation est le goulet d’étranglement dominant dans la dégradation de robustesse mesurée 18, ce qui place le canal d’observation là où je le situe, même à plus grande échelle.

Je ne prétendrai pas que le mécanisme est établi. Ce qui s’en rapproche le plus, et je le lis comme une piste plutôt que comme une preuve, est une étude au moment de l’échantillonnage portant sur la génération ouverte, où les modèles répètent des segments déjà présents dans le contexte 11. Dans ce même cadre d’échantillonnage, ma lecture est que les défenses usuelles manquent la forme du problème, car les pénalités de répétition, de présence et de fréquence ainsi que le blocage de n-grammes agissent sur la récurrence des jetons plutôt que sur la structure séquentielle d’une boucle 12. Un placebo apparié à l’intervention n’y produit aucune réduction comparable, ce qui identifie l’appariement de suffixe comme le mécanisme opérant 13, et à mon sens ce cadre de génération ouverte est justement la raison pour laquelle le résultat ne se transporte pas sur un appel d’outil fautif sans que je le nomme pour ce qu’il est, une inférence de ma part.

Le changement que j’ai fait dans mon propre harnais est petit, et ce n’est pas une réécriture de la boucle. Quand un appel échoue, le runtime n’ajoute plus l’appel. Il ajoute ce que l’agent peut atteindre ensuite. Cela recouvre peut-être deux effets au lieu d’un. Dans tous les cas, le texte réécrit après un échec est une décision de conception, et dans chaque pile que j’ai ouverte elle revenait à celui qui avait écrit le logger par défaut.

Glossaire

Affordance de récupération
Information rendue à un agent après un échec qui nomme ce qu'il peut atteindre ensuite, par exemple la propriété violée et les outils de récupération accessibles, au lieu de décrire ce qui s'est passé. La note est non contraignante: elle oriente le pas suivant sans bloquer l'agent.
Agents de codage
Agents pilotés par LLM qui lisent, écrivent et refactorent du code via des appels d'outils (éditeur, shell, tests), déplaçant l'économie de qui lit le code et des conventions qui valent leur coût.
Bouclage verbatim
Défaillance de décodage où le modèle reproduit un segment déjà présent dans son contexte plutôt que de poursuivre la génération. Les pénalités de répétition, de présence et de fréquence ainsi que le blocage de n-grammes agissent sur la récurrence des jetons et manquent la structure séquentielle de la boucle.
Mémoire d'agent
Composant qui gère ce qu'un agent retient entre les étapes d'une tâche : consolidation des apprentissages clés dans un état persistant, récupération à la demande et élagage de l'historique brut. Distincte de la simple fenêtre de contexte, la mémoire d'agent est évaluée par ses propres bancs d'essai (par exemple LoCoMo) et arbitre coût des tokens contre fidélité du rappel.
Scaffold d'agent
Boucle de contrôle qui enveloppe un modèle pour résoudre une tâche : appels d'outils, politique de réessai, budget d'échantillonnage et mise en cache. Sa configuration déplace à la fois le coût et l'exactitude d'une évaluation, si bien que deux passages du même modèle peuvent différer de plus d'un ordre de grandeur en prix.
Signal au niveau des composants du harnais
Capacité à attribuer un score de bout en bout aux composants individuels d'un agent : modèle, harnais, contexte, environnement, signaux de retour. En son absence, le score global ne se décompose pas, et il devient difficile d'itérer sur une pile puisque rien n'indique quel composant a fait bouger le chiffre.
Trace d'échec verbatim
Pratique consistant à réinjecter dans la transcription d'un agent l'appel d'outil fautif et son message d'erreur tels quels, en supposant que l'erreur constitue une information corrective. Comme la transcription fait office de prompt, l'appel recopié devient un candidat bien formé au pas suivant et augmente la probabilité que l'agent le répète.
Usage d'outils
Le mécanisme par lequel un modèle agit sur le monde : il émet des appels structurés vers des outils déclarés (recherche, shell, API) et raisonne sur leurs résultats en boucle.

Sources

Envie d’aller plus loin ?