De que partes um agent harness é feito?
Um agent harness é feito de sete camadas: gestão de contexto, catálogo de ferramentas, sistema de permissão, sandbox de execução, estado de sessão, orquestração de subagentes e controle de custo. Cada uma resolve uma pergunta que o modelo não resolve. Cada uma falha de um jeito reconhecível, e é pelo sintoma que você descobre qual delas está faltando.
A divisão é de responsabilidade, não de arquivo. Num harness pequeno as sete cabem em duzentas linhas e nenhuma tem nome próprio. O que o harness faz continua sendo o mesmo trabalho quando ele tem sete módulos ou uma função só; o que muda é a facilidade de descobrir qual parte errou.
Vale começar pelas duas que carregam mais efeito. A camada de contexto decide o que o modelo vê, e a camada de permissão decide o que ele pode fazer com isso. As outras cinco existem em boa parte para sustentar essas duas quando a tarefa fica longa.
O que cada camada responde
Contexto decide o que entra na janela e o que sai dela quando o espaço acaba. Sem ela o agente parece esquecido: refaz uma busca que já tinha feito, reabre um arquivo que já tinha lido, contradiz uma decisão de quinze iterações atrás. A camada não avisa quando descarta algo, e é por isso que a falha dela chega sempre disfarçada de burrice do modelo.
Ferramentas decide o que existe para ser chamado, como cada coisa é descrita e o que acontece com um argumento inválido. Sem ela o agente vira um chat: ele descreve o comando que rodaria, em prosa, e para. Descrição de ferramenta é prompt, e o formato em que a ação é pedida muda o resultado mesmo com o modelo travado, que foi o achado central do trabalho que desenhou uma interface própria para o agente em vez de reaproveitar o terminal do humano1.
Permissão decide o que roda direto, o que para e pergunta, e o que é negado
sem pergunta. Sem ela todo comando é aprovado, o que funciona até o primeiro
rm num caminho relativo errado.
Sandbox decide o alcance: qual diretório, qual rede, quanto tempo, quanto disco. Permissão e sandbox são a mesma preocupação em dois níveis. A primeira é política que você escreve; a segunda é limite que o sistema impõe quando a política falha.
Sessão decide o que sobrevive ao fim da execução. Sem ela, fechar o terminal apaga a tarefa. O modelo não tem memória entre chamadas: tudo que parece continuidade é essa camada regravando o estado a cada passo. A versão barata é gravar o histórico bruto em disco e recarregar, e ela funciona até o histórico não caber mais na janela que o recarregou.
Subagentes decide quando uma sub-tarefa merece uma janela limpa. Sem ela o
agente carrega o barulho da exploração até o fim, e a decisão importante da
iteração 3 divide espaço com a saída de um grep da iteração 4. Plataformas
abertas de agente já tratam coordenação entre agentes como parte da plataforma,
no mesmo nível de sandbox e interface2.
Custo decide quando parar. Limite de passos, teto de tokens, tempo máximo. Sem ela você conhece o teto pela fatura, e o modo de falha típico não é o gasto grande de uma vez, é o loop de duas ferramentas que se chamam em alternância por quarenta iterações.
O que atravessa cada fronteira
A parte que raramente é escrita é o formato do dado em cada passagem. As camadas não trocam objetos ricos entre si: cada fronteira converte, e toda conversão perde alguma coisa.
Da montagem para o modelo passa uma string só. Instruções de sistema, catálogo de ferramentas, histórico e arquivos abertos chegam como uma sequência de tokens sem hierarquia. O modelo não sabe o que é regra e o que é histórico; ele infere pela posição e pela formatação que você escolheu.
Do modelo para a política passa um pedido estruturado: nome de ferramenta mais argumentos. É o ponto mais estreito do ciclo e o único com validação barata. Um argumento fora do schema pode voltar como erro para o modelo corrigir ou derrubar a iteração, e as duas opções produzem comportamentos diferentes na tarefa inteira.
Da execução para o retorno passa o resultado de um processo: código de saída, saída padrão, saída de erro, tempo gasto. Aqui já não existe estrutura nenhuma. São bytes, e podem ser 200 ou 40 milhões.
Do retorno para a montagem passa texto truncado. Esta é a fronteira mais
destrutiva e a menos documentada. Alguém decidiu quantas linhas cabem, se o
corte é no começo ou no fim, se stderr entra junto, se o código de saída
aparece. Um agente que “tenta a mesma coisa três vezes” quase sempre está
recebendo uma versão da falha em que a mensagem que resolveria o problema foi
cortada.
Um caso concreto: uma suíte de teste que falha imprime centenas de linhas de progresso e termina com o diff que interessa. Cortar nas primeiras 100 linhas entrega ao modelo só os testes que passaram. Cortar nas últimas 100 entrega o diff e esconde qual arquivo estava sendo compilado quando quebrou. As duas políticas são defensáveis, produzem trajetórias diferentes na mesma tarefa, e nenhuma das duas costuma estar escrita em lugar nenhum.
Por que a ordem não é negociável
As camadas parecem intercambiáveis num diagrama e não são no código.
A permissão precisa rodar antes da execução, e essa é óbvia. A menos óbvia é que o truncamento precisa rodar depois da execução e antes da montagem do próximo contexto, porque é o único ponto onde ainda existe a saída inteira para decidir o que preservar. Harness que trunca no momento da montagem já perdeu a saída original e corta no escuro.
O controle de custo precisa rodar antes da chamada ao modelo, não depois. Um teto verificado depois já foi estourado. Isso parece detalhe até você calcular que um catálogo grande de ferramentas com histórico cheio pode custar mais numa chamada do que nas cinco anteriores somadas.
A camada de contexto precisa saber o limite real, não o anunciado. Um benchmark de 2024 avaliou 17 modelos de contexto longo em 13 tarefas e encontrou queda grande de desempenho conforme o comprimento cresce; entre os que declaravam 32 mil tokens ou mais, cerca de metade se sustentava nos 32 mil3. O número anunciado é o teto do que a API aceita, não a faixa em que o modelo continua achando o que você colocou lá.
As camadas vazam umas nas outras
Elas não são independentes, e é isso que torna o diagnóstico traiçoeiro. Um encadeamento comum, com o sintoma no fim da fila:
- Você conecta três servidores de ferramenta e o catálogo passa de 60 descrições.
- O catálogo ocupa mais espaço fixo em toda chamada, então a janela chega ao limite mais cedo.
- A camada de contexto compacta antes, e o resumo perde a restrição que o usuário deu na primeira mensagem.
- O agente propõe uma ação que a restrição proibia.
- A camada de permissão para e pergunta, você aprova sem lembrar da restrição.
- A tarefa termina errada e o custo dobra.
O sintoma aparece em custo e em qualidade. A causa está na camada de ferramentas, três saltos atrás. Nenhuma troca de modelo mexe nisso, e é por essa razão que o mesmo modelo parece melhor numa ferramenta do que noutra.
O mínimo viável
Nem toda camada precisa existir no primeiro dia.
Com montagem de contexto, duas a quatro ferramentas e um limite de passos você tem um agente que resolve tarefa real. Montar esse mínimo do zero é o melhor jeito de ver onde as decisões ficam, porque cada omissão vira um bug seu em vez de um comportamento inexplicado de uma ferramenta de terceiro.
Permissão granular, sessão persistente, subagentes e roteamento de modelo podem esperar. Todos os quatro resolvem problemas de escala, e nenhum deles aparece numa tarefa de dez iterações rodando na sua máquina.
O sandbox é a exceção e merece o alerta na figura. Enquanto todo comando vier de texto que você escreveu, o risco é o seu próprio erro. No momento em que o agente lê uma issue do GitHub, uma página web ou um arquivo que veio de fora, esse conteúdo entra na mesma janela que as instruções e passa a poder propor ações. Um trabalho de 2023 montou um emulador para testar agentes contra 36 ferramentas de alto risco em 144 casos e mediu falhas com consequência séria em 23,9% dos casos até no agente mais seguro da amostra4. O número é de um arranjo específico e não é uma taxa universal, mas a ordem de grandeza não é a de um caso raro.
Onde a divisão em camadas engana
Camada não é módulo. A separação é conceitual. Tentar traduzir cada uma em um arquivo com interface própria cedo demais produz abstração que precisa ser desmontada na primeira vez que o truncamento precisar saber quanto de janela sobrou. Contexto e retorno são a mesma decisão vista de dois lados.
Mais camada não é melhor. Um trabalho de 2024 mostrou o contrário com número: um processo fixo de três fases, sem deixar o modelo escolher o próximo passo, chegou a 32,00% no SWE-bench Lite a US$ 0,70 por instância, à frente dos agentes open-source da época5. Parte do que se chama de camada é complexidade competindo com uma capacidade que o modelo já tem.
As sete não custam igual. Contexto e ferramentas são decisões de todo dia. Subagentes e roteamento de modelo são decisões que a maioria dos times toma uma vez e não revisita. Distribuir atenção igualmente entre as sete é o erro mais comum de quem acabou de ler um diagrama como o da Figura 1.
A percepção do usuário não é uma camada, mas se comporta como uma. O que o agente mostra enquanto trabalha muda o julgamento sobre a mesma trajetória. Streaming e a experiência de espera não alteram nenhuma decisão do modelo e ainda assim mudam se a pessoa interrompe a tarefa na metade.
Nada disso conserta inconsistência. As camadas reduzem o custo de cada falha e não transformam um agente que acerta seis vezes em dez num que acerta dez.
Como montar isso na prática
- Escreva o loop antes de escrever as camadas. Montar, chamar, executar,
devolver. Quatro funções e um
whilecom contador. - Coloque o limite de passos no primeiro commit. É a única camada que protege você de si mesmo enquanto o resto está errado.
- Registre o que atravessa cada fronteira, não o que o terminal mostrou. A requisição inteira, o pedido de ferramenta bruto, a saída completa antes do corte e o texto que voltou depois dele.
- Trate o truncamento como decisão de produto. Escreva em algum lugar quantas linhas cabem, de que lado o corte acontece e o que sinaliza que houve corte. Se não estiver escrito, está espalhado.
- Acrescente camada por sintoma, não por completude. Sessão quando perder trabalho doer. Subagente quando a janela encher por exploração. Permissão granular quando a confirmação virar clique automático.
- Suba o sandbox no dia em que entrar conteúdo de terceiro. Não antes, e não uma semana depois.
Quanto cada camada custa
Em tokens, a conta é desigual e vale conhecer a ordem de grandeza.
Ferramentas é a camada com custo fixo mais visível: um schema com cinco parâmetros e descrição curta costuma ficar entre 150 e 400 tokens, e o catálogo inteiro é reenviado a cada iteração. Contexto é a de custo crescente, porque o histórico só aumenta até alguém cortar. Subagentes tem custo em rajada, já que cada um paga o próprio prompt de sistema e o próprio catálogo.
Permissão, sandbox, sessão e custo praticamente não gastam token. Elas gastam latência e trabalho de engenharia, o que aparece na conta de outro jeito: uma confirmação síncrona custa segundos de pessoa, e é o recurso mais caro do conjunto.
A conta que vale fazer é a razão entre custo fixo e custo útil. Se o catálogo de ferramentas ocupa 12 mil tokens e a tarefa média usa 40 mil, um terço do que você paga em toda chamada é catálogo, e a maior parte dele descreve ferramentas que aquela tarefa nunca vai chamar. Conte os seus antes de aceitar qualquer estimativa, inclusive esta: são duas linhas de código e o número costuma surpreender.
Footnotes
-
Yang et al. (2024) investigaram como o desenho da interface afeta o desempenho do agente e construíram uma interface específica para ele, com navegação de repositório, edição verificada e execução de teste. ↩
-
Wang et al. (2024) descrevem a plataforma OpenHands, em que sandbox de execução, coordenação entre múltiplos agentes e integração de benchmarks são partes declaradas da plataforma, não do agente. ↩
-
Hsieh et al. (2024) avaliaram 17 modelos de contexto longo em 13 tarefas e encontraram queda acentuada conforme o comprimento cresce, com cerca de metade dos que declaram 32 mil tokens sustentando desempenho nesse comprimento. ↩
-
Ruan et al. (2023) emularam execução de ferramenta com um modelo para testar agentes em 36 ferramentas de alto risco e 144 casos; segundo o avaliador automático deles, até o agente mais seguro falhou de forma arriscada em 23,9% das vezes. ↩
-
Xia et al. (2024) mostraram que um processo fixo de localizar, corrigir e validar, sem decisão autônoma de próximo passo, superou os agentes open-source da época no SWE-bench Lite com custo menor por instância. ↩
Perguntas frequentes
- Quais são as camadas de um agent harness?
- Sete: gestão de contexto, catálogo de ferramentas, sistema de permissão, sandbox de execução, estado de sessão, orquestração de subagentes e controle de custo. Contexto e ferramentas decidem o que entra na chamada. Permissão e sandbox decidem o que sai dela para o mundo. Sessão, subagentes e custo decidem quanto tempo aquilo dura.
- O que um harness precisa ter para funcionar?
- Três coisas: uma rotina que monta o contexto, um punhado de ferramentas com schema validado e um limite de passos. Com isso um agente já resolve tarefa real. As outras quatro camadas existem para o dia em que a tarefa passa de vinte iterações, o comando apaga o arquivo errado ou a sessão cai no meio.
- Qual é a diferença entre a camada de permissão e o sandbox?
- A permissão decide antes: esta ação específica roda, para e pergunta, ou é proibida. O sandbox decide o alcance: se a ação rodar, até onde ela chega no sistema de arquivos, na rede e no relógio. A primeira é uma política que você escreve; a segunda é um limite que o sistema operacional impõe.
- Dá para começar sem sandbox?
- Só enquanto todo comando vier de texto que você escreveu. Assim que o agente lê uma issue, uma página ou um arquivo de terceiro, esse conteúdo vira entrada não confiável e o sandbox deixa de ser opcional. Um estudo de 2023 mediu falhas de alto risco em 23,9% dos casos até no agente mais seguro que testaram.
- Framework de agente já não me dá essas camadas?
- Dá algumas, quase nunca todas, e raramente as que faltam são as que você percebe. Frameworks costumam entregar loop, catálogo de ferramentas e uma noção de memória. Permissão granular, sandbox de verdade, retomada de sessão e teto de custo costumam ficar por sua conta, e são exatamente as quatro que só doem em produção.
- Como sei qual camada está causando o problema?
- Pelo sintoma, que é diferente em cada uma. Agente que refaz trabalho é contexto. Agente que descreve a ação em vez de executar é ferramenta. Comando destrutivo que passou é permissão. Sessão que recomeça do zero é estado. Fatura maior que o esperado é custo. Confirme lendo a trajetória, nunca o terminal.
Referências
- Wang, X. et al.. OpenHands: An Open Platform for AI Software Developers as Generalist Agents (2024)arXiv:2407.16741
- Yang, J. et al.. SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering (2024)arXiv:2405.15793
- Ruan, Y. et al.. Identifying the Risks of LM Agents with an LM-Emulated Sandbox (2023)arXiv:2309.15817
- Xia, C. S. et al.. Agentless: Demystifying LLM-based Software Engineering Agents (2024)arXiv:2407.01489
- Hsieh, C.-P. et al.. RULER: What's the Real Context Size of Your Long-Context Language Models? (2024)arXiv:2404.06654