Orkas Orkas
Accueil Blog Architecture
Architecture

Détecter les boucles n’est pas détecter l’enlisement : repérer les Agents qui tournent à vide sans se répéter

Orkas possède trois protections contre les boucles. Aucune ne repère un modèle compétent qui stagne, car elles cherchent toutes à savoir s’il se répète — et un modèle bloqué ne le fait jamais. Voici cet angle mort, la définition du progrès fondée sur les résultats que nous avons empruntée à BEACON et ce que nous prévoyons de mesurer avant tout changement.

Voici la première note d’une série sur la conception d’Agents pour les tâches de longue durée, née d’une lecture approfondie de BEACON (université du Zhejiang, arXiv:2605.06078).

Pour qu’un Agent tienne sur une tâche longue, deux conditions nous semblent essentielles :

  • Il continue d’avancer vers l’objectif. Cela implique la compaction du contexte — ce qu’on peut oublier sans risque —, la conception des jalons — comment savoir qu’une étape est vraiment terminée — et la prévention de la stagnation — quelque chose doit détecter qu’il est bloqué.
  • Il peut réfléchir sur son travail et s’améliorer.

Cet article porte sur la prévention de la stagnation, car c’est ce qui nous a le plus coûté.

La version courte Un Agent qui tourne en rond sans se répéter doit lui aussi être détecté La détection de stagnation est intégrée à Orkas : une longue exécution vous signale qu’elle est bloquée au lieu de dépenser silencieusement le reste de votre budget.
Télécharger Orkas — gratuit

Le symptôme

Des utilisateurs nous l’ont signalé, et nous l’avons aussi constaté en interne : certaines tâches très longues cessent d’avancer en cours de route.

Les journaux montrent pourtant un Agent occupé : il lit des fichiers, effectue des recherches, exécute des commandes, sans rester inactif. Mais une demi-heure plus tard, rien n’a avancé.

Notre première explication était la perte de contexte : la compaction avait supprimé la trace d’une voie déjà essayée, et l’Agent la tentait à nouveau. L’examen conjoint du code et des journaux a révélé que ce n’était que la moitié du problème.

Nous avions déjà des garde-fous — trois niveaux

NiveauCritèreSeuils
Répétition exacteNom de l’outil + arguments canonisés, identiques octet par octetLOOP_WARN=3 avertissement / LOOP_HARD=5 arrêt forcé
Quasi-doublonIdentique, sauf les champs volatils d’identifiant ou d’horodatageNEAR_DUP_LOOP_WARN=6 / NEAR_DUP_LOOP_HARD=12
Convergence de la boucle improductive≥2 compactions et ≥75% du budget de boucle d’outils consomméSPIN_CONVERGENCE_MIN_COMPACTIONS=2
SPIN_CONVERGENCE_TOOL_LOOP_RATIO=0.75

Le commentaire de ce troisième niveau dit, littéralement : Signal composé « tourne peut-être en rond après une perte de contexte ». Quelqu’un avait déjà anticipé le problème. Il ne venait donc pas de l’absence de dispositif, mais de l’incapacité de notre dispositif à le détecter.

L’angle mort : les trois détecteurs regardent les entrées

La signature utilisée à chaque niveau est tool name + canonicalized args. Elle répond à une seule question : faites-vous deux fois la même chose ?

Mais un modèle capable qui se bloque ne répète pas ses appels. Il fait ceci :

lire le fichier A → grep X → relire A sur une autre plage de lignes
  → exécuter une commande légèrement différente → lire le fichier B → refaire un grep …

Chaque appel a une signature distincte. Les trois niveaux restent silencieux. Et sur toute cette période, le nombre de changements d’état vérifiables est nul : aucun fichier réellement réécrit, aucune commande produisant un résultat nouveau, aucun événement irréversible.

Détecter les boucles n’est pas détecter la stagnation. La première approche examine les entrées. La seconde doit examiner les sorties.

L’article fournit précisément cette définition côté sorties

La récompense intrasegment de BEACON :

r_t = R_ms · γ^(t_k − t)    if the segment ends in a milestone
    = 0                     otherwise

Un segment qui ne se termine pas par un jalon reçoit exactement zéro, quel que soit le nombre d’actions qu’il contient. Le nombre d’actions n’entre jamais dans la formule. C’est la formalisation la plus nette que nous ayons vue de activité ≠ progrès.

La référence de comparaison est encore plus sévère. Elle correspond au rendement moyen du groupe par étape : un segment de 8 étapes, lorsque la moyenne du groupe est de 5, voit donc son avantage entier tiré vers le négatif, avec une pénalité proportionnelle au dépassement. Tourner en rond n’est pas simplement sans récompense ; c’est activement et proportionnellement pénalisé.

La figure 8 de l’article montre une trajectoire échouée dont les deux dernières actions reçoivent une valeur identique de −2.20. Cette fin de trajectoire — après le dernier jalon, sans en atteindre un autre — est la forme mathématique de la stagnation. Elle est fréquente : les trajectoires qui accomplissent au moins un sous-objectif mais échouent à la tâche représentent de façon stable 39–47% des échantillons.

Une ablation écarte les déclencheurs fondés sur le nombre d’étapes

PartitionnementScorepar rapport à la référence (72.8)
Découpage aléatoire en 5 parties74.2+1.4
Jalons réels91.4+17.2

Découper selon un nombre arbitraire d’étapes apporte presque rien. Découper selon la structure réelle apporte beaucoup.

Revenons au critère de notre troisième niveau : 75% du budget de boucle d’outils consommé. C’est un déclencheur fondé sur un nombre arbitraire d’étapes. Il mesure ce qui a été dépensé, pas ce qui a été accompli. La bonne formulation est :

✗  if steps > N                              → intervene
✓  if steps > N AND zero verified milestones → intervene

La seconde ne se déclenchera pas à tort sur une tâche légitimement longue qui progresse, puisqu’elle atteint des jalons en chemin. La première, si.

Il existe aussi une boucle d’amplification

Mettons les constantes côte à côte. La compaction se déclenche à 82% de la fenêtre de contexte. La convergence de boucle improductive exige deux compactions et 75% du budget de boucle avant de se déclencher.

tourner en rond → le contexte se remplit → la compression se déclenche → l’état durable disparaît du résumé
                → reconstituer ce qui a été perdu → continuer à tourner en rond

Le détecteur déduit que l’Agent tourne en rond en observant des compactions répétées, alors que la compaction est précisément l’étape qui provoque l’amnésie. Il détecte un symptôme en aval et doit attendre que la boucle ait tourné deux fois.

Pire, son intervention consiste à inviter le modèle à se réancrer dans son état durable. Si cet état est précisément ce que la compaction a supprimé, il n’y a plus rien auquel se raccrocher. C’est un correctif dans la couche de prompt pour un problème de couche d’état.

Ce que nous ajoutons : la détection de stagnation côté sorties

Un quatrième niveau, construit autour de deux compteurs. Tous deux sont calculés mécaniquement à partir des observations d’outils déjà enregistrées par l’hôte ; aucun ne nécessite de jugement du modèle.

Étapes depuis le dernier jalon vérifié. L’indicateur de progrès le plus simple possible, utilisé dans le critère composé ci-dessus plutôt que seul.

Nouveaux changements d’état dédupliqués. Le plus utile des deux :

  • Une lecture de fichier dont l’empreinte du contenu correspond à une lecture précédente n’est pas une information nouvelle : relire le même fichier sur une autre plage de lignes ne change pas l’empreinte.
  • Une commande dont le nom, le code de sortie et l’empreinte du résultat correspondent tous à une exécution antérieure n’apporte pas d’information nouvelle.
  • Une écriture dont l’empreinte après exécution égale celle d’avant signifie que rien n’a réellement été écrit.

Ce compteur vise exactement le cas que manque la comparaison des signatures : chaque action est différente, le gain d’information est nul. Le critère est mécanique et n’exige aucune compréhension sémantique.

La pression doit ensuite être continue, plutôt que se limiter à un rappel :

afficher le compteur dans le contexte pour que le modèle le voie
  → imposer une révision du plan (reconnaître que cette voie est une impasse)
    → demander à l’utilisateur
      → abandonner, tout en préservant les jalons déjà atteints

Ce dernier palier compte. Si l’exécution doit s’arrêter, elle doit conserver ce qu’elle a acquis : ces mêmes 39–47% de progrès partiel dont l’article mesurait la perte.

Ce que l’article ne nous donne pas

BEACON est une méthode d’entraînement. Elle façonne les gradients pour que la politique entraînée erre moins, mais n’a aucun mécanisme propre de détection ou d’intervention à l’exécution. Elle fournit une définition du progrès, pas un contrôleur. C’est à nous de concevoir seuils, paliers d’escalade et conditions d’abandon.

Sa référence par étape exige aussi une longueur moyenne de segment dans un groupe. En production, une tâche utilisateur donnée ne s’exécute généralement qu’une fois : aucun groupe n’existe. Le meilleur substitut disponible est la statistique historique de tâches similaires, nettement plus bruitée et sans la garantie d’isolation de la variance de l’article.

La première étape consiste à mesurer, pas à corriger

Avant de changer une logique de décision, nous voulons instrumenter le système et répondre à une question encore sans réponse : parmi les stagnations en production, combien relèvent de l’amnésie et combien de l’absence de gradient ?

  • Si elles s’accompagnent surtout d’un gain d’information nul alors que les signatures d’appels diffèrent toutes → type sans gradient. Les trois niveaux existants ne peuvent structurellement pas le détecter ; la détection côté sorties est la solution.
  • Si elles s’accompagnent surtout de relectures de contenus déjà supprimés par la compaction → type amnésie. Il faut alors corriger ce que la compaction préserve.

Ces deux conclusions exigent des investissements complètement différents. Mesurer avant de concevoir coûte moins cher, et l’instrumentation est presque gratuite puisque les observations existent déjà.

Tout ce qui précède dépend d’une notion utilisée sans être définie : un jalon vérifié. La prochaine note porte sur ce point. Pourquoi déclarer une étape terminée ne prouve pas qu’elle l’est, quelles deux moitiés existent déjà dans le produit sans avoir été reliées, et un critère absent de l’article : regarder l’irréversibilité, pas l’importance.