Tools
Rilevamento dei cicli degli strumenti
OpenClaw dispone di due meccanismi di protezione cooperanti contro gli schemi ripetitivi di chiamate agli strumenti,
entrambi configurati in tools.loopDetection:
- Rilevamento dei cicli (
enabled) - disabilitato per impostazione predefinita. Monitora la cronologia mobile delle chiamate agli strumenti per individuare schemi ripetuti e nuovi tentativi con strumenti sconosciuti. - Protezione post-Compaction (
postCompactionGuard) - abilitata ogni volta cheenablednon è esplicitamentefalse. Si attiva dopo ogni nuovo tentativo successivo alla Compaction e interrompe l'esecuzione se l'agente ripete la stessa terna(tool, args, result)entro la finestra.
Imposta tools.loopDetection.enabled: false per disattivare entrambi i meccanismi di protezione.
Perché esiste
- Rilevare sequenze ripetitive che non producono progressi.
- Rilevare cicli ad alta frequenza senza risultati (stesso strumento, stessi input, errori ripetuti).
- Rilevare specifici schemi di chiamate ripetute per strumenti di polling noti.
- Interrompere i cicli overflow del contesto -> Compaction -> stesso ciclo, invece di lasciarli proseguire indefinitamente.
Blocco di configurazione
Valori predefiniti globali, con tutti i campi documentati:
{ 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 }, }, },}Sostituzione per singolo agente (facoltativa, in agents.list[].tools.loopDetection):
{ agents: { list: [ { id: "safe-runner", tools: { loopDetection: { enabled: true, warningThreshold: 8, criticalThreshold: 16, }, }, }, ], },}Le impostazioni per singolo agente si sovrappongono al blocco globale campo per campo (inclusi
detectors e postCompactionGuard annidati), quindi un agente deve impostare solo i
campi che desidera modificare.
Comportamento dei campi
| Campo | Valore predefinito | Effetto |
|---|---|---|
enabled |
false |
Interruttore principale per i rilevatori basati sulla cronologia mobile. false disabilita anche la protezione post-Compaction. |
historySize |
30 |
Numero di chiamate recenti agli strumenti conservate per l'analisi. |
warningThreshold |
10 |
Numero di ripetizioni dopo il quale uno schema viene classificato come semplice avviso. |
criticalThreshold |
20 |
Numero di ripetizioni che determina il blocco di uno schema ciclico senza progressi. In caso di configurazione errata, il runtime lo limita a un valore superiore a warningThreshold. |
unknownToolThreshold |
10 |
Blocca le chiamate ripetute allo stesso strumento non disponibile dopo questo numero di tentativi falliti. Non è controllato da detectors. |
globalCircuitBreakerThreshold |
30 |
Interruttore globale per l'assenza di progressi, applicato a tutti i rilevatori. In caso di configurazione errata, il runtime lo limita a un valore superiore a criticalThreshold. Non è controllato da detectors. |
detectors.genericRepeat |
true |
Avvisa in caso di chiamate ripetute con lo stesso strumento e gli stessi argomenti; le blocca quando restituiscono anche risultati identici. |
detectors.knownPollNoProgress |
true |
Rileva schemi noti di polling senza progressi (process con action: "poll"/"log", command_status). |
detectors.pingPong |
true |
Rileva schemi ping-pong alternati senza progressi tra due chiamate. |
postCompactionGuard.windowSize |
3 |
Numero di tentativi per cui la protezione resta attiva dopo la Compaction e numero di terne identiche che interrompe l'esecuzione. |
Per exec, l'hashing dell'assenza di progressi confronta risultati stabili dei comandi (stato,
codice di uscita, indicatore di timeout, output) e ignora metadati volatili del runtime come
durata, PID, ID sessione e directory di lavoro. L'hashing dei risultati dell'invio di messaggi
in uscita rimuove gli ID volatili specifici di ogni chiamata (ID messaggio, ID file, timestamp),
affinché un risultato "inviato" non appaia identico a un altro risultato "inviato".
Quando è disponibile un ID esecuzione, la cronologia viene valutata solo all'interno di tale esecuzione,
quindi i cicli Heartbeat pianificati e le nuove esecuzioni non ereditano conteggi obsoleti dei cicli
dalle esecuzioni precedenti.
Configurazione consigliata
- Per i modelli più piccoli, imposta
enabled: truee lascia le soglie ai valori predefiniti. I modelli di punta raramente necessitano del rilevamento basato sulla cronologia mobile e possono lasciare l'interruttore principale sufalse, continuando comunque a beneficiare della protezione post-Compaction. - Mantieni le soglie nell'ordine
warningThreshold < criticalThreshold < globalCircuitBreakerThreshold; il runtime aumentacriticalThresholdeglobalCircuitBreakerThresholdse vengono impostate a un valore uguale o inferiore alla soglia che devono superare. - Se si verificano falsi positivi:
- Aumenta
warningThresholde/ocriticalThreshold. - Facoltativamente, aumenta
globalCircuitBreakerThreshold. - Disabilita solo il rilevatore specifico che causa problemi (
detectors.<name>: false). - Riduci
historySizeper ottenere una finestra cronologica più breve.
- Aumenta
- Per disabilitare tutto, inclusa la protezione post-Compaction, imposta
esplicitamente
tools.loopDetection.enabled: false.
Protezione post-Compaction
Dopo un nuovo tentativo di Compaction successivo a un overflow del contesto, l'esecutore attiva una
protezione a finestra breve per le chiamate agli strumenti immediatamente successive. Se l'agente emette la stessa
terna (toolName, argsHash, resultHash) per postCompactionGuard.windowSize
volte entro tale finestra, la protezione conclude che la Compaction non ha interrotto il
ciclo e termina l'esecuzione con un errore compaction_loop_persisted.
La protezione è controllata dal flag principale tools.loopDetection.enabled, con una
particolarità: rimane abilitata quando il flag non è impostato o è true e viene
disattivata solo quando il flag è esplicitamente false. Questo comportamento è intenzionale: la protezione
serve a interrompere i cicli di Compaction che altrimenti consumerebbero una quantità illimitata di token,
quindi anche un utente senza configurazione beneficia della protezione.
{ tools: { loopDetection: { // master switch; set false to disable the guard along with the rolling detectors enabled: true, postCompactionGuard: { windowSize: 3, // default }, }, },}- Un valore
windowSizeinferiore è più restrittivo (meno tentativi prima dell'interruzione). - Un valore
windowSizesuperiore concede all'agente più tentativi di recupero. - La protezione non interrompe mai l'esecuzione finché i risultati cambiano; si attiva solo con risultati identici byte per byte nell'intera finestra.
- Si attiva esclusivamente subito dopo un nuovo tentativo di Compaction, non in altri momenti dell'esecuzione.
Log e comportamento previsto
Quando viene rilevato un ciclo, OpenClaw registra un evento di ciclo e genera un avviso oppure blocca il ciclo successivo dello strumento in base alla gravità, proteggendo dal consumo incontrollato di token e dai blocchi, senza compromettere il normale accesso agli strumenti.
- Gli avvisi vengono emessi per primi.
- Il blocco avviene quando uno schema persiste oltre la soglia di avviso.
- Le soglie critiche bloccano il ciclo successivo dello strumento e mostrano chiaramente il motivo del rilevamento del ciclo nel record dell'esecuzione.
- La protezione post-Compaction genera errori
compaction_loop_persistedche indicano lo strumento responsabile e il numero di chiamate identiche.
Argomenti correlati
Criteri di autorizzazione e rifiuto per l'esecuzione nella shell.
Livelli di impegno del ragionamento e interazione con i criteri del provider.
Creazione di agenti isolati per limitare comportamenti incontrollati.
Schema completo di tools.loopDetection e semantica dell'unione.