Documentación
caché de prompts
Marca una vez un prefijo estable del prompt con cache_control, o accede a un modelo Claude en formato OpenAI, que no tiene ese campo, y Kunavo colocará los puntos de ruptura por ti. Cada llamada posterior que reutilice el prefijo se factura a una fracción del precio de entrada: 10% del precio de entrada en la mayoría de los modelos de chat, con un mínimo de 2.5%. La capa de enrutamiento de Kunavo mantiene caliente la caché al fijar tu conversación a la misma clave del proveedor upstream.
En un prompt del sistema de 30.000 tokens con Claude Sonnet 5, una lectura de caché cuesta $0.14 / 1M en lugar de $1.4 / 1M. En una sesión en la que un agente vuelve a enviar el mismo contexto 50 veces, la caché ahorra ~90 % de la factura de entrada.
Cómo habilitarlo
Añade un punto de ruptura cache_control: { type: "ephemeral" } a cualquier bloque del sistema, mensaje o definición de herramienta. El modelo almacena en caché el tramo hasta ese punto de ruptura en la primera llamada; las llamadas posteriores que compartan los mismos bytes de prefijo accederán a la caché.
from openai import OpenAI
client = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1",
)
# Mark the large, stable prefix once with cache_control.
# Every subsequent call that sends the same prefix reads it back
# from cache at 0.10× the input rate on Claude Sonnet 5.
# Per-model rates are in the pricing table below.
SYSTEM = [
{
"type": "text",
"text": open("long_system_prompt.txt").read(),
"cache_control": {"type": "ephemeral"},
},
]
resp = client.chat.completions.create(
model="claude-sonnet-5",
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": "Summarize the doc above in 3 bullets."},
],
)
u = resp.usage
# OpenAI-compat fields populated by Kunavo:
# - prompt_tokens_details.cached_tokens — read from cache
# - cache_creation_input_tokens — written to cache this call
print(u.prompt_tokens_details.cached_tokens,
getattr(u, "cache_creation_input_tokens", 0))Formato de transmisión idéntico al de la API nativa Messages: cache_control se transmite a Claude sin traducir:
# Native Anthropic Messages API — cache_control passes through untranslated.
curl https://api.kunavo.com/v1/messages \
-H "Authorization: Bearer $KUNAVO_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-5",
"system": [
{
"type": "text",
"text": "<your large stable system prompt>",
"cache_control": { "type": "ephemeral" }
}
],
"messages": [
{ "role": "user", "content": "Summarize the doc above in 3 bullets." }
],
"max_tokens": 1024
}'Puntos de ruptura automáticos en los endpoints en formato OpenAI
Los formatos OpenAI Chat Completions y Responses no tienen ningún campo cache_control: OpenAI almacena contenido en caché implícitamente en sus propios servidores. Claude no lo hace: solo almacena en caché lo que marca un punto de ruptura. Por tanto, un cliente que se comunica en formato OpenAI no tiene forma de solicitar el almacenamiento en caché, y una traducción directa de su solicitud llega a Claude sin ningún punto de ruptura; así, cada turno de una conversación larga vuelve a facturar todo el historial a la tarifa de entrada completa.
Por eso, cuando accedes a un modelo Claude a través de /v1/chat/completions o /v1/responses, Kunavo establece los puntos de ruptura que el protocolo no puede transmitir. No tienes que activar nada. Esto solo se aplica a los modelos Claude: todas las demás familias se ofrecen mediante un protocolo cuyo proveedor almacena contenido en caché de forma implícita, sin necesidad de colocar puntos de ruptura.
# Plain OpenAI Chat Completions — no cache_control anywhere in the body.
# The format has no field for one; Kunavo inserts the breakpoints instead.
resp = client.chat.completions.create(
model="claude-sonnet-5",
messages=[
{"role": "system", "content": LONG_SYSTEM_PROMPT},
{"role": "user", "content": "first question"},
{"role": "assistant", "content": "...previous answer..."},
{"role": "user", "content": "follow-up"},
],
)
u = resp.usage
# Turn that writes the cache:
# u.cache_creation_input_tokens -> 18,000
# u.prompt_tokens_details.cached_tokens -> 0
# Next turn, same prefix, inside the 5-minute window:
# u.cache_creation_input_tokens -> 240 (only the new turn)
# u.prompt_tokens_details.cached_tokens -> 18,000
#
# Both stuck at 0 on a conversation well over the threshold? The prefix is
# changing between calls — a timestamp or request id inside the cached span.Dónde se colocan y en qué orden se consume el presupuesto:
- Un punto de ruptura móvil en el último mensaje: en el último bloque de contenido del último mensaje, para almacenar en caché todo lo anterior; si la solicitud termina con un mensaje de sistema que permanece en la conversación (ver más abajo), se coloca en cambio en el bloque justo anterior a ese mensaje. Solo se añade cuando
messagesya contiene un turno del asistente: una escritura en caché se factura a1.25×de la entrada, así que marcar un prompt que nadie volverá a enviar cuesta una cuarta parte más y no ahorra nada. Un turno previo del asistente demuestra que este prefijo exacto está a punto de volver a recibirse. - Uno en
systemy otro entools: el encabezado estable del prompt. Conviene marcarlo incluso en una llamada de un solo uso, porque quien envía un prompt del sistema una vez casi siempre vuelve a enviar el mismo en la siguiente llamada. - Delante de un mensaje de sistema que permanece en la conversación: lo que el punto móvil y los puntos en
systemytoolsdejen del presupuesto, en el bloque justo anterior al último mensaje de ese tipo que tenga algo después, y luego delante del anterior. Se ocupa en último lugar, porque solo lo necesita un cliente que mueve un mensaje así de un turno a otro; una conversación sin mensajes de ese tipo, que son casi todas, no tiene esta posición.
Hay dos límites. Si el prompt tiene menos de 8,192 caracteres —sumando los mensajes, system y los esquemas de herramientas—, no se inserta nada: Anthropic ignora silenciosamente un punto de ruptura en un prefijo cuya longitud es inferior a su mínimo almacenable en caché (1,024 tokens, 2,048 en Haiku) y no cobra ni una escritura ni una lectura, por lo que colocarlo ahí no serviría de nada. Además, Anthropic acepta como máximo 4 puntos de ruptura por solicitud: un quinto provoca un error 400, no se ignora silenciosamente.
Un mensaje de sistema o de desarrollador enviado después de la primera respuesta del modelo permanece en la conversación, en el turno en que se envió, en lugar de subirse a system: subirlo cambiaría el inicio del prompt en el turno en que se añade y volvería a escribir todo el historial en la caché. Claude lo recibe como mensaje de sistema donde el proveedor upstream lo acepta y, si no, como texto dentro de ese turno del usuario, entre etiquetas <system-reminder>. Un mensaje de sistema enviado antes de la primera respuesta del modelo, o uno cuyo propio punto de ruptura pide la caché de una hora, sigue yendo a system.
/v1/messages, no se inserta nada: el cuerpo se transmite tal como lo enviaste y todos los puntos de ruptura que contiene son tuyos.Los informes no cambian: se rellenan los mismos campos cached_tokens y cache_creation_input_tokens descritos en Campos de respuesta, tanto si los puntos de ruptura los añadiste tú como si los insertó la pasarela. Por tanto, el objeto de uso permite comprobar si un punto de ruptura insertado realmente produjo un acierto.
Precios
Las tarifas de caché se derivan del precio de entrada de cada modelo, según las proporciones establecidas por cada proveedor; las tablas siguientes son la referencia y todas las tarifas se calculan a partir del precio de entrada de ese modelo, en lugar de introducirse manualmente. Las lecturas de caché se facturan a 0.10× de la entrada tanto en Anthropic como en OpenAI, con 2 excepciones: 0.025× on Claude Fable 5.1, 0.05× on Claude Opus 5.5. Las escrituras en caché se facturan a 1.25× de la entrada en todos los modelos Claude y en GPT-6 Astra, GPT-6 Sol, GPT-6 Luna, GPT-5.6 Sol y GPT-5.6 Terra. Kunavo factura las escrituras con TTL de 1 hora de Claude al mismo 1.25×, por debajo del 2× de Anthropic. Todos los demás modelos no tienen un precio de escritura aparte: sus escrituras se facturan a la tarifa de entrada normal. En cualquier caso, un prefijo que se reutilice al menos una vez cuesta menos almacenado en caché que si se envía de nuevo. Cada categoría mantiene el descuento propio del modelo, por lo que sus precios de caché tienen el mismo descuento respecto a la tarifa de lista del proveedor que sus precios de entrada y salida.
Anthropic
| Model | Input | Cache read | Cache write |
|---|---|---|---|
| Claude Fable 5.1 | $7 | $0.175 0.025× | $8.75 1.25× |
| Claude Fable 5 | $7 | $0.7 0.10× | $8.75 1.25× |
| Claude Opus 5.5 | $2.8 | $0.14 0.050× | $3.5 1.25× |
| Claude Opus 5 | $3.5 | $0.35 0.10× | $4.375 1.25× |
| Claude Opus 4.8 | $3.5 | $0.35 0.10× | $4.375 1.25× |
| Claude Opus 4.7 | $3.5 | $0.35 0.10× | $4.375 1.25× |
| Claude Opus 4.6 | $3.5 | $0.35 0.10× | $4.375 1.25× |
| Claude Sonnet 5 | $1.4 | $0.14 0.10× | $1.75 1.25× |
| Claude Sonnet 4.6 | $2.1 | $0.21 0.10× | $2.625 1.25× |
| Claude Haiku 4.5 | $0.7 | $0.07 0.10× | $0.875 1.25× |
OpenAI
| Model | Input | Cache read | Cache write |
|---|---|---|---|
| GPT-6 Astra | $4 | $0.4 0.10× | $5 1.25× |
| GPT-6 Sol | $0.8 | $0.08 0.10× | $1 1.25× |
| GPT-6 Luna | $0.04 | $0.004 0.10× | $0.05 1.25× |
| GPT-5.6 Sol | $2 | $0.2 0.10× | $2.5 1.25× |
| GPT-5.6 Terra | $0.7 | $0.07 0.10× | $0.875 1.25× |
| GPT-5.5 | $2 | $0.2 0.10× | $2 1× |
max(catalog_cost, upstream × markup) por llamada: el precio mínimo se calcula según la tarifa de entrada almacenada en caché, no la tarifa normal, para que el ahorro te llegue en lugar de quedar anulado.El enrutamiento por afinidad mantiene caliente la caché
Las cachés de prompts del proveedor upstream son específicas de cada clave de API. Si cada solicitud llega a una clave de proveedor upstream aleatoria, la tasa de aciertos de caché es ~1/N. Kunavo deriva un hash estable de tu prompt del sistema + el primer mensaje del usuario y enruta todas las llamadas con el mismo prefijo a la misma clave del proveedor upstream. Utiliza hashing de rendezvous ponderado, por lo que solo se reasigna ~1/N de las claves cuando cambia el grupo.
No tienes que configurar nada. El enrutamiento por afinidad se aplica automáticamente a todas las llamadas de chat. (Las imágenes, el video y TTS usan enrutamiento aleatorio: no existe una caché por clave para esas modalidades).
Métricas del panel
Cuando tus llamadas empiecen a tener aciertos de caché, /app/usage mostrará dos métricas agregadas para el intervalo seleccionado:
- Tasa de aciertos: tokens de entrada almacenados en caché ÷ total de tokens de entrada. Cálculo exacto a partir de los recuentos de tokens por llamada.
- Ahorro: USD ahorrados durante este intervalo, calculados por modelo con su tarifa real de lectura de caché (sin aproximaciones mediante promedios generales). Es una estimación a precios de catálogo: dado que las facturas reales tienen un mínimo igual al precio del catálogo y las llamadas con aciertos de caché pueden quedar por debajo de ese mínimo, la cifra es un límite superior ajustado del ahorro real. En las cargas de trabajo de chat habituales, ambas cifras difieren en unos pocos puntos porcentuales.
La página de detalles de cada llamada (/app/usage/<id>) muestra los recuentos de tokens almacenados en caché y de escritura en caché cuando son distintos de cero, así como el importe facturado real.
Campos de respuesta
Kunavo muestra los tokens de caché en ambos formatos de respuesta. En el endpoint compatible con OpenAI /v1/chat/completions:
| Campo | Significado |
|---|---|
usage. | Total de tokens de entrada (incluye los almacenados en caché y los de escritura en caché). |
usage. | Subconjunto de la entrada servido desde la caché. |
usage. | Tokens escritos en la caché durante esta llamada (se facturan según la tarifa de escritura en caché del modelo, indicada en las tablas anteriores). |
En la API nativa Messages, en /v1/messages, se transmiten los campos originales de Anthropic:
| Campo | Significado |
|---|---|
input_tokens | Entrada nueva (no almacenada en caché). |
cache_ | Servido desde la caché y facturado a 0.10× de la entrada (0,025× en Claude Fable 5.1, 0,05× en Claude Opus 5.5). |
cache_ | Escrito en la caché durante esta llamada (se factura a 1.25× la entrada; también las escrituras con TTL de 1 hora, por debajo del 2× de Anthropic). |
Próximos pasos
- Referencia de la API Messages: formato nativo de Anthropic con ejemplos completos de caché.
- Almacenamiento en caché de prompts de Claude: cifras del objeto de uso que permiten diagnosticar una caché y tres formas en que el enrutamiento a través de una pasarela reduce la tasa de aciertos.
- Facturación y libro mayor: cómo interactúa el precio mínimo max() que tiene en cuenta la caché con el costo upstream.
- Tabla de precios completa: precios de entrada y salida sin caché para todos los modelos de chat, con la tabla secundaria de caché al final.