Idea en 30 segundos
Step limits es un control de runtime que detiene a la fuerza un run cuando el agente entra en bucle o no muestra progreso.
Cuándo se necesita: cuando un agente trabaja en loop, interactúa con tools y puede repetir las mismas acciones en producción.
Problema
Sin step limits, un agente suele "hacer algo" pero no avanzar hacia el resultado. En demos puede parecer normal. En producción eso se convierte rápido en costo, latencia y ruido en logs.
Patrón típico:
- una respuesta de tool inestable
- repetición de la misma acción
- otra repetición
- y el mismo ciclo otra vez
Analogía: es como un navegador que repite la ruta en la misma intersección. El auto se mueve, pero no se acerca al destino.
Para evitar que esto se convierta en incidente, los límites deben estar en el runtime loop, no en UI ni en el prompt.
Solución
La solución es mover el control de steps a una capa policy en nivel runtime. Cada step se verifica después de formar la siguiente acción, pero antes de ejecutarla.
El policy layer devuelve una de estas decisiones:
allowstop (reason=max_steps)stop (reason=loop_detected)stop (reason=no_progress)
Esta es una capa separada del sistema, no parte del prompt ni de la lógica del modelo.
Step limits ≠ Budget controls
Son capas de control distintas:
- Step limits controlan el comportamiento del bucle (cuántos y qué pasos ejecuta el agente)
- Budget controls controlan recursos del run (tiempo, dinero, cantidad de acciones)
Uno sin el otro no alcanza:
- sin step limits, un bucle puede correr mucho tiempo sin progreso
- sin budget controls, incluso un bucle "limitado" puede ser costoso
Ejemplo:
- step limits:
max_steps=18,max_repeat_action=3 - budget controls:
max_seconds=45,max_usd=1.00
Métricas de control de steps
Estas verificaciones trabajan juntas en cada paso del agente.
| Métrica | Qué controla | Mecánicas clave | Para qué |
|---|---|---|---|
| Step cap | Longitud máxima del run | max_stepscontador de pasos en runtime | Detiene un bucle infinito antes de que crezca el costo |
| Repeat-action control | Repetición de la misma acción | max_repeat_actionclave tool + args | Detecta loops donde el agente repite la misma llamada |
| No-progress control | Situaciones sin progreso real | no_progress_windowrevisión de cambios de estado | Detiene el run cuando hay pasos pero no hay progreso |
| Stop reason surfacing | Transparencia de la causa de parada | stop reason explícitopartial response | Usuario y equipo ven por qué se detuvo el run |
Cómo se ve en la arquitectura
La capa step policy se ubica en el runtime loop entre planificación y ejecución de acción.
Cada decisión (allow o stop) se registra en audit log.
Cada paso del agente pasa por este flow antes de ejecutarse: runtime no ejecuta la siguiente acción directamente, primero pasa los step-checks.
Resumen del flow:
- Runtime forma la siguiente acción
- Step policy layer verifica
max_steps, repeticiones y progreso allow-> se ejecuta la siguiente acción del agentestop-> se devuelven stop reason + partial response- ambas decisiones se escriben en audit log
Ejemplo
Un agente de soporte llama search.docs muchas veces por una respuesta externa inestable.
Con step limits:
max_steps = 18max_repeat_action = 3no_progress_window = 4
-> el run se detiene con un stop reason explícito en lugar de seguir en loop infinito.
La política de step limits detiene el incidente en nivel de runtime loop, no dependiendo del comportamiento del modelo.
En código se ve así
El esquema simplificado de arriba muestra el control flow principal. En práctica, los step-checks se ejecutan de forma centralizada antes de cada acción.
Ejemplo de configuración step:
step_limits:
max_steps: 18
max_repeat_action: 3
no_progress_window: 4
while True:
# Aquí, un paso se cuenta como intención de acción, no como acción ya ejecutada.
state = state.with_step_increment()
action = planner.next(state) # planner forma la acción para este paso
repeat_key = make_repeat_key(action.name, action.args) # clave normalizada tool+args
decision = step_policy.check(state, action, repeat_key=repeat_key)
if decision.outcome == "stop":
audit.log(
run_id,
decision.outcome,
reason=decision.reason,
step=state.steps,
action=action.name,
repeat_key=repeat_key,
)
return stop(decision.reason)
result = tool.execute(action.args)
state = state.apply(action, result)
decision = Decision.allow(reason="step_ok")
audit.log(
run_id,
decision.outcome,
reason=decision.reason,
step=state.steps,
action=action.name,
repeat_key=repeat_key,
result=result.status,
)
if result.final:
return result
Step policy suele verificar tres señales: límite de pasos, repetición de acciones y ausencia de progreso.
Para loop detection se usa clave tool+args, no solo action.name.
Cómo se ve durante la ejecución
Escenario 1: se alcanzó max_steps
- Runtime forma el paso 19 e incrementa el contador.
- Policy detecta exceso de
max_steps. - Decisión:
stop (reason=max_steps). - La causa de parada se escribe en audit log.
- El usuario recibe una partial response.
Escenario 2: loop detectado
- Runtime forma
search.docsvarias veces con los mismos args. - Policy cuenta repeticiones por
tool+args. - Decisión:
stop (reason=loop_detected). - El run se detiene antes de otra llamada innecesaria.
- En logs se ve causa exacta y acción.
Escenario 3: ejecución normal
- Runtime forma un paso nuevo.
- Policy verifica límites: todo dentro de rango.
- Decisión:
allow. - Se ejecuta la siguiente acción del agente.
- Resultado y decisión se registran en audit log.
Errores típicos
- poner
max_stepssolo en UI y no en runtime loop - no devolver stop reason explícito en la respuesta
- contar solo tool calls e ignorar pasos
- no verificar repeticiones (
tool + args) y no-progress - loguear solo pasos exitosos sin decisiones stop
- poner
max_stepsdemasiado alto "por si acaso"
Resultado: el run parece activo, pero el bucle crece más rápido que la visibilidad del equipo.
Autoevaluación
Chequeo rápido de step limits antes de lanzar a producción:
Progreso: 0/8
⚠ Faltan controles base de governance
Antes de production necesitas como mínimo control de acceso, límites, audit logs y parada de emergencia.
FAQ
P: ¿Con qué max_steps debería empezar?
R: Para la mayoría de runs síncronos, empieza con 15-25. Luego ajusta según frecuencia de eventos stop en escenarios reales.
P: ¿Solo max_steps alcanza?
R: No. Como mínimo agrega max_repeat_action y control no-progress. En producción también necesitas budgets (max_seconds, max_usd, max_tool_calls).
P: ¿Qué importa más: repeat detection o no-progress?
R: Ambos. Repeat detection captura repeticiones explícitas; no-progress captura loops "suaves" donde cambian acciones pero no hay progreso.
P: ¿Qué debe ver el usuario cuando se detiene el run?
R: Partial response + stop reason explícito + una acción siguiente breve (reformular solicitud o relanzar con otro scope).
P: ¿Step limits reemplaza kill switch?
R: No. Step limits gobierna cada run, kill switch sirve para parada global de emergencia.
Dónde encaja Step Limits en el sistema
Step limits es una de las capas de Agent Governance. Junto con RBAC, budgets, approval y audit, forman un sistema unificado de control de ejecución.
Páginas relacionadas
Siguiente sobre este tema:
- Resumen de Agent Governance — modelo general de control de agentes en producción.
- Budget Controls — cómo limitar tiempo, acciones y costo.
- Rate limiting para agentes — cómo limitar frecuencia de solicitudes a tools y API.
- Kill switch — cómo detener un agente de forma urgente durante un incidente.
- Infinite loop — failure mode típico de bucles y cómo detectarlo.