Depois de aprender a entender código existente e a corrigir bugs com verificação de causa raiz, chega o momento de melhorar aquilo que já funciona. Ao final deste capítulo você vai saber pedir ao Codex refatorações seguras, exigir que os testes existentes continuem passando, trabalhar em passos pequenos e revisáveis, conduzir migrações de versão de biblioteca e otimizar desempenho com base em medições, e não em palpites.
O que é refatorar, e o que não é
Refatoração é mudar a estrutura interna do código sem alterar o seu comportamento observável. Comportamento observável é tudo aquilo que o mundo de fora enxerga: o valor retornado por uma função, o formato de uma resposta de API, os efeitos no banco de dados, as mensagens de erro. Se o resultado visível muda, aquilo não é refatoração, é uma alteração de funcionalidade, e precisa ser tratada como tal.
Essa distinção importa muito quando se trabalha com um agente de programação. O Codex é muito bom em reorganizar código, mas, se você não disser explicitamente que o comportamento deve permanecer idêntico, ele tende a aproveitar a viagem para consertar coisas que ele julga erradas, renomear campos de resposta ou adicionar validações novas. O resultado é um diff grande, difícil de revisar, que mistura arrumação com mudança de regra.
As três condições antes de começar
Refatorar sem rede de segurança é como trocar o motor com o carro andando. Antes de abrir a sessão, garanta três coisas:
- Árvore do Git limpa. Nenhuma alteração pendente. Assim qualquer linha modificada no diff foi o agente que escreveu.
- Suíte de testes verde agora. Rode os testes você mesmo antes de pedir qualquer coisa. Se já estavam falhando, você nunca saberá se a falha depois é culpa da refatoração.
- Comando de teste registrado no AGENTS.md. Com a regra permanente no lugar, o agente costuma rodar a suíte por conta própria a cada etapa; ainda assim, o que está no AGENTS.md é orientação e não garantia, então confirme na saída da sessão se os testes realmente rodaram e passaram.
Quando o trecho a refatorar não tem teste nenhum, a decisão é simples: ou você cria uma cobertura mínima antes, ou reduz o escopo a mudanças que uma ferramenta consiga validar sozinha, como renomear um símbolo local. Atenção: em linguagens dinâmicas como Python, o interpretador só acusa um nome errado quando aquela linha é executada, então apoie-se em linter e verificador de tipos, e lembre que acessos por texto, como getattr ou nomes vindos de configuração, não são checados automaticamente. Refatoração ampla em código sem teste é aposta.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
Primeiro o diagnóstico, depois a cirurgia
Um erro comum é chegar dizendo "refatore este módulo". O agente então decide sozinho o que é bom, e você recebe uma reescrita inteira. O caminho melhor é separar em duas etapas: primeiro um relatório de pontos de melhoria, depois a execução do que você aprovar.
Analise @src/pedidos/service.py em modo somente leitura.
Liste no máximo oito pontos de melhoria estrutural, sem alterar
nenhum arquivo. Para cada ponto informe:
- arquivo e faixa de linhas
- problema em uma frase
- refatoração sugerida
- risco de quebrar comportamento: baixo, médio ou alto
- esforço estimado: pequeno, médio ou grande
Ordene por relação entre benefício e risco.
Não sugira mudanças de funcionalidade nem novas dependências.
Escrever "modo somente leitura" no pedido não impede edições por si só: é preciso selecionar o modo somente leitura no próprio cliente, na política de aprovação ou na configuração do sandbox. Com essa restrição ativa, o agente não consegue gravar alterações; mesmo assim, confira o estado da árvore do Git ao final da sessão. Você lê a lista, descarta o que não faz sentido para o seu contexto e escolhe um item. Um item só.
Passos pequenos, um tipo de mudança por vez
A regra de ouro é a seguinte: cada etapa deve produzir um diff que você consiga revisar com atenção em poucos minutos, e terminar com a suíte de testes verde e um commit. Se o agente propuser tocar em doze arquivos de uma vez, interrompa e peça a divisão.
Também vale separar tipos de mudança. Renomear e extrair função no mesmo commit torna o diff ilegível, porque a ferramenta de comparação não consegue mostrar que aquele bloco só mudou de lugar. Faça o movimento estrutural em um commit e a renomeação em outro.
Um pedido de etapa bem formado tem mais ou menos esta cara:
Extraia o cálculo de frete das linhas 88 a 134 de
@src/pedidos/service.py para uma função calcular_frete
no mesmo arquivo.
Restrições: não mude assinatura pública de criar_pedido,
não altere mensagens de erro, não crie arquivos novos.
Critérios de aceitação: pytest -q passa sem alterações
nos testes, e o diff não contém mudanças de comportamento.
Ao final, liste qualquer trecho que você mudou e que não
seja puramente estrutural.
Aquela última linha é valiosa. Ela obriga o agente a confessar desvios que, de outra forma, passariam escondidos no meio do diff.
Um catálogo de refatorações e como verificá-las
Cada tipo de refatoração tem um risco típico e uma forma própria de conferência. A tabela abaixo resume as mais comuns no dia a dia.
| Refatoração | Risco | Como verificar |
|---|---|---|
| Extrair função ou método | Baixo | Testes verdes e diff sem linhas de lógica novas |
| Renomear com consistência | Baixo a médio | Busca textual pelo nome antigo, incluindo strings, migrações e documentação |
| Eliminar duplicação | Médio | Conferir se as cópias eram mesmo idênticas em intenção, não só em forma |
| Modernizar sintaxe | Baixo | Linter e testes, mais checagem da versão mínima da linguagem suportada |
| Migrar versão de biblioteca | Alto | Notas de versão, testes de integração e execução manual do fluxo principal |
Sobre eliminar duplicação, vale um alerta. Nem todo código repetido deve ser unificado. Duas regras de negócio que hoje são iguais por coincidência vão divergir amanhã, e a função compartilhada vira um emaranhado de parâmetros booleanos. Peça ao Codex que justifique por que os trechos representam o mesmo conceito antes de fundi-los.
Sobre renomear, o cuidado é o alcance. Peça explicitamente que o agente procure o nome antigo em todo o repositório, incluindo arquivos de configuração, textos de log, nomes de colunas e documentação, e que liste as ocorrências que decidiu não alterar, com a justificativa.
Migrar versões de biblioteca sem sustos
A migração é a refatoração de maior risco, porque o comportamento que muda não está no seu código, está na dependência. Um roteiro que funciona bem com o Codex tem quatro etapas.
- Peça um levantamento de impacto antes de mexer em qualquer coisa: quais arquivos usam a biblioteca, quais funções e quais delas foram descontinuadas na versão nova.
- Dê ao agente a fonte da verdade. Se a sessão está sem acesso à rede, baixe você mesmo as notas de versão e o guia de migração e aponte o arquivo com uma menção de arquivo. Sem isso, o risco de alucinação sobre a nova API é alto.
- Atualize a dependência e corrija um módulo por vez, rodando a suíte a cada módulo, com commit entre eles.
- Ao final, execute manualmente o fluxo principal da aplicação. Testes automatizados raramente cobrem mudanças sutis de formatação, fuso horário ou serialização.
Desempenho só com medição
Pedir ao Codex que "deixe este código mais rápido" costuma produzir micro-otimizações inúteis e código mais difícil de ler. Otimização sem medição é folclore. O ciclo correto tem cinco movimentos.
Primeiro, defina a meta em números: a rota de listagem responde hoje em oitocentos milissegundos no percentil noventa e cinco e precisa ficar abaixo de duzentos. Segundo, peça ao agente um script de medição reprodutível, com dados de volume realista, gerados de forma sintética ou devidamente anonimizados: nunca aponte o benchmark para o banco de produção nem traga dados pessoais de clientes para a sua máquina, tanto pelo risco de indisponibilidade quanto pelas obrigações da LGPD. Terceiro, rode um perfilador, ou seja, uma ferramenta que mostra quanto tempo cada função consome, e peça a interpretação da saída. Quarto, otimize apenas o trecho que domina o tempo total. Quinto, meça de novo e compare.
Rode scripts/bench_listagem.py e me mostre o tempo médio atual.
Em seguida, gere o perfil com cProfile e aponte as três funções
que mais consomem tempo, com percentual de cada uma.
Não altere código ainda.
Muitas vezes o perfil revela algo estrutural, como uma consulta repetida dentro de um laço, e a correção é uma mudança pequena com ganho enorme. Se a otimização proposta piorar a legibilidade, exija um comentário explicando por que aquele trecho é assim, com o número medido registrado. Ganho de desempenho sem medição registrada tende a ser desfeito pelo próximo desenvolvedor, ou pelo próximo agente.
Revisando o diff de uma refatoração
A revisão aqui tem foco diferente da revisão de uma correção de bug. Você está procurando o que não deveria ter mudado. Sinais de alerta no diff:
- Validações ou verificações de nulo que desapareceram durante a reorganização.
- Blocos de tratamento de exceção que passaram a engolir o erro em silêncio.
- Valores padrão de parâmetros alterados, mesmo que pareçam equivalentes.
- Ordem de operações trocada em código que depende de efeitos colaterais.
- Testes modificados. Em refatoração pura, o arquivo de teste não deveria mudar. Se mudou, há três explicações possíveis: o teste dependia de detalhes internos, você renomeou um símbolo que os testes referenciam, ou o comportamento mudou.
Esse último item merece uma pergunta de controle direta ao agente: por que este teste precisou mudar? A resposta separa uma adaptação legítima de um teste que foi ajustado para acomodar um comportamento novo.
Recapitulando
Refatorar com o Codex é uma disciplina de contenção. Comece com árvore limpa, suíte verde e comando de teste no AGENTS.md. Peça primeiro um relatório de pontos de melhoria em modo somente leitura e escolha um item por vez. Escreva pedidos com restrições explícitas de comportamento imutável e exija que o agente declare qualquer mudança que não seja puramente estrutural. Separe renomeação de movimentação de código, desconfie de duplicações que só parecem iguais e trate migração de biblioteca como o item de maior risco, alimentando o agente com as notas de versão reais. Em desempenho, meça, perfile, otimize o gargalo dominante e meça de novo. E, ao revisar, procure o que sumiu sem aviso, não apenas o que apareceu.