Claude Code criou de novo uma função que já existia? Como evitar código duplicado no projeto

Claude Code código duplicado quase sempre é falta de visão, não falta de capacidade: se o arquivo original nunca entrou no contexto da sessão, o agente escreve do zero uma função que o projeto já tinha. A correção tem três camadas: abrir a tarefa em plan mode (Shift+Tab ou /plan), pedir exploração da base com o subagente Explore antes de qualquer escrita, e gravar a regra de reuso no CLAUDE.md da raiz para ela sobreviver à próxima sessão. Depois, /simplify ou /code-review no diff pegam o que passou.
Você abre o diff e lá está: uma função novinha, nome diferente, fazendo exatamente o que o utilitário do projeto já fazia há um bom tempo
A sensação é de que o agente ignorou seu código de propósito
Mas não é bug do seu projeto, e nem birra do modelo
É comportamento conhecido: quando o agente não enxerga o que já existe, ele resolve o problema do jeito mais barato que conhece, escrevendo do zero
O Nik Haldimann escreveu sobre isso na newsletter Next Generation Of, em 4 ways to combat Claude’s code duplication, separando a duplicação em dois eixos: a dificuldade de reusar código de biblioteca que já está lá, e a dificuldade de extrair uma biblioteca nova quando o padrão se repete
A boa notícia é que a correção mora em dois lugares bem concretos: no jeito que você monta o pedido, e na configuração do repositório
Bora destrinchar por sintoma? 🙂
Sintoma 1: o agente criou uma função que já existia em outro arquivo
O sintoma é fácil de reconhecer: formatCurrency nasce em src/checkout/, com a mesma lógica do formatMoney que mora em src/utils/ desde sempre
Mesma coisa, nome diferente, arquivo diferente
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 116 aulas
- 4 projetos
- 9h 23min
A causa: o arquivo original nunca entrou na janela de contexto
O agente não tem raio-x do repositório
Ele enxerga o que foi carregado na sessão, e só
Se src/utils/ nunca apareceu, para efeitos práticos aquele utilitário não existe
É como pedir pra um dev novo implementar uma feature sem dar acesso ao repo inteiro: ele vai escrever o que sabe escrever
A solução: exploração antes da escrita
O Claude Code tem um subagente nativo chamado Explore, que serve exatamente pra isso: buscar e entender uma base de código sem fazer alteração nenhuma (ele é read-only)
E ele aceita um nível de profundidade informado na chamada: quick pra buscas pontuais, medium pra uma exploração equilibrada e very thorough pra análise abrangente
Esse subagente roda em janela de contexto própria e devolve só o resumo pra conversa principal, o que evita entupir sua sessão com dump de arquivo
Depois, confere o que de fato foi carregado com:
/context
O /context mostra o que está na janela de contexto da sessão atual
Se o arquivo que você jurava estar lá não aparece, achou a causa raiz da duplicação
Esse mesmo raciocínio de "primeiro entender, depois mexer" é o que separa um agente útil de um gerador de gambiarra, e vale muito além da duplicação: é o mesmo problema de dar contexto de projeto pra um dev novo, só que com IA no lugar
Como prevenir
Tarefa de feature não começa no modo escrita
Começa em plan mode, que é o assunto do próximo sintoma
Sintoma 2: ele já começou a editar antes de olhar o projeto
O sintoma aqui é a primeira ação da sessão
Você manda o pedido, e a primeira ferramenta que aparece é Write ou Edit
Zero busca antes
A causa: nada no fluxo obriga a busca prévia
No modo padrão, escrever é permitido desde o primeiro token
Se o pedido não exige pesquisa e o fluxo não impede a escrita, o caminho mais curto vence
A solução: plan mode
No plan mode o Claude Code usa apenas ferramentas de leitura
A pesquisa da base vai pro subagente Plan, que explora em uma janela de contexto separada, enquanto a conversa principal fica somente leitura
Pra entrar, duas opções:
Shift+Tab
O Shift+Tab cicla entre os modos nessa ordem: default → acceptEdits → plan
Ou prefixa o prompt:
/plan refatorar o fluxo de checkout
E se você entrou sem querer, ou mudou de ideia no meio, Shift+Tab de novo sai do plan mode sem aprovar plano nenhum
Como prevenir
Adota plan mode como padrão de entrada em qualquer tarefa não trivial
Custa uns segundos a mais no começo e economiza aquele diff gigante que reimplementa metade do utils
Sintoma 3: a duplicação volta toda sessão nova
Esse é o mais frustrante
Você explica na conversa, ele entende, corrige, usa o utilitário certo
Aí você fecha o terminal
Na próxima sessão, função duplicada de novo 😛
A causa: a instrução morreu junto com o contexto
Correção dita no chat vale pra aquele chat
Sessão nova é página em branco, e tudo que você combinou evaporou junto
Esse é o mesmo motivo pelo qual tanta gente corre atrás de memória persistente pra agentes de IA: sem isso, você fica repetindo a mesma instrução pra sempre
A solução: CLAUDE.md na raiz
O CLAUDE.md é o arquivo markdown de instruções persistentes do projeto, do seu fluxo pessoal ou da organização, e ele é lido no começo de cada sessão
É ali que a regra de reuso precisa morar, e é exatamente a recomendação do artigo do Nik Haldimann: uma seção de instruções de reuso no CLAUDE.md da raiz do projeto
Se você ainda não tem um, tem atalho:
/init
O /init explora a base de código (arquivos de pacote, documentação existente, arquivos de configuração e estrutura) e gera um CLAUDE.md inicial com comandos de build, comandos de teste, visão da estrutura e convenções detectadas
Depois disso, dá pra conferir o que existe de memória com:
/memory
Ele lista CLAUDE.md, CLAUDE.local.md e outros locais de memória nos escopos de usuário e de projeto, incluindo entradas de arquivos que ainda nem existem
Tome cuidado com um detalhe: um CLAUDE.md que só existe na sua máquina resolve o problema pra você e pra mais ninguém
Como prevenir
Commita o arquivo no repositório
Assim a regra vale pro time inteiro, e não só pra quem lembrou de escrever
Como montar o pedido que força a busca antes da escrita
Agora a parte prática
Esse é o esqueleto de pedido que inverte a ordem natural do agente (que é escrever primeiro, olhar depois)
- Entra em plan mode antes de descrever a tarefa.
Shift+Tabaté chegar em plan, ou prefixa com/plan
O erro comum deste passo: descrever a tarefa inteira e só depois lembrar do plan mode, quando o agente já mandou o primeiro Write
- Pede a exploração da base explicitamente, com nível de profundidade. O subagente Explore aceita
quick,mediumouvery thorough, e você escolhe conforme o espalhamento da lógica
Antes de propor qualquer código, explore a base com profundidade
very thorough e me diga se já existe algo que faça formatação de
valor monetário, em qualquer pasta, com qualquer nome
O erro comum deste passo: usar quick numa base onde a lógica pode estar espalhada em vários módulos com nomes diferentes
- Exige a lista do que já existe ANTES de qualquer proposta. Não é enfeite: é o que te dá o material pra decidir entre reusar, estender ou criar
O erro comum deste passo: aceitar um "não encontrei nada parecido" sem olhar o que ele realmente carregou (roda /context)
- Só então aprova a escrita. Com a lista na mão, você aponta o arquivo que deve ser reaproveitado em vez de deixar a decisão no automático
O erro comum deste passo: aprovar o plano por cansaço, sem ler a parte em que ele diz "vou criar um novo helper"
- Revisa o diff depois de escrever. O
/simplifyroda agentes em paralelo que revisam o código alterado quanto a reuso, qualidade, eficiência e aderência aoCLAUDE.md, tudo em uma única passada, e pode ser anexado ao prompt depois de você fazer as mudanças
/simplify
O erro comum deste passo: rodar no meio da implementação, quando ainda tem metade do trabalho pra sair
- Se quiser um segundo par de olhos no diff, usa o
/code-review. Ele checa o diff atual em busca de bugs de correção e limpezas, e aceita--fixpra aplicar os achados
/code-review --fix
Passando um número de PR, ele revisa o pull request em vez do diff local
O erro comum deste passo: usar --fix sem olhar o que foi aplicado depois
Onde escrever a regra de reuso: CLAUDE.md, regras por caminho ou subagente
Aqui muita gente trava, porque tem mais de um lugar possível
A escolha depende do tamanho do projeto e do tipo de tarefa
| Cenário | Onde a regra vive |
|---|---|
| Projeto pequeno, uma convenção só | Seção de reuso no CLAUDE.md da raiz |
| Monorepo ou área específica | Regra em .claude/rules/ com o campo paths no frontmatter, ou um CLAUDE.md por diretório |
| Tarefa que precisa explorar E modificar | Subagente general-purpose |
| Tarefa só de entendimento, sem tocar em nada | Subagente Explore (read-only) |
Por que regra escopada por caminho ajuda tanto:
Uma regra com paths apontando pra algo como src/api/** fica fora do contexto quando você está trabalhando em outra parte da árvore
Ou seja: você não paga contexto por instrução que não tem nada a ver com a tarefa do momento
A doc recomenda commitar esses arquivos no repositório, pelo mesmo motivo do CLAUDE.md: regra que só existe local não é convenção de time
E onde esses arquivos ficam?
Dois escopos
Escopo de projeto: arquivos em .claude/ dentro do repo, e na raiz no caso de CLAUDE.md, .mcp.json e .worktreeinclude
Escopo global: ~/.claude/, valendo pra todos os seus projetos
No Windows, ~/.claude resolve pra %USERPROFILE%\.claude
E na hora de escolher o subagente:
Até aqui você viu dois: o Explore e o Plan
Mas tem um terceiro que entra justo quando a tarefa passa do entendimento
Se o pedido é "me diga se isso já existe", é Explore, que busca e entende sem alterar
Se é "acha e refatora", aí sim general-purpose, que cobre exploração mais modificação, raciocínio complexo e múltiplos passos dependentes
Cada subagente roda em janela de contexto própria e devolve só o resumo, o que é ótimo: a busca pesada não polui a conversa principal
Quando vale barrar a escrita com hook em vez de confiar no prompt
Tem uma diferença importante que vale internalizar
Prompt e CLAUDE.md orientam
Hook impede
Se o seu problema é "às vezes ele ignora a convenção", orientação resolve na maioria dos casos
Se o seu problema é "não pode, em hipótese alguma, criar arquivo novo nessa pasta", orientação não é garantia
Como o PreToolUse se encaixa nisso:
O hook PreToolUse roda depois que o Claude monta os parâmetros da ferramenta e antes do processamento da chamada
Ele casa com ferramentas nativas como Bash, Edit, Write, Read, Glob, Grep, Agent e WebSearch
Ou seja: ele está no lugar certo pra ver um Write chegando e reagir antes de qualquer coisa acontecer no disco
A decisão vai dentro de um objeto hookSpecificOutput, com quatro saídas possíveis: allow, deny, ask e defer, além da possibilidade de modificar o input
E tem precedência definida entre hooks: deny > defer > ask > allow
Na prática, o deny ganha de todo mundo, o que é exatamente o que você quer numa trava dura
O trade-off é honesto: hook é mais trabalho de configuração e mais atrito no dia a dia
Começa pelo CLAUDE.md
Se a duplicação insistir mesmo com a regra escrita e commitada, aí sim vale escalar pro mecanismo de bloqueio
O que fazer na próxima sessão
Se tem uma ideia pra levar deste post, é essa: duplicação é falta de visão, não falta de capacidade
O agente não reusa o que não enxerga
Então o roteiro pra sua próxima sessão é curtinho:
- Se o projeto ainda não tem
CLAUDE.md, roda/init - Adiciona a seção de instruções de reuso e commita o arquivo
- Abre a próxima tarefa em plan mode, com pedido explícito de exploração antes de qualquer proposta
- Passa
/simplifyno diff antes de abrir o PR
E se você não lembra o que tem disponível na sua instalação, tem um truque bobo que resolve: digita / no prompt vazio
Ele lista todos os comandos disponíveis, incluindo os customizados, os de plugin e os que vieram de MCP
É bem provável que você tenha coisa boa instalada e nem saiba 😀
Até o próximo post!
Perguntas frequentes
Por que o Claude Code cria uma função que já existe em outro arquivo do projeto?
Porque ele só enxerga o que foi carregado na janela de contexto daquela sessão, não o repositório inteiro. Se o arquivo com a função original nunca entrou em jogo, para efeitos práticos ela não existe, e o agente resolve escrevendo do zero. O Nik Haldimann descreve isso como um dos dois eixos de duplicação: dificuldade de reusar código de biblioteca que já está lá.
Como confirmar se o Claude Code realmente carregou um arquivo específico na sessão?
Digitando /context, que mostra o que está de fato na janela de contexto da sessão atual. Se o arquivo que deveria ter sido lido não aparece na lista, essa é a causa raiz de uma duplicação. É o comando certo pra checar antes de desconfiar do modelo.
O plan mode do Claude Code bloqueia qualquer edição de arquivo?
Sim, no plan mode o Claude Code usa apenas ferramentas de leitura, e a pesquisa da base de código fica a cargo do subagente Plan, em janela de contexto própria. Pra entrar, o atalho é Shift+Tab, que cicla entre default, acceptEdits e plan, ou prefixar o prompt com /plan. Apertar Shift+Tab de novo sai do plan mode sem aprovar plano nenhum.
Em qual pasta o CLAUDE.md precisa ficar para valer no projeto inteiro?
O CLAUDE.md fica na raiz do repositório, mesmo escopo de arquivos como .mcp.json e .worktreeinclude. Já as regras específicas ficam dentro de .claude/rules/ com escopo de caminho definido no campo paths. Existe ainda o escopo global em ~/.claude, que vale pra todos os projetos (no Windows isso resolve pra %USERPROFILE%\.claude).
Qual a diferença entre o subagente Explore e o subagente Plan no Claude Code?
O Explore é read-only e serve pra buscar ou entender código sem alterar nada, com três níveis de profundidade: quick, medium e very thorough. O Plan também é read-only, mas atua especificamente dentro do plan mode, pesquisando a base em uma janela de contexto separada enquanto a conversa principal permanece somente leitura. Já o general-purpose é o único dos três que também modifica arquivos, usado em tarefas com múltiplos passos dependentes.
Dá pra usar /simplify ou /code-review depois que o código duplicado já foi gerado?
Dá sim, os dois atuam sobre o que já foi escrito. O /simplify roda agentes em paralelo revisando o código alterado quanto a reuso, qualidade, eficiência e aderência ao CLAUDE.md numa única passada. Já o /code-review checa o diff atual atrás de bugs de correção e limpezas, podendo aplicar os achados direto com a flag –fix.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
Bateu o limite de uso do Claude Code? Como retomar a tarefa sem refazer tudo
Bateu o limite de uso do Claude Code? Veja como retomar a tarefa de onde parou com /usage, CLAUDE.md e --continue, sem refazer nada.
Como pagar o Claude Code no Brasil: cartão, dólar, IOF e quanto fica em reais
Claude Code preço Brasil na prática: câmbio, IOF de 3,5% e quanto fica na fatura. Planos Pro e Max convertidos em reais e como pagar com cartão.
Como instalar uma skill no Claude Code: passo a passo
Saiba como instalar skill no Claude Code: use a pasta pessoal para todas as sessões ou a pasta de projeto para versionar. Frontmatter YAML é obrigatório.
