Claude Platform Docs
MessagesGestión de contexto

Diagnóstico de caché

Diagnostica fallos inesperados de la caché de prompts comparando solicitudes consecutivas e identificando exactamente dónde divergió el prefijo del prompt.

El almacenamiento en caché de prompts ("prompt caching") 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 de un mensaje anterior pueden invalidar la caché silenciosamente. 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.

Cómo funciona el diagnóstico de caché

Cuando el encabezado beta está presente, la API almacena una huella digital ("fingerprint") 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 de 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 el diagnóstico junto con el uso 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 el contenido sin procesar del prompt), se conservan durante un tiempo limitado, están restringidas a tu organización y espacio de trabajo, y no se utilizan para ningún otro propósito.

Uso básico

Envía el encabezado beta en cada turno. En el primer turno, pasa "previous_message_id": null para activar la función sin un mensaje previo con el que 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: actívalo 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: referencia 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}")

Streaming

En las respuestas con streaming, diagnostics aparece en el evento message_start.

# Turno 2: usa 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 contiene el campo diagnostics completo; consulta Formato de respuesta para ver los valores posibles.

Propagar el diagnóstico a través de un bucle de conversación

En una conversación de varios turnos, lleva el id de la respuesta más reciente como previous_message_id en cada turno. La primera iteración pasa null para activar la función; cada iteración posterior pasa el id de la respuesta anterior.

client = anthropic.Anthropic()

SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"

messages = []
prev_id = None

for i, user_message in enumerate(
    ["Summarize section 1.", "Now section 2.", "Now section 3."]
):
    messages.append({"role": "user", "content": user_message})

    r = client.beta.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        cache_control={"type": "ephemeral"},
        system=SYSTEM,
        messages=messages,
        diagnostics={"previous_message_id": prev_id},
        betas=["cache-diagnosis-2026-04-07"],
    )

    if r.diagnostics is not None and r.diagnostics.cache_miss_reason is not None:
        print(f"Turn {i + 1} cache_miss_reason: {r.diagnostics.cache_miss_reason.type}")

    messages.append({"role": "assistant", "content": r.content})
    prev_id = r.id

Formato de respuesta

El campo diagnostics en el Message de respuesta tiene cuatro estados posibles:

ValorSignificado
campo ausenteLa solicitud no incluyó diagnostics, o faltaba el encabezado beta.
nullO bien previous_message_id era null (primer turno, nada que comparar), o bien 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ápidamente. Trátalo como no concluyente y revisa 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 nulo, tiene este aspecto:

{
  "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
    }
  }
}

Tipos de motivos de fallo de caché

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.

TipoQué significaQué cambiar
model_changedEl 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_changedEl 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_changedEl 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).
messages_changedEl 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 la 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_foundNo 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 llevaba el encabezado beta, provenía 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.
unavailableLa 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 las conversaciones muy largas en las que 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.

Leer el diagnóstico junto con el uso

diagnostics responde a "¿cambió mi solicitud?", mientras que usage.cache_read_input_tokens responde a "¿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; revisa el siguiente turno) ni cuando su type es previous_message_not_found o unavailable (no se produjo ninguna comparación).

Resultado del diagnósticoTokens leídos de cachéInterpretación
nullaltoFunciona como se espera. Tu prefijo es estable y la caché acertó.
nullbajo o ceroTus 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 *_changedbajo o ceroEs tu error. La solicitud cambió; corrige la causa indicada por type.
cache_miss_reason es un tipo *_changedaltoPoco 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 el impacto es bajo.

Limitaciones

  • Beta: Los nombres de los campos y su semántica pueden cambiar mientras esta función esté en beta.
  • Solo Claude API: No disponible en Amazon Bedrock ni en Google Cloud.
  • Retención limitada: Las huellas digitales para la búsqueda de previous_message_id expiran después de un período corto. Ejecuta las comparaciones de diagnóstico entre solicitudes cercanas en el tiempo.
  • Mismo espacio de trabajo: La solicitud anterior debe haberse ejecutado en la misma organización y espacio de trabajo. Para verificarlo, compara el encabezado de respuesta anthropic-workspace-id en las dos respuestas.
  • Horizonte de comparación: Para conversaciones muy largas en las que el único cambio está muy adentro en la lista de mensajes, la respuesta puede ser unavailable en lugar de una ubicación precisa.
  • Mejor esfuerzo: El diagnóstico nunca bloquea ni hace fallar tu solicitud. Si la información de diagnóstico no está disponible, la respuesta devuelve unavailable, o cache_miss_reason: null cuando la comparación aún se estaba ejecutando.

Retención de datos

El diagnóstico de caché es elegible para ZDR (con condiciones). 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 restringida a tu organización y espacio de trabajo. Las huellas digitales expiran después de un período corto y no se utilizan para ningún otro propósito.

Para conocer la elegibilidad para ZDR de todas las funciones, consulta API y retención de datos.

Ver también

Compatibility

Supported platforms
  • Claude APIBeta

Was this page helpful?