Prompt Caching en Claude: reduce tu factura de API un 90%
El mes pasado revisé los gastos de API de un proyecto que lleva seis semanas en producción. Un agente conversacional para análisis de documentos legales. El cliente lo usa unas 40 veces al día.
La factura: $340 en un mes.
El system prompt tenía 8.000 tokens. Las definiciones de herramientas, otros 3.000. En cada llamada, esos 11.000 tokens se procesaban desde cero. Cuarenta veces al día. Treinta días al mes.
Activé prompt caching. La siguiente factura: $38.
No cambié la lógica del agente. No modifiqué los prompts. Solo añadí tres líneas de configuración.
Eso es lo que hace el prompt caching de Claude. Y la mayoría de developers que trabajan con la API de Anthropic aún no lo tienen activado.
Qué es el prompt caching y cómo funciona
Cuando haces una llamada a la API de Claude, pagas por cada token que el modelo procesa. System prompt, herramientas, historial de conversación, contexto de documentos: todo se cobra como tokens de entrada.
El problema es que en la mayoría de aplicaciones reales, una parte enorme de esos tokens es idéntica en cada llamada. Tu system prompt no cambia. Las definiciones de tus herramientas no cambian. El contexto de un documento que estás analizando no cambia entre preguntas del usuario.
El prompt caching te permite marcar esas partes estáticas para que Claude las almacene en caché. La documentación oficial de prompt caching cubre todos los modelos y casos edge. La primera vez que se procesa ese contenido, se escribe en caché. En las llamadas posteriores, en lugar de reprocesar esos tokens, Claude los lee desde el caché.
El coste de un cache write es 1.25x el precio base — ligeramente más caro que una llamada normal. El coste de un cache read es 0.1x el precio base. Es decir, un 90% más barato.
En un agent loop con 40 llamadas al día, pagas el 1.25x una vez. Las otras 39 veces pagas el 0.1x. La aritmética es brutal a tu favor.
El TTL del caché
El caché tiene un TTL (Time To Live) de 5 minutos por defecto. Mientras haya llamadas dentro de esa ventana, el caché se renueva automáticamente sin coste adicional. Si una conversación tiene mensajes frecuentes, el caché se mantiene activo.
Existe también un TTL de 1 hora, que cuesta 2x el precio base en la escritura. Útil cuando tienes contextos que se reutilizan con menos frecuencia pero son muy costosos de regenerar.
El mínimo de tokens para activar el caché
No todo se puede cachear. El sistema exige un mínimo de tokens para crear una entrada de caché. Para claude-sonnet-4-6 y claude-opus-4-8, el mínimo es 1.024 tokens. Para claude-haiku-4-5, el umbral sube a 4.096 tokens — cuatro veces más alto, relevante si usas Haiku con prompts cortos. Si tu system prompt tiene menos tokens que el mínimo de tu modelo, el caché no se activa.
En proyectos donde el system prompt es corto, la estrategia correcta es incluir el contexto del dominio directamente en el system prompt hasta superar ese umbral, o cachear las definiciones de herramientas junto con el sistema.
Cómo habilitarlo: código TypeScript con el SDK oficial
Aquí está el patrón que uso en producción. Nada de magia — tres cambios concretos en tu código.
Habilitación básica: system prompt con cache_control
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
system: [
{
type: "text",
text: `Eres un asistente especializado en análisis de documentos legales.
Tu rol es:
- Identificar cláusulas de riesgo en contratos
- Resumir términos clave de forma clara y precisa
- Señalar inconsistencias o ambigüedades legales
- Comparar términos con estándares del sector
[...aquí va el resto del system prompt extenso, con contexto del dominio,
instrucciones detalladas, ejemplos de formato de respuesta, etc.
Debe superar los 1.024 tokens para activar el caché...]`,
cache_control: { type: "ephemeral" }, // <-- esto es todo lo que necesitas
},
],
messages: [
{
role: "user",
content: "Analiza la cláusula de terminación de este contrato: ...",
},
],
});
console.log(response.usage);
En la primera llamada, usage mostrará:
{
"input_tokens": 45,
"cache_creation_input_tokens": 1280,
"cache_read_input_tokens": 0,
"output_tokens": 312
}
En la segunda llamada (dentro de los 5 minutos):
{
"input_tokens": 45,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 1280,
"output_tokens": 289
}
cache_read_input_tokens tiene el 10% del coste. El system prompt completo se leyó desde caché. Esos 1.280 tokens no se procesaron desde cero.
Cacheando herramientas y system prompt juntos
Cuando tienes definiciones de herramientas largas — algo habitual en agentes con MCP o con múltiples funciones — el ahorro se multiplica. Aquí el patrón para cachear ambas cosas:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
// Las definiciones de herramientas son estáticas — candidatas perfectas para caché
const tools: Anthropic.Tool[] = [
{
name: "search_legal_database",
description: `Busca en la base de datos legal precedentes y jurisprudencia relevante.
Usa esta herramienta cuando necesites comparar cláusulas con casos anteriores o
encontrar interpretaciones judiciales de términos específicos. La búsqueda incluye
bases de datos de España, México, Argentina y Colombia. Devuelve hasta 10 resultados
ordenados por relevancia con fecha, tribunal y resumen del caso.`,
input_schema: {
type: "object" as const,
properties: {
query: {
type: "string",
description: "Término o frase legal a buscar",
},
jurisdiction: {
type: "string",
enum: ["ES", "MX", "AR", "CO", "ALL"],
description: "Jurisdicción a consultar",
},
date_range: {
type: "string",
description: "Rango de fechas en formato YYYY-YYYY",
},
},
required: ["query"],
},
},
{
name: "analyze_clause_risk",
description: `Analiza el nivel de riesgo de una cláusula contractual.
Evalúa factores como onerosidad excesiva, cláusulas abusivas según legislación
vigente, asimetría de obligaciones y exposición a penalidades. Devuelve un score
de riesgo del 1 al 10 con justificación detallada y recomendaciones de negociación.`,
input_schema: {
type: "object" as const,
properties: {
clause_text: {
type: "string",
description: "Texto completo de la cláusula a analizar",
},
contract_type: {
type: "string",
description: "Tipo de contrato (laboral, mercantil, arrendamiento, etc.)",
},
},
required: ["clause_text"],
},
},
// cache_control al final del array de tools — marca el punto de caché
];
// Añadimos cache_control al último tool para cachear todo el bloque
const toolsWithCache = tools.map((tool, index) =>
index === tools.length - 1
? { ...tool, cache_control: { type: "ephemeral" as const } }
: tool
);
const response = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 2048,
system: [
{
type: "text",
text: "Eres un asistente especializado en análisis legal...",
cache_control: { type: "ephemeral" }, // system prompt cacheado
},
],
tools: toolsWithCache, // tools cacheadas
messages: [
{
role: "user",
content: "¿Cuál es el riesgo de esta cláusula de no competencia?",
},
],
});
Monitorizar el ahorro en tiempo real
Esta función te dice exactamente cuánto has ahorrado en cada llamada:
interface CostMonitor {
inputTokensCost: number;
cacheWriteCost: number;
cacheReadCost: number;
outputTokensCost: number;
totalCost: number;
savings: number;
savingsPercent: number;
}
// Precios para claude-sonnet-4-6 por millón de tokens (en dólares)
const PRICING = {
input: 3.0,
cacheWrite: 3.75, // 1.25x
cacheRead: 0.3, // 0.1x
output: 15.0,
};
function calculateCallCost(usage: Anthropic.Usage): CostMonitor {
const inputCost = (usage.input_tokens / 1_000_000) * PRICING.input;
const cacheWriteCost =
((usage.cache_creation_input_tokens ?? 0) / 1_000_000) * PRICING.cacheWrite;
const cacheReadCost =
((usage.cache_read_input_tokens ?? 0) / 1_000_000) * PRICING.cacheRead;
const outputCost = (usage.output_tokens / 1_000_000) * PRICING.output;
const totalCost = inputCost + cacheWriteCost + cacheReadCost + outputCost;
// Coste hipotético sin caché (todos los tokens al precio base)
const totalInputTokens =
usage.input_tokens +
(usage.cache_creation_input_tokens ?? 0) +
(usage.cache_read_input_tokens ?? 0);
const costWithoutCache =
(totalInputTokens / 1_000_000) * PRICING.input + outputCost;
const savings = costWithoutCache - totalCost;
const savingsPercent =
costWithoutCache > 0 ? (savings / costWithoutCache) * 100 : 0;
return {
inputTokensCost: inputCost,
cacheWriteCost,
cacheReadCost,
outputTokensCost: outputCost,
totalCost,
savings,
savingsPercent,
};
}
// Uso:
const monitor = calculateCallCost(response.usage);
console.log(`Ahorro: $${monitor.savings.toFixed(6)} (${monitor.savingsPercent.toFixed(1)}%)`);
Qué debes cachear y qué no
Los mejores candidatos para el caché
System prompts largos. Es el caso más obvio. Si tu system prompt tiene instrucciones de rol, reglas de formato, contexto del dominio y ejemplos, estás mirando fácilmente 2.000-8.000 tokens que se repiten en cada llamada. Cachear el system prompt es lo primero que debes activar.
Definiciones de herramientas (tools). Especialmente en agentes con MCP o con muchas funciones. Las definiciones de tools incluyen nombres, descripciones detalladas y schemas completos. Pueden sumar 3.000-5.000 tokens fácilmente. Son siempre estáticas dentro de una sesión.
Contexto de documentos. Si tu aplicación analiza un documento largo (un contrato, una especificación técnica, un PDF), ese documento va en el mensaje del usuario pero cambia muy poco. Puedes cachearlo con cache_control en el bloque del contenido del mensaje.
Historial de conversación en agent loops. En un loop donde el agente tiene muchos turnos, cachear el historial acumulado evita pagar por reprocesar el contexto completo en cada iteración.
Qué NO debes cachear
El turno actual del usuario. Es el error más común. El mensaje que el usuario acaba de escribir cambia en cada llamada — si intentas cachearlo, el caché nunca tendrá un hit porque el contenido es siempre distinto.
Tokens de extended thinking. Si usas extended thinking con Claude, los tokens del proceso de razonamiento interno no se cachean. Esto es relevante si estás midiendo ahorros en pipelines que usan thinking — los números no escalarán de la misma forma.
Contenido que cambia con frecuencia. Si tienes un bloque de contexto que se actualiza cada pocos minutos (resultados de una búsqueda en tiempo real, estado de una sesión volátil), no tiene sentido marcarlo para caché porque nunca habrá un hit.
Bloques demasiado pequeños. Si un bloque tiene menos de 1.024 tokens, el sistema no lo cacheará. No añadas cache_control a fragmentos pequeños — solo añade latencia sin beneficio.
Comparación de coste: sin caching vs con caching
Escenario real: un agente con 40 llamadas diarias durante 30 días.
- System prompt: 5.000 tokens
- Tools: 3.000 tokens
- Pregunta del usuario: ~100 tokens (variable)
- Respuesta del modelo: ~400 tokens (variable)
- Modelo:
claude-sonnet-4-6
| Escenario | Coste por llamada | Total mensual |
|---|---|---|
| Sin caching (8.100 input + 400 output) | $0.0303 | $36.36 |
| Con caching — 1ª llamada del día (cache write 8.000 + 100 input + 400 output) | $0.037 | — |
| Con caching — llamadas 2–40 (cache read 8.000 + 100 input + 400 output) | $0.0084 | — |
| Con caching — total diario (1ª + 39 × $0.0084) | $0.365/día | $10.95 |
Ahorro: 70%. Y esto asumiendo que el caché expira cada día. Con conversaciones más densas donde el TTL de 5 minutos se aprovecha bien, el ahorro sube al 85-90%.
Preguntas frecuentes sobre prompt caching en Claude
¿El caché es compartido entre usuarios?
No. El caché es privado por workspace de Anthropic. Desde febrero de 2026, hay aislamiento completo por workspace. Los datos de un usuario nunca se mezclan con los de otro.
¿Qué pasa si cambio el system prompt? ¿Se invalida el caché?
Sí. El caché funciona por contenido exacto. Si modificas un solo carácter del bloque cacheado, se genera una nueva entrada de caché (cache write) en la siguiente llamada. El caché anterior expira según su TTL sin coste adicional.
¿Puedo cachear múltiples bloques en la misma llamada?
Sí, hasta un máximo de cuatro breakpoints de caché por request. La restricción importante es el orden: los bloques con TTL más largo (1 hora) deben aparecer antes que los de TTL más corto (5 minutos) en la estructura del request.
¿El caching funciona con streaming?
Sí. El prompt caching es compatible con la API de streaming de Claude. Los campos cache_creation_input_tokens y cache_read_input_tokens aparecen en el evento message_start del stream — no en message_delta. Es el primer evento emitido, antes de que lleguen los tokens de respuesta.
El siguiente nivel: combinar con Claude Code
Si ya estás explorando agentes más complejos, el prompt caching cambia la ecuación de coste de forma radical. Un agent loop sin caching que hace 10 iteraciones paga los tokens del system prompt y las tools diez veces. Con caching, los paga una vez y lee el resto.
En Claude Code: Effort, Models, Tools y Context hay una sección completa sobre cómo gestiona Claude Code el contexto en agent loops largos — es el contexto perfecto para entender dónde encaja el caching a nivel de infraestructura.
Y si quieres construir productos reales sobre la API de Anthropic con esta clase de optimizaciones ya integradas desde el primer sprint, el curso Construye con IA: De la Idea al Producto con Claude cubre el stack completo — desde la arquitectura del agente hasta el control de costes en producción.
Lo que puedes hacer hoy
Si tienes una aplicación que usa la API de Claude en producción, abre el código y busca dónde defines el system prompt. Si es una cadena de texto plana, conviértela en un array con cache_control: { type: "ephemeral" }.
Eso solo. Una línea de cambio. Comprueba la siguiente factura.
Si además tienes tools largas, aplica el mismo patrón al último elemento del array de herramientas. Tendrás dos puntos de caché activos y el ahorro será inmediato.
El prompt caching no es una optimización avanzada que requiere rediseñar tu arquitectura. Es una configuración de tres minutos que debería estar activa en cualquier aplicación seria sobre la API de Claude. Si no la tienes, estás pagando de más desde el primer día.
Bezael Pérez — Fundador de Dominicode. Developer senior con 15+ años construyendo software. Si construyes con IA y quieres profundizar más allá de los tutoriales, en Dominicode Labs estamos trabajando en proyectos reales con la API de Anthropic, arquitecturas de agentes y todo lo que no cabe en un post.
