# Detén llamadas repetidas y bucles de agentes

Aplica un límite de pasos y detecta llamadas idénticas mediante registros de la aplicación.

## Define cuándo detener el flujo

Un modelo puede proponer la misma llamada varias veces cuando falta un resultado o no lo entiende. Pon un límite en la aplicación que ejecuta el bucle. No dependas únicamente de que la siguiente respuesta del modelo decida detenerse.

Empieza con dos reglas: un máximo de pasos por ejecución y un máximo de llamadas idénticas consecutivas. Ajusta los límites a tu proceso. Repetir una lectura puede ser útil; repetir una escritura puede tener consecuencias. Este ejemplo local detiene una operación antes de ejecutarla y no llama a MandAPI ni a herramientas.

## Comprueba las llamadas antes de ejecutarlas

Normaliza la acción y los argumentos, y calcula un hash de su representación. Incluye solo campos que definan la operación. Fechas de solicitud o identificadores aleatorios harían que operaciones equivalentes parecieran distintas.

```python
import hashlib
import json

class LoopGuard:
    def __init__(self, max_steps=8, max_identical=2):
        self.max_steps = max_steps
        self.max_identical = max_identical
        self.steps = 0
        self.last = None
        self.repeated = 0

    def check(self, name, arguments):
        if self.steps >= self.max_steps:
            raise RuntimeError("Limite de pasos alcanzado")
        raw = json.dumps(
            {"name": name, "arguments": arguments},
            sort_keys=True, separators=(",", ":"),
        )
        fingerprint = hashlib.sha256(raw.encode()).hexdigest()
        self.repeated = self.repeated + 1 if fingerprint == self.last else 1
        self.last = fingerprint
        if self.repeated > self.max_identical:
            raise RuntimeError("Operacion repetida detenida")
        self.steps += 1
        return {"step": self.steps, "fingerprint": fingerprint}

guard = LoopGuard()
print(guard.check("lookup_order", {"order_id": "demo-001"}))
print(guard.check("lookup_order", {"order_id": "demo-001"}))
try:
    guard.check("lookup_order", {"order_id": "demo-001"})
except RuntimeError as error:
    print(error)
```

## Conéctalo al bucle del modelo

Aplica la comprobación después de validar la propuesta y antes de ejecutar la operación. Guarda el registro con el identificador de ejecución, resultado y motivo de parada. Cuando se detenga, devuelve una explicación o deriva la tarea a una persona. Las reglas pertenecen a tu aplicación; no intervienen una Decisions API ni puntuaciones de confianza.

## Comprueba el resultado

La demostración permite dos consultas idénticas y detiene la tercera. Prueba también llamadas diferentes hasta alcanzar el máximo de pasos. El hash detecta repetición exacta normalizada, no equivalencia semántica; mantén el límite de pasos como control independiente.

## Referencias

- [https://openrouter.ai/docs/cookbook/building-agents/detect-agent-loops-with-scaledown](https://openrouter.ai/docs/cookbook/building-agents/detect-agent-loops-with-scaledown)
