Prompt caching con la Claude API: reduce tus costos de entrada sin cambiar de modelo
El prompt caching reduce el costo de las entradas grandes y estables —tu system prompt, las definiciones de herramientas, los ejemplos few-shot— a aproximadamente el 10% del precio de entrada normal en solicitudes repetidas. El mecanismo es una coincidencia de prefijo: coloca un marcador cache_control al final de tu contenido estable y mantén todo lo volátil después de él. El error que destruye las tasas de aciertos de caché es dejar que un timestamp o un UUID se cuele en el prefijo.
Cada miércoles. 28.400+ operadores. Sin relleno.
✓ Revisa tu bandeja — haz clic en el enlace de confirmación para completar el registro.
✓ ¡Ya estás suscrito!
✓ Ya estás en la lista.
Table of contents
Open Table of contents
- Qué hace realmente el prompt caching
- La regla de coincidencia de prefijo
- Sobre qué poner un marcador de caché
- Qué NO cachear (los invalidadores silenciosos)
- Verificando tu tasa de aciertos de caché
- El TTL de 1 hora: cuándo vale la pena el costo extra de escritura
- Pre-calentamiento: hacer que la primera solicitud sea barata
- Prompt caching en bucles agénticos
- Cómo se ve en la factura
- La conclusión del operador
Qué hace realmente el prompt caching
Cada llamada a la API de Claude envía tokens. Sin caché, cada token de tu solicitud —system prompt, definiciones de herramientas, ejemplos few-shot y el mensaje del usuario— se cobra a la tarifa de entrada normal. Con caché, un prefijo de esos tokens se almacena en los servidores de Anthropic después de la primera solicitud. En las solicitudes posteriores que comparten ese prefijo exacto, pagas un precio de lectura de caché en lugar de volver a procesarlos desde cero.
La diferencia de costo es real:
- Escritura de caché: ~1,25× el precio base de entrada (TTL de 5 minutos) o ~2× (TTL de 1 hora)
- Lectura de caché: ~0,1× el precio base de entrada
- Punto de equilibrio: 2 solicitudes con TTL de 5 minutos, 3 solicitudes con TTL de 1 hora
Una vez que superas el punto de equilibrio —lo cual ocurre rápido en cualquier agente que se ejecuta más de unas pocas veces al día— cada acierto de caché adicional es un descuento de ~90% sobre esos tokens.
La regla de coincidencia de prefijo
Esta es la única regla de la que se desprende todo lo demás: la clave de caché es una coincidencia de prefijo de tu prompt renderizado.
Los servidores de Anthropic almacenan el contenido renderizado desde el inicio de tu prompt hasta el marcador cache_control. Para que ocurra un acierto de caché en la siguiente solicitud, cada token desde el inicio del prompt hasta ese marcador debe ser idéntico, byte por byte.
El orden de renderizado para la coincidencia de prefijo es: tools → system → messages. Así que tu arreglo de herramientas se hashea primero, luego el bloque system, y después los mensajes en orden.
Lo que esto significa en la práctica: el contenido estable debe ir primero. Si tu system prompt hace referencia a algo dinámico —una fecha actual, un ID de usuario, un ID de rastreo de solicitud— y aparece antes del marcador cache_control, la caché fallará en cada solicitud porque el prefijo cambia constantemente.
Sobre qué poner un marcador de caché
Los objetivos de mayor impacto son:
1. Tu system prompt
Los system prompts suelen ser el bloque estable más grande. Una persona de agente detallada, una lista de reglas de comportamiento, un conjunto de instrucciones de formato de salida: todo esto es idéntico en cada invocación del mismo agente. Márcalo:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
system: [
{
type: "text",
text: `You are a content operations agent for alejandrorioja.com.
Your job is to draft blog posts in Alejandro's voice: direct, practitioner,
first-person, numbered lists, honest caveats. No hedging. No filler.
Every section must earn its place.
[... 2000 more tokens of stable instructions ...]`,
cache_control: { type: "ephemeral" },
},
],
messages: [
{
role: "user",
content: "Draft a post about prompt caching.",
},
],
});El cache_control: { type: "ephemeral" } en el bloque system le indica a Claude que cachee todo hasta ese bloque, incluyéndolo. El arreglo messages es volátil —distinto en cada solicitud— y queda fuera del límite de la caché.
2. Definiciones de herramientas
Si tu agente usa herramientas, esas definiciones pueden ser considerables. Un esquema de herramienta bien documentado, con descripción, nombres de parámetros y valores enum, puede llegar a 500–1.000 tokens por herramienta. Con 5 herramientas, eso son hasta 5.000 tokens que pagas por reprocesar en cada llamada:
const response = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
tools: [
{
name: "search_airtable",
description: "Search the Airtable content queue...",
input_schema: { type: "object", properties: { query: { type: "string" } } },
},
// ... more tools ...
{
name: "post_to_kit",
description: "Schedule a broadcast via the Kit API...",
input_schema: { /* ... */ },
// Mark the last tool to cache the entire tools array
} as Anthropic.Tool & { cache_control: { type: "ephemeral" } },
],
system: "...",
messages: [...],
});Marca la última herramienta del arreglo. La coincidencia de prefijo cubrirá el arreglo completo de herramientas a partir de ese punto.
3. Ejemplos few-shot en messages
Si pasas ejemplos few-shot estáticos como mensajes iniciales en el arreglo messages, esos también se pueden cachear. Estrúcturalos como los primeros N mensajes y marca el último turno de ejemplo:
const messages: Anthropic.MessageParam[] = [
{
role: "user",
content: [
{
type: "text",
text: "Here are examples of posts in my voice:\n\n[Example 1...]\n\n[Example 2...]",
cache_control: { type: "ephemeral" },
} as Anthropic.TextBlockParam & { cache_control: { type: "ephemeral" } },
],
},
{
role: "assistant",
content: "Understood. I'll follow that voice.",
},
// The actual user turn follows — this is volatile, no cache marker
{
role: "user",
content: actualUserRequest,
},
];Qué NO cachear (los invalidadores silenciosos)
Estas son las cosas que parecen estables pero no lo son, y que arruinarán tu tasa de aciertos en silencio. La API no te avisará. Simplemente verás cache_creation_input_tokens en cada solicitud y te preguntarás por qué.
Timestamps en el system prompt. El error más común con diferencia:
// This invalidates the cache on every request
const system = `You are an agent. Current time: ${new Date().toISOString()}`;Mueve los timestamps al mensaje del usuario, que es donde corresponden:
// Stable system prompt — cacheable
const system = `You are an agent. Use the current time provided by the user.`;
// Volatile user message — not cached
const userMessage = `Current time: ${new Date().toISOString()}. Run the daily brief.`;UUIDs aleatorios e IDs de rastreo. El mismo problema. Si inyectas un ID de rastreo en el bloque system para tus logs, cada solicitud recibe un prefijo nuevo.
Serialización JSON no determinista. Si serializas un objeto dentro del system prompt y el orden de las claves no está garantizado, la cadena renderizada puede diferir aunque los datos subyacentes sean los mismos. Serializa con un orden de claves estable o usa una cadena de plantilla.
Selección dinámica de ejemplos few-shot. Si eliges los ejemplos few-shot según la consulta actual y los colocas en el prefijo cacheado, has hecho que el prefijo “estable” dependa de la consulta. O te comprometes con ejemplos fijos para la capa de caché, o mueves los ejemplos dinámicos al turno de mensaje sin cachear.
Verificando tu tasa de aciertos de caché
Cada respuesta incluye metadatos de uso. Revísalos:
const response = await client.messages.create({ /* ... */ });
console.log({
inputTokens: response.usage.input_tokens,
cacheRead: response.usage.cache_read_input_tokens,
cacheWrite: response.usage.cache_creation_input_tokens,
outputTokens: response.usage.output_tokens,
});En la primera solicitud: cache_creation_input_tokens será distinto de cero y cache_read_input_tokens será 0. Esa es la escritura.
En un acierto de caché: cache_read_input_tokens será distinto de cero y cache_creation_input_tokens será 0. Esa es la lectura.
Si ves cache_creation_input_tokens en cada solicitud, tu prefijo está cambiando. Agrega una sentencia de log que imprima los primeros 200 caracteres de tu system prompt renderizado antes de cada llamada: un timestamp flotante saltará a la vista de inmediato.
El TTL de 1 hora: cuándo vale la pena el costo extra de escritura
El TTL por defecto es de 5 minutos. Si tu agente se ejecuta a baja frecuencia —menos de una vez cada 5 minutos— estarás pagando costos de escritura de caché en la mayoría de las solicitudes sin obtener lecturas.
// Opt into a 1-hour TTL
cache_control: { type: "ephemeral", ttl: "1h" }La escritura con TTL de 1 hora cuesta ~2× el precio base de entrada en lugar de 1,25×. La cuenta: si estás acertando la caché 3 o más veces por hora, el TTL de 1 hora ahorra dinero. Si tu agente se ejecuta una vez al día (como mi resumen diario), ni siquiera el TTL de 1 hora ayudará: pagas costos de escritura cada vez. En ese caso, el beneficio de la caché es modesto a menos que el system prompt sea enorme.
Mi agente de resumen diario tiene un system prompt de 3.000 tokens pero se ejecuta una vez al día. La caché no ayuda. Mi agente de newsletter se ejecuta docenas de veces por sesión mientras redacta: la caché ahorra de forma sustancial.
Pre-calentamiento: hacer que la primera solicitud sea barata
Si sabes que se avecina un pico de tráfico —un trabajo por lotes, el lanzamiento de una API— puedes pre-calentar la caché con una solicitud ficticia de bajo costo:
// Pre-warm: write the cache at near-zero output cost
await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1, // minimal output
system: [{ type: "text", text: stableSystemPrompt, cache_control: { type: "ephemeral" } }],
messages: [{ role: "user", content: "ping" }],
});
// Now the real requests read from cacheEsto es útil sobre todo para el procesamiento por lotes, donde levantas muchas solicitudes en paralelo y quieres que cada una acierte una caché caliente en lugar de competir por escribirla.
Prompt caching en bucles agénticos
En un bucle agéntico de múltiples turnos, el historial de la conversación crece en cada turno. La caché es lo bastante inteligente para manejar esto: usa una ventana de retrospección de 20 bloques, buscando el prefijo coincidente más largo dentro de los últimos 20 bloques de contenido.
La implicación práctica: mantén tu contenido estable (system prompt, definiciones de herramientas) anclado en la parte superior. El historial de conversación creciente al final del arreglo messages no romperá la coincidencia de prefijo de los bloques estables: están antes del contenido volátil, y la coincidencia de prefijo empieza desde arriba.
En la práctica, mis agentes estructuran los turnos así:
System (cached) → Tools (cached) → Few-shot (cached) → Turn 1 → Turn 2 → ... → Current turnLa caché cubre todo hasta el marcador del few-shot. El historial de turnos creciente posterior se reprocesa cada vez, pero eso está bien: esos tokens son específicos de la sesión y pequeños en comparación con el prefijo estable.
Cómo se ve en la factura
Toma un agente de alta frecuencia: 100 llamadas al día, system prompt de 4.000 tokens, precios de Sonnet.
Sin caché:
- 100 × 4.000 tokens × $3/1M = $1,20/día
Con caché (TTL de 5 min, asumiendo 50 llamadas/hora en el pico):
- 1 escritura cada 5 minutos × $3,75/1M × 4.000 tokens = ~$0,02/día en escrituras
- ~98 lecturas/día × $0,30/1M × 4.000 tokens = $0,12/día en lecturas
Eso es una reducción de aproximadamente 90% en esos tokens de entrada. A escala —1.000 llamadas al día— la diferencia se compone aún más. Y esto se suma a cualquier ahorro por enrutamiento de modelos de la matemática de Haiku vs Sonnet: la caché funciona en todos los niveles.
La conclusión del operador
El prompt caching es la optimización de costos más fácil de la Claude API: un campo adicional en los bloques de contenido que ya estás escribiendo. La restricción es la disciplina en torno a la estabilidad del prefijo: nada dinámico antes del marcador de caché. Si logras mantener tu system prompt, tus herramientas y cualquier ejemplo estático libres de contenido volátil, pagarás ~10% del costo de entrada normal en cada acierto de caché. Para agentes de alta frecuencia con prompts estables grandes, esto es una palanca más grande que cambiar de nivel de modelo.
Relacionado: Matemática de costos de agentes de IA: cuándo Haiku le gana a Sonnet · Agentes disparados por eventos vs. agentes programados · Las 5 herramientas de IA que realmente uso para manejar mi negocio
Cada miércoles. 28.400+ operadores. Sin relleno.
✓ Revisa tu bandeja — haz clic en el enlace de confirmación para completar el registro.
✓ ¡Ya estás suscrito!
✓ Ya estás en la lista.
Recibe el manual de IA en tu buzón
Cada miércoles. 28.400+ operadores. Sin relleno.
Revisa tu bandeja de entrada.
Te enviamos un correo de confirmación — haz clic en el enlace para completar tu suscripción. Revisa spam si no lo ves en un minuto.
Ya estás suscrito.
Bienvenido — la próxima edición llegará pronto a tu bandeja.
Ya estás en la lista — búscalo cada miércoles.