Claude Code possui um slash command chamado /simplify, que analisa seu código automaticamente. Eu passei um diff gigante — cerca de 500 linhas em 8 arquivos. O resultado foi… interessante. Encontrou coisas que eu não teria notado. Mas também me fez perder tempo com problemas irrelevantes.
Então, desmontamos tudo e reconstruímos peça por peça.
O que faz o /simplify
É um skill que já vem embutido no Claude Code (não é necessário instalar). Ele executa três agentes em paralelo, cada um analisando o mesmo diff sob um ângulo diferente:
- Code Reuse — Há utilitários existentes que poderiam substituir o novo código?
- Code Quality — Estado redundante, copy-paste, abstrações falhas, stringly-typed code.
- Efficiency — I/O desnecessário, concorrência mal aproveitada, memory leaks.
Os três agentes retornam suas análises, e o sistema tenta consertar automaticamente o que é identificado.
O que ele encontrou corretamente
O agente de reuse detectou um helper duplicado verbatim em duas suítes de testes. Mesmo nome, mesmas linhas, dois arquivos diferentes. Movi para um módulo compartilhado. Limpo.
Já o de efficiency descobriu que havia um acesso duplo ao disco por iteração em um laço de processamento: carregar o estado, modificar, salvar, ler dados, recarregar e salvar novamente. Duas escritas quando uma seria suficiente. Eu não teria percebido isso sozinho.
Além disso, apontou que um buffer de memória não tinha uma rotina de limpeza no path de erro. Se algo desse errado entre a alocação e a liberação, resultaria em leak. No path principal, havia limpeza. Era o clássico copy-paste que esquece os detalhes.
Até aqui, tudo certo. Três resultados válidos e acionáveis. Mas o problema do /simplify não é com o que ele detecta — e sim com tudo que não importa e ainda assim ele reporta.
Onde ele falha
Muito ruído em severidade baixa. Sugeriu eliminar um campo de um struct porque era “redundante” com uma propriedade computada. São 8 bytes. Esse campo é utilizado em mais de 10 partes do código e nos testes. O custo de alterar supera em muito o benefício de economizar um inteiro.
Não entende o contexto do projeto. Reportou como ALTO um padrão de concorrência que, na teoria, era um risco. Estava correto em abstrato. Mas já havia sido documentado no arquivo CLAUDE.md do projeto, tinha um lint dedicado, estava numa allowlist e havia uma tarefa aberta sobre o mesmo. O agente não sabia nada disso porque trabalha apenas com o diff, no vazio.
Não diferencia “incorreto” de “melhorável”. O acesso duplo ao disco era ineficiente, mas funcional. O padrão de concorrência era uma bomba relógio. Ambos saíram com prioridade MÉDIA. A priorização é linear.
Sugere enums para dados externos. Disse que alguns campos de um DTO deveriam ser enums em vez de strings. Mas esses campos vêm de uma API externa. Apenas são lidos e exibidos. Convertê-los em enum exigiria um custom decoding e não agregaria valor prático — se a API adicionasse um novo valor, o enum quebraria em vez de degradar de forma elegante.
Esses são erros que qualquer desenvolvedor com contexto do projeto eliminaria em dois segundos. Mas /simplify não tem contexto. Ele tem um diff e boas intenções.
As três melhorias que apliquei
Depois de ver os resultados, identifiquei três problemas estruturais no /simplify e os corrigi em um skill personalizado que chamei de /improve.
1. Injetar o contexto do projeto
Cada agente recebe o CLAUDE.md, as tarefas em aberto no tracker, e os resultados dos linters antes de emitir os apontamentos. Se algo já está gerido, ele menciona, mas não reporta como novo.
Isso elimina apenas a categoria mais irritante de false positives: aquelas que você já conhece e tem sob controle.
2. Filtro de custo/benefício
Antes de reportar, cada agente estima quantos arquivos seriam impactados pela solução. Se o esforço superar o benefício — como renomear um campo em mais de 10 lugares para um ganho marginal de legibilidade — ele descarta.
Isso pode parecer óbvio, mas /simplify não faz. Trata mudanças de uma linha e refactors que afetam 15 arquivos com a mesma prioridade.
3. Separar “conserto automático” de “criação de tarefa”
Os apontamentos são classificados em dois tipos:
auto-fix: mecânico, ≤3 arquivos, sem risco. Aplicado diretamente.issue: requer planejamento, afeta >3 arquivos, ou altera uma interface. É criado como uma tarefa no tracker.
Assim, o review não tenta resolver questões que precisam de reflexão.
O que descartei (e por quê)
Um segundo LLM como revisor. A ideia soa interessante — cross-model validation, mais olhos, outro tipo de training. Na prática, o gargalo não é a quantidade de olhos, mas a qualidade do contexto. Um segundo modelo sem acesso ao CLAUDE.md nem ao tracker retornaria exatamente o mesmo: opiniões genéricas de “melhores práticas” que já estão em livros.
Classificação em 4 níveis de severidade. Comecei com CRÍTICO/ALTO/MÉDIO/BAIXO, mas com o filtro de custo/benefício ativado, quase tudo que passa pelo filtro é MÉDIO ou ALTO. As outras categorias se esvaziam. Mais categorias não implicam em melhor priorização.
O conselho Jedi
E aqui vem a ideia que mudou tudo.
Semanas atrás escrevi sobre invocar especialistas como mentores — pedir a um LLM que adote a perspectiva de Tufte, Munger ou qualquer outro. Funcionou incrivelmente bem para design.
E se, em vez de três agentes genéricos (reuse, quality, efficiency), criássemos três agentes com nome, filosofia e regras de decisão específicas?
A ideia leva um nome que qualquer fã de Star Wars reconhece: o conselho Jedi. Três mestres com perspectivas distintas avaliando o mesmo caso. Mas atenção — não se trata de o LLM fazer uma interpretação superficial soltando frases famosas. Trata-se de cada “sábio” aplicar regras específicas de filtragem que um revisor genérico não aplicaria.
Os três sábios (e por que eles)
Kent Beck — Simplicidade. “Make it work, make it right, make it fast — in that order.” É o cara que diz “essas três linhas duplicadas estão ok, não extraia um helper ainda.” Sua regra fundamental: a regra do três. NÃO reportar duplicação até que o mesmo bloco apareça três vezes. Duas vezes é coincidência. Três, um padrão. E se o conserto afetar mais arquivos do que o código original, provavelmente não vale a pena.
Mas Beck não é apenas simplicidade. Também procura bugs de correção: casos onde a escolha óbvia tem semântica diferente da correta. Por exemplo: aquele async que parece inofensivo, mas herda um contexto problemático. Ou um default que funciona em tests, mas explode em produção.
Martin Fowler — Design. Os code smells são sintomas, não doenças. Refatorar é uma disciplina, não um hobby. Sua regra fundamental: sugerir refatoração apenas quando há uma mudança concreta que se beneficiaria dela. “Refatorar sem propósito é turismo por bases de código.” Se um string vem de uma API externa e só é lido, não sugira convertê-lo em enum. Se um campo está sempre sincronizado com outro por design, a redundância é intencional.
Mike Acton — Desempenho. “The purpose of all programs is to transform data from one form to another.” Se você não mediu, não tem um problema de desempenho — tem uma opinião. Sua regra fundamental: I/O é o que mais importa na maioria das aplicações. CPU raramente é o gargalo. Disco e rede, sim.
Acton não opina — mede
É aqui que a coisa fica interessante. Mike Acton não faz apenas análise estática. Ele realiza duas coisas:
Contagem estática de I/O: analisa o diff em busca de operações de leitura/escrita para disco, rede, ou banco de dados. Mapeia cada operação para seu contexto: está em um laço? Em path crítico? Gera uma tabela de frequências.
Profiling real: se o diff altera código do hot path e o projeto pode ser compilado, executa um profiler e condensa os resultados. Se um hotspot coincide com o código do diff, ele retorna com números — não opiniões.
A tabela de I/O inclui estimativas de magnitude: leitura SSD ~0.5ms, escrita ~1ms, persistência ~2-5ms, rede ~100-500ms. Não busca precisão — apenas identificar operações que, somadas, ultrapassem o limite aceitável.
O risco (e como evitá-lo)
Antes que você saia criando um conselho Jedi para cada pull request, há um elefante na sala: o LLM pode fazer interpretação superficial. Dizer “como diria Kent Beck…” e depois dar um conselho genérico com o nome dele.
Para prevenir isso, as instruções dadas não dizem “adote a perspectiva de Kent Beck.” Elas dizem: “aplique esta regra específica: se um conserto afetar mais arquivos do que a parte que corrige, descarte.”. Regras objetivas, não vibes.
O resultado: mesmo diff, dois reviews
Apliquei o mesmo diff no /simplify e no /improve. Mesmos códigos. Mesmos parâmetros.
| /simplify | /improve | |
|---|---|---|
| Relatados | 8 | 5 |
| Erros falsos | 3-4 | 0 |
| Pioras evitadas | 1 | |
| … Complex Translating Continuation…. |