Para saber cómo se aplica la retención cero de datos (ZDR) a esta función, consulta API y retención de datos.
El almacenamiento en caché de prompts reduce significativamente la latencia y el costo, pero solo cuando el comienzo de tu prompt es idéntico byte por byte a una solicitud reciente. Una herramienta reordenada, una marca de tiempo interpolada en tu indicación del sistema o una edición a un mensaje anterior pueden invalidar silenciosamente la caché. Sin el diagnóstico de caché, la única señal es que usage.cache_read_input_tokens cae a cero, sin ninguna indicación de qué cambió.
El diagnóstico de caché cierra esa brecha. Pasa el id de tu respuesta anterior, y la API compara las dos solicitudes y te dice dónde divergieron (el modelo, la indicación del sistema, las herramientas o el historial de mensajes) para que puedas corregir la causa raíz en lugar de adivinar.
El diagnóstico de caché está en beta. Incluye el encabezado beta cache-diagnosis-2026-04-07 en tus solicitudes a la API para usar esta función.
El diagnóstico de caché actualmente está disponible solo en la API de Claude. No es compatible con Amazon Bedrock ni Google Cloud.
Cuando el encabezado beta está presente, la API almacena una huella digital ligera de cada solicitud, indexada por el id de la respuesta. En tu siguiente solicitud, incluye ese id como diagnostics.previous_message_id. La API reconstruye la huella digital para la nueva solicitud, la compara con la almacenada y adjunta un objeto diagnostics a la respuesta describiendo el primer punto de divergencia.
La comparación se refiere a la estructura de la solicitud, independientemente de si la caché realmente acertó. Consulta Leer el diagnóstico junto con usage para saber cómo combinar el resultado de diagnostics con usage.cache_read_input_tokens.
Las huellas digitales contienen solo hashes y estimaciones de conteo de tokens (nunca contenido sin procesar del prompt), se retienen por un tiempo limitado, están limitadas a tu organización y espacio de trabajo, y no se usan para ningún otro propósito.
Envía el encabezado beta en cada turno. En el primer turno, pasa "previous_message_id": null para optar por la función sin un mensaje previo con el cual comparar. En los turnos siguientes, pasa el id de la respuesta anterior.
client = anthropic.Anthropic()
SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"
# Turno 1: activar con previous_message_id=None
r1 = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[{"role": "user", "content": "Summarize section 1."}],
diagnostics={"previous_message_id": None},
betas=["cache-diagnosis-2026-04-07"],
)
# Turno 2: referenciar el id de la respuesta anterior
r2 = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
)
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")En las respuestas de streaming, diagnostics aparece en el evento message_start.
# Turno 2: streaming, haciendo referencia al id de la respuesta anterior
with client.beta.messages.stream(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print()
r2 = stream.get_final_message()
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")El evento message_start lleva el campo diagnostics completo; consulta Formato de respuesta para ver los valores posibles.
En una conversación de múltiples turnos, lleva el id de la respuesta más reciente hacia adelante como previous_message_id en cada turno. La primera iteración pasa null para optar por la función; cada iteración subsiguiente pasa el id de la respuesta anterior.
Este flujo de trabajo no se traduce bien a un comando de shell único. Consulta las pestañas de los SDK para ver el patrón del bucle; la solicitud HTTP por turno es idéntica a la de Uso básico.
El campo diagnostics en el Message de la respuesta tiene cuatro estados posibles:
| Valor | Significado |
|---|---|
| campo ausente | La solicitud no incluyó diagnostics, o faltaba el encabezado beta. |
null | O bien previous_message_id era null (primer turno, nada con qué comparar), o se ejecutó una comparación y no se encontró divergencia. |
{"cache_miss_reason": null} | La comparación todavía se estaba ejecutando cuando se serializó la respuesta. Esto puede ocurrir cuando la respuesta comienza muy rápidamente. Trátalo como no concluyente y verifica el siguiente turno. |
{"cache_miss_reason": {...}} | Se adjunta un cache_miss_reason. Para los tipos *_changed, esto identifica el primer punto de divergencia; previous_message_not_found y unavailable son casos en los que no se produjo ninguna comparación. |
Cuando cache_miss_reason no es null, se ve así:
{
"id": "msg_01Xyz...",
"type": "message",
"role": "assistant",
"content": [{ "type": "text", "text": "..." }],
"usage": {
"input_tokens": 42,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 41850,
"output_tokens": 210
},
"diagnostics": {
"cache_miss_reason": {
"type": "system_changed",
"cache_missed_input_tokens": 41850
}
}
}cache_miss_reason es una unión discriminada por type. La respuesta reporta solo la divergencia más temprana, así que corrígela primero; las posteriores pueden estar ocultas detrás de ella.
| Tipo | Qué significa | Qué cambiar |
|---|---|---|
model_changed | El model difiere de la solicitud anterior (por ejemplo, un enrutador, una prueba A/B o un mecanismo de respaldo seleccionó un modelo diferente). La caché es por modelo. | Mantén el modelo constante dentro de una conversación en caché. |
system_changed | El parámetro system difiere. Típicamente se interpoló una marca de tiempo, un ID de solicitud u otro valor por solicitud en la indicación del sistema. | Haz que la indicación del sistema sea una constante estable a nivel de bytes y mueve los datos dinámicos al primer mensaje user después de tu punto de ruptura de caché. |
tools_changed | El arreglo tools difiere: se agregaron, eliminaron o reordenaron herramientas entre turnos, o el JSON de input_schema de la herramienta se serializó de forma no determinista. | Envía la misma lista de herramientas en cada turno en un orden fijo con esquemas serializados de forma determinista (por ejemplo, ordena las claves). |
messages_changed | El modelo, el sistema y las herramientas coinciden, pero una entrada anterior en messages fue alterada, reordenada o eliminada en lugar de solo agregarse al final. Típicamente el historial de la conversación fue truncado o editado, o los turnos del asistente y los bloques tool_result se volvieron a serializar de manera diferente al reenviarlos. | Trata el historial como de solo anexado; devuelve el content del asistente y los resultados de herramientas textualmente. |
previous_message_not_found | No existe ninguna huella digital almacenada para el previous_message_id proporcionado. Esto no es evidencia de que tu solicitud haya cambiado. Típicamente la solicitud anterior no llevaba el encabezado beta, provino de un espacio de trabajo diferente, o ha pasado demasiado tiempo desde que se envió. | Envía el encabezado beta en cada turno y mantén los turnos consecutivos cercanos en el tiempo. |
unavailable | La información de diagnóstico no estuvo disponible para esta solicitud. Esto incluye el caso en que model, system y tools coinciden pero otro parámetro de la solicitud que afecta al prompt (tool_choice, thinking, context_management, output_config, output_format, o el conjunto de encabezados anthropic-beta activos) difiere, y conversaciones muy largas donde la divergencia está más allá del horizonte de comparación. Tu solicitud se procesó normalmente. | Mantén constantes los parámetros de la solicitud que afectan al prompt durante la vida útil de una conversación en caché. Si persiste, aplica las verificaciones manuales en Solución de problemas comunes en la página de almacenamiento en caché de prompts. |
Los cuatro tipos *_changed también llevan un entero cache_missed_input_tokens: una estimación de cuántos tokens de entrada cayeron después del punto de divergencia, dándote una idea de cuánto prefijo almacenable en caché se perdió. Se deriva de longitudes en bytes antes de la tokenización, así que trátalo como un indicador de magnitud en lugar de una cifra de facturación. Puede diferir de (y ocasionalmente exceder) usage.input_tokens.
diagnostics responde "¿cambió mi solicitud?" mientras que usage.cache_read_input_tokens responde "¿acertó la caché?". Combinarlos te dice dónde buscar.
Esta matriz se aplica a los turnos donde pasaste un previous_message_id real. En el primer turno (previous_message_id: null), diagnostics siempre es null y cache_read_input_tokens normalmente es cero porque la caché se está escribiendo, no leyendo; no se necesita ninguna solución de problemas. La matriz tampoco se aplica cuando cache_miss_reason es null (la comparación todavía está pendiente; verifica el siguiente turno) o cuando su type es previous_message_not_found o unavailable (no se produjo ninguna comparación).
| Resultado del diagnóstico | Tokens leídos de caché | Interpretación |
|---|---|---|
null | alto | Funciona como se espera. Tu prefijo es estable y la caché acertó. |
null | bajo o cero | Tus solicitudes coinciden pero la entrada de caché ya no estaba disponible. Considera acortar los intervalos entre turnos o usar el TTL de caché de 1 hora. |
cache_miss_reason es un tipo *_changed | bajo o cero | Es tu error. La solicitud cambió; corrige la causa indicada por type. |
cache_miss_reason es un tipo *_changed | alto | Poco común. Ocurrió un cambio tarde en el prompt pero un punto de ruptura cache_control anterior aún acertó. Vale la pena corregirlo, pero de bajo impacto. |
previous_message_id expiran después de un período corto. Ejecuta comparaciones de diagnóstico entre solicitudes cercanas en el tiempo.unavailable en lugar de una ubicación precisa.unavailable, o cache_miss_reason: null cuando la comparación todavía se estaba ejecutando.El diagnóstico de caché es elegible para ZDR (calificado). Anthropic no almacena el texto sin procesar de tus prompts ni las salidas de Claude para esta función.
La huella digital almacenada para cada solicitud consiste únicamente en hashes criptográficos y estimaciones de conteo de tokens, indexada por el id de la respuesta y limitada a tu organización y espacio de trabajo. Las huellas digitales expiran después de un período corto y no se usan para ningún otro propósito.
Para la elegibilidad de ZDR en todas las funciones, consulta API y retención de datos.
Was this page helpful?