April 20267 min readJohan Bretonneau

Vimos a un agente de IA quemar 200 $ a las 3 de la mañana
Te presentamos a Guardian

Un agente RAG atrapado en un retry loop, un context window que se hinchaba más allá de 200K tokens, y el momento en que entendimos que ningún proveedor LLM te alerta a tiempo. Este es el sistema anti-bucle que construimos para que no vuelva a pasar.

Mi teléfono vibró a las 3:14. Era el dashboard de facturación de Anthropic, había puesto una alerta de umbral a 100 $/día solo para sentirme responsable. La alerta decía que acababa de superarlo.

Ya iba por 143 $. El tiempo que tardé en abrir el portátil, estaba en 167 $. El tiempo que tardé en matar el proceso, estaba en 201 $.

Un agente. Tres horas. Doscientos dólares.

Esto es lo que pasó, por qué ninguna red de seguridad LLM existente lo cogió, y lo que construimos para que no vuelva a pasar, ni a nosotros, ni a nadie usando HiWay2LLM.

La timeline

2:47. Un job programado se dispara en nuestro agente de research interno. Es un pipeline RAG que lee un batch de documentos, extrae insights, y escribe un resumen en base de datos. Run nocturno normal. Coste esperado: unos 3 $.

2:49. El primer documento que carga está mal formado, un PDF de 800 páginas que ha sido OCRizado a galimatías, pero con un patrón de caracteres específico que disparó el bucle de razonamiento del agente. El agente decide que debe "releer el documento" para entenderlo.

2:52. Relee el documento. Cada relectura envía el contexto completo de 800 páginas a Claude Opus. Cada llamada: ~180 000 tokens. A 15 $/M en input, son 2,70 $ por llamada. El agente ataca ahora cada 40 segundos.

3:01. El agente cae sobre un error de tool use. Su resultado de tool vuelve vacío. El agente "decide" hacer retry. El retry vuelve a enviar todo el contexto. Más el resultado de tool anterior. Más el nuevo resultado de tool. El contexto está ahora a 210 000 tokens por llamada.

3:14. Mi teléfono vibra. Acabo de gastar 143 $ de mi propia pasta en un agente que relee galimatías OCR en bucle. El email de alerta de Anthropic, muy amablemente, llega con 9 minutos de retraso para cuando lo veo.

3:16. Hago SSH y mato el proceso a mano. Daños finales: 201 $.

Tres horas de sueño, fuera. Doscientos pavos, fuera. ¿Y lo más inquietante? Si mi teléfono hubiera estado en silencio, habría seguido corriendo hasta las 9 cuando me hubiera levantado. A ese ritmo, son otros 600 $.

El patrón subyacente

No es un caso aislado. En cuanto trabajas en apps LLM a cualquier escala, ves la misma clase de problema una y otra vez:

  • Un agente con function calling que entra en bucle sobre un error de tool porque "no entiende" por qué el tool ha fallado.
  • Un chat cuyo contexto crece sin fin porque nadie ha puesto tope a la longitud de conversación.
  • Un job batch que hace retry en un 429 transitorio, pero cada retry es más pesado que el anterior.
  • Una instancia de dev dejada corriendo de noche sobre una clave API compartida, nadie mira.
  • Un health check (el que nos quemó 40 $/día en nuestro primer post) que ataca cada 30 minutos contra Opus.

El hilo conductor no es "el código tenía un bug". El hilo conductor es que ninguna capa entre tu código y el proveedor vigila los patrones sospechosos en tiempo real. El proveedor ve llamadas API individuales. Tu aplicación ve bucles de agente individuales. Nadie ve el conjunto.

Por qué las soluciones existentes no funcionan

Pensarías que las alertas de facturación del lado proveedor gestionan esto. No, y aquí va por qué:

Están basadas en umbrales, no en tasas. Anthropic me mandó un email cuando superé los 100 $. Vale. Pero para cuando leo el email, estoy en 167 $. A 50 $/hora de burn, los umbrales no sirven, necesitas alertas de tasa, y los proveedores no las ofrecen.

Son solo email. No puedes cablear una alerta de facturación a un kill-switch. En el mejor caso, avisan a un humano. Si el humano no está despierto, el burn continúa.

Tienen un grano demasiado grueso. Tienes un umbral por cuenta. No puedes decir "alértame si una conversación supera los 5 $" o "mata cualquier request con un contexto por encima de 180K tokens".

Son post-hoc. El sistema de facturación agrega el uso en ventanas de 15 minutos, no en tiempo real. Para cuando decide que has superado un umbral, ya llevas 15 minutos quemando por encima.

Así que si quieres detectar un gasto descontrolado en tiempo real, tienes que construirlo tú mismo. O ponerlo en la capa infra.

Lo que hace Guardian

Guardian es el sistema que construimos tras ese incidente de las 3 de la mañana. Está sentado en el proxy HiWay2LLM e inspecciona cada request antes de que alcance el proveedor upstream. Busca cuatro categorías específicas de líos:

1. Detección de bucles vía fingerprinting de requests. Cada request recibe una huella, un hash del mensaje de usuario, del system prompt, y de los últimos turnos de conversación (3 últimos). Si la misma huella aparece más de N veces en una ventana, bloqueamos.

En nuestro incidente de las 3 de la mañana, el agente enviaba el mismo prompt "relee el documento y extrae insights" con un contexto ligeramente más largo cada vez. El mensaje de usuario era idéntico. El fingerprinting lo coge en la 3.ª llamada.

Toggleable. Por defecto: 5 huellas idénticas en 5 minutos = block.

2. Throttling del tamaño del contexto. Contamos los tokens a la entrada (usando el tokenizer del proveedor upstream para ser precisos). Tres umbrales:

  • A 50K tokens: logueamos un warning en el dashboard de usuario.
  • A 100K tokens: throttle, backoff exponencial requerido entre llamadas.
  • A 200K tokens: hard block, ack manual requerido para continuar.

Nuestro agente enviaba contextos de 210K tokens. Guardian habría bloqueado a 200K, antes incluso de que la primera llamada cara llegara a Anthropic.

3. Detección de zombie agents. Si una clave API tira requests fuera del horario de oficina configurado, sin señal de interacción humana (sin tokens de sesión UI, sin headers interactivos), Guardian flaguea. Optas in por clave: "esta clave es para el batch nocturno, tiene derecho a tirar a las 3" o "esta clave es para mi chatbot, si tira a las 3 hay un problema".

4. Alerting sobre spikes de coste. Trackeamos el burn horario rolling por clave. Si la hora actual es 3× la media móvil de 24 h, Guardian puede:

  • Enviar un webhook (Slack, PagerDuty, tu propio endpoint).
  • Auto-throttlear la clave a N requests por minuto.
  • Hard-killear todas las requests siguientes hasta reactivación.

Las tres acciones son toggleables independientemente. Eliges tu nivel de paranoia.

Una vista al fingerprinting

La función de hash es más simple de lo que podrías creer. Esto es básicamente lo que hacemos:

function fingerprintRequest(req: LLMRequest): string {
  const lastThreeTurns = req.messages.slice(-3);
  const systemPrompt = req.messages.find(m => m.role === "system")?.content ?? "";

  const normalized = {
    system: systemPrompt.trim().slice(0, 500),
    turns: lastThreeTurns.map(m => ({
      role: m.role,
      content: m.content.trim().slice(0, 1000),
    })),
    model: req.model,
  };

  return sha256(JSON.stringify(normalized)).slice(0, 16);
}

Dos cosas que importan:

  • No fingerprinteamos todo el contexto. Una conversación de agente acumula tokens en el tiempo, así que una huella full-context nunca matchearía dos veces. Fingerprinteamos la intención (último turno de usuario + system + cola), que es estable incluso cuando la conversación crece.
  • Normalizamos agresivamente. Trim de espacios, slice a longitud fija. Si no, un timestamp o un session ID invalidaría la huella y nos perderíamos el bucle.

Es una función de 40 líneas. Eso es todo. El curro fue encontrar qué partes fingerprintar, no la cripto.

Por qué su sitio está en la capa infra

Una protección así solo funciona de verdad si está delante de cada request, con visibilidad sobre toda la forma del tráfico, no cosida en el camino retry de cada app. Un router compartido es el sitio natural:

  • La deduplicación necesita estado global sobre todos los clientes.
  • Las matemáticas de burn-rate solo tienen sentido cuando ves todo el gasto.
  • Los kill-switches deben poder interrumpir llamadas en vuelo, no solo throttlear la siguiente.
  • Los umbrales evolucionan con los precios de los modelos; no quieres que ese tuning esté esparcido por las apps.

Puedes perfectamente construir una versión estrecha en una sola app. Equipos lo hacen, y aguanta hasta que la forma del tráfico cambia. Mover el tema a una capa por debajo significa que cada app sobre HiWay2LLM hereda la protección sin escribir una línea.

El fix que aguantó

Tras desplegar Guardian internamente, replayeamos el incidente de las 3 de la mañana contra el nuevo proxy en staging. Guardian bloqueó en la 3.ª llamada. Daños totales en el replay simulado: 8,10 $ en lugar de 201 $.

No hemos tenido más incidentes de agente descontrolado desde entonces. Ni uno solo. El primer mes, Guardian bloqueó:

  • 3 bucles de health-check (coste evitado: 340 $)
  • 12 events de context bloat por encima de 150K tokens
  • 1 zombie agent en un env de dev que empezó a hacer retry a las 2 un sábado

Es dinero real ahorrado sobre patrones reales, en un mes, en una sola empresa. Una vez que lo tienes en marcha, entiendes que cualquier equipo debería tener esto. Ningún proveedor lo ofrece. Ningún SaaS revendedor lo ofrece. Lo construyes o lo tienes.

Si haces correr llamadas LLM en producción, necesitas esta capa. No eventualmente, ahora. La llamada de las 3 de la mañana que no quieres recibir es la que no sabías que era posible.

Empezar a ahorrar →

Sin tarjeta bancaria


Lecturas relacionadas: Cómo redujimos nuestros costes LLM un 85 %, Las matemáticas ocultas del pricing LLM.

Share

Was this useful?

Comments

Be the first to comment.