Claude Platform Docs
MessagesGerenciamento de contexto

Diagnóstico de cache

Diagnostique falhas inesperadas no cache de prompt comparando requisições consecutivas e identificando exatamente onde o prefixo do prompt divergiu.

O cache de prompt ("prompt caching") reduz significativamente a latência e o custo, mas apenas quando o início do seu prompt é idêntico, byte a byte, a uma requisição recente. Uma ferramenta reordenada, um timestamp interpolado no seu prompt do sistema ou uma edição em uma mensagem anterior podem invalidar o cache silenciosamente. Sem o diagnóstico de cache, o único sinal é usage.cache_read_input_tokens caindo para zero, sem nenhuma indicação do que mudou.

O diagnóstico de cache ("cache diagnostics") preenche essa lacuna. Passe o id da sua resposta anterior, e a API compara as duas requisições e informa onde elas divergiram (o modelo, o prompt do sistema, as ferramentas ou o histórico de mensagens), para que você possa corrigir a causa raiz em vez de adivinhar.

Como o diagnóstico de cache funciona

Quando o cabeçalho beta está presente, a API armazena uma "fingerprint" (impressão digital) leve de cada requisição, indexada pelo id da resposta. Na sua próxima requisição, inclua esse id como diagnostics.previous_message_id. A API reconstrói a fingerprint da nova requisição, compara-a com a armazenada e anexa um objeto diagnostics à resposta descrevendo o primeiro ponto de divergência.

A comparação diz respeito à estrutura da requisição, independentemente de o cache ter sido efetivamente atingido. Consulte Lendo o diagnóstico junto com o uso para saber como combinar o resultado de diagnostics com usage.cache_read_input_tokens.

As fingerprints contêm apenas hashes e estimativas de contagem de tokens (nunca o conteúdo bruto do prompt), são retidas por um tempo limitado, têm escopo restrito à sua organização e workspace, e não são usadas para nenhuma outra finalidade.

Uso básico

Envie o cabeçalho beta em cada turno. No primeiro turno, passe "previous_message_id": null para aderir sem uma mensagem anterior com a qual comparar. Nos turnos subsequentes, passe o id da resposta anterior.

client = anthropic.Anthropic()

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

# Turno 1: opte por participar com 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: referencie o id da resposta 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

Em respostas com streaming, diagnostics aparece no evento message_start.

# Turno 2: faça streaming, referenciando o id da resposta 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}")

O evento message_start carrega o campo diagnostics completo; consulte Formato da resposta para ver os valores possíveis.

Encadeando o diagnóstico em um loop de conversa

Em uma conversa de múltiplos turnos, leve adiante o id da resposta mais recente como previous_message_id em cada turno. A primeira iteração passa null para aderir; cada iteração subsequente passa o id da resposta 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 da resposta

O campo diagnostics no Message da resposta tem quatro estados possíveis:

ValorSignificado
campo ausenteA requisição não incluiu diagnostics, ou o cabeçalho beta estava ausente.
nullOu previous_message_id era null (primeiro turno, nada para comparar), ou uma comparação foi executada e não encontrou divergência.
{"cache_miss_reason": null}A comparação ainda estava em execução quando a resposta foi serializada. Isso pode acontecer quando a resposta começa muito rapidamente. Trate como inconclusivo e verifique o próximo turno.
{"cache_miss_reason": {...}}Um cache_miss_reason está anexado. Para os tipos *_changed, isso identifica o primeiro ponto de divergência; previous_message_not_found e unavailable são casos em que nenhuma comparação foi produzida.

Quando cache_miss_reason não é nulo, ele tem esta aparência:

{
  "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 motivo de falha de cache

cache_miss_reason é uma união discriminada por type. A resposta informa apenas a divergência mais antecipada, então corrija-a primeiro; divergências posteriores podem estar ocultas atrás dela.

TipoO que significaO que mudar
model_changedO model difere da requisição anterior (por exemplo, um roteador, teste A/B ou fallback selecionou um modelo diferente). O cache é por modelo.Mantenha o modelo constante dentro de uma conversa em cache.
system_changedO parâmetro system difere. Normalmente um timestamp, ID de requisição ou outro valor por requisição foi interpolado no prompt do sistema.Torne o prompt do sistema uma constante estável em bytes e mova os dados dinâmicos para a primeira mensagem user após o seu ponto de interrupção de cache.
tools_changedO array tools difere: ferramentas foram adicionadas, removidas ou reordenadas entre turnos, ou o JSON de input_schema das ferramentas foi serializado de forma não determinística.Envie a mesma lista de ferramentas em cada turno, em uma ordem fixa, com schemas serializados de forma determinística (por exemplo, ordene as chaves).
messages_changedO modelo, o system e as tools coincidem, mas uma entrada anterior em messages foi alterada, reordenada ou removida em vez de apenas receber acréscimos. Normalmente o histórico da conversa foi truncado ou editado, ou turnos do assistente e blocos tool_result foram re-serializados de forma diferente no reenvio.Trate o histórico como somente de acréscimo (append-only); devolva o content do assistente e os resultados de ferramentas literalmente.
previous_message_not_foundNão existe fingerprint armazenada para o previous_message_id fornecido. Isso não é evidência de que sua requisição mudou. Normalmente a requisição anterior não carregava o cabeçalho beta, veio de um workspace diferente, ou passou tempo demais desde que foi enviada.Envie o cabeçalho beta em cada turno e mantenha turnos consecutivos próximos no tempo.
unavailableAs informações de diagnóstico não estavam disponíveis para esta requisição. Isso inclui o caso em que model, system e tools coincidem, mas outro parâmetro de requisição que afeta o prompt (tool_choice, thinking, context_management, output_config, output_format ou o conjunto de cabeçalhos anthropic-beta ativos) difere, e conversas muito longas em que a divergência está além do horizonte de comparação. Sua requisição foi processada normalmente.Mantenha constantes os parâmetros de requisição que afetam o prompt durante toda a vida de uma conversa em cache. Se persistir, aplique as verificações manuais em Solução de problemas comuns na página de cache de prompt.

Lendo o diagnóstico junto com o uso

diagnostics responde "minha requisição mudou?", enquanto usage.cache_read_input_tokens responde "o cache foi atingido?". Combiná-los indica onde procurar.

Esta matriz se aplica a turnos em que você passou um previous_message_id real. No primeiro turno (previous_message_id: null), diagnostics é sempre null e cache_read_input_tokens normalmente é zero porque o cache está sendo gravado, não lido; nenhuma solução de problemas é necessária. A matriz também não se aplica quando cache_miss_reason é null (a comparação ainda está pendente; verifique o próximo turno) ou quando seu type é previous_message_not_found ou unavailable (nenhuma comparação foi produzida).

Resultado do diagnósticoTokens lidos do cacheInterpretação
nullaltoFuncionando como esperado. Seu prefixo é estável e o cache foi atingido.
nullbaixo ou zeroSuas requisições coincidem, mas a entrada de cache não estava mais disponível. Considere reduzir os intervalos entre turnos ou usar o TTL de cache de 1 hora.
cache_miss_reason é um tipo *_changedbaixo ou zeroBug seu. A requisição mudou; corrija a causa indicada por type.
cache_miss_reason é um tipo *_changedaltoRaro. Uma mudança ocorreu no final do prompt, mas um ponto de interrupção cache_control anterior ainda foi atingido. Vale corrigir, mas o impacto é baixo.

Limitações

  • Beta: Os nomes e a semântica dos campos podem mudar enquanto este recurso estiver em beta.
  • Somente Claude API: Não disponível no Amazon Bedrock nem no Google Cloud.
  • Retenção limitada: As fingerprints para consulta de previous_message_id expiram após um curto período. Execute comparações de diagnóstico entre requisições próximas no tempo.
  • Mesmo workspace: A requisição anterior deve ter sido executada na mesma organização e workspace. Para verificar, compare o cabeçalho de resposta anthropic-workspace-id nas duas respostas.
  • Horizonte de comparação: Para conversas muito longas em que a única mudança está profundamente na lista de mensagens, a resposta pode ser unavailable em vez de uma localização precisa.
  • Melhor esforço: O diagnóstico nunca bloqueia nem faz sua requisição falhar. Se as informações de diagnóstico não estiverem disponíveis, a resposta retorna unavailable, ou cache_miss_reason: null quando a comparação ainda estava em execução.

Retenção de dados

O diagnóstico de cache é elegível para ZDR (qualificado). A Anthropic não armazena o texto bruto dos seus prompts nem as saídas do Claude para este recurso.

A fingerprint armazenada para cada requisição consiste apenas em hashes criptográficos e estimativas de contagem de tokens, indexada pelo id da resposta e com escopo restrito à sua organização e workspace. As fingerprints expiram após um curto período e não são usadas para nenhuma outra finalidade.

Para a elegibilidade ZDR em todos os recursos, consulte API e retenção de dados.

Veja também

Compatibility

Supported platforms
  • Claude APIBeta

Was this page helpful?