Tools
Detección de bucles de herramientas
OpenClaw dispone de dos mecanismos de protección que cooperan contra patrones repetitivos de llamadas a herramientas,
ambos configurados en tools.loopDetection:
- Detección de bucles (
enabled): desactivada de forma predeterminada. Supervisa el historial reciente de llamadas a herramientas para detectar patrones repetidos y reintentos de herramientas desconocidas. - Protección posterior a Compaction (
postCompactionGuard): activada siempre queenabledno sea explícitamentefalse. Se activa después de cada reintento de Compaction y cancela la ejecución si el agente repite la misma terna(tool, args, result)dentro de la ventana.
Establezca tools.loopDetection.enabled: false para desactivar ambos mecanismos de protección.
Por qué existe
- Detectar secuencias repetitivas que no producen ningún avance.
- Detectar bucles de alta frecuencia sin resultados (misma herramienta, mismas entradas y errores repetidos).
- Detectar patrones específicos de llamadas repetidas para herramientas de sondeo conocidas.
- Interrumpir los ciclos de desbordamiento de contexto -> Compaction -> mismo bucle, en lugar de permitir que se ejecuten indefinidamente.
Bloque de configuración
Valores predeterminados globales, con todos los campos documentados:
{ tools: { loopDetection: { enabled: false, // interruptor principal de los detectores basados en el historial reciente historySize: 30, warningThreshold: 10, criticalThreshold: 20, unknownToolThreshold: 10, globalCircuitBreakerThreshold: 30, detectors: { genericRepeat: true, knownPollNoProgress: true, pingPong: true, }, postCompactionGuard: { windowSize: 3, // se activa tras un reintento de Compaction; se ejecuta salvo que enabled sea explícitamente false }, }, },}Anulación por agente (opcional, en agents.list[].tools.loopDetection):
{ agents: { list: [ { id: "safe-runner", tools: { loopDetection: { enabled: true, warningThreshold: 8, criticalThreshold: 16, }, }, }, ], },}La configuración de cada agente se superpone al bloque global campo por campo (incluidos
detectors y postCompactionGuard anidados), por lo que un agente solo necesita definir los
campos que desea modificar.
Comportamiento de los campos
| Campo | Valor predeterminado | Efecto |
|---|---|---|
enabled |
false |
Interruptor principal de los detectores basados en el historial reciente. false también desactiva la protección posterior a Compaction. |
historySize |
30 |
Número de llamadas recientes a herramientas que se conservan para su análisis. |
warningThreshold |
10 |
Número de repeticiones antes de que un patrón se clasifique únicamente como advertencia. |
criticalThreshold |
20 |
Número de repeticiones necesario para bloquear un patrón de bucle sin avances. Si la configuración es incorrecta, el entorno de ejecución lo ajusta por encima de warningThreshold. |
unknownToolThreshold |
10 |
Bloquea las llamadas repetidas a la misma herramienta no disponible después de este número de fallos. No depende de detectors. |
globalCircuitBreakerThreshold |
30 |
Interruptor global de bucles sin avances para todos los detectores. Si la configuración es incorrecta, el entorno de ejecución lo ajusta por encima de criticalThreshold. No depende de detectors. |
detectors.genericRepeat |
true |
Advierte sobre llamadas repetidas con la misma herramienta y los mismos argumentos; las bloquea cuando también devuelven resultados idénticos. |
detectors.knownPollNoProgress |
true |
Detecta patrones conocidos de sondeo sin avances (process con action: "poll"/"log", command_status). |
detectors.pingPong |
true |
Detecta patrones alternos de ping-pong sin avances entre dos llamadas. |
postCompactionGuard.windowSize |
3 |
Número de intentos durante los que la protección permanece activa después de Compaction y número de ternas idénticas que cancela la ejecución. |
Para exec, el hash de ausencia de avances compara resultados estables del comando (estado,
código de salida, indicador de tiempo agotado y salida) e ignora metadatos volátiles del entorno de ejecución, como
la duración, el PID, el identificador de sesión y el directorio de trabajo. Los resultados del envío de mensajes
salientes se procesan mediante hash después de eliminar los identificadores volátiles de cada llamada (identificador del mensaje, identificador del archivo y marca de tiempo),
de modo que un resultado "enviado" no parezca idéntico a otro resultado "enviado"
distinto. Cuando hay un identificador de ejecución disponible, el historial solo se evalúa dentro de esa ejecución,
por lo que los ciclos programados de Heartbeat y las ejecuciones nuevas no heredan recuentos de bucles obsoletos
de ejecuciones anteriores.
Configuración recomendada
- Para modelos más pequeños, establezca
enabled: truey conserve los umbrales predeterminados. Los modelos principales rara vez necesitan detección basada en el historial reciente y pueden mantener el interruptor principal enfalsesin dejar de beneficiarse de la protección posterior a Compaction. - Mantenga los umbrales ordenados como
warningThreshold < criticalThreshold < globalCircuitBreakerThreshold; el entorno de ejecución incrementacriticalThresholdyglobalCircuitBreakerThresholdsi los establece en un valor igual o inferior al umbral que deben superar. - Si se producen falsos positivos:
- Aumente
warningThresholdocriticalThreshold, o ambos. - Opcionalmente, aumente
globalCircuitBreakerThreshold. - Desactive únicamente el detector específico que cause problemas (
detectors.<name>: false). - Reduzca
historySizepara acortar la ventana del historial.
- Aumente
- Para desactivar todo, incluida la protección posterior a Compaction, establezca
explícitamente
tools.loopDetection.enabled: false.
Protección posterior a Compaction
Después de un reintento de Compaction tras un desbordamiento de contexto, el ejecutor activa una
protección de ventana corta para las siguientes llamadas a herramientas. Si el agente emite la misma
terna (toolName, argsHash, resultHash) postCompactionGuard.windowSize
veces dentro de esa ventana, la protección concluye que Compaction no interrumpió el
bucle y cancela la ejecución con un error compaction_loop_persisted.
La protección está controlada por el indicador principal tools.loopDetection.enabled, con una
particularidad: permanece activada cuando el indicador no está definido o es true y solo se
desactiva cuando el indicador es explícitamente false. Esto es intencional: la protección
existe para salir de bucles de Compaction que, de otro modo, consumirían una cantidad ilimitada de tokens,
por lo que un usuario sin configuración también recibe esta protección.
{ tools: { loopDetection: { // interruptor principal; establézcalo en false para desactivar la protección junto con los detectores basados en el historial reciente enabled: true, postCompactionGuard: { windowSize: 3, // valor predeterminado }, }, },}- Un valor menor de
windowSizees más estricto (menos intentos antes de la cancelación). - Un valor mayor de
windowSizeproporciona al agente más intentos de recuperación. - La protección nunca cancela la ejecución mientras los resultados cambien; solo la activan los resultados idénticos byte por byte en toda la ventana.
- Solo se activa inmediatamente después de un reintento de Compaction, no en otros puntos de una ejecución.
Registros y comportamiento esperado
Cuando se detecta un bucle, OpenClaw registra un evento de bucle y advierte o bloquea el siguiente ciclo de herramientas según la gravedad, lo que protege frente al consumo descontrolado de tokens y los bloqueos, a la vez que conserva el acceso normal a las herramientas.
- Primero se emiten advertencias.
- El bloqueo se produce cuando el patrón persiste más allá del umbral de advertencia.
- Los umbrales críticos bloquean el siguiente ciclo de herramientas y muestran un motivo claro de detección de bucle en el registro de la ejecución.
- La protección posterior a Compaction emite errores
compaction_loop_persistedque indican la herramienta responsable y el número de llamadas idénticas.
Temas relacionados
Política de autorización y denegación para la ejecución en el shell.
Niveles de esfuerzo de razonamiento e interacción con las políticas del proveedor.
Creación de agentes aislados para limitar comportamientos descontrolados.
Esquema completo de tools.loopDetection y semántica de combinación.