Como pedir uma otimização de performance ao Claude Code sem virar reescrita do projeto

otimizar código com Claude Code sem reescrever o projeto inteiro
Resposta rápida

Otimizar código com Claude Code dá errado quando o pedido é só um adjetivo: "deixa isso mais rápido". Sem alvo, o modelo procura o problema no projeto inteiro e volta com um diff gigante. O formato que segura o escopo tem cinco blocos: alvo (arquivo e função), medida de referência antes e meta depois (medida por você, não pelo modelo), invariantes que não podem mudar (comportamento, assinatura, dependências), um bloco explícito de fora de escopo e um passo de verificação ponta a ponta. Rode em plan mode primeiro, leia o plano, só então aprove 🙂

Você pede pra deixar UMA função mais rápida e volta um diff de 14 arquivos

A função alvo virou três, apareceu uma biblioteca nova, duas assinaturas mudaram e agora tu tem que revisar meio projeto pra descobrir se alguma coisa quebrou

A culpa quase nunca é do modelo

O pedido é que saiu torto: sem alvo delimitado, sem medida de referência e sem uma lista do que NÃO pode mudar, "otimizar" é um convite aberto pra reescrever o que der na telha

A doc oficial de boas práticas do Claude Code é bem direta nisso: referencie arquivos específicos, mencione restrições e aponte padrões de exemplo, porque quanto mais precisa a instrução, menos correção depois

Então bora montar o pedido do jeito certo, bloco por bloco, com o texto do prompt sendo construído na sua frente

O que ter pronto antes de abrir o pedido

Antes de digitar qualquer coisa, junte essas quatro coisas

Se faltar alguma, o pedido vai nascer largo e o resto do post não salva

  • O trecho identificado: nome do arquivo e nome da função ou do método. Não vale "a parte do relatório está lenta", isso não é alvo, é sintoma
  • Uma medida de referência coletada por você: tempo, número de queries, uso de memória, o que fizer sentido no seu caso. A medição é tarefa sua, com as ferramentas que tu já usa no projeto
  • Os testes que provam o comportamento atual: se não existe teste, o mínimo é ter um jeito manual repetível de conferir que a saída continua igual
  • O repositório sob controle de versão: a própria doc do checkpointing orienta continuar usando Git pra histórico permanente, porque o checkpointing só rastreia arquivos editados na sessão atual e não faz rewind de symlink nem hard link

Sobre esse último ponto, se liga: o Claude Code guarda snapshots de arquivos dos 100 checkpoints mais recentes da sessão

Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 120 aulas
  • 4 projetos
  • 9h 45min

É ótimo pra desfazer besteira na hora, mas é rede de segurança de sessão, não substituto de commit

E mais uma: se você estava mexendo em outra coisa antes, roda /clear pra resetar o contexto entre tarefas não relacionadas

Contexto sujo de outra tarefa é um dos jeitos mais fáceis de o modelo "aproveitar a viagem" e mexer em arquivo que não tem nada a ver

Passo a passo: como montar o pedido de otimização

A ideia é simples: o pedido tem cinco blocos fixos (alvo, medida, invariantes, fora de escopo, verificação), e no fim ficam duas decisões suas: planejar antes ou pedir direto, e aprovar ou não o plano que aparecer

  1. Delimite o alvo citando arquivo e função

Nada de "o sistema de busca"

Escreva o caminho do arquivo e o nome exato da função, e diga que a mudança deve ficar ali dentro

   Alvo: a função buscarPedidosDoCliente em src/repositories/pedidos.js
   Mexa apenas nesse arquivo e nessa função

O erro comum deste passo: pedir pra "investigar onde está lento" sem delimitar nada. A doc avisa que investigação sem escopo faz o Claude ler centenas de arquivos e encher o contexto, e a correção é delimitar a investigação ou jogar a exploração pra subagents, pra não torrar o contexto principal

  1. Declare a medida de referência antes e a meta depois

O número é seu, e você precisa deixar isso explícito no prompt, senão o modelo "acha" que melhorou e segue a vida

   Medida atual (medida por mim, não estime nem invente):
   a chamada faz 1 query por pedido retornado
   Meta: reduzir o número de queries mantendo o mesmo resultado
   Não afirme ganho de performance sem que eu meça depois

O erro comum deste passo: aceitar estimativa de ganho como se fosse medição. Se o número não saiu da sua execução, ele não existe

  1. Liste as invariantes

Invariante é o que continua igual, doa a quem doer

Três que quase sempre entram: comportamento observável, assinatura das funções e dependências

   Invariantes (não podem mudar):
   - o retorno continua sendo uma lista de objetos com os mesmos campos e na mesma ordem
   - a assinatura buscarPedidosDoCliente(clienteId, filtros) fica idêntica
   - nenhuma dependência nova no package.json

O erro comum deste passo: achar que "não quebre nada" é uma invariante. Não é, é um desejo. Invariante é específica e verificável

  1. Escreva o bloco "fora de escopo" de forma explícita

Esse é o bloco que a maioria pula, e é justamente ele que segura o diff

A doc diz com todas as letras que as especificações mais úteis nomeiam os arquivos e as interfaces envolvidas E declaram o que está fora de escopo

   Fora de escopo:
   - refatorar outras funções do arquivo
   - renomear variáveis por estilo
   - mexer em testes, configuração, build ou camada de rotas
   - trocar o ORM ou a estratégia de cache do projeto

O erro comum deste passo: listar só o que você já viu dar errado uma vez. Pense no que está PERTO do alvo e seria tentador mexer

  1. Feche com o passo de verificação ponta a ponta

A mesma orientação da doc: a spec boa termina com um passo de verificação que prova que funciona

   Verificação: rode a suíte de testes de pedidos e me mostre a saída
   Depois me diga exatamente qual comando eu devo rodar para medir de novo

O erro comum deste passo: deixar a verificação implícita. "Confira se está tudo ok" não é verificação, é torcida

  1. Decida entre planejar antes ou pedir direto

Pra entrar no plan mode, você pressiona Shift+Tab pra alternar os modos de permissão no CLI, ou prefixa um único prompt com /plan

Fora do terminal a troca também existe: pelo indicador de modo no VS Code ou pelo seletor de modo no Desktop

Em plan mode o Claude lê arquivos e roda comandos de exploração, escreve um plano e não edita o código-fonte

O erro comum deste passo: planejar tudo, sempre. A própria doc manda pular o plano quando o escopo é claro e a correção é pequena: se você consegue descrever o diff em uma frase, peça direto

  1. Revise o plano e só então aprove

Em plan mode as edições ficam bloqueadas até você aprovar o plano (a exceção são sessões com bypass de permissões)

Use isso: leia a lista de arquivos que ele pretende tocar ANTES de liberar

Se aparecer arquivo que você não citou no bloco de alvo, o pedido está largo e dá pra corrigir antes de existir qualquer linha escrita

O erro comum deste passo: aprovar no automático porque o plano "parecia razoável". O plano é o momento mais barato de dizer não

Juntando tudo, o prompt final fica assim:

Alvo: a função buscarPedidosDoCliente em src/repositories/pedidos.js
Mexa apenas nesse arquivo e nessa função

Medida atual (medida por mim): 1 query por pedido retornado
Meta: reduzir o número de queries mantendo o mesmo resultado
Não afirme ganho de performance sem medição minha

Invariantes:
- retorno com os mesmos campos e na mesma ordem
- assinatura buscarPedidosDoCliente(clienteId, filtros) idêntica
- nenhuma dependência nova

Fora de escopo: outras funções do arquivo, renomeações por estilo,
testes, configuração, build, rotas, troca de ORM ou de cache

Verificação: rode os testes de pedidos, mostre a saída
e me diga o comando exato para eu medir de novo

Legal né? 😀 É comprido, mas você escreve uma vez e reaproveita pra vida toda

Três pedidos prontos para copiar e adaptar

Mesmo esqueleto, três situações diferentes

Troca os nomes pelos do seu projeto e segue o jogo

1. Consulta lenta numa função de acesso a dados:

Alvo: listarFaturasPorPeriodo em app/data/faturas.py

Medida atual (minha): a consulta percorre a tabela inteira
antes de filtrar por data
Meta: filtrar no banco, não em memória

Invariantes:
- mesmo formato de retorno (lista de dicionários, mesmas chaves)
- assinatura listarFaturasPorPeriodo(inicio, fim) inalterada
- sem biblioteca nova e sem alterar o schema do banco

Fora de escopo: migrations, models, camada de serviço e qualquer
outra função do arquivo

Verificação: rode os testes de faturas e me mostre a saída;
depois diga o comando para eu medir a consulta de novo

2. Laço pesado num script de processamento:

Alvo: o laço principal de processa_lote em scripts/importar.py

Medida atual (minha): o script relê o arquivo de referência
a cada item do lote
Meta: ler a referência uma vez só

Invariantes:
- a ordem dos registros processados continua a mesma
- os mesmos logs continuam sendo emitidos
- nada de multiprocessing, threads ou dependência nova

Fora de escopo: o parser de CSV, o módulo de validação,
o formato do arquivo de saída

Verificação: rode o script no lote de exemplo em fixtures/
e compare a saída com a esperada, arquivo por arquivo

3. Endpoint com tempo de resposta alto:

Alvo: o handler GET /relatorios/mensal em src/routes/relatorios.ts

Medida atual (minha): o handler monta o relatório inteiro
em memória antes de responder
Meta: reduzir o trabalho feito por requisição

Invariantes:
- contrato da resposta idêntico (mesmos campos, mesmos tipos, mesmo status)
- assinatura do handler e o caminho da rota inalterados
- sem cache novo, sem fila, sem middleware novo

Fora de escopo: autenticação, outros endpoints do arquivo,
validação de entrada

Verificação: rode os testes de integração de relatórios
e me mostre a resposta do endpoint antes e depois no mesmo payload

Repara que em nenhum deles a palavra "otimizar" aparece sozinha

Sempre tem alvo, número e fronteira

Sinais de que a resposta saiu do escopo (e o que fazer na hora)

Dá pra pegar o desvio cedo, antes de virar bola de neve

Cada sintoma abaixo aponta pra um bloco que faltou no seu pedido:

Sintoma Causa provável no pedido O que fazer na hora
O diff toca arquivos que você não citou Alvo largo demais, sem arquivo e função nomeados Esc pra parar no meio da ação e redirecionar citando o arquivo
A assinatura de uma função mudou Invariante de assinatura não declarada Esc duas vezes ou /rewind, restaurar só o código e refazer o pedido com a assinatura escrita
Apareceu dependência nova Faltou "nenhuma dependência nova" nas invariantes Rewind do código e novo pedido com a restrição explícita
O retorno mudou de formato Comportamento observável não estava listado Rewind e declarar campos, tipos e ordem do retorno
A sessão começou a ler dezenas de arquivos sem relação Investigação sem delimitação Esc e reabrir a investigação delimitada, ou empurrar a exploração pra subagents

Sobre as duas teclas que salvam o dia

O Esc para o Claude no meio da ação e o contexto é preservado, então você redireciona sem começar do zero

Já o Esc duas vezes (ou o comando /rewind) abre o menu de rewind, com as opções de restaurar só a conversa, só o código, os dois, ou resumir a partir de uma mensagem

Esse menu é o mesmo que salva a sua pele quando o pedido de correção vira outra coisa, e a lógica de escopo aqui é irmã da que vale quando a correção quebra outra coisa

A prevenção é chata e funciona: reescreve o pedido MENOR, volta pro plan mode com Shift+Tab e tenta de novo

Menor quase sempre quer dizer uma função só, uma invariante a mais e um bloco de fora de escopo mais duro

E cuidado com um caso específico: quando a "otimização" começa a remover código que ele considerou morto

Aí o assunto já é outro, vale usar o formato de pedido pra apagar código com segurança em vez de deixar isso entrar de carona num pedido de performance

Como deixar os limites permanentes no projeto

Escrever as mesmas invariantes em todo prompt cansa

Dá pra fixar boa parte disso no projeto:

  1. Escreva as regras no CLAUDE.md

O Claude Code lê instruções, configurações, skills, subagents e memória do diretório do projeto e de ~/.claude no diretório home (no Windows, %USERPROFILE%\.claude)

As instruções persistentes vão em arquivos CLAUDE.md, e existe suporte a CLAUDE.md aninhados em subdiretórios

Ou seja: regra que vale só pra camada de dados pode morar dentro da pasta da camada de dados

   ## Performance
   Mudanças de performance ficam restritas ao arquivo citado no pedido
   Nenhuma dependência nova sem eu pedir
   Assinaturas públicas e formato de retorno não mudam em pedido de performance
   Ganho de performance só é afirmado depois de medição minha

O erro comum deste passo: transformar o CLAUDE.md num manifesto de 300 linhas. Regra curta e específica vale mais que filosofia

  1. Trave ferramentas e comandos com regras deny no settings.json

No bloco permissions do settings.json você define o que pode e o que não pode

As regras são avaliadas na ordem deny, depois ask, depois allow, e as regras deny impedem o uso da ferramenta especificada

   {
     "permissions": {
       "allow": ["Bash(npm run lint)"],
       "deny": ["Read(./.env)"]
     }
   }

O erro comum deste passo: escrever um deny largo achando que um allow mais específico abre exceção. Não abre! Um deny amplo como Bash(aws *) bloqueia toda chamada que casa com o padrão, inclusive as que também casariam com um allow mais estreito como Bash(aws s3 ls)

  1. Saiba onde foi parar aquele "não perguntar de novo"

Quando você aprova uma permissão escolhendo não perguntar de novo, ela é salva em .claude/settings.local.json na raiz do repositório git, valendo para sessões futuras naquele repositório

Vale dar uma olhada nesse arquivo de vez em quando pra ver o que você liberou no piloto automático numa sexta à noite 😛

O erro comum deste passo: esquecer que esse arquivo existe e depois estranhar por que o Claude parou de perguntar algo

Uma nota sobre os modos, já que eles entram nessa conversa: hoje existem Auto (um classificador revisa as ações em segundo plano e bloqueia as arriscadas), Manual (pergunta antes de editar arquivos e rodar comandos), Accept edits (edita arquivos e roda comandos comuns de sistema de arquivos sem perguntar) e Plan

Nos planos Pro, Max e Team, o Auto é o modo de permissão inicial embutido para sessões interativas de terminal e de VS Code

Saber em qual modo você está muda MUITO a sensação de "ele fez sozinho"

Conclusão

Otimização é pedido com fronteira, não pedido com adjetivo

"Deixa mais rápido" é adjetivo

"Nesta função, deste arquivo, com este número atual, sem mexer nisso, e prove com este comando" é fronteira

E tem uma parte que não dá pra terceirizar: a medida é sua, antes e depois

O modelo escreve o código, mas quem diz se ficou mais rápido é a sua execução

Próximo passo bem concreto pra hoje: escolhe UMA função lenta do seu projeto, mede, escreve o pedido no formato dos cinco blocos (alvo, medida, invariantes, fora de escopo, verificação) e roda primeiro em plan mode com Shift+Tab

Lê o plano, confere a lista de arquivos, e só então aprova

Se o plano já estiver querendo abrir meio projeto, tu economizou uma revisão inteira antes de qualquer linha ser escrita 🙂

até o próximo post!

Perguntas frequentes

O que fazer se o Claude Code mexer em arquivo fora do escopo mesmo depois de eu delimitar o pedido de otimização?

Aperte Esc pra parar o Claude no meio da ação, sem perder o contexto, e redirecione o pedido. Se a edição indevida já aconteceu, use Esc duas vezes ou o comando /rewind pra restaurar só o código, só a conversa, ou os dois.

Dá pra impedir automaticamente que o Claude Code edite arquivos sensíveis durante uma otimização?

Sim, dá pra configurar regras deny no bloco "permissions" do settings.json, como Read(./.env), que a doc usa de exemplo. As regras são avaliadas na ordem deny, depois ask, depois allow, e um deny amplo bloqueia até chamada que também casaria com um allow mais específico.

O checkpointing do Claude Code substitui o commit no Git antes de pedir uma otimização de performance?

Não. O checkpointing guarda snapshots de arquivos só dos 100 checkpoints mais recentes da sessão atual, e não faz rewind de arquivo symlink ou hard link. A própria doc orienta continuar usando Git pra ter histórico permanente.

Preciso reescrever alvo, invariantes e fora de escopo toda vez que peço uma otimização com Claude Code?

Não precisa: instruções persistentes de projeto podem ficar em arquivos CLAUDE.md, que o Claude Code lê do diretório do projeto (com suporte a CLAUDE.md aninhados em subdiretórios) e de ~/.claude no diretório home. Assim as restrições padrão do seu jeito de pedir otimização já chegam prontas na sessão.

Quais modos de permissão existem no Claude Code além do plan mode pra controlar o quanto ele mexe sozinho no código?

Além do plan mode, o Claude Code tem o Auto, que deixa um classificador revisar as ações em segundo plano e bloquear as arriscadas, o Manual, que pergunta antes de editar arquivos e rodar comandos, e o Accept edits, que edita arquivos e roda comandos comuns de sistema de arquivos sem perguntar. Nos planos Pro, Max e Team, o Auto é o modo de permissão inicial embutido para sessões interativas de terminal e de VS Code.

Onde consigo trocar de modo de permissão do Claude Code fora do terminal?

A troca também existe pelo indicador de modo no VS Code e pelo seletor de modo no Claude Desktop, além do Shift+Tab no CLI. É o mesmo mecanismo usado pra entrar e sair do plan mode antes de pedir a otimização.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares