Índice
5 min de leitura

O design de cache que reduz os custos de API do Claude Code em 90%

Meus custos de API saltaram 10x quando o cache quebrou em produção. No mesmo dia, engenheiros da Anthropic explicaram exatamente o motivo.

Ontem eu tinha um trabalho urgente em produção. No meio da sessão, o meu prompt cache quebrou. A conta de API daquela única hora foi mais alta do que a dos três dias anteriores combinados.

O timing foi quase cômico. Naquela mesma noite, Thariq (que construiu o Claude Code na Anthropic) e Lance Martin da Anthropic publicaram posts sobre o design de prompt caching. Lendo as explicações deles, percebi que o meu cache era frágil por design, não por acidente.

Aqui está o que extraí de ambos os posts, filtrado pela dor de produção que acabei de experimentar.

Prefix matching significa que a ordem é tudo

O prompt caching na API da Anthropic funciona por correspondência a partir do início da requisição, token por token. No momento em que um único caractere difere da versão em cache, tudo depois daquele ponto vira cache miss. Sem correspondência parcial. Sem pular adiante.

A equipe do Claude Code trata a ordenação do prompt como infraestrutura. O system prompt estático vai primeiro. Depois o CLAUDE.md. Depois o contexto de sessão. As mensagens da conversa vão por último, porque mudam a cada turno. Essa ordenação faz com que o prefixo estável e caro seja cacheado e reutilizado em todas as requisições da sessão.

Tokens cacheados custam 10% dos tokens de entrada regulares. Essa diferença explica por que um cache quebrado parece um aumento de preço de 10x.

O meu erro foi embutir um timestamp no system prompt. Cada requisição gerava um novo timestamp, o que fazia com que os primeiros tokens fossem diferentes sempre. Nada depois conseguia ser cacheado. Um log de debug no lugar errado, e eu estava pagando o preço cheio em mais de 100K tokens por requisição.

A equipe do Claude Code também relatou que a ordenação não determinística das definições de ferramentas causa cache misses. Se suas ferramentas serializam em ordens diferentes entre requisições, o cache quebra naquele ponto, mesmo que as ferramentas em si não tenham mudado.

Envie atualizações pelas mensagens, não editando o system prompt

Quando o contexto muda no meio de uma sessão (um arquivo é modificado, o horário atualiza, um modo muda), o instinto é editar o system prompt. Não faça isso. Qualquer edição no system prompt invalida todo o prefixo cacheado.

O Claude Code lida com isso deixando o system prompt intocado após a primeira requisição. O contexto alterado vai na próxima mensagem do usuário, encapsulado numa tag system-reminder. O modelo lê da mesma forma, mas o prefixo do cache permanece intacto.

O Plan Mode é um bom exemplo. Mudar para Plan Mode poderia significar trocar definições de ferramentas, o que quebraria o cache. Em vez disso, o Claude Code implementa isso como uma chamada de ferramenta (EnterPlanMode) que o próprio modelo pode invocar. O conjunto de ferramentas nunca muda. Quando o modelo detecta um problema difícil, ele pode entrar no Plan Mode por conta própria, sem nenhuma modificação no system prompt.

A mesma lógica se aplica à troca de modelos. Mudar de modelo no meio de uma conversa quebra o cache completamente. O Claude Code evita isso rodando modelos diferentes como subagentes em contextos separados, mantendo o cache da conversa pai intacto.

Oculte ferramentas em vez de removê-las

Servidores MCP podem carregar dezenas de ferramentas. Incluir todas elas em cada requisição é caro. Mas remover ferramentas entre requisições quebra o cache porque as definições de ferramentas fazem parte do prefixo cacheado.

A solução da equipe do Claude Code: defer_loading. Em vez de incluir os schemas completos das ferramentas, eles inserem stubs leves contendo apenas o nome da ferramenta e um flag defer_loading: true. Os stubs ficam sempre na mesma ordem, mantendo o prefixo do cache idêntico. Quando o modelo realmente precisa do schema completo de uma ferramenta, ele chama a ferramenta ToolSearch para carregá-lo sob demanda.

Esse padrão está disponível na API da Anthropic hoje. Você pode implementar a mesma abordagem de stub-e-busca nos seus próprios agentes.

O peakji do Manus chamou a taxa de acerto do cache de a métrica mais decisiva para agentes em produção. Depois de ontem, concordo.

A compressão de contexto tem uma armadilha de cache

Quando uma conversa preenche a janela de contexto, você precisa comprimir: resumir o histórico e continuar numa forma reduzida. A abordagem óbvia é chamar a API com um prompt de sumarização. Mas se essa chamada de sumarização usar um system prompt diferente ou definições de ferramentas diferentes, ela não vai corresponder ao cache existente. Você acaba processando toda a conversa de mais de 100K tokens sem nenhum benefício de cache, exatamente no momento em que os custos são mais altos.

O Claude Code resolve isso reutilizando o system prompt e as definições de ferramentas exatos da conversa pai para a chamada de compressão. Apenas a mensagem final do usuário muda para uma instrução de compressão. O prefixo cacheado da conversa pai ainda corresponde, então você paga o preço cheio apenas pela nova mensagem e pelo output do resumo.

A Anthropic desde então incorporou esse padrão na API como um recurso de compactação. Eles também lançaram o auto-caching, onde definir cache_control uma vez no corpo da requisição gerencia os breakpoints do cache automaticamente.

Taxa de acerto do cache como métrica operacional

A equipe do Claude Code monitora a taxa de acerto do cache da mesma forma que equipes de ops monitoram uptime. Quando o número cai, eles tratam como um incidente.

Essa perspectiva mudou como penso no design de prompts. Cada edição no system prompt, cada reordenação de ferramentas, cada troca de modelo no meio da sessão é um incidente em potencial. O token mais barato é aquele que acerta o cache, e ontem aprendi exatamente o quanto a alternativa custa.

Assine a newsletter

Receba atualizações sobre meus projetos mais recentes, artigos e experimentos com IA e desenvolvimento web.