[!NOTE] Traduction automatique Cet article a été traduit automatiquement depuis la version originale en anglais.

Harness engineering pour les agents AI : conception du boucle autour du modèle

Partie 6 de la série « Ingénierie de la pile Agentic »

Le reasoning loop d’un agent sélectionne l’action suivante. Son harness fournit le contexte, valide et autorise les tool calls proposés, envoie les appels acceptés au runtime, enregistre les résultats, et détermine si la tâche est terminée.

Les modèles proposent des modifications et peuvent déclarer les tâches terminées, tandis que le harness contrôle les permissions ainsi qu’il interprète les vérifications d’acceptation qui déterminent si la boucle peut s’arrêter. Partie 5 Il a abordé le runtime qui permet de maintenir le processus en cours d’exécution. Cet article se concentre sur le code de contrôle présent à l’intérieur de ce runtime : comment déterminer si chaque modification est bénéfique et comment assurer que les mécanismes de contrôle générés restent localisables au fur et à mesure que le harness évolue.

Au-delà du premier contrôle d’acceptation explicite, chaque tentative de réessai, transfert ou évaluateur supplémentaire constitue une hypothèse concernant une défaillance observée. Il ne trouve sa place que lorsque une comparaison contrôlée démontre qu’il apporte une amélioration.

Pour rendre ce chemin de contrôle concret, j’utiliserai un petit répertoire de magasin fictif. La tâche de programmation consiste à abaisser le seuil permettant une remise automatique de 10 % de 100 aˋ75 à 75 . src/checkout.py. Le dépôt présente deux vérifications obligatoires :

Cet exemple constitue un outil pédagogique et non une application réelle ou benchmark. Chaque tentative débute à partir du même commit ainsi que des données de test initiales. Le harness ne pourra valider la modification que lorsque les deux commandes réussiront et que le suivi logique reliera ces résultats au commit testé.

Les sections suivantes passent délibérément à deux autres exemples. Un ordre de mise en stage API démontre pourquoi les appels entraînant un changement d’état nécessitent une protection contre la réexécution, tandis qu’une migration d’adaptateur de paiement illustre ce qu’il faut pour que une nouvelle session de modèle reprenne le travail inachevé. Le laboratoire complémentaire situé vers la fin est à nouveau distinct : il est exécutable, mais il contient des tâches simulées génériques plutôt que ce répertoire de stockage.

TL;DR : Commencez par un seul modèle, quelques outils spécialisés, ainsi qu’une vérification explicite d’acceptation. Ajoutez des tentatives de réexécution lorsque les traces indiquent des échecs temporaires des appels. Mettez en place un transfert de progression lorsque les sessions reprises effectuent à nouveau le même travail. Lorsque vous testez l’une de ces modifications, maintenez inchangées la version du modèle, les tâches, l’outil d’évaluation et le budget total. Supprimez ce composant s’il n’améliore pas le résultat mesuré.

Le diagramme illustre l’évolution du taux de remise depuis la proposition jusqu’à la preuve. Le harness fournit la tâche et les fichiers, puis vérifie la proposition formulée. edit_file les arguments et les permissions, puis il envoie la requête acceptée. Une fois que runtime a appliqué l’édition, harness exécute les tests de unité ainsi que les tests d’acceptation dans le navigateur. Une commande qui échoue est renvoyée au modèle en tant qu’élément de preuve pour une nouvelle tentative ; deux commandes réussies rendent la modification éligible à l’acceptation.

Une modification du taux de remise via le harness


Ce que possède le harness

celui d’OpenAI Guide pas à pas sur le boucle Codex Il décrit le cycle de base. Le harness assemble un prompt, demande au modèle quelle action effectuer ensuite, envoie une tool call acceptée au runtime, ajoute le résultat obtenu, puis réitère la demande jusqu’à ce que le harness accepte ce résultat ou restitue le contrôle à l’utilisateur.

Les implémentations peuvent fusionner plusieurs responsabilités en un seul processus. Les limites de défaillance restent cependant distinctes :

TermTâcheExemple d’agent de codage
ModèlePropose un texte, un tool call, ou une réponse finaleSuggère une modification pour src/checkout.py
Reasoning loopSélectionne le prochain mouvement parmi les contextes disponiblesVérifier, modifier, tester, vérifier à nouveau
HarnessFournit le contexte nécessaire, autorise et envoie les appels, enregistre les résultats obtenus, puis vérifie si la tâche est terminée.Permet des modifications sous src/ et nécessite à la fois des tests nommés
RuntimeExécute les appels tout en maintenant le processus en vie et isoléOuvrier, sandbox, stockage de session, file d’attente

Lorsqu’une panne se produit, diagnostiquez la frontière censée répondre. Un plan insuffisant peut nécessiter de meilleures instructions ou un raisonnement basé sur le modèle. Si edit_file vise un chemin en dehors de src/Le harness doit le rejeter, tandis qu’un processus sandbox qui s’arrête avant l’exécution de la modification fait partie du runtime, ce dernier devant alors redémarrer le travailleur ou signaler la panne.

celui de OpenAI lui-même harness – étude de cas en ingénierie Il décrit une instance d’application démarrable pour chaque worktree. L’équipe a également intégré l’automatisation de navigateur dans l’environnement de l’agent, tout en rendant accessibles les journaux, les métriques et les traces.

Une tâche telle que « aucun intervalle dans ces quatre parcours utilisateurs critiques ne doit dépasser deux secondes » est devenue testable, car l’agent pouvait exécuter l’application et interroger les mêmes indicateurs que ceux qu’un ingénieur examinerait. Cette étude de cas est spécifique au produit. Ce qui est transférable, c’est la condition sous-jacente au résultat : l’application ainsi que ses indicateurs de performance devaient être disponibles à l’intérieur de l’environnement de l’agent.

Lopopolo, l’auteur de cette étude de cas, maintient un Guide de terrain pour harness ingénierie cela désigne les deux leviers sur lesquels s’appuie cet article : considérer le modèle ainsi que l’agent de codage comme des boîtes noires, et concevoir le contexte ainsi que les outils qui les entourent. Sa manière de présenter les choses explique également pourquoi une grande partie du harness se révèle être du code ordinaire.

La barre de qualité d’une organisation, ses procédures, son historique des exceptions ainsi que ses relations d’autorité restent en dehors de la portée de ce qu’un modèle général peut connaître. Le harness les fait apparaître sous forme d’instructions de répertoire, de règles d’autorisation et de vérifications d’acceptation. Chaque exécution acceptée peut renvoyer les enseignements qu’elle a acquis vers ces artefacts, au lieu de devoir compter sur la session suivante pour les redécouvrir.


Suivre l’évolution du taux de remise depuis la proposition jusqu’à l’acceptation

Pour la tâche de remise définie ci-dessus, le modèle propose de modifier calculate_discount dans src/checkout.py. Plusieurs événements interviennent avant cela modifier le code est considéré comme une avancée :

  1. Le constructeur de contexte fournit la tâche, les instructions du répertoire, les fichiers pertinents, les tool results antérieurs, ainsi que le plan actuel.
  2. Le modèle propose un edit_file appel avec un chemin et un texte de remplacement.
  3. La frontière de l’outil (le code harness entre la proposition et l’exécution) valide les arguments, vérifie le chemin par rapport à la portée autorisée, et demande une approbation si l’opération en a besoin.
  4. Le runtime applique la modification dans le sandbox et renvoie un résultat structuré.
  5. Le harness s’exécute pytest tests/test_checkout.py, suivi de pnpm playwright test tests/checkout_discount.spec.ts, et lit les deux codes de sortie. Le test dans le navigateur vérifie la réduction visible de $8 sur le panier initialisé à $80.
  6. Le harness détermine la signification des résultats. Une vérification échouée devient un nouveau contexte pour la prochaine itération du modèle, tandis qu’une exécution réussie fait de la tâche un candidat à l’achèvement.
  7. Un résultat positif ne devient une preuve d’achèvement qu’après que le harness ait enregistré la commande, le code de sortie ainsi que la version de l’artefact testé dans le journal d’audit.

À l’étape 2, aucun fichier n’a été modifié. Le harness peut donc rejeter la demande. ../../secrets.env, il faut obtenir une autorisation pour exécuter une commande destructrice, ou bien interrompre un exécution qui a épuisé son budget. Une fois les tests terminés, le harness lit lui-même leurs codes de sortie. Le modèle ne peut pas marquer sa propre modification comme réussie.

Le trace doit afficher le chemin proposé ainsi que le texte de remplacement, la décision de permission, les fichiers qui ont été modifiés, le commit testé, et les résultats des deux commandes. Une étape finale done Un message ne contenant pas ces enregistrements ne prouve pas que ce changement a réussi les vérifications requises.


Déterminer où chaque règle est appliquée

Appliquer tests/checkout_discount.spec.ts Dans une logique de programme normale, le harness envoie la commande Playwright au runtime, lit son code de sortie et refuse de terminer l’exécution tant que celle-ci échoue. Un prompt peut rappeler au modèle d’exécuter le test, mais il ne peut pas l’empêcher de déclarer un succès en l’absence de preuves.

D’autres règles s’appliquent aux couches distinctes :

Placer la règle dansAdéquation parfaiteExemple
Prompt ou compétenceOrdre de recherche, conventions de codage et format du planLire AGENTS.md avant d’éditer le code de vérification de paiement
Frontière de l’outilValidation des arguments, chemins autorisés, approbations et accès aux outilsAutoriser uniquement les écritures sous src/
Code déterministeLes budgets, les délais d’attente, les tentatives de réessai, les codes de sortie des tests, ainsi que les portes de déploiementMaintenez la session en cours tant que le test Playwright échoue.
Évaluateur distinctRévision visuelle ou critères nécessitant un jugement de type humainComparer un diagramme généré à une grille d’évaluation écrite

Les contrats d’outil séparent la proposition de l’autorisation

La tâche de remise ne nécessite que des modifications de fichiers et des commandes de test. Un API qui modifie d’état présente un mode de défaillance différent, il convient donc de changer les exemples pour cette section. Supposons que l’agent puisse appeler create_test_order en opposition à un service de gestion des commandes en phase de préparation, lors de la création des données de test. Cet outil ne fait pas partie des vérifications d’acceptation liées aux tâches de remise. Il s’avère utile dans ce contexte, car un délai d’expiration peut masquer le fait que le service ait bien créé une commande.

Les limites de l’outil nécessitent bien plus qu’une simple description en langage naturel. Pour create_test_order, le harness nécessite un contrat avec :

La description en langage naturel est le texte affiché au modèle. Elle peut par exemple indiquer : « Créez une commande de test pour la vérification du paiement. » Cette phrase aide le modèle à déterminer quand proposer create_test_order. Il n’autorise pas l’appel. Dans cet exemple, le client de harness, à savoir MCP, valide les arguments, applique ses propres règles, et vérifie la fiabilité du serveur, les exigences d’approbation ainsi que les critères de sécurité liés aux tentatives de réessai avant d’envoyer quoi que ce soit.

Un serveur MCP publie des descriptions d’outils ainsi que des annotations sur le comportement optionnel vers le client. Un serveur défectueux ou malveillant pourrait décrire un outil capable de modifier l’état comme étant inoffensif. Si le client acceptait automatiquement cette affirmation, il pourrait l’exécuter ou tenter à nouveau l’opération. create_test_order sans approbation et en créant une copie, de sorte que la spécification MCP exige que les clients traitent Les annotations d’outil en tant que sources non fiables à moins que le serveur lui‑même ne soit fiable.

La spécification ne définit pas de paramètre de confiance universel. Le client doit donc disposer d’une politique de confiance explicite pour son déploiement ; un serveur ne peut pas rendre ses propres annotations fiables. Cette politique détermine quels métadonnées peuvent influencer les décisions relatives aux autorisations ou aux tentatives de répétition, et quelles annotations restent uniquement consultatives.

La réessai d’une appel modifiant l’état nécessite une protection contre la répétition

Un problème de tentative de réessai plus complexe apparaît lorsque create_test_order Il crée la commande, mais sa réponse HTTP est perdue. Le harness détecte un délai d’attente et ne peut pas déterminer si le serveur a terminé la requête. La répétition de l’appel peut entraîner la création d’une deuxième commande.

Une tentative de consultation du statut peut être répétée lorsque le service est défini comme uniquement en lecture. Une requête de création nécessite une protection, telle qu’une clé d’idempotence : le client y associe un identifiant unique de requête, et le service renvoie le premier résultat au lieu de créer une nouvelle commande lorsqu’il repère à nouveau cet identifiant. Sans cette protection, le harness doit vérifier si la commande existe ou demander une décision humaine avant de tenter à nouveau. AWS décrit ce schéma dans ses documents. guidelines pour l’idempotence API.

L’acceptation nécessite des preuves indépendantes

Un succès create_test_order La réponse ne prouve que le fait que l’outil a renvoyé des données. Elle ne démontre pas pour autant qu’une tâche de codage a réussi ses tests. Si un test de navigateur ultérieur dépend de l’ordre d’exécution prévu, le harness doit valider le schéma de la réponse et exécuter ce test avant d’accepter la modification de code.

Certains critères ne peuvent pas être réduits à un code de sortie. Pour une tâche distincte de conception visuelle, un évaluateur nouveau peut comparer une page ou un diagramme rendu avec une grille d’évaluation écrite. Les équipes doivent vérifier cet évaluateur à l’aide d’avis humains avant de l’utiliser comme étape de validation finale.


Une migration d’adaptateur de paiement nécessite une transition

Passez à une autre tâche, mais restez dans le répertoire du magasin fictif. L’agent doit maintenant migrer le processus de paiement du adaptateur de paiement v1 vers v2. Ce travail concerne le gestionnaire de paiement, le client de paiement, les paramètres de configuration ainsi que les tests, ce qui peut nécessiter plus d’une session de modèle.

Avant que la première session n’atteigne sa limite de contexte, elle a modifié plusieurs fichiers, initié un paiement local sandbox, et est partie tests/payment_migration.spec.ts Échec. Ce test d’acceptation par navigateur effectue un paiement via l’adaptateur v2 et vérifie l’ID du fournisseur enregistré. Un résumé de la conversation peut guider la prochaine session du modèle, mais il ne permet pas de redémarrer le sandbox ni de déterminer quels fichiers sont actuellement modifiés.

La prochaine session doit récupérer trois éléments :

Quelles données doivent être récupérées ?Qu’il comprendComment cela peut échouer
Historique de conversationMessages, tool calls, ainsi que les résultats renvoyésLes anciens détails évincent la tâche en cours.
Environnement de travailFichiers, paiement sandbox, et état de test dans le navigateurLe transcript indique qu’un service est en cours d’exécution alors qu’il était déjà mort.
Progress de la tâchePlan : vérifications terminées, approbation en attente, prochaine actionLa prochaine session reprend le travail déjà effectué.

La compactation remplace les messages anciens par un résumé plus court afin de permettre la poursuite de la session en cours. Un transfert de progression enregistre ce dont a besoin la session suivante : la branche actuelle, les fichiers modifiés, la dernière commande de test ainsi que ses résultats, et l’étape non résolue suivante. Si la conversation précédente contient des hypothèses obsolètes, le harness peut lancer une nouvelle session de modèle à partir de ce transfert et de l’espace de travail actuel. Le remplacement d’un travailleur défaillant et la restauration de ses processus constituent quant à eux une tâche de récupération distincte, appelée runtime.

Une petite modification de la documentation peut ne pas nécessiter aucun de ces mécanismes. La migration des paiements requiert un transfert de responsabilités dès que les travaux dépassent la limite d’une session, car la nouvelle session du modèle doit reconstruire à la fois l’espace de travail et l’état de la tâche.

les expériences d’Anthropic avec agents de codage à exécution prolongée il utilisait l’historique Git ainsi qu’un fichier de progression entre les sessions, tandis que ses versions ultérieures harness-rapport de conception Il sépare la compression du transfert de contexte vierge et indique l’orchestration supplémentaire, l’utilisation des tokens ainsi que le temps d’exécution nécessaire pour effectuer ces transferts.


Utiliser les traces pour distinguer trois types d’échecs

Les trois lignes suivantes présentent des schémas d’exemple de traces, et non des exécutions mesurées ni des résultats provenant du laboratoire associé. Chaque ligne illustre un type de défaillance différent, et par conséquent une réponse harness distincte.

Ce que enregistre la traceQue s’est-il passé ?Réponse correcte
Le mode lecture seule get_order_status la fonction de rappel renvoie 503; aucune appel entraînant un changement d’état n’est en cours d’exécutionUne recherche transitoire a échoué.Réessayer la recherche en appliquant une limite et un mécanisme de backoff
create_test_order Une expiration du délai est déclenchée, puis une recherche de statut permet d’identifier la commande. 123 sous la clé d’idempotence checkout-42Le service a créé la commande, mais la réponse a été perdue.Restituez l’ordre existant ; ne créez pas un autre.
L’édition et les tests unitaires réussissent, mais le suivi ne présente aucun résultat pour tests/checkout_discount.spec.ts dans le commit testéLes preuves d’acceptation requises manquent.Maintenez la session en cours et lancez le test d’acceptation dans le navigateur

Cette distinction est importante car un 503 Cela ne rend pas chaque appel sûr à être réessayé. La première ligne correspond à une recherche en lecture seule. La deuxième ligne représente une requête modifiant l’état, de sorte que la clé d’idempotence ainsi que l’état côté serveur déterminent si une nouvelle tentative de création est autorisée. La troisième ligne n’est absolument pas due à une panne d’outil ; le harness n’a pas encore recueilli les preuves nécessaires pour valider la modification du rabais.

Un enregistrement de conversation consigne ce que le modèle a perçu. Il n’est pas possible de déterminer si le service de commande a effectué une demande avant que la réponse ne disparaisse. La trace doit relier l’appel du client, la décision d’approbation, la clé d’idempotence, le résultat ou la recherche de statut serveur, la transaction testée, ainsi que le résultat du test d’acceptation. Ces champs indiquent à harness quel des trois chemins il emprunte.

Symptôme récurrentPetite modification à testerQuelles métriques mesurer
Les recherches en lecture seule échouent temporairement.Réessai borné avec backoffTaux de récupération, appels supplémentaires, temps d’exécution
Les sessions reprises reprennent le travail déjà effectué.Transfert structuré des états d’avancementActions de l’outil dupliquées après la reprise
Les tests requis manquent à la phase de finalisation.Tâches acceptées sans avoir subi toutes les vérifications requises
Les défauts visuels survivent aux vérifications déterministes.Évaluateur neuf accompagné d’une grille d’évaluation écriteDéfauts détectés, rejets faux, temps d’examen
L’agent modifie des éléments en dehors de son champ d’action.Permission d’outil plus restreinteAppels bloqués et suppressions manuelles

Avant d’ajouter un composant, définissez le défaut récurrent que celui-ci doit réduire ainsi que le nombre à suivre. Retirez le composant si une comparaison contrôlée n’améliore pas suffisamment ce chiffre pour justifier son coût.


Mesurer un seul changement à la fois

Une ablation permet de déterminer si un composant harness est responsable de l’effet escompté, en modifiant ou en supprimant ce composant tout en maintenant le reste de l’expérience inchangé. Par exemple, l’analyse statique fournie par l’éditeur améliore-t-elle les performances de ce modèle sur cet ensemble de tâches ?

Utilisez le protocole suivant :

  1. Geler la version du modèle, les instances de tâche, l’environnement, le correcteur d’évaluation, ainsi que prompts en dehors de la composante soumise à test.
  2. Allouer aux deux variantes le même budget total en tokens, en temps et en coûts financiers.
  3. Déterminer le nombre d’essais ou la règle d’arrêt avant de lancer la comparaison.
  4. Exécuter les mêmes instances de tâche dans les deux variantes. Étant donné que les sorties des modèles varient, il convient de répéter chaque tâche plusieurs fois.
  5. Fournir la valeur moyenne accompagnée de l’écart type ou de l’intervalle de confiance.
  6. Compter tous les essais lancés, y compris ceux dus aux délais d’exécution, aux arrêts imposés par la politique, aux harness plantages, ainsi qu’aux échecs de l’évaluateur.

Le taux de réussite seul peut masquer l’existence d’un composant coûteux. Au minimum, suivez le nombre de tâches défectueuses considérées comme terminées, le coût et le temps passé par tâche achevée, les erreurs des outils, les commandes dupliquées, les minutes consacrées aux revues, ainsi que les suppressions manuelles des autorisations. Choisissez la métrique qui reflète réellement le coût pour le produit. Une augmentation de deux points dans le nombre de tâches terminées constitue un mauvais échange si cela double la file d’attente des revues.

Une expérience de migration de paiement en parité permet d’évaluer de manière mesurable le transfert des progrès. Chaque paire contrôle/traitement part du même commit de répertoire et est initialisée avec checkpoint, ainsi qu’avec le même modèle, la même tâche, le même évaluateur et le même budget total. Le transfert constitue le seul paramètre à modifier. La métrique principale compte les actions redondantes des outils après la reprise : une action est considérée comme redondante lorsque son opération et son artefact correspondent à une étape déjà accomplie par la session précédente.

Un test apparié d’un composant harness

Le Article sur SWE-agent Corrige les problèmes de GPT-4 Turbo sur la sous-ensemble de 300 tâches du SWE-bench Lite et indique un taux de résolution de 18,0 % avec son interface complète, contre 11,0 % pour l’agent fonctionnant uniquement en mode shell. L’étude modifie également certaines fonctionnalités spécifiques de l’interface :

Changement d’interfaceRésolu
Interface complète SWE-agent18.0%
Éditeur sans vérification de conformité15.0%
Fichier complet plutôt qu’un visualiseur à 100 lignes12.7%
Historique complet des observations au lieu des cinq dernières15.0%

Ces valeurs correspondent à ce modèle, benchmark, ainsi qu’à un plafond de 4 $ par tâche. Le without linting, full file, et full history Les lignes représentent les tests uniques utiles : chacun modifiait une fonctionnalité d’interface tout en maintenant le modèle ainsi que la configuration d’évaluation inchangés.

LangChain a publié une version plus étendue comparaison de modèles fixes pour deepagents-cli. Il indique une amélioration selon Terminal-Bench 2.0, passant de 52,8 % à 66,5 %. gpt-5.2-codex La correction a été appliquée alors que son équipe modifiait le system prompt, les outils ainsi que le middleware. Ce rapport regroupe plusieurs modifications tout en omettant l’intervalle de confiance, la comparaison du budget total corrigé et le tableau d’ablation par modification. En conséquence, ce résultat ne permet pas d’identifier quelle modification est réellement utile.

Anthropic’s Rapport d’application à exécution prolongée Il s’agit d’une étude de cas qualitative et spécifique au produit, et non d’une expérience contrôlée benchmark. Son évaluateur a vérifié 27 critères liés à l’éditeur de niveaux au cours du Sprint 3. L’équipe indique que les appels effectués par l’évaluateur constituaient une charge supplémentaire pour des tâches que Opus 4.6 pouvait accomplir de manière fiable en autonomie, mais qui nécessitaient néanmoins une assistance près des limites du modèle ; c’est pourquoi des composants harness ont été supprimés un par un après la mise à niveau du modèle. Cet exemple justifie la révalidation des structures de base existantes lorsqu’il y a des changements dans le modèle, sans pour autant permettre d’estimer l’ampleur générale de l’impact.


Conserver l’harness modifiable une fois qu’il a trouvé sa place

L’ablation permet de maintenir harness à une taille réduite, mais son code peut néanmoins survivre au modèle pour lequel il a été ajusté. Une requête telle que « masquer les secrets dans chaque chemin de capture » définit un comportement, et non un fichier. Dans un harness en environnement de production, ce comportement peut s’étendre sur plusieurs étapes d’exécution ainsi que sur des états partagés. Un humain ou un agent de codage doit identifier tous les lieux où cette implémentation a lieu avant de pouvoir la modifier en toute sécurité.

Un préprint de 2026 de Wang et al., le Harness Manuel, Ce passage qualifie cette étape de comportementalisation. Le manuel établit une carte axée sur le comportement à partir du codebase harness. L’analyse statique permet d’extraire un graphe de programme dépourvu d’appels de modèle, puis un LLM organise ses unités en phases d’exécution.

Le mainteneur ou l’agent de codage commence par une vue d’ensemble du système, ouvre l’étape d’exécution correspondante, puis descend jusqu’aux entrées ancrées dans le code pour une fonction ou un fichier. Une vue de registre enregistre les endroits où l’état partagé est écrit et lu entre les différentes étapes. Cette hiérarchie permet de conserver une vue d’ensemble concise tout en assurant un accès direct au code source.

La fraîcheur des données fait l’objet d’une règle distincte. Chaque localisateur doit se référer au repository en temps réel. Le manuel exclut les entrées obsolètes sans deviner, et chaque diff non vide réssyncrone les entrées qu’il affecte.

Le diagramme simplifie le cycle de modification : une requête ne concernant que le comportement descend à travers les différents niveaux du manuel ; chaque localisateur potentiel est vérifié contre le répertoire en temps réel avant que le plan ne soit généré, et chaque différence appliquée ré-synchronise la carte.

Acheminer un changement de comportement via le manuel harness

Le Évaluation des manuels il suit le protocole prôné dans cet article. Sur deux plateformes open source (Terminus-2, six fichiers Python, ainsi que le monorepo Codex contenant 2 267 fichiers Rust), un planificateur en lecture seule alimenté par DeepSeek-V4-Pro a soit exploré directement le répertoire, soit utilisé le manuel comme intermédiaire. Les requêtes, les permissions relatives au répertoire et aux outils, ainsi que le décodage étaient identiques dans les deux cas. Trois évaluateurs (GPT-5.5, Opus 4.8, DeepSeek-V4-Pro) ont noté chaque plan d’édition en fonction de la localisation, du contrôle du périmètre et du raisonnement :

HarnessTaux de victoire de référenceAide fournie par un manuelTokens de planification
26.7%45.6%−8.6%
Codex monorepo (2 267 fichiers)28.3%38.3%−12.7%

Le planificateur assisté par un manuel a remporté plus souvent la compétition et a utilisé moins de tokens de planification dans les deux répertoires. Les mêmes conditions s’appliquent à ce résultat : trois LLM juges ont évalué les plans d’édition générés par un modèle de planificateur sur deux plateformes d’essai. L’étude portait sur l’évaluation des plans eux-mêmes, et non sur l’exécution des différences ni sur les taux de défauts de production.

Les sections précédentes utilisent des traces pour expliquer pourquoi un composant existe. Cette carte répond à la question suivante : où se trouve ce composant lorsqu’il doit être modifié ?


Testez la méthode dans le laboratoire d’accompagnement

Le harness – projet de démonstration dans le commit 517353f3 il s’agit d’un exercice de petite taille et déterministe comprenant 12 tâches synthétiques génériques couvrant des modifications de code telles que fix-parser-edge-case, split-large-module, et wire-browser-test. Il ne met pas en œuvre le répertoire de stockage fictif.

Chaque fixture de tâche définit un niveau de difficulté ainsi que quatre conditions booléennes : un outil instable, une perte de progression, un manque d’implémentation, et une fin de tâche ambiguë. Le simulateur déduit une cinquième condition pour les tâches difficiles qui nécessitent également un fichier de progression : l’absence de context_reset, la compactation conserve les hypothèses obsolètes. Un évaluateur déterministe ne marque une tâche comme réussie que lorsque la configuration sélectionnée prend en compte toutes les conditions applicables. Aucun modèle ni service externe n’est exécuté.

Les commandes répondent à des questions différentes :

make check
make run
make failures

La section causale de make run Voici à quoi cela ressemble :

component                 control  treatment  delta
retry_policy              8/12     12/12       +4
progress_handoff          7/12     12/12       +5
evaluator                 8/12     12/12       +4
fail_closed_acceptance    7/12     12/12       +5
context_reset            10/12     12/12       +2

Pour chaque ligne, le contrôle correspond à la configuration complète avec un composant retiré ; le traitement ne restaure que ce composant. La matrice cumulative précédente est utile pour s’orienter, mais certaines de ses lignes voisines ajoutent plusieurs composants en même temps et ne permettent donc pas d’identifier une cause.

Le laboratoire valide chaque paire déclarée avant de la lancer. Ses tests de régression incluent également une paire intentionnellement invalide qui modifie simultanément la politique de tentative et l’évaluateur ; le validateur la rejette.

Le schéma de configuration du laboratoire vérifie les cinq champs de composant. Cet extrait exécutable montre la même protection appliquée à une paire de transfert de progression valide :

from dataclasses import dataclass, fields


@dataclass(frozen=True)
class Config:
    progress_handoff: bool = False
    evaluator: bool = False
    retry_policy: bool = False
    fail_closed_acceptance: bool = False
    context_reset: bool = False


def changed_components(control: Config, treatment: Config) -> tuple[str, ...]:
    return tuple(
        field.name
        for field in fields(control)
        if getattr(control, field.name) != getattr(treatment, field.name)
    )


control = Config(progress_handoff=False, evaluator=True, retry_policy=True)
treatment = Config(progress_handoff=True, evaluator=True, retry_policy=True)
assert changed_components(control, treatment) == ("progress_handoff",)

Commencez par une boucle et une vérification d’acceptation

Je commencerais par créer un agent de codage harness à partir d’un modèle performant, d’instructions relatives au répertoire de code, de quelques outils spécialisés, d’un sandbox, ainsi que d’un test d’acceptation explicite. J’enregistrerais les tool calls, les résultats, les coûts et ce test final dans un seul fichier de suivi, afin que les premières erreurs utiles soient immédiatement visibles, sans avoir à les reconstituer à partir des journaux du terminal ou des transcriptions de conversations. Il s’agit ici d’une base de référence proposée, et non de données provenant d’un système déployé.

À partir de là, ne ajoutez que ce que le suivi des performances justifie. Enregistrez qui maintient chaque composant, combien de tokens ou de secondes il ajoute, ainsi que quel test de régression justifierait son suppression après une mise à jour du modèle.

Six mois plus tard, une personne qui observe progress_handoff=True Il doit être capable de localiser les traces défaillantes qui en justifient l’état ainsi que les cas de régression qui le maintiennent encore dans cette situation. Ces traces expliquent pourquoi ce composant existe ; une carte du comportement actuel indique quant à elle où il convient d’intervenir.


Références


Série : Conception de la pile Agentic