Was this page helpful?
Esta función califica para Zero Data Retention (ZDR) (retención cero de datos) con retención técnica limitada. Consulta la sección Retención de datos para obtener detalles sobre qué se retiene y por qué.
El prompt caching (almacenamiento en caché de prompts) reduce significativamente la latencia y el costo, pero solo cuando el inicio 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 en un mensaje anterior pueden invalidar silenciosamente la caché. Sin los diagnósticos de caché, la única señal es que usage.cache_read_input_tokens cae a cero, sin ninguna indicación de qué cambió.
Los diagnósticos de caché cierran esa brecha. Pasa el id de tu respuesta anterior y la API compara las dos solicitudes y te indica 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.
Los diagnósticos de caché están en beta. Incluye el encabezado beta cache-diagnosis-2026-04-07 en tus solicitudes a la API para usar esta función.
Los diagnósticos de caché actualmente están disponibles solo en la API de Claude. No son compatibles con Amazon Bedrock ni Vertex AI.
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 que describe 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 los diagnósticos 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 recuento de tokens (nunca el contenido sin procesar del prompt), se conservan 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 habilitar la función sin un mensaje previo con el cual comparar. En los turnos siguientes, pasa el id de la respuesta anterior.
En las respuestas de streaming, diagnostics aparece en el evento message_start.
El evento message_start incluye el campo diagnostics completo; consulta Formato de respuesta para conocer los valores posibles.
En una conversación de múltiples turnos, transfiere el id de la respuesta más reciente como previous_message_id en cada turno. La primera iteración pasa null para habilitar la función; cada iteración posterior pasa el id de la respuesta anterior.
El campo diagnostics en el Message de 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ó ninguna divergencia. |
{"cache_miss_reason": null} | La comparación aún se estaba ejecutando cuando se serializó la respuesta. Esto puede ocurrir cuando la respuesta comienza muy rápido. 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 informa 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. Normalmente 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 interrupción de caché. |
tools_changed | El arreglo tools difiere: se agregaron, eliminaron o reordenaron herramientas entre turnos, o el JSON de input_schema de las herramientas 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). |
Los cuatro tipos *_changed también incluyen un entero cache_missed_input_tokens: una estimación de cuántos tokens de entrada quedaron después del punto de divergencia, lo que te da una idea de cuánto prefijo cacheable se perdió. Se deriva de las longitudes en bytes antes de la tokenización, así que trátalo como un indicador de magnitud en lugar de un número 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 indica dónde buscar.
Esta matriz se aplica a los turnos en los que 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 aún está pendiente; verifica el siguiente turno) o cuando su type es previous_message_not_found o unavailable (no se produjo ninguna comparación).
| Resultado de diagnósticos | Tokens de lectura 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 | Tu error. La solicitud cambió; corrige la causa indicada por type. |
cache_miss_reason es un tipo *_changed | alto | Poco frecuente. Ocurrió un cambio tarde en el prompt pero un punto de interrupción cache_control anterior aún acertó. Vale la pena corregirlo, pero tiene 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 aún se estaba ejecutando.Los diagnósticos de caché son elegibles para ZDR (calificados). 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 recuento 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 conocer la elegibilidad de ZDR en todas las funciones, consulta API y retención de datos.
client = anthropic.Anthropic()
SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"
# Turno 1: habilita la opción con previous_message_id=None
r1 = client.beta.messages.create(
model="claude-opus-4-8",
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: referencia el id de la respuesta anterior
r2 = client.beta.messages.create(
model="claude-opus-4-8",
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}")# Turno 2: haz streaming, referenciando el id de la respuesta anterior
with client.beta.messages.stream(
model="claude-opus-4-8",
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}")messages_changed | El modelo, el sistema y las herramientas coinciden, pero una entrada anterior en messages fue alterada, reordenada o eliminada en lugar de agregarse al final. Normalmente el historial de conversación se truncó o editó, o los turnos del asistente y los bloques tool_result se volvieron a serializar de forma 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. Normalmente la solicitud anterior no incluía 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 estaba disponible para esta solicitud. Esto incluye el caso en que model, system y tools coinciden pero otro parámetro de 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 solicitud que afectan al prompt durante toda la vida de una conversación en caché. Si persiste, aplica las verificaciones manuales de Solución de problemas comunes en la página de almacenamiento en caché de prompts. |