Ir al contenido principal
Tu agente entra en bucle. No lo sabe. Y tú tampoco.

Tu agente entra en bucle. No lo sabe. Y tú tampoco.

AI Engineering
6 min readPor Daily Miranda Pardo

El agente llevaba cuarenta minutos ejecutándose cuando alguien se dio cuenta. Cuatrocientas dieciséis iteraciones. 1,2 millones de tokens. Una sesión que costó casi cuatro euros —y no terminó porque resolviera el problema. Terminó porque alguien apagó el servidor.

Esto le pasó a un equipo que había testeado su agente a fondo. Los tests pasaban. El happy path funcionaba. Lo que no habían testeado era qué ocurre cuando el agente no puede avanzar.

El patrón ReAct y su talón de Aquiles

La mayoría de agentes autónomos siguen alguna variante del patrón ReAct (Reason + Act): el modelo razona, decide qué tool usar, la ejecuta, observa el resultado y vuelve a razonar. Es elegante, funciona bien en demos, y tiene un problema estructural: no hay exit condition natural.

El loop termina cuando el modelo decide que ha terminado —que devuelve una respuesta final en lugar de llamar a otra tool. Pero los modelos no siempre lo hacen. Si el modelo está atascado, si la tool devuelve un error que el modelo no sabe interpretar, o si el estado de la conversación no le da señales claras de que puede parar, sigue ejecutando indefinidamente.

Y mientras ejecuta, consume tokens. Y los tokens cuestan dinero.

Agentes IA en bucle — terminación en producción

Los tres síntomas de un agente en bucle

En producción, un agente atascado suele mostrar uno de estos patrones:

1. Llama a la misma tool con los mismos parámetros. El modelo recibe el mismo error cada vez, no sabe cómo salir, e intenta lo mismo repetidamente esperando un resultado diferente. El agente no está siendo estúpido: está haciendo lo que los patrones de su entrenamiento le dicen que haga cuando algo falla.

2. Alterna entre dos tools sin avanzar. Llama a tool A, que le dice que necesita información. Llama a tool B para conseguirla. Tool B le dice que necesita el resultado de A. El agente está en un deadlock que él no detecta como deadlock.

3. Genera reasoning correcto pero nunca llama a la tool final. El modelo razona, elabora, refinó la pregunta varias veces... pero no da el último paso. Esto ocurre cuando el system prompt es ambiguo sobre cuándo se considera que la tarea está completa.

En los tres casos, sin un mecanismo de terminación, el agente sigue. Y tú no te enteras hasta que ves la factura de la API.

Cómo implementar terminación correcta

La solución no es confiar en el modelo para que decida cuándo parar. Es imponer límites externos que el agente no puede ignorar.

1. Iteration counter con hard limit

El límite de iteraciones es lo más básico y lo más frecuentemente omitido:

interface AgentConfig {
  maxIterations: number;
  tokenBudget: number;
  onLimitReached: (reason: 'iterations' | 'tokens') => AgentResponse;
}

async function runAgent(
  prompt: string,
  tools: Tool[],
  config: AgentConfig
): Promise<AgentResponse> {
  let iterations = 0;
  let totalTokens = 0;
  const messages: Message[] = [{ role: 'user', content: prompt }];

  while (true) {
    if (iterations >= config.maxIterations) {
      return config.onLimitReached('iterations');
    }

    const response = await callLLM(messages, tools);
    totalTokens += response.usage.total_tokens;

    if (totalTokens >= config.tokenBudget) {
      return config.onLimitReached('tokens');
    }

    if (response.stop_reason === 'end_turn') {
      return { success: true, content: response.content };
    }

    iterations++;
    messages.push(...processToolCalls(response));
  }
}

El parámetro onLimitReached es importante: decide qué responder cuando se alcanza el límite. En la mayoría de casos, la respuesta correcta no es un error genérico. Es devolver lo que el agente ha conseguido hasta ese punto con un mensaje de que no pudo completar la tarea.

2. Progress detection para detectar stagnación

El iteration counter evita loops infinitos pero no detecta si el agente está avanzando. Para eso, necesitas comparar el estado entre iteraciones:

interface AgentState {
  lastToolCalled: string | null;
  lastToolArgs: string | null;
  consecutiveRepeats: number;
}

function detectStagnation(
  currentTool: string,
  currentArgs: string,
  state: AgentState
): boolean {
  const sameCall =
    currentTool === state.lastToolCalled &&
    currentArgs === state.lastToolArgs;

  if (sameCall) {
    state.consecutiveRepeats++;
  } else {
    state.consecutiveRepeats = 0;
  }

  return state.consecutiveRepeats >= 3;
}

Si el agente llama a la misma tool con los mismos argumentos tres veces seguidas, es una señal clara de que está atascado. Puedes interrumpirlo, inyectar un mensaje de sistema con instrucciones adicionales, o escalar a un humano —depende de tu caso de uso.

3. Token budget con alerta temprana

El hard limit de tokens evita el coste extremo, pero conviene añadir una alerta cuando el agente supera el 70-80% del presupuesto:

const TOKEN_BUDGET = 50_000;
const ALERT_THRESHOLD = 0.7;

if (totalTokens > TOKEN_BUDGET * ALERT_THRESHOLD) {
  // Inyectar mensaje que incentiva al agente a concluir
  messages.push({
    role: 'user',
    content: 'Wrap up your current task with what you have. Provide a partial result if needed.'
  });
}

Este mensaje de "cierre suave" a menudo hace que el agente termine limpiamente en lugar de cortar abruptamente al alcanzar el límite.

Cómo monitorizarlo en producción

Un agente con terminación correcta en código no es suficiente si no tienes visibilidad de cuándo se activan esos límites. En cualquier sistema de integración de agentes IA que construimos, añadimos:

  • Alertas por sesiones de alta duración (más de N iteraciones o más de X segundos)
  • Métricas de token consumption por sesión — una sesión que supera 5x la media es sospechosa
  • Log estructurado del stop reason — distinguir end_turn de max_iterations de stagnation te dice exactamente qué tipo de problema tienes

Sin estos logs, cuando algo sale mal en producción estás revisando timestamps para intentar reconstruir qué pasó. Con ellos, tienes el historial completo.

El error que cometió ese equipo

Volviendo al ejemplo del principio: el equipo había implementado un timeout de red de 60 segundos en las llamadas HTTP. Pero no tenían ningún límite en el número de iteraciones del agente. Cada iteración hacía su llamada HTTP dentro del timeout, así que el timeout de red nunca se disparaba. El agente podía iterar indefinidamente siempre que cada tool call individual tardara menos de un minuto.

El problema no estaba en el código de la tool. Estaba en la ausencia de un límite en el loop del agente.

Este es el tipo de arquitectura que revisamos cuando trabajamos con equipos en sus servicios de agentes IA: no los happy paths, sino los casos de borde que solo aparecen en producción real.

Conclusión

Los agentes autónomos sin terminación correcta no son un riesgo teórico. Son un coste operativo real y un punto de fallo que aparece exactamente cuando más usuarios tienes —que es cuando más caro sale.

La terminación no es complejidad extra: es la diferencia entre un prototipo y un sistema que puedes poner en producción con confianza.

¿Tienes un agente en producción y no estás seguro de si tiene estos controles implementados? Cuéntame cómo está diseñado y lo revisamos juntos.

Escríbeme por WhatsApp →

Compartir artículo

LinkedInXWhatsApp

¿Procesos repetitivos en tu empresa?

Descarga gratis el Mapa de Automatización IA — los 5 procesos que más tiempo roban y cómo resolverlos.

Sin spam. Solo el PDF. Puedes darte de baja cuando quieras.

Escrito por Daily Miranda Pardo

Ayudo a empresas a automatizar procesos, crear agentes IA y conectar sistemas inteligentes.