El primer mes que ejecuté agentes con cualquier volumen real, gasté $1,400 y la mayor parte fue desperdicio. No fue el modelo pensando con esfuerzo en problemas difíciles — eso es dinero bien gastado. Era reenviar el mismo system prompt de 40K tokens sin caché en cada solicitud, ejecutar todo al máximo de effort, y usar Opus para hacer grep de archivos. Pura fuga.
El objetivo no es hacer tu agente más barato haciéndolo más tonto. Cualquiera puede bajar a un modelo menor y llamarlo control de costos. El objetivo es cortar el desperdicio y mantener la inteligencia donde importa. Aquí es donde va el dinero realmente y cómo tapo cada fuga.
El prompt caching es la palanca más importante
Si estás ejecutando un agente con un system prompt estable y grande y un conjunto de herramientas, y tu cache_read_input_tokens es cero, estás quemando dinero. El caching es una coincidencia de prefijo — la API almacena el prompt renderizado hasta un punto de ruptura, y las lecturas cuestan aproximadamente la décima parte del precio de entrada completo.
El problema: cualquier cambio de byte en cualquier lugar del prefijo invalida todo lo que viene después. El asesino clásico es una marca de tiempo en el system prompt.
system = f"You are an agent. Current time: {datetime.now()}" # cache dead on arrival
Ese datetime.now() hace que cada solicitud sea un prefijo único. Nada se almacena en caché nunca. Mueve las cosas volátiles — marcas de tiempo, IDs de solicitud, la pregunta real — al final, después de tu último punto de ruptura de caché. Mantén el system prompt y la lista de herramientas congelados e idénticos a nivel de byte.
Cómo saber si está funcionando: revisa usage.cache_read_input_tokens en solicitudes repetidas. Si es un número grande, estás cacheando. Si es cero, compara dos prompts renderizados y encuentra el byte que está cambiando. Siempre es algo tonto — un JSON dump sin ordenar, un UUID, una fecha. En una sesión de agente larga esta es la diferencia entre una ejecución de $4 y una de $0.40, y no cambia nada sobre la calidad de salida. Dinero gratis.
Ajusta el effort por ruta, no maximices todo
El parámetro effort controla cuánto piensa el modelo. El instinto es subirlo a max en todas partes para que el agente sea lo más inteligente posible. Instinto equivocado. En los modelos Opus actuales, high es el punto óptimo para la mayoría del trabajo, y max a menudo solo quema tokens extra en exceso de pensamiento con rendimientos decrecientes.
Más importante aún: no todos los pasos en un bucle de agente necesitan la misma capacidad mental. Un paso de clasificación, una decisión de "qué archivo debo ver", una puerta sí/no — esos funcionan bien en low o medium. Reserva high y xhigh para el razonamiento verdaderamente difícil y la planificación a largo plazo.
# cheap gate
client.messages.create(model="claude-opus-4-8", output_config={"effort": "low"}, ...)
# the real work
client.messages.create(model="claude-opus-4-8", output_config={"effort": "high"}, ...)
Ejecuté un barrido de effort en mi propio conjunto de evaluación — medium, high, xhigh — y encontré que high igualó a xhigh en calidad para la mayoría de mis rutas con un gasto de tokens notablemente menor. No sabrás tus números hasta que midas. No recurras por defecto a max por miedo.
Subagentes para el trabajo barato
Aquí hay un truco que es tanto una jugada de costos como una jugada de caching. Cuando necesitas completar una subtarea barata — explorar un directorio, resumir un archivo, hacer grep de algo — no lo hagas en línea en tu bucle principal costoso. Genera un subagente en un modelo más barato.
Por qué también es una ventaja de caching: cambiar de modelo a mitad de conversación invalida tu caché, porque los cachés tienen alcance de modelo. Si bajas tu bucle principal de Opus a Haiku para un grep y vuelves, has destruido tu caché de prefijo dos veces. Un subagente mantiene el bucle principal en un modelo y un caché, mientras el trabajo barato ocurre al costado en Haiku. Claude Code hace exactamente esto — sus subagentes Explore se ejecutan en Haiku precisamente por esta razón.
Edición de contexto y compactación para ejecuciones largas
Las sesiones de agente largas acumulan resultados de herramientas obsoletos y bloques de pensamiento antiguos. Cada turno los reenvías todos al precio de entrada completo. Dos herramientas arreglan esto.
La edición de contexto elimina los resultados de herramientas viejos de la transcripción antes de que el modelo los vea. La compactación resume el historial del lado del servidor cuando te acercas al límite de la ventana. Son diferentes — editar poda, compactar condensa — y los agentes largos a menudo usan ambas. El ahorro se acumula: una sesión de 40 turnos que reenviaría 200K tokens de salida de herramientas muerta en cada turno en cambio envía un resumen compacto.
Un problema que atrapa a todos con la compactación: añade el response.content completo de vuelta cada turno, no solo el texto extraído. El estado de compactación vive en esos bloques de contenido. Extrae solo el texto y lo pierdes silenciosamente, y tus costos vuelven a subir mientras te preguntas por qué.
Observa el número correcto
Última cosa. Cuando depures costos, no te quedes mirando input_tokens solo. El total real es input_tokens + cache_creation_input_tokens + cache_read_input_tokens. He visto gente entrar en pánico porque un agente de larga ejecución solo muestra 4K input_tokens y asumen que algo está roto — no, el resto fue servido desde caché. Ese 4K es el resto sin caché. Suma los tres o estás leyendo el indicador equivocado.
Nada de esto hace tu agente más tonto. El caching es gratis. El ajuste de effort mantiene la capacidad mental donde cuenta. Los subagentes ponen el trabajo barato en modelos baratos. La jugada tonta es la que suena inteligente: bajar a un modelo más débil en todas partes y ver cómo se desploma la calidad para ahorrar unos dólares. Corta el desperdicio primero. El desperdicio es enorme, y está escondido en una marca de tiempo que olvidaste.
