Conceptos básicos del almacenamiento en caché de prompts
8 ejemplos para empezar con el almacenamiento en caché de prompts: 5 básicos y 3 intermedios.
Prerrequisitos
- Instala el SDK:
pip install anthropic - Configura tu clave API en el entorno:
export ANTHROPIC_API_KEY=sk-ant-... - Todos los ejemplos a continuación usan
anthropic.Anthropic(), que lee esa variable de entorno automáticamente.
Ejemplos básicos
1. Añadir un único breakpoint cache_control
Marca el final de un prompt del sistema largo como almacenable en caché.
import anthropic
client = anthropic.Anthropic()
long_policy_text = "Eres el asistente de soporte de Acme Corp. " * 300
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
system=[
{
"type": "text",
"text": long_policy_text,
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "¿Cuál es tu plazo de reembolso?"}],
)
print(response.content[0].text)cache_controlse establece en el bloque de contenido del sistema, no en la solicitud en su conjunto.- Todo hasta e incluyendo este bloque es elegible para el almacenamiento en caché.
- La primera llamada siempre escribe en la caché; aún no puede ser un acierto.
{"type": "ephemeral"}utiliza el TTL predeterminado de 5 minutos.
Relacionado: Cómo funciona realmente la coincidencia de prefijos del almacenamiento en caché de prompts - por qué esto tiene que ser idéntico en bytes para acertar.
2. Comprobar usage.cache_creation_input_tokens en la primera llamada
Confirma que la primera solicitud escribió una entrada de caché.
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
system=[
{
"type": "text",
"text": long_policy_text,
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "¿Cuál es tu plazo de reembolso?"}],
)
print("tokens de escritura de caché:", response.usage.cache_creation_input_tokens)
print("tokens de lectura de caché:", response.usage.cache_read_input_tokens)cache_creation_input_tokensdebería ser distinto de cero aquí: esa es la escritura en caché.cache_read_input_tokensdebería ser0en esta primera llamada, ya que no había nada que leer todavía.- Estos campos residen en
response.usage, junto con losinput_tokensyoutput_tokensnormales.
3. Repetir la misma solicitud y confirmar un acierto de caché
Envía un prefijo idéntico de nuevo dentro de la ventana TTL.
response_2 = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
system=[
{
"type": "text",
"text": long_policy_text,
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "¿Hacen envíos internacionales?"}],
)
print("tokens de lectura de caché:", response_2.usage.cache_read_input_tokens)- El bloque
systemes idéntico en bytes al del ejemplo 1, por lo que el prefijo coincide. - Solo el último mensaje del usuario cambió, y se encuentra después del breakpoint.
cache_read_input_tokensdebería ser ahora distinto de cero: este es el acierto de caché.- La respuesta sigue respondiendo correctamente a la nueva pregunta; el almacenamiento en caché solo evita reprocesar el prefijo compartido.
4. Establecer un TTL explícito
Elige la ventana de caché de 1 hora en lugar del valor predeterminado de 5 minutos.
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
system=[
{
"type": "text",
"text": long_policy_text,
"cache_control": {"type": "ephemeral", "ttl": "1h"},
}
],
messages=[{"role": "user", "content": "¿Cuál es tu plazo de reembolso?"}],
)"ttl": "1h"extiende cuánto tiempo sobrevive una entrada antes de que deba ser reescrita.- El TTL de 1 hora tiene un multiplicador de coste de escritura en caché más alto que el valor predeterminado de 5 minutos.
- Omitir
ttles lo mismo que"5m". - Elige 1 hora para sesiones que probablemente abarquen más de unos pocos minutos entre llamadas.
Relacionado: Opciones de TTL de caché y referencia de precios - comparación completa de las dos ventanas.
5. Almacenar en caché definiciones de herramientas en lugar del prompt del sistema
Coloca el breakpoint en un esquema de herramienta grande.
tools = [
{
"name": "search_docs",
"description": "Busca en la base de conocimiento interna." * 20,
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
"cache_control": {"type": "ephemeral"},
}
]
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
tools=tools,
messages=[{"role": "user", "content": "Busca nuestra política de vacaciones."}],
)cache_controlpuede ir en la última herramienta de una listatools, no solo ensystem.- Las herramientas se evalúan antes del prompt del sistema en el prefijo efectivo.
- Esto vale la pena hacerlo cuando tienes muchos esquemas de herramientas grandes que rara vez cambian.
- Un catálogo de herramientas estable junto con un prompt del sistema cambiante aún puede almacenar en caché las herramientas por separado.
Ejemplos intermedios
6. Superponer dos breakpoints: Herramientas y Sistema
Almacena en caché herramientas y el prompt del sistema como dos segmentos separados y actualizables de forma independiente.
tools = [
{
"name": "search_docs",
"description": "Busca en la base de conocimiento interna." * 20,
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
"cache_control": {"type": "ephemeral"},
}
]
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
tools=tools,
system=[
{
"type": "text",
"text": long_policy_text,
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "¿Cuál es tu plazo de reembolso?"}],
)
print(response.usage.cache_read_input_tokens, response.usage.cache_creation_input_tokens)- El breakpoint de las herramientas almacena en caché los esquemas de herramientas como su propio segmento de prefijo.
- El breakpoint del sistema almacena en caché las herramientas + el sistema como un segundo segmento más largo.
- Si solo cambia el prompt del sistema, el segmento de herramientas aún puede acertar mientras que el segmento del sistema se reescribe.
- Dos breakpoints es el límite práctico para la mayoría de los prompts cotidianos; más que eso añade contabilidad sin mucho beneficio adicional.
Relacionado: Colocación de breakpoints
cache_controlen prompts del sistema y herramientas - las reglas de ordenación completas.
7. Crear un pequeño ayudante que registre la efectividad de la caché
Envuelve una llamada para que cada solicitud informe su tasa de aciertos de caché.
def call_with_cache_report(client, **kwargs):
response = client.messages.create(**kwargs)
usage = response.usage
total_prefix = usage.cache_read_input_tokens + usage.cache_creation_input_tokens
hit_rate = (
usage.cache_read_input_tokens / total_prefix if total_prefix else 0.0
)
print(
f"lectura={usage.cache_read_input_tokens} "
f"escritura={usage.cache_creation_input_tokens} "
f"tasa_acierto={hit_rate:.0%}"
)
return response
call_with_cache_report(
client,
model="claude-sonnet-5",
max_tokens=200,
system=[
{
"type": "text",
"text": long_policy_text,
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "¿Cuál es tu plazo de reembolso?"}],
)- Centralizar esta comprobación en un único ayudante hace que las regresiones de caché sean visibles en los registros en lugar de estar enterradas en objetos de respuesta individuales.
- Una
tasa_aciertoque cae inesperadamente al0%es la primera señal de que algo upstream cambió el prefijo. - Este patrón se escala limpiamente para envolver cada llamada a
messages.createen una aplicación más grande. - Considera emitir estos números a tu sistema de métricas en lugar de solo imprimirlos.
Relacionado: Verificación de aciertos de caché con
cache_read_input_tokens- una mirada más profunda a la creación de este tipo de comprobación.
8. Combinar un prompt del sistema almacenado en caché con una conversación en crecimiento
Mantén el prompt del sistema almacenado en caché mientras que el array de mensajes crece turno a turno.
conversation = [{"role": "user", "content": "¿Cuál es tu plazo de reembolso?"}]
def cached_turn(client, conversation, user_text):
if user_text:
conversation.append({"role": "user", "content": user_text})
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=300,
system=[
{
"type": "text",
"text": long_policy_text,
"cache_control": {"type": "ephemeral"},
}
],
messages=conversation,
)
conversation.append({"role": "assistant", "content": response.content[0].text})
return response
r1 = cached_turn(client, conversation, None)
r2 = cached_turn(client, conversation, "¿Y para los artículos abiertos?")
print(r2.usage.cache_read_input_tokens)- El breakpoint del prompt del sistema permanece idéntico entre turnos, por lo que sigue acertando en la caché incluso a medida que
conversationcrece. - Solo el array de mensajes, que se encuentra después del breakpoint, cambia entre turnos.
- Este es el patrón semilla para el almacenamiento en caché de agentes de múltiples turnos, cubierto con más detalle en otra parte de esta sección.
- Ten en cuenta el crecimiento del contexto: una conversación de larga duración eventualmente necesita ser recortada independientemente del almacenamiento en caché.
Relacionado: Estrategia de caché para conversaciones de agentes de múltiples turnos - colocación de breakpoints por turno para conversaciones en crecimiento.
Versiones de la pila: Escrito contra la línea de modelos Claude actual a partir de ~junio de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado) y Claude Haiku 4.5 - y el SDK oficial
anthropicde Python (última versión 0.x). Los nombres de los modelos, las versiones del SDK y los precios cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs antes de confiar en ellos.