· 8 min · Engenharia

Os recursos problemáticos do Claude Code: onde seu fluxo de trabalho com agentes falha

Os recursos problemáticos do Claude Code: onde seu fluxo de trabalho com agentes falha

As funcionalidades problemáticas do Claude Code são, em sua maioria, problemas de limites

O erro mais custoso do Claude Code que já vi não foi uma edição de código ruim. Foi uma edição correta feita no estado errado do repositório.

Um desenvolvedor pediu ao Claude Code para “atualizar o middleware de autenticação e executar os testes”. A árvore de trabalho já continha uma migração de outra tarefa que ainda não havia sido registrada em um commit. Claude inspecionou arquivos suficientes para entender o middleware, modificou a implementação correta, executou um formatador e informou que havia concluído com sucesso. O diff resultante era tecnicamente plausível, mas misturava duas alterações sem relação entre si e tornava a revisão posterior quase impossível.

Essa é a lição incômoda por trás de muitas funcionalidades problemáticas do Claude Code: o sistema muitas vezes está fazendo exatamente o que seu fluxo de trabalho incentiva. O problema é que um agente com acesso ao sistema de arquivos, acesso ao shell, memória em arquivos de instruções e um objetivo definido em conversa não respeita naturalmente os limites que os desenvolvedores pressupõem.

Algumas críticas descrevem fraquezas reais do produto. Outras descrevem escolhas deliberadas que se tornam perigosas quando tratadas como padrões invisíveis. A pergunta útil não é se Claude Code deveria ser “mais autônomo” ou “menos autônomo”. É onde a autonomia termina, como esse limite é representado e se o desenvolvedor consegue observar o que aconteceu.

O padrão surpreendente: contexto não é isolamento

Claude Code foi projetado para operar em um diretório de trabalho real. Ele pode inspecionar o repositório, editar arquivos, invocar ferramentas e iterar com base na saída dos comandos. Isso é muito mais útil do que pedir a um modelo que retorne um patch a partir de um prompt abstrato.

Isso também significa que o diretório atual faz parte do estado efetivo do agente.

Na prática, Claude Code pode encontrar:

  • Alterações de outra tarefa ainda não registradas em um commit
  • Arquivos gerados que parecem fontes confiáveis
  • Configuração local que difere da usada na CI
  • Credenciais ou variáveis de ambiente acessíveis por meio de ferramentas
  • Worktrees, repositórios aninhados ou diretórios vinculados por links simbólicos
  • A CLAUDE.md arquivo de instruções que muda o comportamento sem aparecer no prompt
  • Scripts de compilação que acessam a rede ou executam limpezas destrutivas

O agente pode perceber essas condições, mas percebê-las não é o mesmo que impor isolamento. Um modelo pode dizer “Encontrei alterações não relacionadas” e ainda assim prosseguir se o pedido do usuário parecer claro.

Uma sessão disciplinada começa com uma verificação explícita do estado:

git status --short
git branch --show-current
git diff --stat
pwd

Também prefiro declarar o limite no primeiro prompt:

Work only on the request in this session. Do not modify existing unrelated changes.
Before editing, report the current branch, dirty files, and the files you intend to change.
Do not commit, reset, checkout, or delete files.

Isso parece repetitivo até que uma sessão dê errado. Instruções para agentes não são controles de acesso. São orientações de comportamento, e orientações de comportamento são probabilísticas.

A escolha do produto é compreensível: forçar cada tarefa a ocorrer em um ambiente isolado e descartável tornaria os fluxos de trabalho comuns mais lentos e menos convenientes. Mas o padrão ainda atribui responsabilidade demais ao usuário para entender o estado do repositório antes de delegar.

CLAUDE.md É poderoso e, por isso, fácil de interpretar mal

As instruções de projeto são um dos melhores recursos do Claude Code. Elas registram comandos de teste, restrições arquiteturais, convenções de nomenclatura e expectativas de revisão uma única vez, em vez de repeti-los em cada prompt.

Elas também são uma forma de acoplamento oculto.

Um repositório pode conter instruções que dizem ao Claude para:

  • Executar um gerenciador de pacotes específico
  • Preferir um diretório a outro
  • Atualizar snapshots
  • Evitar alterar arquivos gerados
  • Usar um comando de implantação ou de banco de dados
  • Ler arquivos de instruções adicionais

O usuário vê a tarefa, mas o agente vê a tarefa junto com uma hierarquia de instruções. Quando o comportamento surpreender você, inspecione as instruções efetivas em vez de presumir que o modelo ignorou o prompt.

Mantenha as instruções de projeto curtas e operacionais:

# Repository instructions

- Run `npm test` for the unit suite.
- Run `npm run lint` before describing the work as complete.
- Do not edit files under `generated/`; update the source and regenerate only when requested.
- Never run production deployment commands.
- Preserve unrelated working-tree changes.

Evite colocar objetivos vagos como “sempre tomar a melhor decisão arquitetural” nesse arquivo. Instruções amplas aumentam a margem de decisão do agente justamente onde você quer um comportamento previsível.

Limites de controle: confirmação não é um modelo de segurança

O sistema de permissões do Claude Code oferece um mecanismo de controle útil, mas é fácil superestimar o que ele garante.

Uma solicitação de confirmação geralmente responde a uma pergunta específica: esta ação da ferramenta deve acontecer agora? Ela não responde necessariamente a estas perguntas:

  • O comando é semanticamente seguro?
  • O modelo entendeu os efeitos colaterais do comando?
  • O caminho de destino está dentro do projeto pretendido?
  • Um script executará comandos adicionais?
  • O comando envia código-fonte ou segredos pela rede?
  • A alteração é reversível?

Um comando aparentemente inofensivo pode ocultar comportamentos significativos:

npm run test

O script pode excluir um cache, iniciar um contêiner, acessar um serviço remoto ou executar um hook de pós-instalação. O Claude Code pode pedir permissão para executar o comando, mas não pode transformar um comando de shell em um limite de capacidades totalmente verificado.

Permissões no nível do projeto podem reduzir solicitações rotineiras:

{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(npm run lint)",
      "Bash(git diff -- *)"
    ],
    "deny": [
      "Bash(rm *)",
      "Bash(git reset *)",
      "Bash(git checkout *)",
      "Read(.env)",
      "Read(.env.*)",
      "Read(secrets/**)"
    ]
  }
}

Trate isso como documentação de políticas e redução de atrito, não como um ambiente isolado. Os padrões devem ser restritos. Permitir Bash(npm *) é conveniente, mas autoriza todos os scripts npm, inclusive aqueles que você talvez não tenha inspecionado.

A divisão prática é:

LimiteEm que ajudaO que não resolve
Confirmação de uso de ferramentasImpedir uma ação imediatamente indesejadaEfeitos ocultos em comandos aprovados
Regras de permissãoPolítica de uso de ferramentas repetível e previsívelInterpretação semântica de scripts
Planejamento somente leituraReduzir edições prematurasAnálise incorreta ou estado do repositório que passou despercebido
Contêiner ou worktreeIsolamento do sistema de arquivos e do ambienteAlterações inadequadas dentro do ambiente isolado
Revisão humanaValidação da intenção e da qualidadeDetectar todos os efeitos colaterais em tempo de execução
Verificações de CIVerificação reproduzívelProteger segredos locais durante a sessão

Para trabalhos de alto impacto, use isolamento no nível do sistema operacional: uma worktree descartável, um contêiner, credenciais restritas e uma política de rede adequada à tarefa. As solicitações de permissão do Claude Code complementam esses controles; não os substituem.

A observabilidade é mais fraca do que a transcrição sugere

A transcrição de um agente parece oferecer observabilidade porque contém mensagens como “Vou inspecionar as rotas”, chamadas de ferramentas, saídas de comandos e um resumo final. Mas uma transcrição não é o mesmo que um registro de auditoria.

As perguntas importantes que ficam sem resposta geralmente são:

  • Quais arquivos foram lidos, mas não mencionados?
  • Quais arquivos de instruções influenciaram a decisão?
  • Quais variáveis de ambiente, exatamente, estavam visíveis?
  • Um script de shell executou processos filhos?
  • Quais comandos alteraram o estado?
  • O que o modelo considerou verificado e o que considerou apenas inferido?
  • Um comando que falhou foi executado novamente com uma interpretação diferente?

O Claude Code oferece controles interativos úteis, como /status, /permissions, /compact, /clear, /rewind e /doctor. Use-os, mas entenda seu escopo. Eles ajudam você a inspecionar ou gerenciar a sessão atual; não criam automaticamente um registro duradouro de alterações adequado à análise de incidentes.

Para trabalhar em repositórios, crie sua própria trilha simples de evidências:

git status --short
git diff --name-only
git diff --check
npm test
git diff --stat

Um hook pode impor controles sobre o uso de ferramentas. Por exemplo, um hook PreToolUse pode inspecionar um comando Bash proposto e rejeitar operações especialmente arriscadas:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 .claude/hooks/reject-dangerous.py"
          }
        ]
      }
    ]
  }
}

Um hook mínimo pode ler a entrada da ferramenta fornecida pelo protocolo de hooks do Claude Code e rejeitar comandos que contenham operações destrutivas conhecidas:

#!/usr/bin/env python3
import json
import sys

event = json.load(sys.stdin)
command = event.get("tool_input", {}).get("command", "")

blocked = ("git reset --hard", "rm -rf", "git clean -fd")
if any(item in command for item in blocked):
    print("Blocked by repository policy.", file=sys.stderr)
    sys.exit(2)

sys.exit(0)

Os campos exatos dos eventos de hooks e a configuração compatível podem variar conforme a versão do Claude Code, portanto verifique o esquema local antes de padronizar esse padrão. O princípio de projeto importante permanece: coloque controles inegociáveis em políticas executáveis, não apenas em texto.

Modo de falha: o agente prioriza a conclusão da tarefa

A interação recompensa naturalmente um modelo de linguagem por produzir progresso. Se os testes falham, ele tende a investigar. Se aparece um erro de tipo, ele tende a corrigi-lo. Esse ciclo é valioso, mas pode transformar “faça a alteração solicitada” em “faça o repositório passar em todas as verificações por qualquer meio que pareça plausível localmente”.

Os sintomas comuns incluem:

  • Atualizar um snapshot em vez de corrigir o comportamento
  • Ampliar uma asserção de teste para acomodar uma regressão
  • Adicionar um ramo de compatibilidade sem confirmar sua necessidade
  • Alterar diretamente a saída gerada
  • Executar um formatador em arquivos não relacionados
  • Tratar a aprovação de um teste de escopo restrito como evidência de que a funcionalidade está completa
  • Repetir um comando que falhou sem mudar a suposição subjacente

A solução é definir condições de parada, não apenas objetivos:

Implement the parser change.
Run only the parser unit tests first.
Do not modify tests unless a test is demonstrably incorrect.
Do not update snapshots without showing the before/after behavior.
Stop after two failed repair attempts and summarize the failure.
Finish with the exact files changed and commands run.

Isso reduz a tendência do agente de converter incerteza em mais edições.

Um padrão particularmente eficaz é a execução em duas fases:

  1. Peça uma investigação e uma proposta de plano sem edições.
  2. Revise a lista de arquivos, os riscos e a estratégia de testes.
  3. Inicie um segundo prompt que autorize a implementação dentro desses limites.

O planejamento não é uma garantia. É um ponto de verificação em que a pessoa pode detectar uma interpretação errada antes que ela se torne um diff.

Modo de falha: a compressão de contexto perde detalhes operacionais

Sessões longas são úteis para depuração, mas acabam exigindo compactação ou resumo. O modelo retém uma representação comprimida, em vez de todas as saídas anteriores das ferramentas. Objetivos de alto nível costumam ser preservados. Restrições pequenas nem sempre são preservadas com a mesma fidelidade.

Isso cria uma armadilha comum: no início da sessão, você diz “não mexa nos arquivos de migração”; depois, o agente encontra um teste de esquema que falha e propõe exatamente isso.

Para trabalhos com restrições importantes:

  • Repita as invariantes após /compact
  • Mantenha a lista de arquivos ativos em um arquivo de anotações visível ou em uma issue
  • Use sessões separadas para tarefas não relacionadas
  • Prefira uma nova sessão a uma sessão extremamente longa e sem rumo
  • Execute novamente git diff --name-only antes de aceitar o resultado

A compensação é simples. O contexto persistente melhora a continuidade, enquanto um contexto novo melhora a previsibilidade. Nenhum dos dois é universalmente superior.

Modo de falha: “concluído” significa plausível localmente

O Claude Code pode executar testes, mas executar testes não significa que eles sejam adequados. Ele pode escolher o comando relevante mais rápido, seguir as instruções do repositório ou parar após um comando que pareça suficiente. Um resultado aprovado pode significar apenas que um caminho funcionou em um ambiente local.

Torne a verificação explícita e exija evidências:

Before finishing:
- Run `git diff --check`.
- Run `npm test -- --runInBand`.
- Report the exact commands and whether each passed.
- Distinguish tests run from tests not run.
- Do not claim production behavior was verified.

Para sistemas baseados em API, peça ao agente que inspecione as estruturas de requisições e respostas, em vez de inferi-las a partir de um wrapper. Uma chamada mínima à API do Claude pode ser assim:

import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=512,
    system="Return JSON only.",
    messages=[
        {"role": "user", "content": "Classify this event: login_failed"}
    ],
)

print(response.model_dump_json(indent=2))

A resposta contém blocos de conteúdo estruturado, não apenas uma string. Um código que presume que response.content[0].text sempre representa o resultado semântico completo se torna frágil quando o uso de ferramentas ou múltiplos blocos entram no fluxo de trabalho.

Essa é outra questão de limites: o resumo em linguagem natural do modelo não é um contrato de interface. Analise as saídas estruturadas, valide-as e retenha os metadados brutos das requisições quando a depuração exigir.

Quais críticas são falhas do produto?

Alguns comportamentos merecem melhorias no nível do produto:

  • Pode ser difícil entender rapidamente as instruções e permissões importantes que estão efetivamente em vigor.
  • É muito fácil confundir um resumo final em linguagem natural com uma verificação completa.
  • A experiência de confirmação não consegue comunicar todos os efeitos colaterais de comandos de shell arbitrários.
  • O estado de sessões longas e a compactação podem tornar as restrições menos visíveis.
  • O estado do repositório não é automaticamente isolado de trabalhos não relacionados.

Outros comportamentos são uma consequência razoável do projeto escolhido:

  • Um agente que pode editar e executar é mais útil do que um assistente que apenas produz patches.
  • Pedir autorização antes de cada leitura ou teste de baixo risco tornaria o fluxo de trabalho penosamente lento.
  • O acesso amplo ao repositório permite depurar problemas que atravessam os limites entre compilação, testes e código-fonte.
  • A correção iterativa é necessária em projetos reais, nos quais o primeiro comando costuma falhar.

A resposta adequada é uma operação em camadas: permissões restritas, ambientes descartáveis para tarefas arriscadas, prompts explícitos, sessões curtas, hooks executáveis e verificação mecânica.

Recomendações Práticas

  • Inspecione git status, a branch e o diff antes de conceder ao Claude Code autorização de escrita.
  • Trate CLAUDE.md como uma política executável do projeto e mantenha-a concisa.
  • Use padrões restritos de allow e deny para permissões; nunca os confunda com isolamento em sandbox.
  • Coloque controles para comandos destrutivos em hooks ou no ambiente de execução que os envolve.
  • Separe o planejamento da implementação em alterações pouco familiares ou de alto impacto.
  • Repita as restrições críticas após a compactação e antes da verificação final.
  • Exija comandos de teste exatos e diferencie “não executado” de “aprovado”.
  • Revise git diff --name-only, git diff --checke o diff completo antes de fazer o merge.
  • Use contêineres, credenciais restritas ou worktrees descartáveis quando os efeitos colaterais do shell forem relevantes.
  • Trate a autonomia do Claude Code como uma capacidade a ser moldada, não como uma configuração de confiança a ser ativada ou desativada.

A crítica central é válida: um fluxo de trabalho agêntico torna os limites de controle implícitos exatamente no momento em que deveriam ser explícitos. Mas isso não torna o fluxo de trabalho inutilizável. Significa que equipes experientes precisam fornecer os limites que faltam por meio de configuração, isolamento, observabilidade e revisão.

A

A AI Prime Tech publica este blog. Os artigos são redigidos com assistência de IA; confira detalhes específicos de cada versão, como IDs de modelos, preços e limites, na documentação oficial antes de se basear neles.

Obtenha acesso mais barato à API do Claude

Uma única chave de API para Claude Opus 5.5, Sonnet 5, Haiku 4.5 e Fable 5.1, além de GPT-6 modelos. Pague conforme o uso, sem assinatura.

Obtenha Sua Chave de API →
A AI Prime Tech é um gateway de API independente de terceiros. Claude™ e Anthropic® são marcas comerciais da Anthropic, PBC. Não há afiliação nem endosso implícitos.