o problema
Toda requisição a um modelo de linguagem processa o prompt inteiro do zero. Isso é irrelevante quando o prompt tem 200 tokens e roda uma vez. Vira o custo dominante quando ele carrega vinte exemplos de resposta, um documento longo e um conjunto grande de definições de tools — e quando esse mesmo bloco volta para o servidor a cada passo.
Um loop agêntico é o pior caso. Cada chamada de tool exige uma requisição nova, e cada requisição nova reenvia toda a conversa anterior mais o resultado que acabou de chegar. O que não mudou é reprocessado em toda volta. Quem paga por token vê a conta crescer com o número de turnos; quem se importa com latência vê o time-to-first-token preso ao tamanho do prefixo, não ao trabalho novo.
a ideia
Retomar de um prefixo. Se os primeiros blocos do prompt são idênticos aos de uma requisição recente, o processamento deles já foi feito — dá para continuar dali. A API expõe isso como um marcador, cache_control, colocado num bloco de conteúdo: tudo até aqui é reaproveitável.
A analogia que se sustenta é a de cache de camadas de build. A chave é cumulativa e a ordem é fixa: tools, depois system, depois messages. Mudar algo numa camada invalida ela e todas as seguintes. Editar a descrição de uma tool derruba o cache inteiro. Mudar tool_choice derruba só as messages. Ligar ou desligar web search reescreve o system prompt, então derruba system e messages.
como funciona
Três regras explicam quase todo o comportamento observável:
- Escrita só no breakpoint. Marcar um bloco grava exatamente uma entrada: o hash do prefixo que termina ali. Nenhuma entrada é criada em posições anteriores.
- Leitura anda para trás. A cada requisição o sistema calcula o hash no seu breakpoint e procura a entrada correspondente. Se não achar, recua um bloco por vez, testando o hash de cada posição anterior.
- A janela de lookback é de 20 blocos, contando o próprio breakpoint. Fora disso o sistema desiste — ou recomeça no próximo breakpoint explícito, e você tem até 4.
Daí sai o erro mais caro que a documentação descreve. Prefixo estático nos blocos 1 a 5, bloco 6 com um timestamp e a mensagem do usuário, cache_control no bloco 6. O hash muda toda vez. O lookback percorre 5, 4, 3, 2, 1 e não acha nada, porque nunca houve escrita naquelas posições. Escrita nova a cada requisição, leitura zero — pior que não usar cache, já que a escrita custa 1,25x o input base. A correção é mover o marcador para o bloco 5.
Há dois modos. No automático, um cache_control no topo do corpo da requisição e o breakpoint caminha sozinho para o último bloco cacheável conforme a conversa cresce; serve para chat multi-turno, em que o sufixo novo é sempre menor que a janela. No explícito, você posiciona os marcadores à mão — necessário quando seções mudam em frequências diferentes, ou quando o sufixo varia, porque aí o modo automático cai exatamente na armadilha acima.
O retorno vem em três campos de usage: cache_creation_input_tokens, cache_read_input_tokens e input_tokens, este último contando só o que veio depois do último breakpoint. O total de input é a soma dos três.
Também dá para pré-aquecer o cache: max_tokens: 0 lê o prompt, grava a entrada no breakpoint e retorna com content vazio e stop_reason: "max_tokens", sem cobrar output.
o que isso custou
O casamento é exato, byte a byte, até o bloco marcado. Isso transforma qualquer não-determinismo de serialização em bug de custo: a própria documentação avisa que Go e Swift randomizam a ordem das chaves em JSON e quebram o cache dos blocos tool_use.
O piso de tokens é silencioso. Prompts abaixo do mínimo do modelo — 512 tokens no Opus 5, 1.024 no Sonnet 5, 4.096 no Haiku 4.5 — passam sem cache e sem erro. Você só descobre olhando os campos de usage.
O TTL conta do início da requisição, não do fim da resposta: quatro minutos gerando output consomem quatro dos cinco minutos de vida. Requisições paralelas não compartilham a entrada até a primeira resposta começar. Não existe invalidação manual. Blocos de thinking não podem ser marcados com cache_control, embora sejam cacheados junto do resto quando aparecem em turnos anteriores — e contam como input token quando lidos. O pré-aquecimento com max_tokens: 0 é recusado com streaming, thinking estendido, structured outputs, tool_choice forçado e dentro do Batches.
E o isolamento não é uniforme: por workspace na Claude API, na Claude Platform on AWS e no Microsoft Foundry; só por organização no Bedrock e no Google Cloud.
onde isso aparece hoje
O caching está em todos os modelos Claude ativos e em todas as plataformas; o modo automático é a exceção, indisponível na integração legada do Bedrock. Em cima dele nasceram outras coisas na mesma documentação: o diagnóstico de cache em beta, que compara requisições consecutivas e aponta onde o prefixo divergiu, e as mensagens de system no meio da conversa em Opus 5, Opus 4.8, Fable 5 e Mythos 5, que existem para você acrescentar instrução sem tocar no prefixo já cacheado. O max_tokens: 0 substitui a gambiarra de max_tokens: 1 que a comunidade usava para aquecer cache.