SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-26

Por que agentes de código ignoram instruções

Seu arquivo manda o agente parar, mas ele continua. Veja as 4 causas, incluindo contexto ausente, regras vagas e compactação no Claude Code, antes de reescrever a regra.

Por que os agentes de programação ignoram as suas instruções

Os agentes de programação ignoram as suas instruções por quatro motivos, e nenhum deles é o facto de ter sido demasiado educado. A regra nunca esteve na janela de contexto. A regra era demasiado vaga para ser comparada com uma ação. Havia algo no contexto que a contradizia, normalmente o código que o agente tinha acabado de ler. Ou a regra continua carregada, mas está muito atrás do turno atual, e o agente está a trabalhar com base no que está mais próximo.

Cada causa tem a sua própria correção, por isso o primeiro passo é distingui-las. Letras maiúsculas e a palavra IMPORTANT não são um diagnóstico. Os mecanismos abaixo usam Claude Code como exemplo prático, porque o seu comportamento de carregamento e compactação está documentado em detalhe em August 2026. Outras ferramentas diferem nos pormenores, mas comportam-se da mesma forma em termos gerais.

Primeiro, dois termos. A janela de contexto é o bloco de texto que o modelo vê num determinado turno: o prompt do sistema, os ficheiros de instruções, a conversa e todos os ficheiros que o agente leu. O harness é o programa que envolve o modelo, ou seja, o componente que lê os ficheiros do disco e monta esse bloco. Quase todas as queixas neste artigo são, na realidade, queixas sobre o harness, não sobre o modelo.

O seu ficheiro de instruções é uma mensagem, não uma definição

Um ficheiro de instruções não é configuração. Nada no runtime lê CLAUDE.md e aplica essa regra. O harness lê o ficheiro do disco e cola o texto na conversa. No Claude Code, esse conteúdo é enviado como uma mensagem do utilizador colocada depois do system prompt. Isto significa que o modelo vê as suas regras da mesma forma que vê qualquer outro texto introduzido por si.

Isto tem uma consequência desconfortável. As suas regras competem com todas as outras partes do texto apresentado, em condições de igualdade. Uma regra é uma afirmação. O ficheiro que o agente acabou de abrir é evidência. Quando os dois entram em conflito, a evidência muitas vezes prevalece. Não é gerado nenhum erro, porque, do ponto de vista do modelo, nada correu mal.

A documentação oficial afirma isto de forma clara: os ficheiros de instruções são tratados como contexto, não como configuração aplicada. Para bloquear uma ação independentemente da decisão do modelo, precisa de um hook, não de uma frase. Guarde esta ideia. A maioria das correções no final deste artigo aplica-a a um caso específico.

Quais ficheiros de instruções são carregados e quando

Claude Code percorre a árvore de diretórios a partir do diretório onde foi iniciado. Todos os ficheiros CLAUDE.md e CLAUDE.local.md existentes desde a raiz do sistema de ficheiros até ao diretório de trabalho são carregados por completo no arranque. São concatenados por essa ordem. Assim, o ficheiro mais próximo do diretório onde iniciou é lido por último. Dentro do mesmo diretório, o ficheiro .local é acrescentado depois do ficheiro principal.

Os ficheiros em subdiretórios abaixo do diretório de trabalho comportam-se de forma diferente. Não são carregados no arranque. São carregados quando o agente lê um ficheiro nesse diretório. O mesmo se aplica às regras associadas a caminhos em .claude/rules/ que tenham um campo de frontmatter paths:: entram no contexto quando é lido um ficheiro correspondente, e não em cada turno.

Esta diferença explica uma parte significativa das falhas comunicadas. Coloca uma regra em packages/api/CLAUDE.md, faz uma pergunta sobre a API e o agente responde sem nunca abrir um ficheiro em packages/api/. A regra não foi ignorada. Nunca esteve presente. Se o repositório distribuir as instruções por ficheiros de instruções por pacote num monorepo, esta é a primeira coisa a verificar, sempre.

Existe ainda outro problema de carregamento. É a causa mais comum da mensagem "o agente ignorou as minhas instruções": Claude Code lê CLAUDE.md, não AGENTS.md. Um repositório que tenha adotado AGENTS.md como padrão e não tenha CLAUDE.md não fornece nada para o Claude Code carregar. A ponte suportada é um ficheiro CLAUDE.md cuja primeira linha seja @AGENTS.md. Essa linha importa o ficheiro no arranque. Pode acrescentar notas específicas do Claude Code abaixo dela. Também pode usar um symlink quando não tem nada adicional para acrescentar. Decidir o que deve pertencer a esse ficheiro é uma questão separada, abordada em separar as instruções do agente da documentação para pessoas.

Confirme se o ficheiro foi carregado antes de o reescrever

Não altere o texto até confirmar que o agente consegue ver o ficheiro. Há duas verificações, e a mais simples vem primeiro.

Execute /context dentro da sessão. O comando apresenta a janela atual dividida por categoria, e a lista Memory files mostra o nome de cada ficheiro de instruções efetivamente carregado. Se um ficheiro não aparecer nessa lista, não está na conversa. Por isso, nada do que escrever dentro dele terá efeito. /memory lista as localizações dos ficheiros e abre-os para edição, incluindo os que ainda não existem.

Para obter uma confirmação mais detalhada, registe os carregamentos. O evento de hook InstructionsLoaded é acionado sempre que um CLAUDE.md ou um ficheiro de regras entra no contexto. O respetivo matcher indica o motivo do carregamento: session_start, nested_traversal, path_glob_match, include ou compact. Coloque isto em .claude/settings.json:

{
  "hooks": {
    "InstructionsLoaded": [
      {
        "matcher": "nested_traversal",
        "hooks": [
          {
            "type": "command",
            "command": "cat >> /tmp/instructions-loaded.log"
          }
        ]
      }
    ]
  }
}

O hook recebe o payload como JSON através da entrada padrão, por isso cat acrescenta o registo completo. Monitorize-o com tail -f /tmp/instructions-loaded.log enquanto trabalha. O código de saída deste evento é ignorado. Assim, o hook apenas observa e nunca bloqueia. Se o seu ficheiro aninhado nunca aparecer nesse log durante uma sessão em que esperava que fosse carregado, pare de reescrever o texto. O problema está na localização.

O que uma sessão longa faz às suas regras

Aplicam-se aqui dois efeitos distintos, e cada um exige uma resposta diferente.

Distância. Uma regra declarada no turno 1 ainda está na janela no turno 90, mas agora compete com 90 turnos de texto mais recente e mais específico para o que está a fazer neste momento. Não pode eliminar este efeito por configuração, mas pode medi-lo. Execute a mesma tarefa numa sessão nova. Se a regra funcionar nessa sessão e falhar numa sessão longa, a distância é a causa.

Compactação. Quando a janela fica cheia, o harness resume a conversa até esse momento e continua a partir desse resumo. O que sobrevive é o que o sumarizador considerou importante, e isso não coincide necessariamente com o que considera importante. A documentação do Claude Code descreve o resultado de cada mecanismo, e as diferenças são grandes. A raiz do projeto CLAUDE.md e as regras sem escopo são reinjetadas a partir do disco depois de uma compactação. A memória automática também é reinjetada a partir do disco. As regras com frontmatter paths: são perdidas até que um ficheiro correspondente seja lido novamente. Os ficheiros CLAUDE.md aninhados em subdiretórios são perdidos até que um ficheiro desse subdiretório seja lido novamente.

Ordene as instruções de acordo com essa tabela, e a ordem de fragilidade torna-se evidente. Uma regra que escreveu apenas no chat é o elemento mais frágil da sessão: só persiste se o resumo a tiver mantido. Uma regra em packages/api/CLAUDE.md vem a seguir, porque foi carregada uma vez, removida pelo resumo e só regressa na próxima leitura nesse diretório. Uma regra no ficheiro da raiz do projeto é a mais durável, porque é relida a partir do disco de cada vez.

Por isso, se uma instrução tiver de se manter durante toda a sessão, deve ficar no ficheiro da raiz do projeto, sem frontmatter paths:. Tudo o resto é um compromisso que deve escolher de forma deliberada. Gerir o que permanece na janela de contexto aborda /compact com um argumento de foco e /clear entre tarefas não relacionadas, sendo que ambos alteram a frequência com que o sumarizador pode decidir quais eram as suas regras.

Por que o código ao redor prevalece sobre a regra

Esta é a falha que as pessoas descrevem com mais frequência e diagnosticam com menos frequência. O seu ficheiro diz que o acesso à base de dados passa pela camada de repositório. O agente escreve um handler que chama diretamente o ORM (object relational mapper). A regra não foi ignorada por uma questão de estilo. As evidências tiveram mais peso.

Uma regra descreve uma preferência. O código demonstra uma preferência. Quando o agente abre três ficheiros do módulo que está prestes a editar e os três chamam diretamente o ORM, o contexto contém uma frase abstrata de um lado e três exemplos concretos, recentes e correspondentes à tarefa do outro. Copiar o padrão local é normalmente o comportamento correto. Neste caso, isso só está errado porque sabe algo que o contexto não sabe: esses ficheiros são código legado.

Por isso, escreva essa informação na regra. As regras que identificam as próprias evidências em contrário resistem ao contacto com um repositório real. As regras que apenas declaram uma preferência não resistem.

O novo acesso à base de dados passa por app/repositories/. Os ficheiros em app/legacy/ ainda chamam diretamente o ORM. Esse é código antigo, não o padrão. Não o copie.

A segunda frase é a parte essencial. Informa o agente sobre o que ele está prestes a encontrar e como deve interpretar isso, antes de o encontrar. A mesma correção aplica-se a qualquer regra que o seu repositório contradiga de forma visível: um estilo de commit que o histórico não segue, uma estrutura de testes que metade da suite ignora, uma convenção de import que só existe no código novo. Sempre que o código discordar do ficheiro, identifique essa discordância no ficheiro.

Uma regra vaga não pode ser verificada e, por isso, não pode ser seguida

"Escreva código limpo." "Não faça engenharia excessiva." "Mantenha a simplicidade." "Tenha cuidado com as migrações." Nenhuma destas regras pode ser testada contra uma ação específica, pelo agente ou por si. Um agente que recebe uma regra que não consegue verificar contra o seu próprio resultado está a adivinhar, e você está a avaliar essa adivinhação com base numa impressão.

Este é o teste a aplicar a cada linha do seu ficheiro. Escreva o comando de shell que terminaria com um código diferente de zero quando a regra fosse violada. Se não conseguir escrever esse comando, a regra não é verificável. Compare estes pares:

  • Não verificável: "Mantenha as funções pequenas." Verificável: "Uma função com mais de 60 linhas precisa de um comentário acima dela a explicar o motivo."
  • Não verificável: "Teste as suas alterações." Verificável: "Execute npm test e cole a contagem de falhas antes de marcar uma tarefa como concluída."
  • Não verificável: "Mantenha os ficheiros organizados." Verificável: "Os handlers HTTP ficam em src/api/handlers/. Não coloque mais nada nesse diretório."
  • Não verificável: "Formate o código corretamente." Verificável: "Use indentação de 2 espaços nos ficheiros .ts."

"Não faça engenharia excessiva" é a regra que as pessoas abandonam primeiro, porque a correção não é uma frase mais curta, mas uma frase mais longa: explicar claramente o que significa a menor alteração que resolve o problema fornece ao agente critérios contra os quais pode comparar o seu próprio diff.

O tamanho é o mesmo problema com outra aparência. As orientações do Claude Code recomendam menos de 200 linhas por ficheiro de instruções e afirmam diretamente que ficheiros mais longos reduzem a adesão. Um ficheiro com 700 linhas não é uma instrução mais firme. São 700 linhas de afirmações com mais possibilidades de se contradizerem, e essas linhas são contabilizadas na sua janela em cada turno, o que se reflete diretamente na utilização de tokens. Estruturar o ficheiro para que cada regra fique sob um título que o leitor possa consultar rapidamente é abordado em escrever um ficheiro de instruções que o agente consegue executar. Melhor ainda, elimine as partes que descrevem em vez de instruírem: uma descrição dos diretórios onde ficam os handlers e os models é uma estrutura que o agente pode consultar quando necessário a partir de um mapa analisado do repositório, em vez de a manter na janela em cada turno.

Como diagnosticar o problema em dez minutos

Execute estes comandos pela ordem apresentada. Saltar diretamente para o último passo faz com que muitas pessoas acabem com um ficheiro extenso de regras imperativas que continua sem funcionar.

  1. Confirme se foi carregado. Execute /context e consulte a lista Memory files. Se o ficheiro não estiver presente, corrija a localização e pare. Nada mais desta lista se aplica ainda.
  2. Reproduza o problema numa sessão nova. Inicie uma sessão nova e forneça a tarefa mais pequena que deveria ativar a regra. Se funcionar no início, mas falhar numa sessão longa, o problema aponta para o contexto ou para a compactação. Se também falhar numa sessão nova, o problema está na própria regra.
  3. Remova a concorrência. Peça a mesma alteração num diretório cujo código existente já siga a regra. Se a conformidade voltar, o código envolvente estava a sobrepor-se à sua instrução.
  4. Procure um conflito. Dois ficheiros com orientações diferentes para o mesmo comportamento constituem uma falha documentada: o modelo pode escolher um deles arbitrariamente e não lhe dirá que o fez.
  5. Torne a regra verificável e teste novamente. Reescreva a regra com um caminho concreto e uma condição. Um aumento significativo da conformidade indica que a formulação era a causa.

O passo 4 requer um comando. Faça grep em todas as fontes de instruções sobre o tópico, e não apenas no ficheiro que estava a editar:

grep -rni "migration" --include="CLAUDE.md" --include="CLAUDE.local.md" .
grep -rni "migration" .claude/rules/ ~/.claude/CLAUDE.md ~/.claude/rules/ 2>/dev/null

Um resultado em dois ficheiros com instruções diferentes é o problema. Elimine uma delas. Não tente estabelecer uma hierarquia usando uma formulação mais forte, porque não existe um mecanismo de hierarquia ao qual possa recorrer.

As correções, por ordem de eficácia

Cada passo abaixo tem mais eficácia do que o anterior e custa mais a configurar. Comece pelo topo quando for barato reformular uma regra. Desça assim que a regra for importante o suficiente para que falhas ocasionais não sejam aceitáveis.

  1. Torne a regra concreta. Indique um caminho, um comando ou uma condição. Adicione as evidências contrárias que o agente encontrará no repositório, como mostrado anteriormente. Isto não tem custo e corrige uma parte surpreendentemente grande dos casos.
  2. Aproxime-a do que ela governa. Um CLAUDE.md aninhado, uma regra com escopo de caminho em .claude/rules/ ou um comentário no início do próprio ficheiro. A regra é então lida juntamente com o código a que se aplica. Aceite a desvantagem: qualquer conteúdo carregado dessa forma é removido na compactação seguinte e volta a ser carregado na próxima leitura correspondente.
  3. Transfira a aplicação da regra para um hook. A prosa pede. Um hook decide. Os hooks executam código em eventos fixos do ciclo de vida e aplicam a regra independentemente da conclusão do modelo.
  4. Entregue a regra a uma ferramenta determinística e elimine a prosa. Formatação, ordem dos imports, comprimento das linhas, imports proibidos e formato das mensagens de commit. ruff format, prettier --write, eslint, um hook pre-commit. O formatador está sempre certo e não consome tokens. A frase está certa na maior parte das vezes e consome tokens em cada interação.

Passo 3 em detalhe. Suponha que os ficheiros de migração nunca podem ser editados pelo agente. Coloque isto em .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
          }
        ]
      }
    ]
  }
}

E isto em .claude/hooks/guard-migrations.sh:

#!/usr/bin/env bash
set -euo pipefail

path=$(jq -r '.tool_input.file_path // empty')

case "$path" in
  */migrations/*)
    echo "Files under migrations/ are written by hand. Stop and ask first." >&2
    exit 2
    ;;
esac

exit 0

Execute chmod +x .claude/hooks/guard-migrations.sh, inicie uma nova sessão e peça ao agente para editar um ficheiro em migrations/. A edição é recusada e a sua mensagem é devolvida como motivo. O código de saída 2 em PreToolUse bloqueia a chamada da ferramenta antes da sua execução, e o texto enviado para stderr é transmitido ao modelo como mensagem de bloqueio. ${CLAUDE_PROJECT_DIR} é resolvido para a raiz do projeto, pelo que o hook funciona independentemente do diretório onde o agente esteja. O agente não precisa de concordar com a regra, de se lembrar dela nem de ainda a ter no contexto. A edição não acontece.

Para uma proibição simples, sem lógica, permissions.deny nas suas definições faz o mesmo sem um script para manter, e os modos de permissão determinam o que é executado sem lhe pedir confirmação. Se uma instrução tiver genuinamente de ficar ao nível do system prompt, em vez de numa mensagem do utilizador, --append-system-prompt coloca-a nesse nível. No entanto, tem de ser transmitida em cada invocação, o que é mais adequado para scripts do que para trabalho interativo.

O que não é possível impor apenas com instruções

Seja claro sobre qual metade deste problema é sua. Posicionamento, formulação, conflitos entre ficheiros e tamanho do ficheiro são problemas do autor, com correções que cabem ao autor. O resto é comportamento do modelo, e uma redação melhor não o elimina.

Concordar não é cumprir. Um agente pode confirmar uma regra, repeti-la corretamente e violá-la duas chamadas de ferramenta depois. A confirmação não tem custo e não permite prever nada. Não a interprete como uma correção nem a conte como um teste.

Alguns hábitos persistem. Adicionar comentários, acrescentar tratamento defensivo de erros, escrever um resumo final, executar o próximo comando óbvio. Estes comportamentos reaparecem quando existe uma regra que os proíbe, embora com uma frequência menor, não nula. Pode medir a sua própria taxa: execute a mesma tarefa 10 vezes em sessões novas e conte as violações. Quando esse número precisa de ser zero, a regra tem de sair do prompt. Declarar uma tarefa concluída quando ainda falta uma parte tem a mesma origem comportamental, e a correção é estrutural, não verbal: a competência unlazy troca a frase por uma árvore de profundidade e ficheiros de controlo que o agente tem de validar antes de poder declarar a tarefa concluída.

A própria sessão torna-se um exemplo. Se o agente violou a regra na interação 12 e deixou passar, essa violação passa a fazer parte do contexto como demonstração e é muito mais recente do que a regra. Corrija uma violação assim que a detetar. Uma violação não corrigida ensina o resto da sessão.

Um ficheiro de instruções não é um limite de segurança. Molda o comportamento, mas não o impõe. Tudo aquilo em que uma falha tem um custo elevado, como credenciais ou comandos destrutivos, deve ser tratado com permissões ou um hook. Manter os segredos fora do alcance de um agente aplica o mesmo princípio aos dados: não peça a um agente para não ler um ficheiro; faça com que o ficheiro não possa ser lido.

A versão curta. Prove que o ficheiro foi carregado, torne a regra verificável, coloque-a junto do objeto que governa e, quando a taxa de falhas continuar a ser relevante, retire-a da prosa. Uma regra que um agente não pode ignorar é uma regra que nunca lhe foi pedida.

FAQ

Por que o Claude Code ignora o meu CLAUDE.md?

Confirme se o ficheiro foi carregado antes de concluir que foi ignorado. Execute /context e consulte a lista Memory files; um ficheiro que não aparece nessa lista não está na conversa. Os ficheiros de instruções são enviados como uma mensagem de utilizador depois do prompt do sistema e tratados como contexto, não como configuração obrigatória. Por isso, não existe garantia de cumprimento estrito. Na maioria dos casos, uma de quatro situações está na origem do problema: o ficheiro está num subdiretório que o agente nunca leu, dois ficheiros entram em conflito e o modelo escolheu um deles arbitrariamente, a regra é demasiado vaga para permitir verificar uma ação, ou o código envolvente demonstra o oposto do que a regra determina.

Editar o ficheiro de instruções durante a sessão altera alguma coisa?

Não para a cópia que já está na conversa. Os ficheiros acima do diretório de trabalho são carregados integralmente no arranque, por isso o texto que o modelo tem é o texto existente nesse momento. Para carregar uma edição, inicie uma nova sessão ou peça ao agente para ler o ficheiro com as ferramentas normais de ficheiros. Isso coloca a versão atual na conversa como uma nova mensagem. Depois de uma compactação, o ficheiro da raiz do projeto é lido novamente do disco, pelo que a nova versão também é carregada nesse momento.

Qual ficheiro prevalece quando um CLAUDE.md na raiz e outro num diretório aninhado entram em conflito?

Nenhum prevalece de forma fiável. Os ficheiros encontrados são concatenados no contexto, em vez de um substituir o outro, pela ordem que vai da raiz do sistema de ficheiros até ao diretório de trabalho. Assim, o ficheiro mais próximo é simplesmente lido por último. Não existe um mecanismo de precedência para resolver contradições, e a documentação do Claude Code afirma que as regras contraditórias podem ser resolvidas arbitrariamente. Escreva os ficheiros aninhados como adições que indiquem o caminho a que se aplicam e elimine a contradição, em vez de tentar impor uma precedência.

As minhas instruções sobrevivem a /compact?

Depende da forma como foram carregadas. O ficheiro da raiz do projeto CLAUDE.md, as regras sem escopo e a memória automática são reinjetados a partir do disco depois de uma compactação. As regras com frontmatter paths: e os ficheiros CLAUDE.md aninhados em subdiretórios perdem-se até que um ficheiro correspondente seja lido novamente. Qualquer conteúdo que tenha escrito apenas no chat sobrevive apenas se o resumidor o tiver mantido. Se uma regra tiver de permanecer válida durante toda a sessão, coloque-a no ficheiro da raiz do projeto sem frontmatter paths:.

Quando deve uma regra tornar-se um hook em vez de permanecer em prosa?

Quando a verificação é determinística e o custo de uma falha é superior ao custo de escrever um pequeno script. Restrições de caminhos de ficheiros, comandos obrigatórios antes de um commit e chamadas de ferramentas proibidas são exemplos que cumprem esse critério. Um hook PreToolUse que termine com o código de estado 2 bloqueia imediatamente a chamada da ferramenta e devolve o texto de stderr ao modelo como motivo. Assim, a regra mantém-se eficaz, esteja ou não ainda presente no contexto. Qualquer decisão que possa ser tomada por um formatador ou linter deve ficar a cargo dessa ferramenta e ser removida integralmente do ficheiro de instruções.