
Burn silencioso: un agente fantasma corrió 4 días antes de que me diera cuenta
Por qué un fallo ruidoso es más fácil de pillar que uno discreto
Un agente LLM que tenía olvidado relanzó la misma llamada 44 veces en 96 horas. Ninguna alerta, ninguna señal. Aquí va la autopsia, el coste en las timelines alternativas, y por qué el burn silencioso es más difícil de cazar que el de las 3 de la mañana.
Token burn rate in a zombie retry loop
Cumulative spend ($) over time - alert threshold shown in red
Una ventana PowerShell que tenía minimizada desde hacía 5 días. Una línea naranja arriba. Un timestamp con un hostname que ya no uso, porque entre tanto había renombrado mi máquina de dev.
Así me enteré de que un agente LLM local llevaba cuatro días enteros corriendo en un retry loop muy apretado. Cuarenta y cuatro timeouts idénticos, disparados por el heartbeat interno del agente cada 30 minutos, contra un context de 32K que desbordaba en cada intento. El gap mediano entre dos fallos: 1800 segundos, exactos. No un humano. Un bucle.
Si ese bucle hubiera apuntado a una API de pago en lugar de a un modelo local, estaría escribiendo otro post. Con un número más gordo.
La autopsia
El agente corría en mi propia máquina, llamando a un modelo 32B local vía Ollama. Cada 30 minutos, salía un heartbeat. Cada 30 minutos, mandaba un prompt que saturaba el context. Cada 30 minutos, el modelo timeout-eaba antes de generar la mínima respuesta útil. El agente loggeaba un error interno y se rendía. Luego esperaba 30 minutos. Luego volvía a empezar.
Aquí va el patrón de fallo extraído de los logs:
| Métrica | Valor |
|---|---|
| Total de timeouts | 44 |
| Duración total | 96 horas (4 días) |
| Gap mediano entre eventos | 1800 s, exactos |
| Generaciones exitosas | 0 |
| Tokens enviados al modelo | ~1,4 M (prefill input, cero output) |
| Cron jobs configurados | 0 |
| Conexiones de cliente activas | 0 |
| Tareas trackeadas en la DB de runs | 0 |
Cero conexiones, cero runs exitosos, cero tareas. El agente ejecutaba un ritual privado para sí mismo. Cuarenta y cuatro veces.
El coste que habría tenido en una API
Las mismas 44 llamadas - mismo tamaño de prompt, mismo patrón de retry - a precios típicos de 2026, sin ninguna optimización:
| Backend | Precio input | Coste sobre 4 días |
|---|---|---|
| Modelo pequeño barato (~1 $/M input) | 1,40 $ | ~1,43 $ |
| Mid-tier (~3 $/M input) | 4,20 $ | ~4,28 $ |
| Top-tier (~15 $/M input) | 21,00 $ | ~21,38 $ |
Ahora activa el prompt caching nativo del lado del proveedor:
| Backend | Sin cache | Cache nativo (~80% hit) |
|---|---|---|
| Mid-tier | 4,28 $ | ~1,20 $ |
| Top-tier | 21,38 $ | ~5,80 $ |
Y ahora activa el semantic cache a nivel gateway. Ahí el cálculo se pone interesante. Los 44 retries eran casi idénticos: el mismo heartbeat enviando el mismo prompt cada 30 minutos. Un semantic cache delante del proveedor devuelve la primera respuesta a todas las llamadas siguientes que machean, sin ir nunca hasta el modelo:
| Setup | Coste mid-tier sobre 4 días |
|---|---|
| API directa, sin cache | 4,28 $ |
| API directa + cache nativo | 1,20 $ |
| Semantic cache gateway (1 call real + 43 cacheados) | ~0,15 $ |
Es decir, 96% de reducción comparado con el setup directo y naïf. Sobre un workload que, por definición, era un bucle apretado sobre el mismo prompt - exactamente el workload para el que se pensó el semantic cache.
Ahora imagina ese bucle no 4 días contra un modelo local gratis, sino 4 meses contra una API de pago. El 96% se convierte en la diferencia entre un error de 20 $ y un error de 500 $.
El burn ruidoso es fácil. El burn silencioso es el problema de verdad.
Ya hemos contado la noche en que un agente quemó 200 $ en 3 horas. Es la versión ruidosa. El umbral del proveedor se dispara, tu teléfono vibra, te conectas por SSH, matas el proceso, te comes el coste.
La versión silenciosa es más dura.
El burn silencioso nunca dispara un umbral. El burn rate horario se queda bajo - unos céntimos por hora como mucho. Ninguna alerta sale jamás. El proveedor ve tráfico normal. Tus dashboards (si solo miras los totales) muestran una línea plana. La única señal de que algo va mal es la forma de las requests: mismo prompt, mismo tamaño de tokens aproximado, mismo timeout, en una cadencia perfecta de 30 minutos, durante semanas.
Un humano mirando una o dos de esas llamadas aisladas no levantaría la mano. Pero:
- Nadie mira las llamadas una a una en producción. Nadie está leyendo la request número 14 000 del día.
- Los resúmenes diarios y semanales lo promedian a ruido. Un bucle que cuesta 0,40 $/día desaparece dentro de la varianza del tráfico legítimo de al lado.
- La anomalía es la ausencia de variación. La detección de anomalías estándar busca spikes. El burn silencioso es lo contrario: el mismo redoble aburrido, hasta el infinito.
El agente de 200 $ a las 3 de la mañana me despertó. El zombie de 4 días no, y nunca me habría despertado.
Lo que la capa de infra puede hacer y tu código no
El fix no es más lógica de retry a nivel aplicación. El fix es una capa que ve la forma del tráfico y reacciona a las formas sospechosas, no solo a los totales sospechosos.
Tres patrones funcionan, y se acumulan:
Deduplicación semántica. Identificar el fragmento de intención del prompt y compararlo con las llamadas recientes. Si la misma intención se repite de forma sospechosa, el gateway hace short-circuit con la respuesta cacheada, rechaza, o alerta. La parte difícil es aislar bien la intención real: demasiado amplia y te pierdes los matches, demasiado estrecha y cualquier variación rompe la detección. Bien calibrada, esta capa hace que el cache hit rate en workloads cargados de retries pase de "ocasional" a "casi todo".
Alertas de loop-detection. Independientes del cache, dispara una alerta cuando la misma huella se repite con cadencia regular. Sobre mi agente, los hashes idénticos a intervalos fijos habrían alertado muy pronto - dentro de la hora o dos siguientes al arranque, no después de 4 días.
Auditorías silenciosas programadas. Un cron semanal que te manda por email el top 10 de las huellas de request más repetidas en todas tus claves. El abuso ruidoso aparece en el gráfico de spikes. El abuso silencioso aparece aquí. Nadie mira nunca el fondo de la distribución porque ahí no hay nada ardiendo.
Nada de esto necesita vivir en tu app. Su sitio es la capa de infra, delante de cada request, con visibilidad global sobre todas las claves y todos los clientes.
Para terminar
Cerré la ventana PowerShell después de matar el proceso. El agente está en pausa, no borrado; volverá cuando tenga un curro de verdad para él. Pero he añadido una nota en el runbook: si esta cosa se rearranca, pasa por un check de huella y una alerta en cada match, antes de tener derecho a llamar a nada.
El burn ruidoso te compra una lección de 200 $ y una llamada a las 3 de la mañana. El burn silencioso ni siquiera te compra eso. Solo corre.
Si despliegas agentes LLM en producción en 2026, la versión ruidosa es la que se cuenta en los blogs. La silenciosa es la que de verdad debería darte miedo.
Sin tarjeta de crédito
Para leer también: Vimos a un agente de IA quemar 200 $ a las 3 de la mañana, Prompt Caching Hit Rate.
Was this useful?
Comments
Be the first to comment.