Construiste el loop agéntico. Las tools se llaman, los resultados vuelven, el modelo razona qué hacer después — todo zumba como un pequeño cerebro autónomo. Entonces abres el dashboard de uso de Anthropic después de un día de pruebas. Ese número no es un error tipográfico. Es el costo de reenviar el mismo system prompt y los mismos tool schemas en cada iteración, a precio completo, a una API stateless que no tiene memoria de lo que le mandaste hace tres segundos.

Y si actualizaste a Opus 4.7 el 16 de abril de 2026 — que probablemente sí — Simon Willison midió que el nuevo tokenizer produce 1.46× más tokens para system prompts idénticos. Tus costos subieron 35-40% de la noche a la mañana por literalmente el mismo texto. El análisis de Finout (27 de abril, 2026) confirma el patrón en múltiples cargas de trabajo.

Por qué "solo optimiza tus prompts" no alcanza

La respuesta obvia: acorta los prompts. Claro, quítales la grasa. Pero en un loop agéntico real, tu prefijo estático — el system prompt, las definiciones de tools (schemas que le dicen al modelo qué herramientas puede llamar y qué parámetros aceptan), y el historial de conversación acumulado — fácilmente alcanza los 10,000+ tokens. Con 6 tools y un system prompt decente, estás viendo ~11,000 tokens de contenido idéntico reenviado en cada turno.

En 10 iteraciones, eso son 110,000 tokens de pura repetición a $5/MTok en Opus 4.7. Son $0.55 solo en costos de input — nada más por bytes que el servidor ya vio. Escala a 50 turnos y estás quemando dólares en una sola conversación.

Ninguna cantidad de recorte de prompts arregla un protocolo fundamentalmente stateless. Necesitas que el servidor recuerde.

La solución: prompt caching

La API de prompt caching de Anthropic (GA desde el 17 de diciembre de 2024) te permite etiquetar bloques de mensajes con un breakpoint de cache_control — un marcador que le dice al servidor "almacena todo hasta este punto". En requests posteriores, si los bytes coinciden exactamente, el servidor lee del cache y te cobra 10% del precio normal de input. Según la documentación de Anthropic, el cache de 5 minutos (por defecto) cuesta 1.25× en la escritura inicial; el cache de 1 hora cuesta 2×.

La matemática es simple: paga un 25% de sobrecargo una vez, obtén 90% de descuento en cada hit posterior. En un loop de 10 turnos, eso es 1 escritura + 9 lecturas. Se paga solo después del primer cache hit.

Paso 1: Cachea el system prompt

El system prompt es el contenido más estable de tu loop. Nunca cambia entre iteraciones. Hazlo cacheable:

response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=4096,
    system=[{
        "type": "text",
        "text": "Tu system prompt largo con instrucciones...",
        "cache_control": {"type": "ephemeral"},  # TTL de 5 min
    }],
    messages=[...],
)

El detalle clave: en Opus 4.7 (y Opus 4.5, Haiku 4.5), el bloque mínimo cacheable es de 4,096 tokens. Si tu system prompt es más corto que eso, Anthropic ignora silenciosamente el marcador cache_control — sin error, sin cache, solo intención desperdiciada. En Sonnet, el mínimo es 1,024 tokens.

/faion es el skill paraguas de faion-network — extrae metodología relevante de 12 dominios especialistas a la conversación, así que antes de diseñar tu estrategia de cache, pregúntale:

/faion
Estoy implementando prompt caching de Anthropic para un loop agéntico multi-tool.
¿Cuál es la mejor estrategia para colocar breakpoints de cache_control cuando tengo
un system prompt, 6 tool schemas y un historial de conversación que crece?

Paso 2: Cachea las definiciones de tools

Los tool schemas — las descripciones JSON del nombre, parámetros y propósito de cada tool — van en el array tools y se procesan antes que el system prompt en la jerarquía de cache. Coloca el cache_control en la última tool del array para cachearlas todas en un solo breakpoint:

tools = [
    {"name": "search_web", "description": "...", "input_schema": {...}},
    {"name": "read_file", "description": "...", "input_schema": {...}},
    {"name": "run_code", "description": "...", "input_schema": {...}},
    {"name": "write_file", "description": "...", "input_schema": {...}},
    {"name": "list_dir", "description": "...", "input_schema": {...}},
    {"name": "submit_result", "description": "...", "input_schema": {...},
     "cache_control": {"type": "ephemeral"}},  # cachea TODAS las tools anteriores
]

Regla crítica: la jerarquía de cache es tools → system → messages. Cambiar cualquier definición de tool entre iteraciones (agregar una tool, renombrar un parámetro) invalida el cache de tools, system Y messages. En un loop agéntico, mantén tu set de tools congelado.

Paso 3: Cachea el prefijo del historial de conversación

Conforme la conversación crece, los mensajes más viejos se vuelven estáticos — no van a cambiar. Coloca un breakpoint en el último mensaje de la porción "estable":

messages = [
    {"role": "user", "content": "Tarea inicial..."},
    {"role": "assistant", "content": "Voy a empezar por..."},
    {"role": "user", "content": [{  # último mensaje estable
        "type": "text",
        "text": "Resultado de tool del paso 3...",
        "cache_control": {"type": "ephemeral"},
    }]},
    {"role": "assistant", "content": "Ahora procesando..."},  # nuevo, sin cache
]

Ahora tienes 3 breakpoints (tools, system, historial). La API permite un máximo de 4. Guarda el último slot para casos especiales.

Paso 4: El truco de la reubicación

Este viene del equipo de ingeniería de ProjectDiscovery, que publicó sus resultados el 10 de abril de 2026. Corren un escáner de seguridad agéntico de 26 pasos y 40 llamadas a tools. Su tasa de cache hit inicial era un patético 7%.

El problema: su system prompt contenía timestamps, memoria de trabajo y variables de runtime que cambiaban en cada llamada. El matching de cache requiere igualdad exacta byte por byte — un solo carácter diferente y el bloque entero falla.

La solución: mover todo el contenido dinámico fuera del system prompt y hacia un mensaje con rol de usuario al final de la conversación. El system prompt se vuelve byte-por-byte idéntico entre llamadas. Su tasa de cache hit saltó del 7% al 74% de la noche a la mañana, eventualmente llegando al 84% con más ajustes — una reducción de costos del 70%.

/faion
¿Cómo debería separar el contenido estático vs. dinámico en un system prompt
agéntico para maximizar las tasas de cache hit? ¿Qué patrones existen para
la división system-prompt-estático + user-reminder-dinámico?

Paso 5: Verifica que realmente está funcionando

Los cache hits son invisibles a menos que los busques. La mayoría de los wrappers de SDK y frameworks de logging no exponen métricas de cache. Necesitas verificar explícitamente:

usage = response.usage
print(f"Cache escrito:  {usage.cache_creation_input_tokens}")
print(f"Cache leído:    {usage.cache_read_input_tokens}")
print(f"Sin cache:      {usage.input_tokens}")

hit_rate = usage.cache_read_input_tokens / (
    usage.cache_read_input_tokens +
    usage.cache_creation_input_tokens +
    usage.input_tokens
) * 100
print(f"Tasa de cache hit: {hit_rate:.1f}%")

En tu segunda iteración del loop, cache_read_input_tokens debería ser grande. Si es cero, algo está invalidando tu cache — busca diferencias a nivel de bytes en tu contenido "estático".

Gotchas que te van a costar plata

1. El precipicio de los 5 minutos. El TTL por defecto (time-to-live — cuánto tiempo el servidor recuerda tu contenido cacheado) es de 5 minutos. Si una llamada a tool tarda 6 minutos (timeout de API externa, cálculo largo), el cache expira. Pagas el sobrecargo de escritura otra vez. Solución: usa "ttl": "1h" para flujos lentos, pero ten en cuenta que cuesta 2× en vez de 1.25× en la escritura. Y los TTLs más largos deben aparecer antes que los más cortos en el request — el orden inverso lanza un error.

2. Orden de las keys en JSON. Algunos lenguajes aleatorizan el orden de las keys de JSON al serializar. Diferente orden de keys = diferentes bytes = cache miss. Fija el orden de serialización o usa sort_keys=True.

3. El lookback de 20 bloques. El sistema busca como máximo 20 bloques de contenido hacia atrás para encontrar entradas cacheadas. En conversaciones largas (>20 bloques), los breakpoints viejos quedan fuera de la ventana de búsqueda. Agrega breakpoints frescos cada ~18 bloques. El estudio de PwC de enero de 2026 encontró que ahí es donde se originan la mayoría de los "cache misses misteriosos".

4. Cachear contenido corto cuesta más. PwC midió que prompts de menos de 500 tokens muestran 10-18% peor latencia con caching debido al overhead. No cachees tu system prompt de 200 tokens. De todas formas necesita superar el mínimo de 4,096 tokens en Opus.

Qué puedes hacer ahora

Tienes tres breakpoints — tools, system, prefijo de historial — y un patrón de monitoreo. El mismo loop agéntico que quemaba $0.55 por conversación de 10 turnos en Opus 4.7 ahora cuesta ~$0.12. Eso no es un error de redondeo; es la diferencia entre un prototipo que demuestras una vez y un sistema que realmente pones en producción. ¿El impuesto del 35% del tokenizer de Opus 4.7? Sigue ahí, pero lo pagas una vez por escritura de cache en vez de en cada maldito turno. Bienvenido a la parte donde la página de facturación deja de darte miedo.