Idea en 30 segundos
No Stop Conditions es un anti-patrón donde un agente se ejecuta sin condiciones claras de finalización.
Como resultado, el agente puede entrar en bucle y gastar presupuesto sin progreso real. Esto aumenta latency, cost y el riesgo de efectos secundarios (cambios de estado).
Regla simple: cada run del agente debe tener stop conditions explícitas para finalización exitosa y salida segura.
Ejemplo del anti-patrón
El equipo crea un agente de soporte que debe encontrar una respuesta en datos internos y devolver el resultado al usuario.
Pero en el loop del agente no hay stop conditions claras.
state = init_state(user_message)
while True:
decision = agent.next_step(state)
result = run_tool(decision.tool, decision.args)
state.append(result)
# no hay has_final_answer(...)
# no hay no_progress(...)
# no hay verificación de repeated_action(...)
En este esquema, el agente puede repetir indefinidamente pasos similares:
search_docs -> fetch_page -> summarize -> search_docs -> ...
Para este caso se necesita un loop controlado con límites explícitos:
for step in range(MAX_STEPS):
...
if has_final_answer(state):
return build_answer(state)
En este caso, la ausencia de stop conditions provoca:
- riesgo de runaway loop (bucle infinito)
- llamadas extra de tool y LLM
- consumo no controlado de tiempo y presupuesto
Por qué aparece y qué sale mal
Este anti-patrón aparece con frecuencia cuando el equipo confía en el modelo y espera que "entienda solo" cuándo detenerse.
Causas típicas:
- no existe
max_steps,timeoutni budget limit explícito - no está definido qué se considera "respuesta lista"
- no hay verificación de
no_progressni de acciones repetidas - el control de parada queda solo en el nivel de infraestructura
Esto produce problemas:
- bucles infinitos o largos - el agente repite pasos similares sin terminar
- mayor latency - la respuesta llega mucho más tarde o no llega
- mayor cost - crece el número de pasos LLM/tool por solicitud
- efectos secundarios (cambios de estado) - acciones repetidas pueden crear registros duplicados, volver a actualizar estado, duplicar API calls o reenviar acciones externas
- resultado inestable - una misma solicitud termina distinto según el run
Señales típicas de producción de que las stop conditions faltan o son débiles:
- una parte visible de los runs termina por timeout de infraestructura, no por parada controlada
- el
P95del número de pasos crece de forma continua - en las trazas se repiten llamadas idénticas con cambios mínimos en argumentos
- el
cost per requestcrece más rápido que elsuccess rate
Es importante que cada paso siguiente es parte de la inference del LLM. Si el loop no tiene condiciones claras de finalización, el modelo sigue eligiendo "un paso más" incluso cuando casi no hay información útil nueva.
Cuando este esquema crece, sin trace ni visualización de ejecución se vuelve difícil explicar por qué un run no se detuvo a tiempo. Por eso los sistemas de producción suelen tener una capa de observabilidad dedicada a los runs de agentes.
Enfoque correcto
Empieza con el loop controlado más simple que cubra de forma estable la mayoría de solicitudes actuales. Agrega nuevas stop conditions solo cuando exista un fallo medible, un riesgo o una limitación del diseño actual.
Marco práctico:
- define una condición positiva de finalización (
final_answer_ready) - define límites de protección (
max_steps,timeout,budget) - agrega verificaciones de
no_progressy acciones repetidas - registra stop reason para cada run y revisa métricas (por ejemplo, mejora de success rate sin aumento fuerte de latency y cost per request)
En práctica, no_progress suele significar repetición de los mismos tool-calls, cambios mínimos en estado o ausencia de información útil nueva tras un paso adicional.
MAX_STEPS = 8
def run_agent(user_message: str):
state = init_state(user_message)
for step in range(MAX_STEPS): # hard limit for runaway loops
if timed_out():
return stop("timeout")
if budget_exceeded():
return stop("budget_exceeded")
decision = agent.next_step(state)
if decision.type == "final_answer":
if validate_output(decision.output): # format, required fields, no empty answer
return decision.output
return stop("invalid_output")
result = run_tool(decision.tool, decision.args)
if no_progress(state, result): # same tool/result pattern or no meaningful state change
return stop("no_progress")
state.append(result)
return stop("max_steps_exceeded")
En este esquema, el loop se vuelve controlado: el sistema devuelve una respuesta válida o se detiene con una razón transparente.
Prueba rápida
Si estas preguntas se responden con "sí", tienes riesgo no-stop-conditions:
- ¿Una parte de los runs termina por timeout en vez de un
stop_reasoncontrolado? - ¿Una solicitud a veces hace una cantidad desproporcionada de pasos sin progreso visible?
- ¿Las trazas muestran repetición de acciones similares sin resultados nuevos?
Cómo se diferencia de otros anti-patterns
No Monitoring vs No Stop Conditions
| No Monitoring | No Stop Conditions |
|---|---|
| Problema principal: el sistema no tiene observabilidad suficiente para ver qué pasa durante un run. | Problema principal: en el loop del agente faltan condiciones claras de finalización. |
Cuándo aparece: cuando faltan logs a nivel run, trazas, métricas y stop_reason. | Cuándo aparece: cuando un run avanza sin max_steps, timeout, budget limit ni verificación no_progress. |
Agents Without Guardrails vs No Stop Conditions
| Agents Without Guardrails | No Stop Conditions |
|---|---|
| Problema principal: el agente opera sin policy boundaries ni límites de sistema. | Problema principal: el agente puede ejecutar bucles infinitos o demasiado largos. |
| Cuándo aparece: cuando no hay allowlist, deny-by-default, límites de budget o safety constraints. | Cuándo aparece: cuando la lógica del loop no tiene criterio explícito de finalización ni stop_reason controlado. |
Autoevaluación: ¿tienes este anti-patrón?
Revisión rápida del anti-pattern No Stop Conditions.
Marca los puntos para tu sistema y revisa el estado abajo.
Revisa tu sistema:
Progreso: 0/8
⚠ Hay señales de este anti-patrón
Intenta mover los pasos simples a un workflow y dejar el agente solo para decisiones complejas.
FAQ
Q: Si tenemos max_steps, ¿eso ya es suficiente?
A: No. max_steps es necesario, pero por sí solo no cubre todos los riesgos. También hacen falta timeout, budget limit, verificación de progreso y un criterio válido de respuesta lista.
Q: ¿Cuándo agregar una nueva stop condition?
A: Cuando exista una señal concreta: incidentes, bucles repetidos o aumento de cost o latency que las reglas actuales no cubren sin complejidad desproporcionada.
Q: ¿Cómo empezar si ahora casi no hay stop conditions?
A: Empieza con lo mínimo: max_steps, timeout, budget, stop_reason en logs. Luego agrega no_progress y validación de respuesta final.
Qué sigue
Anti-patterns relacionados:
- No Monitoring - cuando no ves que el agente entra en bucle o se degrada.
- Too Many Tools - cuando el exceso de herramientas aumenta la cantidad de pasos innecesarios.
- Overengineering Agents - cuando la complejidad extra dificulta controlar la finalización.
Qué construir en su lugar:
- Stop Conditions - modelo base para definir stop conditions seguras.
- Step Limits - cómo definir límites de pasos a nivel governance.
- Budget Controls - cómo limitar costos por run.
- Kill Switch - parada de emergencia cuando el sistema sale de control.