Voltar para artigos
Insights··12 min de leitura

Para onde vão os tokens — o custo real de uma sessão de Claude Code

O que descobri lendo os transcripts das minhas próprias sessões

Faz alguns dias eu resolvi entender uma coisa que vinha me incomodando: pra onde vai o custo quando eu trabalho horas seguidas com um agente de código. Em vez de chutar, fui no lugar onde a resposta estava o tempo todo — os registros das minhas próprias sessões, que ficam salvos como arquivos no meu computador. Este artigo é o que eu encontrei lá, e o que dá pra fazer com isso.

Por que eu fui olhar

Eu uso o Claude Code como ferramenta principal de desenvolvimento, e muitas sessões duram horas. De vez em quando aparece um resumo de uso me dizendo coisas como "sessões longas custam mais mesmo com cache" ou "você usou muito subagente". São avisos úteis, mas genéricos — eles descrevem o sintoma sem me dar o mecanismo. E sem o mecanismo, qualquer ajuste que eu fizesse seria superstição: parar de usar uma coisa que talvez nem fosse o problema.

O que me faltava era entender como o custo se forma, turno a turno, pra poder decidir com base em dado e não em palpite. E aí está o detalhe que muita gente nunca aproveita: o agente salva cada sessão num arquivo de texto local, no formato .jsonl — um arquivo onde cada linha é um objeto JSON, um por mensagem. Dentro de cada resposta do modelo existe um campo usage que registra, com precisão, quantos tokens aquela resposta consumiu, separados por tipo. Token é a unidade que o modelo lê e gera — mais ou menos um pedaço de palavra. Esse campo é uma contabilidade exata do que cada turno custou, e está ali parado, esperando ser lido.

Então eu escrevi um script pequeno pra varrer essas sessões e somar os números. O que segue saiu de centenas de sessões reais, sem nenhuma estimativa: a própria ferramenta registrando a si mesma.

Como a API cobra na verdade

Antes dos números, o mecanismo, porque ele explica tudo o que vem depois.

A API que está por trás do agente é stateless — ela não guarda memória entre uma resposta e a próxima. Isso tem uma consequência que parece óbvia quando você diz em voz alta, mas que muda a forma de pensar: a cada turno, o cliente reenvia a conversa inteira pro modelo. Todas as instruções de sistema, todo o histórico, todos os resultados de ferramentas, tudo de novo, mais a sua mensagem nova. O modelo lê o pacote completo, gera a resposta, e esquece. No turno seguinte, manda tudo outra vez.

Se cobrasse o preço cheio por isso, seria inviável. O que torna possível é o prompt caching — um desconto pesado pra trechos que já foram enviados antes e não mudaram. Funciona porque o começo da conversa é estável: as instruções de sistema do turno 50 são idênticas às do turno 1. Esse pedaço estável é cobrado a uma fração do preço.

Na prática, todo turno tem quatro tipos de token, com pesos bem diferentes. Pra comparar sem depender de preço em dólar, dá pra medir tudo em "input-equivalente", usando as proporções padrão entre eles:

  • input novo — tokens que o modelo nunca viu (a sua mensagem nova). Peso 1.
  • cache_write — gravar um trecho novo no cache pela primeira vez. Peso 1,25.
  • cache_read — reler um trecho que já está no cache (o prefixo estável da conversa). Peso 0,1.
  • output — os tokens que o modelo escreve. Peso 5.

A intuição que quase todo mundo tem é que o caro é o output, porque é a parte "inteligente". Os números dizem outra coisa.

O que os números disseram

A conta não é o que o modelo escreve. É a conversa inteira sendo relida a cada vez que ele responde.

Quando somei os tipos de token nas minhas sessões maiores, o cache_read — a releitura do histórico já cacheado — ficou entre 54% e 73% do custo total de cada sessão. O output, a parte que eu imaginava cara, ficou perto de 10%. O input novo, aquilo que eu de fato digito, não chegou a 1%.

Faz sentido quando você junta com o mecanismo: numa das sessões, o cache_read somou perto de 194 milhões de tokens pra um conteúdo real de uns 4 milhões. Ou seja, a conversa foi relida cerca de 48 vezes ao longo da sessão. Cada vez que o modelo respondeu, ele releu — barato, mas releu — tudo o que já estava ali. Quando "tudo o que já estava ali" é grande, 0,1 vezes uma montanha ainda é uma conta alta, multiplicada por dezenas de turnos.

O segundo achado é o que eu passei a chamar de mochila. Cada coisa que entra no contexto e não sai é cobrada de novo em todos os turnos seguintes. Eu medi o cache_read médio por turno no começo e no fim das sessões longas: ele saiu de uns 140 mil tokens por turno pra mais de 500 mil. Quase quatro vezes mais. Não é que cada turno individual ficou mais inteligente — é que a mochila foi enchendo, e o turno 200 carrega nas costas tudo o que foi acumulado nos 199 anteriores. Um item inútil que entra cedo no contexto é pago centenas de vezes antes da sessão acabar.

E os achados apontaram dois jeitos diferentes de uma sessão ficar cara, que pedem remédios opostos. Um é a sessão de validação visual, em que eu uso uma ferramenta minha que captura o estado da tela como texto pra conferir uma interface — cada captura é grande, e elas vão se empilhando no contexto, inflando o cache_read. O outro é a sessão de edição pesada espalhada por muitos arquivos: aí o vilão é o cache_write, porque editar arquivos dentro de um contexto já enorme força a regravação de pedaços grandes do cache a cada mudança. O primeiro problema se resolve descartando as capturas velhas; o segundo, mantendo o contexto pequeno desde o início. Diagnósticos diferentes, da mesma fatura.

Subagents: baratos onde eu achava caro

Um subagent é uma instância separada do agente que eu disparo pra cuidar de uma sub-tarefa — buscar onde está uma coisa no código, investigar um trecho, propor um plano — e que me devolve só a conclusão. O aviso de uso costuma marcar sessões "pesadas em subagente" como caras, e eu carregava a suspeita de que espalhar subagentes era um desperdício.

Os números corrigiram isso, mas não do jeito que eu esperava. Numa sessão com dezenas de subagentes disparados, cada um me devolveu, em média, só uns 3 KB de texto pro contexto principal. Quer dizer: o subagent não suja a minha janela de contexto — ele me devolve quase nada e absorve o trabalho sujo por fora. O custo dele não está no meu contexto; está numa pilha própria, separada, que cresce com a mesma lógica de mochila, mas isolada.

Isso desloca a decisão. Subagent não é caro nem barato em abstrato — depende de quanto trabalho ele te poupa de carregar. Se eu mandasse um subagent ler 40 arquivos e ele me devolvesse 3 KB de resumo, eu economizei 40 leituras que ficariam pesando no meu contexto por dezenas de turnos. Mas se eu disparo um subagent pra uma tarefa de dois comandos, eu pago uma mini-sessão inteira pra economizar quase nada. A regra que tirei disso é simples: vale a pena delegar quando o trabalho despejaria no meu contexto mais do que o subagent me devolve, e quando eu releria esse peso por muitos turnos. Fora disso, faço inline.

Um termômetro pro contexto

Se o problema é que coisas inúteis ficam sendo pagas turno após turno, a pergunta vira: o que, exatamente, vale a pena manter? Comparando as sessões, percebi que dá pra ordenar os tipos de informação numa espécie de termômetro, de quatro faixas, da que eu sempre quero manter até a que pode sair primeiro.

Um dado ancora tudo: as minhas mensagens — o que eu de fato digito pro agente — são menos de 2,5% do volume de mensagens de uma sessão, mas carregam quase toda a intenção que importa. O sinal é minúsculo; o ruído (os resultados de ferramentas) é a massa. As faixas saem desse contraste entre peso em tokens e durabilidade, ou seja, por quanto tempo aquela informação continua sustentando uma decisão:

  • Crítico — pesa pouquíssimo em tokens e dura a sessão inteira. As instruções e restrições que eu dei, as decisões tomadas e o porquê delas, e principalmente a evolução do alvo: como o trabalho começou mirando uma coisa e, por causa de um achado, passou a mirar outra. É barato de guardar e caro de perder.
  • Importante — pesa, mas precisa ficar de alguma forma. O código que está sendo escrito agora, os erros que apareceram e como foram corrigidos (pra não repetir), os arquivos que importam. Aqui o ideal é manter destilado — um ponteiro pro trecho relevante, não a cópia inteira repetida.
  • Situacional — só vale manter enquanto está ativo. O plano em andamento, as tarefas pendentes, o resultado do último teste. Quando a tarefa fecha, isso pode sair.
  • Efêmero — pesa muito e dura quase nada. As capturas de tela antigas, as leituras de arquivo que já foram substituídas por edições, a saída verbosa de um comando de teste, os dumps de busca. É exatamente a faixa que representa a maior parte da fatura, e é a primeira que deveria ser descartada.

A leitura do termômetro é que um bom corte de contexto mantém o topo e a base — guarda o que é barato e durável, joga fora o que é pesado e morto — e destila o meio. O risco mora na fronteira entre o crítico e o situacional: é onde vive o fio da história, o porquê das viradas, e é justamente o que é fácil perder sem perceber.

Como o /compact funciona por dentro

No agente, a ferramenta que ataca a mochila é o /compact — um comando que resume a conversa até ali e substitui o histórico longo pelo resumo, liberando espaço. Eu usava sem saber o que ele preservava e o que descartava, então fui entender o comportamento dele na prática, observando os resumos que ele mesmo gerou nas minhas sessões.

Três coisas ficaram claras. A primeira é que existe mais de um modo de compactação: um que resume a conversa inteira pra recomeçar a sessão a partir do resumo, e outro, incremental, que mantém o começo intacto e resume só a parte mais recente. A segunda é que o resumo segue um molde fixo de seções — pedido principal e intenção, conceitos técnicos, arquivos e trechos de código, erros e correções, problemas resolvidos, todas as mensagens do usuário, tarefas pendentes, trabalho atual, próximo passo.

A terceira é a mais interessante, e conversa direto com o termômetro. O molde preserva todas as mensagens do usuário, com atenção explícita a "mudança de intenção", e manda manter restrições de segurança na forma literal. Ou seja: aquilo que eu mesmo digitei é o canal protegido — o que eu disse sobrevive ao corte. E o molde se preocupa de forma evidente com não perder o fio da tarefa: ele pede citações literais do trabalho mais recente justamente pra evitar que a interpretação do que estava sendo feito derive na paráfrase.

Isso é bom, e tem dois pontos cegos que valem ouro saber.

O primeiro é o pivô por achado. Quando eu mudo o alvo — "na verdade, vamos por outro caminho" — isso vive numa mensagem minha e sobrevive ao corte. Mas quando é a investigação que muda o alvo — o agente descobre que uma suposição estava errada e o plano tem que mudar —, o porquê dessa virada mora num resultado de ferramenta, e resultado de ferramenta é a primeira coisa que o resumo joga fora. O molde captura a intenção que eu verbalizo, não a que emerge da própria apuração.

O segundo é o viés de recência. Várias seções do molde pedem atenção especial às mensagens mais recentes. Faz sentido pra continuar de onde parou, mas significa que uma decisão fundacional tomada lá no começo — um pivô no turno 50 que moldou tudo o que veio depois — fica subponderada se não foi repetida há pouco. O resumo puxa o foco pro fim da conversa.

Juntando: o /compact é, no fundo, um bom resumidor de estado, ancorado no que eu digito e cuidadoso com a interpretação da tarefa. O que ele não garante é a trajetória — a cadeia de causa entre o que foi descoberto e a mudança de rumo que esse achado provocou, ainda mais quando o achado é antigo.

O que dá pra fazer com isso

O método de leitura dos logs vale por si — qualquer pessoa que use a ferramenta pode rodar a mesma análise nos próprios arquivos de sessão e ver onde o custo dela mora, em vez de confiar no meu. Mas o estudo também aponta ações concretas, e elas saem direto dos achados.

A mais barata é de hábito: abrir cada sessão dentro do diretório do projeto específico, e não numa pasta-raiz que mistura tudo. Sessão sem fronteira é a que mais cresce, mistura arquivos de projetos diferentes na mesma janela e vira aquela sessão de oito horas que carrega tudo. A fronteira do projeto é, sozinha, um limitador natural de contexto.

A segunda decorre do que o /compact não garante. Como o canal protegido são as minhas mensagens e as citações literais recentes, um pivô por achado só sobrevive ao corte se eu o trouxer pra esse canal — declarando a virada de forma explícita no momento em que ela acontece, em vez de deixá-la enterrada num resultado de ferramenta. E o /compact aceita uma instrução de foco junto do comando, então dá pra pedir, sempre, que ele preserve a trajetória dos pivôs e descarte capturas e logs, em vez de aceitar o molde padrão cru.

A terceira é sobre quando cortar. Não é por tamanho cego, é por composição: o melhor momento de compactar é quando a mochila ficou pesada de coisa efêmera — logo depois de um ciclo de validação visual encerrado, quando as capturas de tela já cumpriram seu papel e viraram peso morto. O ganho é direto de calcular: é o tanto de token liberado, multiplicado pelo desconto de releitura, multiplicado por todos os turnos que ainda faltam. Cortar cedo o lixo que ainda seria relido muitas vezes é o que mais economiza.

O que ficou

O que mais me marcou nesse estudo não foi nenhum número específico, foi perceber que o comportamento da ferramenta é legível. Eu não precisava adivinhar pra onde ia o custo, nem seguir conselho genérico sobre "sessões longas" — a contabilidade exata estava num arquivo no meu disco, e o molde de compactação estava observável no próprio resultado que ele produz. Bastou ir ler.

Tem uma camada a mais nisso, que é o tipo de coisa que eu quero registrar aqui. A relação com uma ferramenta de IA melhora muito quando você para de tratá-la como caixa-preta e começa a tratá-la como sistema — com entradas, custos e comportamentos que você pode medir e ajustar. O próximo passo, pra mim, é transformar esses achados em automações pequenas: um lembrete que dispara quando a mochila pesa de lixo, um padrão de compactação que protege a trajetória. Mas isso é o próximo artigo, com o código junto.

Artigos relacionados

Construindo o Monney Works — do mock ao deploy em ~4 horas
Arquitetura
14 min de leitura

Construindo o Monney Works — do mock ao deploy em ~4 horas

A arquitetura por trás do meu blog pessoal

Primeiro artigo do Monney Works. Como a plataforma foi construída em menos de 4 horas com Domain-Driven Design, TDD e Next.js 16, por que ela existe, e o que vai passar por aqui de agora em diante.

Ler mais