Aller au contenu

Détection de boucle d'outils

OpenClaw dispose de deux garde-fous coopératifs pour les modèles d’appels d’outils répétitifs :

  1. Détection de boucle (tools.loopDetection.enabled) — désactivée par défaut. Surveille l’historique déroulant des appels d’outils pour détecter les modèles répétitifs et les tentatives sur des outils inconnus.
  2. Garde-fou post-compaction (tools.loopDetection.postCompactionGuard) — activé par défaut sauf si tools.loopDetection.enabled est explicitement false. S’arme après chaque nouvelle tentative de compactage et abandonne l’exécution lorsque l’agent émet le même triplet (tool, args, result) dans la fenêtre.

Les deux sont configurés dans le même bloc tools.loopDetection, mais le garde-fou post-compaction s’exécute tant que le commutateur principal n’est pas explicitement désactivé. Définissez tools.loopDetection.enabled: false pour désactiver les deux surfaces.

  • Détecter les séquences répétitives qui ne progressent pas.
  • Détecter les boucles sans résultat à haute fréquence (même outil, mêmes entrées, erreurs répétées).
  • Détecter des modèles d’appels répétés spécifiques pour les outils de sondage connus.
  • Empêcher les cycles de débordement de contexte suivis d’une compactage puis de la même boucle de s’exécuter indéfiniment.

Valeurs globales par défaut, avec chaque champ documenté affiché :

{
tools: {
loopDetection: {
enabled: false, // master switch for the rolling-history detectors
historySize: 30,
warningThreshold: 10,
criticalThreshold: 20,
unknownToolThreshold: 10,
globalCircuitBreakerThreshold: 30,
detectors: {
genericRepeat: true,
knownPollNoProgress: true,
pingPong: true,
},
postCompactionGuard: {
windowSize: 3, // armed after compaction-retry; runs unless enabled is explicitly false
},
},
},
}

Remplacement par agent (facultatif) :

{
agents: {
list: [
{
id: "safe-runner",
tools: {
loopDetection: {
enabled: true,
warningThreshold: 8,
criticalThreshold: 16,
},
},
},
],
},
}
ChampPar défautEffet
enabledfalseCommutateur principal pour les détecteurs d’historique déroulant. Le réglage de false désactive également le garde-fou post-compaction.
historySize30Nombre d’appels d’outils récents conservés pour analyse.
warningThreshold10Seuil avant qu’un modèle ne soit classé comme avertissement uniquement.
criticalThreshold20Seuil pour bloquer les modèles de boucle répétitifs sans progrès.
unknownToolThreshold10Bloquer les appels répétés au même outil indisponible après ce nombre d’échecs.
globalCircuitBreakerThreshold30Seuil global de rupture sans progrès pour tous les détecteurs.
detectors.genericRepeattrueAvertit en cas de modèles répétés de même tool + mêmes paramètres et bloque lorsque les mêmes appels renvoient également des résultats identiques.
detectors.knownPollNoProgresstrueDétecte les modèles de type polling connus sans changement d’état.
detectors.pingPongtrueDétecte les modèles alternés de ping-pong.
postCompactionGuard.windowSize3Nombre d’appels de tool post-compaction pendant lesquels la garde reste armée et le nombre de triplets identiques qui interrompt l’exécution.

Pour exec, les vérifications d’absence de progrès comparent les résultats stables des commandes et ignorent les métadonnées d’exécution volatiles telles que la durée, le PID, l’ID de session et le répertoire de travail. Lorsqu’un ID d’exécution est disponible, l’historique récent des appels de tool n’est évalué que dans cette exécution, afin que les cycles de heartbeat planifiés et les nouvelles exécutions n’héritent pas de comptes de boucles périmés des exécutions précédentes.

  • Pour les modèles plus petits, définissez enabled: true et laissez les seuils à leurs valeurs par défaut. Les modèles phares ont rarement besoin de la détection par historique déroulant et peuvent laisser le commutateur principal sur false tout en bénéficiant toujours de la garde post-compaction.
  • Gardez les seuils ordonnés comme warningThreshold < criticalThreshold < globalCircuitBreakerThreshold.
  • En cas de faux positifs :
    • Augmentez warningThreshold et/ou criticalThreshold.
    • Augmentez facultativement globalCircuitBreakerThreshold.
    • Désactivez uniquement le détecteur spécifique posant problème (detectors.<name>: false).
    • Réduisez historySize pour un contexte historique moins strict.
  • Pour tout désactiver (y compris la garde post-compaction), définissez tools.loopDetection.enabled: false explicitement.

Lorsque le lanceur complète une nouvelle tentative de compaction après un dépassement de contexte, il arme une garde à fenêtre courte qui surveille les prochains appels de tool. Si l’agent émet le même triplet (toolName, argsHash, resultHash) plusieurs fois dans la fenêtre, la garde conclut que la compaction n’a pas brisé la boucle et interrompt l’exécution avec une erreur compaction_loop_persisted.

La garde est contrôlée par le fanion maître tools.loopDetection.enabled avec une nuance : elle reste activée lorsque le fanion est non défini ou true et ne se désactive que lorsque le fanion est explicitement false. C’est intentionnel. La garde sert à échapper aux boucles de compactage qui, autrement, consommeraient des tokens illimités, un utilisateur sans configuration bénéficie donc de cette protection.

{
tools: {
loopDetection: {
// master switch; set false to disable the guard along with the rolling detectors
enabled: true,
postCompactionGuard: {
windowSize: 3, // default
},
},
},
}
  • Un windowSize plus bas est plus strict (moins de tentatives avant l’abandon).
  • Un windowSize plus élevé donne à l’agent plus de tentatives de récupération.
  • La garde n’interrompt jamais l’exécution lorsque les résultats changent, uniquement lorsque les résultats sont identiques octet par octet sur la fenêtre.
  • Elle est volontairement étroite : elle ne se déclenche que dans la foulée immédiate d’une nouvelle tentative après compactage.

Lorsqu’une boucle est détectée, OpenClaw signale un événement de boucle et atténue ou bloque le prochain cycle d’outil en fonction de la gravité. Cela protège les utilisateurs contre des dépenses de tokens incontrôlées et des blocages tout en préservant l’accès normal aux outils.

  • Les avertissements viennent en premier.
  • La suppression intervient lorsque les modèles persistent au-delà du seuil d’avertissement.
  • Les seuils critiques bloquent le prochain cycle d’outil et affichent une raison claire de détection de boucle dans l’enregistrement d’exécution.
  • La garde post-compaction émet des erreurs compaction_loop_persisted avec le nom de l’outil en faute et le nombre d’appels identiques.
Approbations d'exécution

Stratégie d’autorisation/refus pour l’exécution de shell.

Niveaux de réflexion

Niveaux d’effort de raisonnement et interaction avec la stratégie du fournisseur.

Sous-agents

Création d’agents isolés pour limiter les comportements incontrôlables.

Référence de configuration

Schéma complet tools.loopDetection et sémantique de fusion.