Un agente de IA puede parecer ocupado mientras repite la misma herramienta, vuelve al mismo subagente o recibe el mismo error en cada turno. El problema no es solo la factura de la API. El bucle también aumenta el contexto, retrasa la respuesta y dificulta saber si la tarea terminó o simplemente agotó el presupuesto.

La solución es hacer que la terminación forme parte del runtime. Combina una condición de finalización, un límite de pasos, un presupuesto de tiempo o tokens y una señal de progreso. Cuando una de esas barreras termina la ejecución, registra un motivo terminal que otra ejecución pueda entender. El modelo puede sugerir que terminó, pero el código debe comprobar la condición.

Este artículo muestra la política en TypeScript sin llamar a un proveedor real. El fragmento es ilustrativo y usa adapters abstractos. Una implementación de producción debe conectar los límites con tu SDK, tus herramientas y tu almacenamiento.

Diagrama que muestra un bucle de agente de IA pasando por una herramienta, progreso y presupuesto antes de detenerse.

Respuesta corta

  • Detén el agente cuando haya una finalización válida, no haya progreso, se agote el presupuesto o aparezca un error irrecuperable.
  • Un límite de pasos evita un bucle infinito, pero no identifica repeticiones ni demuestra que la respuesta sea correcta.
  • Cuenta los pasos de la ejecución y las llamadas por herramienta. Comparte el mismo plazo y presupuesto entre reintentos.
  • Registra completed, budget_exceeded, no_progress o failed como estados distintos.

¿Qué cuenta como un bucle infinito en un agente?

En 2026, el artículo "When Agents Do Not Stop" analizó 6.549 repositorios de agentes y confirmó manualmente 68 fallos de bucle infinito en 47 proyectos, con una precisión del 91,9% para los hallazgos publicados (arXiv, "When Agents Do Not Stop: Uncovering Infinite Agentic Loops in LLM Agents", 2026). El resultado no dice que toda ejecución larga sea defectuosa. Muestra por qué el camino de retorno también necesita un límite verificable.

Una ejecución larga puede estar avanzando. Un agente que revisa páginas nuevas, espera una operación o corrige una prueba puede necesitar varios turnos. El bucle se vuelve sospechoso cuando el estado no cambia, el resultado no aporta evidencia o la misma transición ocurre de nuevo sin una decisión nueva.

Observa estas señales juntas:

  1. La herramienta recibe el mismo nombre y argumentos, o argumentos distintos que llevan al mismo estado.
  2. El historial crece, pero la tarea no tiene una condición de finalización comprobable.
  3. El runtime repite una operación después de un error sin cambiar su contexto, política o recurso.

Una comprobación de repetición no debe bloquear todo polling. Consultar el estado de un job puede ser correcto mientras el estado externo siga en running. La pregunta es si cada comprobación puede cambiar la siguiente decisión. Si no puede, la ejecución debe detenerse o pedir intervención.

¿Por qué no basta con limitar los pasos?

En 2026, el OpenAI Agents SDK documenta maxTurns con un valor predeterminado de 10 y lanza MaxTurnsExceededError al alcanzar el límite (OpenAI Agents SDK, "Running Agents", consultado el 28/08/2026). En el mismo periodo, AI SDK documenta stopWhen y stepCountIs, con 20 pasos como valor predeterminado de ToolLoopAgent (Vercel AI SDK, "Agents: Loop Control", consultado el 28/08/2026). Son valores predeterminados de bibliotecas, no recomendaciones universales.

Un límite duro es la última barrera. Protege contra una condición de finalización que nunca se vuelve verdadera, pero puede cortar una tarea que todavía avanzaba. Tampoco impide que una herramienta cara se ejecute varias veces dentro de un turno ni distingue el progreso real de otra respuesta con el mismo contenido.

Separa al menos estos presupuestos:

  • Pasos de la ejecución: cuántas decisiones del agente pueden ocurrir.
  • Llamadas por herramienta: cuántas veces puede ejecutarse una herramienta en la misma tarea.
  • Tiempo restante: cuánto queda del plazo compartido.
  • Tokens o coste: cuánto se puede gastar antes de otra llamada.

El presupuesto debe consumirse en toda la ejecución. Si cada reintento crea un contador local nuevo, el agente puede respetar cada límite local y aun así superar el global. El resultado del límite también debe ser explícito. failed es distinto de budget_exceeded, que es distinto de completed.

¿Qué condiciones deben terminar el bucle?

En 2026, la guía de arquitectura de agentes de Google Cloud describe dos formas de salida para un patrón de bucle: un número máximo de iteraciones o un estado personalizado. La misma guía advierte que una condición de finalización mal definida puede dejar el bucle ejecutándose para siempre (Google Cloud, "Choose a design pattern for your agentic AI system", consultado el 28/08/2026). Usa ambas capas.

Una política pequeña puede evaluar las condiciones en este orden:

  1. Finalización: ¿la salida contiene el resultado esperado y pasa la validación de la aplicación?
  2. Seguridad: ¿la siguiente llamada está permitida para esta fase y este recurso?
  3. Progreso: ¿cambiaron el estado, la evidencia o la decisión desde el último turno?
  4. Presupuesto: ¿siguen disponibles los pasos, el tiempo, los tokens y las llamadas de herramientas?

Si la finalización es válida, termina con éxito. Si el estado no avanza, registra no_progress y conserva la última evidencia. Si se acaba el presupuesto, registra budget_exceeded sin convertir un resultado parcial en respuesta final. Si la siguiente acción viola la política, termina con blocked.

El modelo puede devolver una palabra como DONE, pero eso es una señal de entrada, no una prueba. Valida el formato, los campos obligatorios y el efecto que la tarea debía producir. Para una arquitectura con fases y transiciones más explícitas, consulta cuándo usar una máquina de estados en un agente de IA.

¿Cómo detectar la falta de progreso sin romper el polling?

En 2026, Microsoft Agent Framework documenta un predicado de continuación que puede devolver continuar, detenerse o enviar feedback para la siguiente iteración, mientras mantiene max_iterations como límite independiente (Microsoft Learn, "Agent looping", consultado el 28/08/2026). La separación es útil: el predicado observa el progreso y el límite protege el proceso cuando esa observación falla.

Empieza con una huella pequeña del estado que controla el runtime. Incluye el nombre de la herramienta, los argumentos normalizados, el identificador del recurso, la versión del estado y una firma breve del resultado. No incluyas secretos ni una respuesta completa solo para crear un hash.

type StopReason =
  | "completed"
  | "no_progress"
  | "budget_exceeded"
  | "blocked"
  | "failed";

type RunState = {
  step: number;
  lastFingerprint?: string;
  repeatedSteps: number;
  reason?: StopReason;
};

function shouldStop(
  state: RunState,
  nextFingerprint: string,
  maxSteps: number,
): StopReason | undefined {
  if (state.step + 1 >= maxSteps) return "budget_exceeded";
  if (state.lastFingerprint === nextFingerprint && state.repeatedSteps >= 1) {
    return "no_progress";
  }
  return undefined;
}

Este fragmento es ilustrativo. No conoce el significado de un recurso externo y no puede demostrar que dos respuestas semánticamente iguales sean inútiles. En producción, combina la huella con una regla por herramienta. Un pollJob puede permitir repeticiones mientras cambia el estado. Un sendMessage debe detenerse después de la primera intención aceptada, aunque la confirmación tarde.

No uses un juez de lenguaje como única condición. Un evaluador puede aprobar la misma respuesta dos veces o pedir refinamiento para siempre. Úsalo para evaluar calidad dentro de un límite controlado por el runtime.

¿Cómo separar finalización, retry y parada?

En 2026, el SDK de Claude Code describe su bucle como una repetición entre la respuesta del modelo y la ejecución de herramientas hasta que aparece una respuesta sin nuevas llamadas (Anthropic, "How the agent loop works", consultado el 28/08/2026). Esa regla termina el ciclo, pero no sustituye la política de la aplicación para salidas incompletas, errores de herramientas o falta de progreso.

Modela la decisión fuera del prompt. Un adapter puede devolver uno de estos resultados:

type Decision =
  | { kind: "continue"; fingerprint: string }
  | { kind: "complete"; output: string }
  | { kind: "stop"; reason: StopReason; detail: string };

async function runBoundedAgent(input: string): Promise<Decision> {
  const state: RunState = { step: 0, repeatedSteps: 0 };

  while (true) {
    const attempt = await modelAndTools(input, state);
    const decision = classifyAttempt(attempt, state);

    if (decision.kind !== "continue") return decision;

    const reason = shouldStop(state, decision.fingerprint, 8);
    if (reason) {
      return { kind: "stop", reason, detail: "termination policy reached" };
    }

    state.repeatedSteps = state.lastFingerprint === decision.fingerprint
      ? state.repeatedSteps + 1
      : 0;
    state.lastFingerprint = decision.fingerprint;
    state.step += 1;
  }
}

El ejemplo es ilustrativo y no se ejecutó contra un proveedor. La función classifyAttempt debe distinguir una respuesta final válida, una tool call que puede continuar, un fallo retryable y un fallo que exige detenerse. El valor 8 es un ejemplo de política local, no un límite recomendado.

El retry es adecuado cuando otro intento todavía puede producir información o resultado sin repetir un efecto externo. Detenerse es adecuado cuando el estado es ambiguo, el error es permanente, la capacidad de la herramienta no está disponible o la tarea ya no tiene presupuesto. La política es más segura cuando el agente recibe el motivo en lugar de un mensaje genérico como try again.

¿Cómo registrar y recuperar un estado terminal?

En 2026, el OpenAI Agents SDK documenta el uso de RunState y el tratamiento de un fallo de maxTurns con un handler específico, sin reproducir automáticamente los efectos de herramientas (OpenAI Agents SDK, "Running Agents", consultado el 28/08/2026). El principio es separar la salida parcial del permiso para reanudar.

Registra al menos:

  • runId y parentRunId cuando exista un handoff;
  • contador de pasos y llamadas por herramienta;
  • presupuesto restante y plazo;
  • último estado conocido y su versión;
  • motivo terminal y la evidencia que lo produjo;
  • referencias a efectos externos que necesitan conciliación.

Una ejecución detenida por no_progress puede reanudarse después de cambiar el contexto. Una ejecución blocked puede necesitar aprobación. Una ejecución budget_exceeded puede necesitar una tarea más pequeña. Ninguna debe volver automáticamente al primer paso sin conservar el motivo anterior.

Para controlar el coste del contexto, trata los resúmenes y el estado persistido como cosas distintas. Un resumen ayuda a la siguiente decisión. Un estado terminal explica por qué se detuvo. La ejecución durable para agentes de IA profundiza en checkpoints y reanudación; aquí el foco es la política de terminación.

Cuando un bucle atraviesa varias sesiones, uso RemoteCode como mi herramienta para mantener visibles el contexto operativo y las decisiones de los agentes. Es una descripción de mi uso, no un resultado medido de este artículo.

¿Cómo comprobar que el agente realmente se detiene?

En 2026, el OpenAI Agents SDK documenta test doubles deterministas para probar workflows multi-turn sin hacer llamadas al modelo ni al proveedor de sandbox (OpenAI Agents SDK, "Testing", consultado el 28/08/2026). Incluso sin esa biblioteca, usa fakes para probar la política antes de conectar el agente con servicios externos.

Prueba al menos estos caminos:

Escenario Resultado esperado
El modelo devuelve una respuesta final válida completed, sin una nueva tool call
La misma herramienta devuelve el mismo estado dos veces no_progress, o una regla específica de polling
El contador global llega al límite budget_exceeded, con el último estado conservado
Una herramienta pide permiso fuera de la fase actual blocked, sin ejecutar el efecto
El modelo devuelve un error retryable dentro del plazo otro intento dentro del presupuesto
Una herramienta inicia un efecto y desaparece su respuesta estado ambiguo, conciliar antes de reintentar

Comprueba también lo que no debe ocurrir. El agente no puede convertir budget_exceeded en completed, reiniciar el contador después de cambiar de proveedor, perder el historial durante un handoff ni confundir un resultado parcial con la respuesta final.

Probar la trayectoria de un agente de IA ayuda a verificar la secuencia completa. Este artículo añade la pregunta de la parada: ¿qué evidencia hizo que el runtime terminara y puede la siguiente ejecución entender ese motivo?

Preguntas frecuentes

¿Cuál es un límite seguro de iteraciones para un agente de IA?

No existe un valor universal. OpenAI Agents SDK usa maxTurns: 10 por defecto, mientras AI SDK documenta 20 pasos para su ToolLoopAgent, pero esos valores pertenecen a bibliotecas distintas (OpenAI Agents SDK, "Running Agents"; Vercel AI SDK, "Agents: Loop Control", consultados el 28/08/2026). Mide la tarea y conserva un límite global.

¿Detectar la misma tool call evita todos los bucles infinitos?

No. Una herramienta puede recibir argumentos distintos y producir el mismo estado, o dos herramientas pueden alternarse. Combina una huella con progreso, tiempo, coste y una condición de finalización. Para polling legítimo, permite repeticiones mientras cambie el estado externo y define un plazo independiente.

¿Qué debe pasar cuando el límite termina antes de la respuesta?

Registra budget_exceeded con el último estado conocido, el motivo y la evidencia disponible. No presentes la salida parcial como éxito. Si la tarea puede continuar, crea una nueva ejecución con contexto resumido. Si un efecto externo es ambiguo, comprueba su estado antes de repetirlo.

Conclusión

Un bucle de agente es más seguro cuando detenerse es una decisión del sistema, no una petición escondida en el prompt. Usa una finalización validada, un límite de pasos, un presupuesto compartido y detección de falta de progreso. Cada barrera cumple una función distinta. Juntas impiden que una tarea sin resolver parezca autonomía.

El agente todavía puede fallar. Es mejor que continuar sin saber por qué. Registra el motivo terminal, conserva el estado y convierte el siguiente paso en un retry, una conciliación, una aprobación o una ejecución más pequeña.

Nota de producción

Samuel Fajreldines es el responsable editorial de este artículo. La investigación usó documentación pública de OpenAI Agents SDK, AI SDK, Microsoft Agent Framework, Claude Code, LangChain, Google Cloud y un artículo técnico de arXiv, además de discusiones públicas de practicantes. La asistencia de IA ayudó con la investigación, comparación, primera redacción, traducción y revisión. El código es ilustrativo; no hubo benchmark con un proveedor real, prueba de cliente ni métrica propia.

Fuentes consultadas