Refatorando e melhorando a qualidade do código com o Codex

Capítulo 9

Tempo estimado de leitura: 12 minutos

+ Exercício
Audio Icon

Ouça em áudio

0:00 / 0:00

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:

  1. Árvore do Git limpa. Nenhuma alteração pendente. Assim qualquer linha modificada no diff foi o agente que escreveu.
  2. 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.
  3. 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.

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

Pessoa revisando diffs lado a lado em dois monitores

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çãoRiscoComo verificar
Extrair função ou métodoBaixoTestes verdes e diff sem linhas de lógica novas
Renomear com consistênciaBaixo a médioBusca textual pelo nome antigo, incluindo strings, migrações e documentação
Eliminar duplicaçãoMédioConferir se as cópias eram mesmo idênticas em intenção, não só em forma
Modernizar sintaxeBaixoLinter e testes, mais checagem da versão mínima da linguagem suportada
Migrar versão de bibliotecaAltoNotas 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.

Mão retirando com cuidado uma peça de uma torre de blocos de madeira

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.

  1. 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.
  2. 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.
  3. Atualize a dependência e corrija um módulo por vez, rodando a suíte a cada módulo, com commit entre eles.
  4. 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.

Agora responda o exercício sobre o conteúdo:

Por que é importante solicitar ao Codex um relatório de pontos de melhoria em modo somente leitura antes de executar uma refatoração?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

O relatório em modo somente leitura serve como uma etapa intermediária de planejamento. Permite que você analise as sugestões, descarte o que não faz sentido no seu contexto e escolha uma mudança de cada vez, evitando refatorações amplas não planejadas. Isso não é sobre tecnicamente impedir edições, mas sobre o processo de trabalho.

Próximo capítulo

Testes automatizados com o Codex: gerando, completando e mantendo suítes de teste

Arrow Right Icon
Capa do Ebook gratuito OpenAI Codex: Guia Completo para Programação com Inteligência Artificial
60%

OpenAI Codex: Guia Completo para Programação com Inteligência Artificial

Novo curso

15 capítulos

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.