Vamos cobrir tudo o que envolve a construção de um harness de codificação: o loop do agente, planejamento, subagentes, sandboxing, memória e checkpointing, tudo construído passo a passo.
Se você já tentou construir seu próprio agente de codificação, sabe como isso funciona. Você conecta um modelo a ferramentas de arquivo e um shell, aponta para um código real, e ele quebra em menos de uma dúzia de chamadas de ferramenta.
Ele lê os arquivos errados, perde o objetivo no meio do caminho e enche o contexto com saídas que não precisa mais.
Então a mesma tarefa passa pelo Claude Code e termina perfeitamente. A conclusão fácil é que a Anthropic simplesmente tem um modelo melhor, e essa conclusão ignora onde o trabalho realmente acontece.
A diferença está no harness. Um harness é o código comum que envolve o modelo, e ele lida com planejamento, execução de ferramentas, memória e segurança, enquanto o modelo apenas decide o próximo passo.
Aqui está a aparência de um agente totalmente equipado com harness quando você o desenha:

GIF
A imagem parece complexa, mas se divide em quatro grupos:
- Memória alimenta o modelo com seu contexto de trabalho, além de fatos que aprendeu em diferentes sessões.
- Habilidades codificam como o agente deve operar, ou seja, os procedimentos, restrições e heurísticas que ele segue.
- Protocolos conectam o agente a usuários, ferramentas e outros agentes.
- O núcleo do harness une tudo com orquestração de subagentes, um sandbox, um avaliador, um loop de aprovação, observabilidade e compressão de contexto.
A Anthropic descreve essa divisão como o cérebro e as mãos. O modelo é o cérebro que escolhe cada ação, e o harness é as mãos que a executam e mantêm a execução no caminho certo.
Portanto, a diferença entre seu agente e o Claude Code não é o modelo, é a maquinaria em torno do modelo.
O Claude Code é um dos harnesses mais capazes em produção hoje, e é construído a partir de um conjunto surpreendentemente pequeno das camadas daquela ilustração. Para ver quanto dessa maquinaria você teria que construir, eu a reconstruí no CrewAI, um framework open-source para orquestrar agentes.
Mais dela se encaixa em recursos nativos do que eu esperava, e a parte que não se encaixa é onde a verdadeira engenharia reside.
Vamos construí-la camada por camada, começando pelo loop central e adicionando planejamento, subagentes, sandboxing e memória por cima. Em cada etapa, marcaremos onde o framework termina e onde seu trabalho começa.
Como funciona o harness do Claude Code
No centro do Claude Code está um loop de agente simples. Você envia uma mensagem, o modelo decide o que fazer em seguida, e ele responde diretamente ou solicita uma ferramenta. Se solicitar uma, a ferramenta é executada, o resultado volta para a conversa, e o modelo decide novamente.
Isso se repete até que o modelo retorne uma resposta final sem mais chamadas de ferramenta.
Dentro desse loop, o modelo lê arquivos, edita código, executa comandos de shell e realiza testes. Estas não são operações separadas. São apenas chamadas de ferramenta diferentes dentro do mesmo loop.
No entanto, o loop sozinho não é suficiente para um agente de codificação confiável. O Claude Code adiciona planejamento, ferramentas de arquivo, subagentes, memória e um sistema de permissão e sandbox em torno dele. Essas camadas não substituem o loop, elas o tornam seguro e confiável o suficiente para trabalho real.

Essa é a arquitetura que vamos reconstruir: primeiro o loop central, depois cada camada por cima, mapeando cada camada para o recurso do CrewAI que a gerencia.
O loop central do agente
O loop executa a mesma sequência até que a tarefa seja concluída:
- Peça ao modelo para realizar a tarefa.
- O modelo responde diretamente ou solicita uma ou mais ferramentas.
- Se ferramentas forem solicitadas, execute-as e retorne os resultados ao modelo.
- Repita com a conversa atualizada.
- Quando o modelo responder sem solicitar nenhuma ferramenta, a tarefa está concluída.

1while True:2 reply = model(messages, tools)3 calls = [b for b in reply if b.type == "tool_use"]4 if not calls: # texto simples, sem chamada de ferramenta: o trabalho está feito5 return reply.text6 messages += [reply, run_all(calls)]
Cada chamada de ferramenta completa uma etapa, fornece novas informações ao modelo e alimenta a próxima decisão. Uma pergunta simples pode terminar em uma iteração, enquanto corrigir um bug complexo ou refatorar uma base de código grande pode levar dezenas de iterações antes que o modelo tenha informações suficientes para produzir uma resposta final.
O CrewAI fornece esse loop de execução automaticamente assim que você cria um agente. Você não implementa o loop while manualmente; você define o agente e atribui a ele uma tarefa.
Construindo o primeiro agente
Vamos criar um agente simples de Correção de Bugs.
1from crewai import LLM, Agent, Crew, Task23bug_fixer = Agent(4 role="Corretor de Bugs",5 goal="Encontrar e descrever a correção para o bug reportado na base de código.",6 backstory="Você lê diretórios e arquivos para construir uma imagem precisa do código.",7 llm="claude-sonnet-4-6",8)910task = Task(11 description="Encontre a correção para {objective}.",12 expected_output="Uma breve descrição da correção e em qual arquivo ela deve estar.",13)1415result = Crew(agents=[bug_fixer], tasks=[task]).kickoff(16 inputs={"objective": "o bug de saque a descoberto em account.py"}17)
Três conceitos para entender aqui:
- Um Agente define quem faz o trabalho, através de sua função, objetivo, LLM e ferramentas.
- Uma Tarefa descreve a atribuição.
- Uma Equipe reúne agentes e tarefas. Chamar kickoff() executa o mesmo loop de execução descrito acima, independentemente de o modelo subjacente ser Anthropic, OpenAI, Google ou outro.
Dando ferramentas ao agente
Ferramentas são o que permitem que um modelo que apenas gera texto realmente trabalhe em uma base de código. Elas leem arquivos, escrevem neles, executam comandos de shell e chamam APIs externas.
O CrewAI oferece ferramentas de sistema de arquivos prontas para uso:
- FileReadTool lê arquivos.
- DirectoryReadTool lista diretórios.
- FileWriterTool escreve arquivos.
1from crewai_tools import DirectoryReadTool, FileReadTool, FileWriterTool23read_file = FileReadTool()4write_file = FileWriterTool()5list_dir = DirectoryReadTool()67filesystem_tools = [read_file, write_file, list_dir]
Elas também funcionam como memória externa. Em vez de manter um resultado de pesquisa grande na janela de contexto do modelo, o agente pode escrevê-lo em um arquivo, manter apenas o nome do arquivo e lê-lo de volta quando necessário.
Isso mantém a janela de contexto menor e o modelo mais focado, que é o que a Anthropic chama de engenharia de contexto.

As ferramentas integradas cobrem apenas fluxos de trabalho comuns. Para algo mais específico, você expõe uma função Python como ferramenta com o decorador @tool.
A docstring atua como o manual de instruções, dizendo ao modelo o que a ferramenta faz, quando usá-la e o que espera como entrada.
1from crewai.tools import tool2import subprocess34@tool("run_tests")5def run_tests(path: str = "tests/") -> str:6 """Execute o conjunto de testes pytest no caminho fornecido e retorne o resultado."""7 result = subprocess.run(8 ["pytest", path, "-q"], capture_output=True, text=True, timeout=1209 )10 output = result.stdout + result.stderr11 return output[-4000:] if len(output) > 4000 else output
Planejando tarefas de longa duração
À medida que as tarefas se tornam mais complexas, um loop de execução simples começa a perder o objetivo original. Depois de muitas chamadas de ferramenta, leituras de arquivo e resultados intermediários, o contexto fica cheio e o objetivo é ofuscado por tudo que veio depois.
Essa degradação lenta é o que as pessoas chamam de apodrecimento do contexto.
O planejamento aborda isso diretamente. O agente constrói um plano passo a passo antes de fazer qualquer trabalho e mantém esse plano no contexto durante toda a execução.
O plano não faz o trabalho. É um roteiro que mantém o modelo conectado ao objetivo original, que é o mesmo trabalho que a lista de tarefas do Claude Code faz.

O CrewAI adiciona isso no nível da equipe com planning=True. Ele gera um plano antes da execução e o mantém disponível à medida que a tarefa progride.
1from crewai import Crew, LLM23crew = Crew(4 agents=self.agents,5 tasks=self.tasks,6 planning=True,7 planning_llm=LLM(model="gpt-4o-mini"),8)
Nota: Por padrão, o CrewAI usa gpt-4o-mini para planejamento, e você pode trocar por qualquer LLM de sua preferência para essa etapa.
Agentes individuais também podem raciocinar sobre seu próprio trabalho com reasoning=True:
1from crewai import Agent23bug_fixer = Agent(4 role="Corretor de Bugs",5 goal="Encontrar e descrever a correção para o bug reportado na base de código.",6 backstory="Você lê diretórios e arquivos para construir uma imagem precisa do código.",7 tools=[FileReadTool()],8 reasoning=True,9 max_reasoning_attempts=3 # Opcional: Define um número máximo de tentativas de raciocínio10)
Planejamento e raciocínio resolvem problemas diferentes. O planejamento constrói um roteiro de alto nível para a tarefa geral, enquanto o raciocínio dá a um agente tempo para pensar sobre sua própria abordagem antes de agir.
Quando o raciocínio está ativado, o agente:
- Reflete sobre a tarefa e elabora um plano de execução.
- Avalia se o plano está pronto.
- Refina o plano, se necessário, até ficar satisfeito ou atingir max_reasoning_attempts.
- Injeta o plano de raciocínio finalizado na tarefa antes da execução.

Juntos, eles mantêm o agente ancorado em tarefas de longa duração e reduzem o desvio do objetivo original.
Delegando com subagentes
O planejamento mantém o agente focado, mas não reduz a quantidade de informação que o modelo precisa reter. Em uma base de código grande, mesmo uma tarefa bem planejada pode exceder uma única janela de contexto.
Encontrar um bug pode exigir a leitura de dezenas de arquivos, e o agente principal não precisa manter todos eles na memória.
Os subagentes resolvem isso através da delegação. O agente principal entrega uma tarefa específica a um agente auxiliar, que trabalha em seu próprio contexto e retorna um breve resumo. O agente principal vê a conclusão, não as etapas intermediárias.

O CrewAI suporta isso através de fluxos de trabalho hierárquicos, onde um agente gerente delega para agentes especialistas e combina seus resultados.
Em nossa configuração anterior, um único agente Corretor de Bugs fazia todo o trabalho pesado. Vamos dividir o trabalho entre um gerente e três especialistas:
- Explorador de Código explora o código e mapeia o repositório.
- Engenheiro de Software implementa a mudança solicitada.
- Executor de Testes executa os testes no sandbox e relata aprovação ou falha.
- Líder de Engenharia supervisiona os três especialistas.

1from crewai import Crew, Agent, Task, Process23explorer = Agent(4 role="Explorador de Código",5 goal="Mapear o repositório e identificar os arquivos relevantes para a tarefa.",6 backstory="Você lê diretórios e arquivos para construir uma imagem do código.",7 tools=[read_file, list_dir],8 llm=llm,9) # O mesmo para os outros dois agentes especialistas1011manager = Agent(12 role="Líder de Engenharia",13 goal="Dividir a solicitação em etapas e delegar cada uma ao especialista certo.",14 backstory="Você decide quem faz o quê, revisa testes, finaliza quando a mudança está pronta.",15 llm=llm,16 allow_delegation=True,17)1819crew = Crew(20 agents=[explorer, coder, tester],21 tasks=[task],22 manager_agent=manager,23 process=Process.hierarchical,24)
Uma coisa a observar é que allow_delegation está desabilitado por padrão, portanto deve ser explicitamente ativado no gerente.
Sandboxing: Protegendo a execução do agente
Um agente com acesso ao shell pode executar um comando destrutivo, e dizer ao modelo para não fazer algo não é uma salvaguarda.
A proteção real vem de duas camadas:
- Um sistema de permissão que exige aprovação para ações sensíveis.
- Um sandbox que isola a execução, para que mesmo comandos aprovados não possam tocar na máquina hospedeira.
A Anthropic usa a mesma abordagem. Mover a execução de código para um sandbox reduz a frequência com que um usuário precisa aprovar ações, ao mesmo tempo que protege o sistema hospedeiro.

Sandboxing no CrewAI
Executar código dentro de um sandbox em vez de na máquina hospedeira aplica essa segunda camada. Nesta configuração, o código é executado dentro do E2B, que cria uma VM nova por sessão e a destrói após o uso.
Comandos de shell e Python são executados inteiramente dentro desse ambiente isolado.

1from crewai_tools import E2BExecTool, E2BPythonTool2sandbox_tools = [E2BExecTool(), E2BPythonTool()] # executar testes / executar código
Aprovação com humano no loop
Definir human_input=True em uma Tarefa pausa a equipe após gerar uma resposta. Você revisa a saída e então a aprova ou a envia de volta para outra iteração.
Quando a execução atinge essa tarefa, o CrewAI aguarda seu feedback através da entrada padrão.
1from crewai import Task23task = Task(4 description=(5 "No diretório de trabalho ./workspace, {objective}. "6 "Explore o código primeiro, faça a alteração, execute os testes e relate."7 ),8 expected_output="Um resumo dos arquivos alterados e o resultado final do teste.",9 human_input=True,10)
Se sua equipe estiver sendo executada por trás de um aplicativo web ou interface de chat, em vez de um terminal, o sistema de humano no loop baseado em webhook do CrewAI lida com a mesma etapa de revisão.
Memória e checkpointing
Por padrão, um agente esquece tudo quando uma execução termina. Volte amanhã para corrigir outro bug no mesmo projeto, e ele começa do zero.
Dois mecanismos permitem que um agente carregue informações entre execuções, e cada um serve a um propósito diferente:
- Checkpointing salva o estado do agente durante uma execução, para que ele possa retomar após uma interrupção ou continuar do mesmo ponto por um caminho diferente.
- Memória persistente armazena fatos em conversas separadas, incluindo preferências do projeto como "sempre formate o código final antes de terminar."

Memória no CrewAI
O CrewAI fornece uma interface de Memória unificada, em vez de tipos separados de memória de curto prazo, longo prazo, de entidade e externa. Ao salvar, ele usa um LLM para identificar detalhes importantes, organizá-los e torná-los recuperáveis posteriormente.
Definir memory=True na equipe dá a ela memória entre execuções. Após cada tarefa, o CrewAI extrai fatos úteis da saída e os armazena, e em execuções futuras ele recupera memórias relevantes e as adiciona ao prompt da tarefa.

1from crewai import Crew23crew = Crew(4 agents=[explorer, coder, tester],5 tasks=[task],6 memory=True,7)
Todos os agentes em uma equipe compartilham sua memória, a menos que um agente tenha sua própria memória atribuída.
Checkpointing no CrewAI
Um checkpoint é um instantâneo do progresso de um agente, incluindo sua configuração, estado da tarefa, memória, resultados intermediários, entradas e histórico de execução.
Por padrão, o CrewAI cria um checkpoint sempre que uma tarefa termina, permitindo que o fluxo de trabalho seja retomado desse ponto se for interrompido.
Os checkpoints podem residir em um de dois armazenamentos integrados:
- JsonProvider salva cada checkpoint como um arquivo JSON separado, que é fácil de ler e inspecionar manualmente.
- SqliteProvider armazena todos os checkpoints em um único banco de dados SQLite, que se comporta melhor sob checkpointing frequente e cargas de trabalho maiores.

1from crewai import Crew23crew = Crew(4 agents=[explorer, coder, tester],5 tasks=[task],6 checkpoint=True,7)
Crew, Flow e Agent aceitam um argumento checkpoint, e os filhos herdam do pai, a menos que definam seu próprio valor.
Juntando tudo
Aqui está o harness completo em uma tarefa, com o loop de execução, ferramentas, planejamento, subagentes, sandboxing e memória trabalhando juntos:
1from crewai import Agent, Crew, LLM, Process, Task2from crewai.tools import tool3from crewai_tools import (DirectoryReadTool, FileReadTool, FileWriterTool,4E2BExecTool, E2BPythonTool)56llm = LLM(model="anthropic/claude-sonnet-4.6")78list_dir = DirectoryReadTool(directory="./workspace")9filesystem_tools = [FileReadTool(), FileWriterTool(), list_dir]10sandbox_tools = [exec_tool, E2BPythonTool()]1112@tool("run_tests")13def run_tests(path: str = "tests/") -> str:14 """Sincronize ./workspace no sandbox, então execute o pytest lá."""15 return E2BExecTool().run(command=sync_and_test_command(path))1617explorer = Agent(role="Explorador de Código", goal="Mapear repositório, identificar arquivos relevantes.",18 tools=[read_file, list_dir], llm=llm)19coder = Agent(role="Engenheiro de Software", goal="Implementar a mudança solicitada.",20 tools=filesystem_tools, reasoning=True, llm=llm)21tester = Agent(role="Executor de Testes", goal="Executar testes no sandbox, relatar aprovação/falha.",22 tools=sandbox_tools + [read_file] + [run_tests], llm=llm)23manager = Agent(role="Líder de Engenharia", goal="Delegar etapas, finalizar quando os testes passarem.",24 allow_delegation=True, llm=llm)2526task = Task(27 description="Em ./workspace, {objective}. Explore, edite, teste, relate.",28 expected_output="Resumo das alterações e saída do teste.", human_input=True,29)30crew = Crew(31 agents=[explorer, coder, tester], tasks=[task],32 manager_agent=manager, process=Process.hierarchical,33 planning=True, memory=True, checkpoint=True,34)35result = crew.kickoff(inputs={"objective": "corrigir testes com falha em account.py"})
Os harnesses de agente são mais fáceis de avaliar quando o sucesso pode ser verificado automaticamente. Um conjunto de testes dá ao agente um objetivo concreto, para que ele possa planejar, editar, testar e repetir até que tudo passe.
Portanto, isso foi testado em uma pequena base de código, uma classe BankAccount com dois bugs reais e cinco testes, três dos quais falhavam. A regra era corrigir apenas a implementação, não os testes.
Isso reflete como a Anthropic avalia agentes de codificação internamente. Um exemplo publicado mostra Claude reconstruindo um clone da interface do claude.ai contra um grande conjunto de testes com falha.
Aqui, o harness levou o projeto de 3 falhas e 2 aprovações para todas as 5 aprovações, com a regra de apenas implementação bloqueando o atalho de editar ou remover os testes com falha.

O que ainda é seu trabalho
Algumas partes do sistema não são construídas para você pelo framework:
- Os prompts. O comportamento de cada agente vem de sua função, objetivo e backstory. Acertar nisso requer teste e iteração, e nenhuma flag de configuração substitui isso.
- O ambiente de execução. O sandbox, seja E2B ou uma VM autogerenciada, precisa ser configurado e conectado.
- A seleção de ferramentas. Quais ferramentas cada agente recebe e qual agente deve ter acesso a quê é uma decisão de design que o framework não toma.
Há também um custo para o próprio harness. Planejamento, subagentes e looping adicionam chamadas de API, portanto, uma configuração de agente complexa pode acabar sendo mais cara do que uma tarefa que uma única chamada de modelo teria resolvido diretamente.
E há uma limitação de longo prazo que vale a pena ter em mente. À medida que os modelos melhoram, parte do arcabouço deixa de ser necessário, porque parte do que é construído em um harness hoje é uma solução alternativa para os limites do modelo atual, em vez de um requisito permanente.
A Anthropic originalmente usava redefinições de contexto para impedir que o Claude Sonnet 4.5 terminasse tarefas muito cedo, e elas não eram mais necessárias com o Claude Opus 4.5, mais capaz.

Concluindo
Essa é a descoberta principal. A capacidade de um agente de codificação reside principalmente no harness, e um framework de orquestração entrega mais desse harness do que você imagina.
O loop, planejamento, delegação, sandboxing e memória chegam como configuração, enquanto os prompts, o ambiente de execução e as escolhas de ferramentas permanecem seus.
Se você quiser executar isso em sua própria base de código, a documentação do CrewAI cobre todos os recursos usados aqui, e o framework é totalmente open source.
Confira a Documentação do CrewAI →
Obrigado por ler!
Saúde! :)





