Como economizar tokens em Claude Code, Codex e Cursor: pare de quebrar o cache
Você abre o Claude Code de manhã e trabalha o dia inteiro na mesma sessão. Às seis da tarde faz uma pergunta de uma linha — "esse teste tá passando?" — e o /usage acusa consumo como se você tivesse enviado o repositório inteiro.
Você enviou. Toda vez.
Economizar tokens num assistente de código tem pouquíssimo a ver com o tamanho do que você digita. A API não guarda nada entre requisições: cada turno reenvia o system prompt, o CLAUDE.md, todas as mensagens anteriores, todos os resultados de ferramenta e só então a sua pergunta. O que decide sua conta no fim do mês é quanto disso o servidor consegue reaproveitar do turno anterior.
Neste post: como o cache de prompt funciona nos três harnesses que os devs realmente usam (Claude Code, Codex e Cursor), as sete ações que quebram esse cache sem você perceber, como medir se ele está funcionando, e oito alavancas concretas para estender a sessão sem estourar o limite.
TL;DR
- O que é: como economizar tokens em assistentes de código, por que a sessão fica cara e o que fazer.
- Ferramentas: Claude Code, OpenAI Codex, Cursor.
- Custo/Acesso: nada para instalar. São comandos, configuração e hábito.
- A regra que resume tudo: cache é comparação de prefixo. Uma mudança em qualquer ponto do começo recomputa tudo que vem depois.
- Link útil: How Claude Code uses prompt caching, a documentação mais explícita que existe hoje sobre invalidação.
Token não é o que você digita
Prompt caching funciona por correspondência exata de prefixo. O servidor compara o começo da sua requisição com o que ele processou recentemente e reaproveita a parte idêntica. Não existe cache por arquivo nem por segmento: a correspondência é exata, e uma mudança em qualquer ponto do prefixo recomputa tudo que vem depois.
Por isso o Claude Code ordena cada requisição em camadas, do que menos muda para o que mais muda:
| Camada | Conteúdo | Muda quando |
|---|---|---|
| System prompt | Instruções centrais, definições de ferramentas, output style | O conjunto de tools carregadas muda, ou o Claude Code é atualizado |
| Contexto de projeto | CLAUDE.md, memória automática, regras | A sessão começa, ou depois de /clear e /compact |
| Conversa | Suas mensagens, respostas, resultados de ferramenta | Todo turno |
Mudança na conversa é barata: as duas camadas de cima continuam em cache. Mudança no system prompt é cara: tudo que vem depois passa a ficar atrás de um prefixo diferente e é reprocessado.
E a diferença de preço é grande. Na API da Anthropic, leitura de cache custa 0,1× o preço do input normal — 10%. A escrita custa 1,25× (ou 2× se você optar pelo TTL de uma hora). Ou seja: cache pago se paga depois de uma única leitura no TTL de cinco minutos, e depois de duas no de uma hora.
Isso não é detalhe de implementação. O time que constrói o Claude Code trata taxa de acerto de cache como uptime de infraestrutura e declara emergência quando ela cai — plan mode, carregamento tardio de ferramentas e compactação foram desenhados em volta dessa restrição. Se o harness da ferramenta é projetado assim, o seu jeito de usar também deveria ser. É esse tipo de disciplina — medir, entender o mecanismo, mudar o hábito — que a gente pratica ao vivo toda semana no Clã Beer and Code: é assinatura, é pago, e é exatamente o ambiente que este post descreve.
Na OpenAI a mecânica é a mesma, com números próprios: o cache exige prefixo de no mínimo 1.024 tokens, a recomendação oficial é conteúdo estático no começo, conteúdo dinâmico no fim, e a partir do GPT-5.6 o prompt_cache_key passou a ser necessário para casamento confiável (cada chave aguenta cerca de 15 requisições por minuto).
As sete ações que queimam seu cache
Estas causam um turno lento e caro. Uma vez só — depois o novo prefixo é cacheado. O problema é que a maioria parece gratuita na hora.
| Ação | Por quê |
|---|---|
/model |
Cada modelo tem cache próprio. Trocar significa reler a conversa inteira sem nenhum acerto |
/effort |
O nível de effort também entra na chave do cache. O Claude Code pede confirmação antes de aplicar |
| Ligar fast mode | Adiciona um header que faz parte da chave. Custa uma vez por conversa — barato no começo da sessão, caro no fim |
| Conectar/desconectar MCP | Definições de ferramenta vivem no system prompt. Só não invalida quando as tools estão diferidas por tool search (o padrão nos modelos suportados) |
| Deny rule de tool inteira | Bash ou WebFetch como deny rule remove a tool do contexto. Regra com escopo (Bash(rm *)) não mexe no prefixo |
/compact |
Substitui o histórico por um resumo. Por definição não compartilha prefixo com o anterior |
| Atualizar o Claude Code | Versão nova normalmente muda system prompt ou definições de tool |
A pegadinha que mais pega gente: opusplan. Nesse setting o modelo resolve para Opus no plan mode e Sonnet na execução — então cada toggle de plan mode é uma troca de modelo, com cache novo. Você acha que está só mudando de modo.
Agora o outro lado, que quase ninguém sabe. Estas não quebram o cache:
- Editar arquivos do repositório. Conteúdo de arquivo só entra em contexto quando o Claude lê. Editar depois não reescreve a leitura antiga: o harness anexa um aviso de que o arquivo mudou.
- Invocar skills e comandos. Eles injetam instruções como mensagem de usuário no ponto da invocação. Nada anterior muda.
/rewind. Trunca a conversa para um ponto anterior — que é exatamente o conteúdo de onde o cache foi construído. Volta para um prefixo já quente.- Trocar permission mode. Não altera system prompt nem tools. A exceção é plan mode com
opusplan, pelo motivo acima. - Subagent. Ele começa uma conversa própria, com cache próprio. Do lado do pai, a chamada e o resultado só são anexados ao fim.
E duas que não quebram o cache nem aplicam a mudança: editar o CLAUDE.md no meio da sessão e trocar output style. Os dois são lidos uma vez no início e ficam em memória. A edição só entra no próximo /clear, /compact ou restart. Se você já editou o CLAUDE.md achando que o Claude passaria a obedecer na mensagem seguinte — não passou.
Meça antes de otimizar
Toda resposta da API traz dois contadores:
| Campo | Significado |
|---|---|
cache_creation_input_tokens |
Tokens escritos no cache neste turno, cobrados a 1,25× |
cache_read_input_tokens |
Tokens servidos do cache, cobrados a ~10% do input normal |
Razão alta de leitura sobre escrita significa que está funcionando. Se a criação continua alta turno após turno, alguma coisa está mudando no seu prefixo.
Dá para acompanhar isso ao vivo numa statusline:
#!/usr/bin/env bash
# ~/.claude/statusline.sh — registre com /statusline. Requer jq.
input=$(cat)
read_tokens=$(echo "$input" | jq -r '.current_usage.cache_read_input_tokens // 0')
write_tokens=$(echo "$input" | jq -r '.current_usage.cache_creation_input_tokens // 0')
if [ "$write_tokens" -gt 0 ]; then
ratio=$(awk "BEGIN { printf \"%.1f\", $read_tokens / $write_tokens }")
else
ratio="--"
fi
printf 'cache %s lidos / %s escritos (%sx)' "$read_tokens" "$write_tokens" "$ratio"
Além disso:
/usagemostra, em plano pago, atribuição de consumo por skill, subagent, plugin e servidor MCP — cada um como percentual do total. E sinaliza comportamentos que respondem por 10% ou mais do consumo recente, como contexto longo ou cache miss./contextmostra o que está ocupando espaço agora.- No Cursor, o Context Usage Report quebra o consumo por system prompt, definições de tool, rules, skills, MCPs e subagents. É clicar no anel de contexto do agente.
- Na API da OpenAI, o campo é
cached_tokensdentro deusage.input_tokens_details(Responses) ouusage.prompt_tokens_details(Chat Completions).
Se cached_tokens fica zerado em requisições com prefixo idêntico, você tem um invalidador silencioso: um datetime.now() no system prompt, um UUID por requisição, um json.dumps sem sort_keys. É a mesma família de problema dos vazamentos de token mais comuns em produção, só que dentro do seu editor.
Tutorial te mostra o caminho — no Clã você constrói junto. Aula ao vivo toda semana, projetos reais de Engenharia de IA, ao lado de quem já está em produção.
Entrar no ClãOito alavancas para economizar tokens e estender a sessão
1. /clear custa zero. /compact é uma requisição grande.
Isso inverte a intuição de muita gente. Para produzir o resumo, o /compact envia uma requisição separada com o mesmo system prompt, as mesmas tools e o mesmo histórico, mais a instrução de sumarizar. Com o cache quente ele lê o prefixo do cache e custa uma fração. Depois de uma pausa longa, sem cache, ele reprocessa o histórico inteiro como input não cacheado.
Ou seja: /compact é mais caro justamente quando você retoma uma sessão antiga. Já o /clear não manda requisição nenhuma.
Regra prática: quer continuidade, /compact num intervalo natural entre tarefas. Quer recomeço, /clear. Quer abandonar um caminho, /rewind — que volta para um prefixo já cacheado em vez de construir um novo.
2. Corte o CLAUDE.md
Ele é carregado em contexto no início de toda sessão. Se tem instrução detalhada de review de PR e de migração de banco, esses tokens estão lá mesmo quando você está mexendo em CSS. A recomendação oficial é manter abaixo de 200 linhas, só o essencial, e mover fluxo especializado para skills — que carregam sob demanda.
3. Filtre a saída antes que ela vire contexto
Um hook de PreToolUse pode reescrever o comando antes de o Claude ver o resultado. Em vez de ele ler um log de 10 mil linhas para achar o erro, o hook faz o grep e devolve as linhas que importam — de dezenas de milhares de tokens para centenas.
#!/usr/bin/env bash
# ~/.claude/hooks/filtra-teste.sh — só as falhas voltam para o contexto.
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
if [[ "$cmd" =~ ^(npm\ test|pytest|php\ artisan\ test|go\ test) ]]; then
novo="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"allow\",\"updatedInput\":{\"command\":\"$novo\"}}}"
else
echo "{}"
fi
Se hooks ainda são território novo pra você, tem um post inteiro sobre isso em Hooks, Slash Commands e MCPs: a anatomia de um harness produtivo.
4. Prefira CLI a MCP quando o CLI existe
gh, aws, gcloud, sentry-cli são mais eficientes em contexto que os MCPs equivalentes, porque não adicionam listagem por ferramenta. E rode /mcp para desligar servidor que você não está usando.
O tamanho do problema tem número: o Cursor migrou para descoberta dinâmica de tools MCP — só os nomes entram no contexto estático, o agente busca o schema quando precisa — e mediu, num teste A/B, redução de 46,9% no total de tokens do agente nas execuções que chamaram alguma tool MCP.
Quase metade. Só de não carregar schema que não vai ser usado.
5. Delegue operação verbosa a subagent
Rodar suite de teste, buscar documentação, processar log. A saída fica no contexto do subagent e só o resumo volta para a conversa principal. Detalhe importante: subagent usa TTL de cinco minutos mesmo em assinatura — o de uma hora vale só para a conversa principal.
6. Fixe modelo e effort por fase de trabalho
Não é "use sempre o modelo barato". É não ficar alternando. Cada troca no meio de uma tarefa longa paga o reprocessamento inteiro, e o ganho do modelo mais barato pode ser menor que a perda de cache. Escolha modelo e effort no começo da sessão; se precisar mudar, mude num ponto onde você já ia limpar o contexto de qualquer jeito.
Sonnet dá conta da maior parte do trabalho de código. Opus fica para decisão de arquitetura e raciocínio multi-etapa. Para subagent simples, dá para especificar model: haiku na configuração.
7. Na API, prefixo estável versionado
Se você é quem constrói o harness, a regra vale igual: system prompt congelado, ordem de tools determinística (ordene por nome), nada de timestamp ou ID de requisição no começo do prompt. Serialize JSON com chaves ordenadas. Contexto dinâmico entra no fim, depois do último breakpoint. Essa é a mesma alavanca que já detalhamos do lado de quem constrói em Cortando custo em 80%: prompt caching, batch e quando NÃO usar reranker.
No Codex, os controles equivalentes são de configuração: model_context_window e model_auto_compact_token_limit definem quando a compactação dispara, e a API de compactação permite compactação server-side via context_management com compact_threshold — sem chamada separada.
8. Entenda o seu TTL
No Claude Code em assinatura, o TTL de uma hora é pedido automaticamente. Se você estourou o limite do plano e passou a consumir usage credits, ele cai para cinco minutos, porque aí você está pagando a escrita. Em API key ou provedor de nuvem, o padrão é cinco minutos e você opta pela hora com ENABLE_PROMPT_CACHING_1H=1.
Isso explica o turno lento depois do almoço: passou do TTL, o cache expirou, e a próxima mensagem reprocessa a conversa inteira.
Quando o problema não é cache, é compactação
Cache miss custa dinheiro e latência. É chato, mas é reversível: o próximo turno já está quente de novo.
Compactação mal feita custa outra coisa — decisão. O resumo substitui o histórico detalhado para o modelo. Uma restrição combinada há duas horas, um caminho já descartado, o ID de um erro específico: se não entrou no resumo, deixou de existir para o agente. E aí ele refaz trabalho que você já pagou.
A defesa não é evitar compactar. É não deixar estado canônico morar só no chat.
- Decisões vão para ADR, issue ou documento no repositório.
- Alterações vão para commit ou branch, não ficam pendentes esperando o fim da sessão.
- Resultados de comando importantes viram artefato em arquivo.
- Instruções de compactação entram no CLAUDE.md: um bloco dizendo o que preservar sempre (arquivos modificados, comandos de teste, restrições) sobrevive melhor que a esperança de que o resumo seja bom.
Checkpoint de ferramenta, /rewind e histórico de sessão são conveniência. Git é fonte de verdade. Esse é o mesmo raciocínio de estado persistente como peça obrigatória do harness — só que aplicado a você usando a ferramenta, não a você construindo uma.
Limitações e pontos de atenção
O cache é mais estreito do que parece. No Claude Code ele é efetivamente escopado por máquina e diretório: o system prompt embute o diretório de trabalho, plataforma, shell, versão de SO e caminhos de memória. Duas sessões em diretórios diferentes constroem prefixos diferentes e não se enxergam — incluindo worktrees do mesmo repositório. Sessões paralelas no mesmo diretório, sim, compartilham.
Agent teams multiplicam. Cada teammate mantém a própria janela de contexto e roda como instância separada. A documentação estima cerca de 7× mais tokens que uma sessão padrão quando os teammates rodam em plan mode.
Os números de custo publicados são média, não previsão. A Anthropic reporta cerca de US$ 13 por dev por dia ativo e US$ 150–250 por dev por mês em deploys enterprise, com 90% dos usuários abaixo de US$ 30 por dia ativo. Isso varia com codebase, modelo e quantas instâncias você roda em paralelo. Se você quer a conta com o preço de hoje, tem a tabela em Claude Code ficou 5x mais caro? O preço real em 2026.
E o mais importante: não confunda medir com otimizar. Baixar effort e desligar thinking economiza token e pode custar qualidade — o que sai mais caro se o agente errar e você precisar refazer. Otimize primeiro o que é gratuito: prefixo estável, contexto limpo, saída filtrada.
FAQ rápido
Trocar de modelo no meio da sessão para economizar compensa?
Raramente. A troca invalida o cache inteiro e a próxima requisição relê toda a conversa sem nenhum acerto. Num histórico grande, o reprocessamento pode custar mais que a economia do modelo mais barato. Se for trocar, troque junto com um /clear.
/compact ou /clear?
/clear quando você mudou de assunto — não manda requisição, custa zero, e é a alavanca mais efetiva de qualidade e custo. /compact só quando você precisa da continuidade, e de preferência num intervalo entre tarefas, não no meio de uma.
Por que o primeiro turno depois de uma pausa é tão lento? Cache expirado. O TTL é de uma hora em assinatura, cinco minutos em API key ou quando você está em usage credits. Passou do prazo, a próxima requisição reprocessa toda a conversa como input não cacheado.
Ter muitos MCPs atrapalha mesmo? Depende de estarem diferidos. Com tool search ativo, só os nomes entram no prefixo e um servidor conectando ou desconectando não derruba o cache. Sem isso, cada mudança na lista de tools invalida tudo — e um servidor pode conectar ou desconectar sozinho, por timeout ou reconexão. O número do Cursor (−46,9% de tokens com descoberta dinâmica) dá a dimensão do desperdício quando o schema inteiro fica carregado à toa.
Conclusão
Economizar tokens em assistente de código não é escrever menos. É três coisas: não mexer no prefixo no meio da tarefa, não deixar entrar em contexto o que não vai ser usado, e não guardar estado importante só no chat.
O resto é consequência. Modelo fixo por fase, CLAUDE.md enxuto, saída filtrada por hook, /clear entre tarefas, /rewind em vez de /compact quando o caminho foi abandonado.
E tem uma métrica que resume o setup inteiro: a razão entre cache_read_input_tokens e cache_creation_input_tokens. Se a leitura domina, você está bem. Se a escrita não cai, alguma coisa no seu prefixo muda toda hora — e é ali que seu limite de uso está indo embora.
Coloca ela na statusline hoje. É a diferença entre achar que a ferramenta ficou cara e saber por quê.
{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.
Conteúdo é o que não falta. Falta quem desembaralhe: o que importa agora é como implementar do jeito certo. No Clã você tem isso ao vivo, toda semana, com quem já filtrou o ruído.
Entrar no Clã