Un thread en Hacker News llegó a 208 puntos esta semana preguntando si los costos de los agentes IA crecen exponencialmente con la complejidad. La discusión es mayormente teórica — modelos matemáticos, análisis de complejidad algorítmica, extrapolaciones. Interesante. Pero yo tengo algo mejor: meses de logs reales de agentes que corrí en producción y en proyectos propios. Y la respuesta empírica es completamente diferente a lo que el thread concluye. No es exponencial. Pero tampoco es lineal ni predecible. Son saltos. Saltos discretos que vos generás sin darte cuenta.
Costos agentes IA 2025: qué dice la teoría vs. qué dicen mis logs
La hipótesis popular — la que el thread de HN da casi por sentada — es que si un agente maneja tareas de complejidad N, el costo en tokens crece como O(N²) o peor. La lógica es intuitiva: más contexto, más herramientas, más iteraciones, todo multiplicado entre sí.
Mi experiencia dice otra cosa.
Llevé tres meses de logs de agentes: el sistema de curación que describí en el post sobre Awesome desactualizadas, los experimentos con SPICE + Claude Code, las métricas que empecé a registrar después de armar CodeBurn, y algunos agentes de automatización interna que no publiqué. En total: 847 runs de agente, 23 tareas distintas, tres modelos diferentes.
Cuando grafiqué costo vs. complejidad de tarea, esperaba una curva. Lo que vi fueron escalones.
# Análisis de distribución de costos por run
# Datos reales anonimizados de mis logs
import pandas as pd
import numpy as np
# Cargo los logs exportados de CodeBurn
df = pd.read_csv('agent_runs_q1_q2_2025.csv')
# Clasifico por rango de costo
df['rango_costo'] = pd.cut(
df['total_tokens'],
bins=[0, 5000, 20000, 80000, 200000, np.inf],
labels=['micro', 'pequeño', 'mediano', 'grande', 'monstruoso']
)
# Lo que esperaba: distribución gradual
# Lo que encontré: agrupamiento fuerte en rangos
print(df['rango_costo'].value_counts())
# Output real:
# pequeño 312 (36.8%)
# micro 298 (35.2%)
# mediano 187 (22.1%)
# grande 41 ( 4.8%)
# monstruoso 9 ( 1.1%)
El 72% de mis runs vive en los dos rangos más baratos. Los runs "monstruosos" son 9. Nueve. En tres meses.
Pero esos 9 runs representaron el 31% de mi gasto total en API.
Dónde están los saltos: las decisiones que no parecen decisiones
Acá es donde se pone interesante. Cuando fui a investigar qué causaba los saltos — especialmente los runs grandes y monstruosos — encontré patrones muy específicos. No es complejidad de la tarea. Es cómo diseñé el agente.
Salto 1: el contexto acumulativo sin límite
El error más caro que cometí fue en el agente de curación. El diseño inicial acumulaba el historial completo de decisiones en el contexto del agente. La lógica era: "necesita saber qué decidió antes para ser consistente".
Correcto en teoría. Catastrófico en práctica.
// Versión original — la que me costó caro
async function procesarBatch(items: CuratedItem[], historial: Decision[]) {
const contexto = {
// ERROR: historial completo siempre incluido
// Con 200 items procesados, esto se volvió enorme
historialCompleto: historial, // ← acá está el problema
itemActual: items[0]
}
return await claude.complete(buildPrompt(contexto))
}
// Versión corregida — ventana deslizante
async function procesarBatchV2(items: CuratedItem[], historial: Decision[]) {
const contexto = {
// Solo las últimas N decisiones relevantes
historialReciente: historial.slice(-10), // ← ventana fija
// Resumen comprimido del historial anterior
resumenHistorial: historial.length > 10
? await generarResumen(historial.slice(0, -10))
: null,
itemActual: items[0]
}
return await claude.complete(buildPrompt(contexto))
}
Este cambio solo redujo el costo de ese agente un 67%. No cambié el modelo. No cambié la tarea. Cambié cómo manejo el contexto.
Salto 2: el modelo "por las dudas"
Después de la conversación sobre escasez en modelos frontier, revisé qué modelo estaba usando para cada subtarea de mis agentes. Encontré algo que me dio vergüenza: usaba Opus para tareas de clasificación simple porque "total, si falla el agente entero es un problema".
Eso es miedo disfrazado de arquitectura.
La realidad: para clasificar si una URL es relevante o no, Claude Haiku con un prompt bien escrito tiene 94% de accuracy en mi dataset. Opus tiene 97%. Pago 15x más por 3 puntos porcentuales en una tarea donde el error tiene costo cero (simplemente reclasifico el caso dudoso).
// Mapa de modelo por tipo de tarea — lo que implementé
const MODELO_POR_TAREA = {
// Clasificación binaria simple → modelo barato
clasificacion_relevancia: 'claude-haiku-4-5',
// Extracción estructurada → modelo medio
extraccion_metadata: 'claude-sonnet-4-5',
// Razonamiento complejo, decisiones con consecuencias → modelo caro
analisis_arquitectura: 'claude-opus-4-5',
// Generación de código con contexto amplio → modelo medio
generacion_codigo: 'claude-sonnet-4-5',
} as const
type TipoTarea = keyof typeof MODELO_POR_TAREA
async function ejecutarConModeloCorrecto(
tarea: TipoTarea,
prompt: string
) {
const modelo = MODELO_POR_TAREA[tarea]
return await anthropic.messages.create({
model: modelo,
messages: [{ role: 'user', content: prompt }],
max_tokens: 1024
})
}
Salto 3: el loop sin condición de salida
Este me costó la friolera de $23 en una noche. Un agente diseñado para iterar hasta "estar satisfecho" con el resultado. Sin definir qué significa estar satisfecho. Sin límite de iteraciones.
El agente corrió 47 veces sobre la misma tarea.
// El error clásico
async function agenteIterativo(tarea: string) {
let resultado = ''
let satisfecho = false
// SIN LÍMITE — esto es una bomba de tiempo
while (!satisfecho) {
resultado = await ejecutarPaso(tarea, resultado)
satisfecho = await evaluarCalidad(resultado) // LLM evaluando LLM
}
return resultado
}
// Versión con circuit breaker
async function agenteIterativoSeguro(
tarea: string,
maxIteraciones: number = 5 // límite explícito siempre
) {
let resultado = ''
let iteracion = 0
while (iteracion < maxIteraciones) {
resultado = await ejecutarPaso(tarea, resultado)
const evaluacion = await evaluarCalidad(resultado)
if (evaluacion.score >= 0.85) break // umbral numérico, no vibe check
iteracion++
// Log para detectar loops costosos
if (iteracion >= 3) {
console.warn(`⚠️ Agente en iteración ${iteracion} — revisar diseño`)
}
}
return { resultado, iteraciones: iteracion }
}
Esta combinación — loops sin límite + LLM evaluando LLM — es el patrón más caro que vi en mis logs. El agente de inferencia en edge con Cloudflare me enseñó que mover el punto de evaluación puede cambiar radicalmente el costo de un loop.
Los gotchas que no están en ningún tutorial
El costo de la "memoria" mal implementada. Todos los frameworks de agentes tienen algún tipo de memoria. Casi ninguno te explica que la memoria ingenua — guardar todo — es exponencial en costo. Cada mensaje nuevo paga por todos los mensajes anteriores. Necesitás compression activa o retrieval selectivo, no append.
El JSON innecesariamente grande. Mis agentes transmiten estado en JSON. Durante semanas no pensé en el tamaño de ese JSON. Tenía campos de debug, metadata redundante, timestamps en formato ISO completo. Comprimir el schema del JSON que circula en el contexto del agente me ahorró en promedio 800 tokens por llamada. Parece poco. Con 300 llamadas al día no es poco.
El system prompt que se duplica. En algunos frameworks, si no tenés cuidado, el system prompt se incluye en cada mensaje del historial además de como system. Lo descubrí mirando los logs de tokenización. Era un system prompt de 2000 tokens que aparecía 8 veces en un context window. 16.000 tokens de overhead puro.
La herramienta que siempre llama a la herramienta más cara. Si tu agente tiene herramientas con costos muy distintos (una llama a GPT-4o, otra hace un lookup en base de datos local) y el agente aprende a preferir la herramienta de LLM porque "es más flexible", vas a tener un problema de costos que parece aleatorio pero no lo es.
FAQ: Costos de agentes IA en 2025
¿Los costos de los agentes IA realmente crecen exponencialmente?
Empíricamente, en mis datos: no. Crecen en saltos discretos vinculados a decisiones de diseño específicas. El crecimiento exponencial que muestra la teoría asume contexto ilimitado y sin compresión — nadie debería diseñar un agente así. El problema real no es complejidad algorítmica sino arquitectura descuidada: contexto acumulativo sin límite, loops sin condición de salida, y selección de modelo "por las dudas".
¿Cuánto gasta en promedio un agente bien diseñado por tarea?
Depende muchísimo de la tarea, pero en mis logs el 72% de los runs quedan entre 1.000 y 20.000 tokens. Con precios actuales de Claude Sonnet, estamos hablando de $0.003 a $0.06 por run. Los runs "monstruosos" (más de 200k tokens) representan el 1% de los casos pero el 31% del gasto — ahí es donde hay que mirar.
¿Vale la pena usar modelos más baratos para subtareas?
Sí, rotundamente. El patrón de routing por complejidad de tarea — Haiku para clasificación, Sonnet para generación, Opus solo para razonamiento complejo — redujo mi gasto mensual un 40% sin degradación perceptible en calidad de output final. La clave es definir métricas de calidad por subtarea para saber qué modelo alcanza.
¿Cómo sé si mi agente tiene un problema de costos antes de que explote?
Tres señales de alerta temprana: (1) el costo por run tiene varianza muy alta — si hay runs que cuestan 10x el promedio, tenés un patrón mal diseñado, (2) el número de herramienta-calls crece más rápido que la complejidad de las tareas, (3) el tamaño promedio del contexto crece run a run en lugar de mantenerse estable. Herramientas como CodeBurn ayudan a detectar esto sistemáticamente.
¿Los circuit breakers en agentes son over-engineering?
No. Son lo mínimo viable. Un agente sin límite de iteraciones en producción es un incidente esperando pasar. El límite no tiene que ser rígido — puede ser "5 iteraciones, o cuando el score supere 0.85, lo que ocurra primero" — pero tiene que existir. El costo de un loop sin fin es potencialmente ilimitado y los LLMs no te van a decir "pará, esto no está funcionando".
¿Es mejor un agente con muchas herramientas especializadas o pocas herramientas generales?
En costos: muchas herramientas especializadas gana, siempre que el routing sea bueno. El problema de las herramientas generales es que el agente tiende a usarlas para todo, incluyendo casos donde una herramienta barata y específica hubiera bastado. El overhead de routing con más herramientas es real pero menor que el overhead de usar una herramienta cara cuando no hace falta.
La conclusión que no me esperaba
Empecé este análisis para responder el thread de HN. Terminé dándome cuenta de algo más incómodo: la mayoría de mis runs caros los generé yo. No por la complejidad de las tareas. Por decisiones de diseño que tomé en 30 segundos, sin pensar en el costo, porque "funcionaba".
El crecimiento exponencial de costos en agentes es un mito parcialmente verdadero. Es verdad si diseñás sin pensar. Es falso si tratás el contexto, los loops y la selección de modelos como decisiones de arquitectura con consecuencias económicas reales.
La buena noticia: una vez que encontrás los saltos en tus propios logs, son fáciles de eliminar. No requieren cambiar el modelo ni la tarea ni el framework. Requieren cambiar cómo pensás sobre el estado y el contexto de tu agente.
La mala noticia: nadie te va a avisar que los estás generando hasta que llegue la factura.
Si no estás midiendo tus runs, empezá hoy. No mañana. Hoy.
Top comments (0)