90% do código na Anthropic é escrito por agentes Claude. Não por engenheiros digitando em uma janela de chat. Mas por agentes autônomos executando loops, chamando ferramentas e enviando código enquanto a equipe dorme.
Siga meu Substack para receber dicas frescas de IA:
Esta é a configuração exata. Passo a passo. Desde a primeira chamada de API até um agente funcional que você pode direcionar para qualquer tarefa.
Este artigo abordará:
1 - por que a maioria dos "agentes" que as pessoas constroem não são agentes
2 - as 5 partes que todo agente funcional precisa
3 - como construir cada parte com Claude, com código
4 - os erros que matam os agentes antes mesmo de serem implantados
Marque isto. Cada bloco de código abaixo funciona.
01. A maioria dos "agentes de IA" não são agentes
Já construí e quebrei mais agentes do que consigo contar. Vi eles queimarem tokens a noite toda e não produzirem nada. Vi eles reescreverem o mesmo arquivo 30 vezes. Vi eles passarem no próprio teste deletando o teste.

Cada falha me ensinou a mesma lição: o modelo não é o problema. A arquitetura ao redor dele é. Este guia é tudo que aprendi, comprimido no caminho mais curto que posso te dar.
Aqui está o que a maioria das pessoas constrói quando diz "agente de IA":
1while True:2 user_input = input("> ")3 response = call_claude(user_input)4 print(response)
Isso é um chatbot. Ele espera por você. Ele faz o que você manda. Ele esquece tudo entre as sessões. Quando você fecha a aba, ele para.
Um agente é um sistema que trabalha em direção a um objetivo sem você sentado na frente dele. Ele descobre o que precisa ser feito, faz um plano, executa, verifica o resultado e, se não estiver pronto - tenta novamente. Você define a direção. O agente faz o trabalho.
"O Claude Code foi de zero a US$ 400 milhões em receita em alguns meses. Começou como um projeto de hackathon. E ainda usa apenas a API pública." -
Boris Cherny, Head of Claude Code
A mesma API à qual você tem acesso agora. Os mesmos modelos. A diferença é a arquitetura ao redor do modelo.

02. As 5 partes de um agente real
Todo agente funcional - Claude Code, Devin, Codex, ou qualquer coisa que você construa - é montado a partir de cinco partes. Falte uma e ele quebra.

03. A camada de API
Tudo começa aqui. Você chama o Claude, o Claude responde. Mas a forma como você o chama determina se você obtém um chatbot ou um agente.

Três coisas importam: o prompt do sistema, a saída estruturada e a temperatura.
O prompt do sistema não é uma saudação. É o manual de operação do seu agente. Toda regra, restrição e comportamento vão aqui. Sem ele, o Claude adivinha o que você quer. Com ele, o Claude segue sua especificação.
1import anthropic23client = anthropic.Anthropic()45response = client.messages.create(6 model="claude-sonnet-4-6",7 max_tokens=4096,8 system="""Você é um agente de revisão de código.910Regras:11- Leia todo o diff antes de comentar12- Sinalize apenas bugs reais, não preferências de estilo13- Se não houver nada errado, diga "LGTM" e pare14- Nunca sugira mudanças que você não testou mentalmente15- Formato de saída: array JSON de {file, line, issue, fix}""",16 messages=[{"role": "user", "content": diff_content}]17)
A saída estruturada torna a resposta do seu agente legível por máquina. Se o Claude retornar texto livre, seu código precisa analisá-lo. Se o Claude retornar JSON, seu código pode usá-lo diretamente.
1# Force a saída JSON dizendo ao Claude a forma exata2system = """Retorne APENAS JSON válido. Sem markdown. Sem explicação.3Schema:4{5 "status": "pass" | "fail",6 "issues": [{"file": str, "line": int, "issue": str}],7 "summary": str8}"""
Temperatura. Defina como 0 para agentes determinísticos. Defina como 0.3-0.5 para trabalho criativo. O padrão (1.0) adiciona aleatoriedade que você quase nunca quer em um agente.
04. Ferramentas
Um modelo sem ferramentas pode raciocinar, mas não pode agir. Ele pode te dizer qual arquivo editar, mas não pode editá-lo. Ele pode descrever uma consulta, mas não pode executá-la.

O uso de ferramentas do Claude permite que você defina funções que o modelo pode chamar. Você descreve a função. O Claude decide quando chamá-la. Você a executa e retorna o resultado. O Claude usa o resultado para continuar raciocinando.
1tools = [{2 "name": "run_sql",3 "description": "Execute uma consulta SQL somente leitura no banco de dados",4 "input_schema": {5 "type": "object",6 "properties": {7 "query": {8 "type": "string",9 "description": "Consulta SQL SELECT a ser executada"10 }11 },12 "required": ["query"]13 }14},15{16 "name": "write_file",17 "description": "Escreva conteúdo em um arquivo no disco",18 "input_schema": {19 "type": "object",20 "properties": {21 "path": {"type": "string"},22 "content": {"type": "string"}23 },24 "required": ["path", "content"]25 }26}]
A descrição da ferramenta importa mais do que você imagina. O Claude a lê para decidir quando e como usar a ferramenta. Uma descrição vaga significa chamadas erradas. Uma descrição precisa significa chamadas precisas.
Comece com 3-5 ferramentas. Ler arquivo, escrever arquivo, executar comando, pesquisar e uma ferramenta específica de domínio para o seu caso de uso. Isso cobre 90% das tarefas do agente.

05. O loop
Esta é a parte que transforma um script em um agente. Sem um loop, seu código chama o Claude uma vez e para. Com um loop, seu código chama o Claude, verifica o resultado e chama novamente até que o trabalho esteja concluído.

Três componentes:
- Verificador. Algo que verifica se a saída é boa. Um conjunto de testes, um verificador de tipos, um linter, uma segunda chamada Claude com critérios rigorosos. Sem isso, você tem o agente concordando consigo mesmo repetidamente.
- Estado. Um registro do que aconteceu. O que funcionou, o que falhou, o que tentar a seguir. Sem estado, o agente comete o mesmo erro a cada passagem.
- Condição de parada. A meta foi atingida, ou um limite rígido diz "após N tentativas, pare e relate". Sem isso, o loop roda para sempre e drena sua conta.
1import json2from pathlib import Path34def run_agent(task: str, max_attempts: int = 5):5 state = {"task": task, "attempts": [], "done": False}67 for i in range(max_attempts):8 # Construir contexto a partir do estado9 context = build_prompt(state)1011 # Chamar Claude com ferramentas12 result = call_claude(context, tools)1314 # Executar quaisquer chamadas de ferramenta15 output = execute_tools(result)1617 # Verificar o resultado18 check = verify(output)1920 # Atualizar estado21 state["attempts"].append({22 "attempt": i + 1,23 "action": result.summary,24 "passed": check.passed,25 "reason": check.reason26 })2728 if check.passed:29 state["done"] = True30 break3132 # Salvar estado para a próxima execução33 Path("state.json").write_text(json.dumps(state, indent=2))34 return state
Este é o esqueleto completo. Todo agente de produção é uma variação desse padrão. Os detalhes mudam. A forma, não.
06. Memória
Sem memória, cada sessão começa do zero. O agente redescobre a estrutura do seu projeto. Reaprende suas convenções. Comete os mesmos erros que cometeu ontem.

Os agentes Claude usam três camadas de memória:
CLAUDE.md é um arquivo markdown na raiz do seu projeto. O Claude Code o lê automaticamente no início de cada sessão. Suas regras, sua stack, suas convenções. Escreva uma vez, leia para sempre.
1# CLAUDE.md23## Projeto4API de gerenciamento de tarefas. Python 3.12, FastAPI, PostgreSQL.56## Regras7- Todas as respostas: schema {data, error, meta}8- Testes obrigatórios para cada novo endpoint9- Mensagens de commit: tipo(escopo): descrição10- Nunca use print() para logging. Use structlog.1112## Problemas conhecidos13- O middleware de autenticação espera x-auth-token, não Authorization14- O conjunto de testes leva 45s completo. Use --filter para iteração.
Skills capturam fluxos de trabalho inteiros. Não apenas prompts - a forma completa: formato de entrada, etapas, formato de saída, regras de validação. A primeira execução leva 20 minutos. A repetição leva 30 segundos.
Arquivo de aprendizados é um registro contínuo de erros. O agente escreve nele após cada sessão. A próxima sessão o lê. Os erros se repetem até serem registrados. Então, param.
1# learnings.md23- A API de pagamento espera a chave de idempotência no cabeçalho, não no corpo4- NOTIFY do PostgreSQL precisa de LISTEN explícito no pool de conexões5- O limitador de taxa conta por chave, não por IP. Testes precisam de chaves únicas.
07. A porta de verificação
A porta é a parte mais difícil de construir e a mais fácil de pular. A maioria das pessoas a pula. É por isso que a maioria dos agentes quebra em produção.

Uma porta de verificação é algo que verifica o trabalho do agente sem que o agente se avalie. O modelo que escreveu o código é generoso demais ao corrigir sua própria lição de casa. Você precisa de uma segunda verificação.
Três padrões que funcionam:
1. Testes automatizados. O agente escreve código. O conjunto de testes é executado. Se os testes falharem, o agente recebe a saída de erro e tenta novamente. É assim que o Claude Code funciona internamente.
1def verify(output):2 # Executar o conjunto de testes3 result = subprocess.run(4 ["pytest", "tests/", "-x", "--tb=short"],5 capture_output=True, text=True6 )7 return {8 "passed": result.returncode == 0,9 "reason": result.stdout if result.returncode != 0 else "todos os testes passam"10 }
2. Verificador de tipos / linter. Execute mypy, ruff ou tsc --noEmit após cada alteração. Captura categorias inteiras de bugs sem escrever um único teste.
3. Segundo modelo como revisor. Use uma chamada Claude separada com um prompt de sistema rigoroso que apenas procura problemas. O escritor é rápido e barato. O revisor é lento e rigoroso. Essa separação é a maior parte da qualidade.
1# Prompt do revisor - separado do construtor2reviewer_system = """Você é um revisor de código rigoroso.3Seu ÚNICO trabalho é encontrar problemas.45Verifique:6- O código corresponde à especificação?7- Existem casos extremos não capturados?8- Todos os testes realmente testam a coisa certa?910Se tudo estiver correto, responda: {"passed": true}11Se algo estiver errado, responda: {"passed": false, "issues": [...]}1213Não sugira melhorias. Apenas sinalize bugs reais."""
O escritor é rápido e barato. O revisor é lento e rigoroso. Essa separação é a maior parte da qualidade.
08. Juntando tudo
Aqui está um agente completo que pega uma URL de issue do GitHub, lê a issue, escreve o código, executa os testes e abre um PR. Cinco partes trabalhando juntas.
1import anthropic, subprocess, json2from pathlib import Path34client = anthropic.Anthropic()5CLAUDE_MD = Path("CLAUDE.md").read_text()6LEARNINGS = Path("learnings.md").read_text()78SYSTEM = f"""Você é um agente de codificação.9Leia a issue. Escreva a correção. Execute os testes.1011Contexto do projeto:12{CLAUDE_MD}1314Problemas conhecidos:15{LEARNINGS}1617Regras:18- Leia toda a base de código antes de alterar qualquer coisa19- Escreva testes para cada alteração20- Se os testes falharem, corrija o código, não os testes21- Pare quando todos os testes passarem"""2223TOOLS = [24 read_file_tool,25 write_file_tool,26 run_command_tool,27 search_codebase_tool,28]2930def run(issue_text, max_attempts=5):31 messages = [{"role": "user", "content": issue_text}]3233 for attempt in range(max_attempts):34 # Chamar Claude35 response = client.messages.create(36 model="claude-sonnet-4-6",37 max_tokens=8192,38 system=SYSTEM,39 tools=TOOLS,40 messages=messages41 )4243 # Executar chamadas de ferramenta44 messages = handle_tool_use(response, messages)4546 # Verificar: executar testes47 test_result = subprocess.run(48 ["pytest", "-x", "--tb=short"],49 capture_output=True, text=True50 )5152 if test_result.returncode == 0:53 print(f"Concluído em {attempt + 1} tentativas")54 return True5556 # Alimentar a falha de volta no loop57 messages.append({58 "role": "user",59 "content": f"Testes falharam:\n{test_result.stdout}\nCorrija e tente novamente."60 })6162 return False
Isso é um agente funcional. Camada de API com prompt de sistema e CLAUDE.md. Ferramentas para operações de arquivo. Um loop com repetição. Memória do learnings.md. Uma porta de verificação via pytest.
Menos de 50 linhas. A mesma arquitetura que o Claude Code usa internamente.
**
09. Os 5 erros que quebram todo agente
- Sem porta de verificação. O agente corrige a própria lição de casa. Ele escreve o código, diz "parece bom" e segue em frente. A saída parece correta e quebra em produção.
- Sem condição de parada. O loop roda até sua fatura de API chegar a US$ 200. Sem um limite rígido, o agente tenta para sempre, reescrevendo o mesmo arquivo 40 vezes. Sempre defina max_attempts. Sempre.
- Sem arquivo de estado. Mesmo erro na tentativa #1 e na tentativa #50. O agente não sabe o que já tentou. Ele propõe a mesma correção quebrada três vezes seguidas porque nada registra a falha.
- Ferramentas demais. Você dá 20 ferramentas ao Claude e ele escolhe a errada. Um modelo com 5 ferramentas claras toma melhores decisões do que um modelo com 20 sobrepostas. Comece pequeno. Adicione ferramentas apenas quando o agente encontrar um obstáculo.
- Prompt de sistema vago. "Seja um bom assistente de codificação" dá a você uma saída genérica. "Todas as respostas devem ser JSON válido, testes obrigatórios para cada alteração, nunca modifique arquivos fora de /src" dá a você um agente que se comporta.
Conclusão:
Um agente funcional não é um prompt melhor. É um sistema: API + ferramentas + loop + memória + porta de verificação. Cinco partes. Falte uma e ele quebra.
A maioria das pessoas lerá isso, marcará como favorito e continuará usando o Claude como um chatbot. Elas colarão uma pergunta de cada vez e copiarão a resposta para a base de código manualmente.
Aqueles que construírem o loop enviarão trabalho enquanto dormem. Mesmo modelo. Mesma API. Mesmo preço. Arquitetura diferente.
Os blocos de código acima todos funcionam. Copie-os. Execute-os. Modifique-os para o seu caso de uso.
Construa um agente esta semana. Aponte-o para uma tarefa que você faz todos os dias. Deixe-o rodar.





