HSLabHSLab · lab aberto de IA
EN
← Voltar ao lab

Engenharia de harness: o agente duas vezes mais rápido sem trocar de modelo

Como a camada em volta do modelo (contexto, ferramentas, ciclo e governança) fez o mesmo pedido cair de 17,3 para 8,4 minutos e de 2,09 milhões para 1,26 milhão de tokens, sem trocar de modelo.

121 → 71chamadas para entregar a mesma tarefa longa

Dezessete minutos para uma resposta que podia sair em oito

Rodamos o mesmo pedido três vezes no OrganIA. Uma tarefa longa, com dezenas de chamadas de ferramenta. Na versão antiga, o agente levava 17,3 minutos e consumia 2,09 milhões de tokens. Na versão nova, 8,4 minutos e 1,26 milhão. A qualidade da resposta subiu.

O modelo era o mesmo.

O que mudou foi uma frase. Quando a conversa ficava grande demais, o sistema podava resultados antigos de ferramenta e deixava um texto no lugar dizendo onde o conteúdo original estava guardado. Esse texto apontava para o material bruto. O modelo lia, entendia que precisava daquilo e ia buscar de novo. Em um dos runs, 26 de 117 chamadas de ferramenta eram releitura: 22% do orçamento gasto recomprando o que ele já tinha lido. Quatro de nove itens da tarefa fecharam sem dado porque o orçamento acabou antes.

Trocamos o ponteiro para apontar primeiro para um registro destilado do trabalho, e só depois para o bruto. A releitura foi de 26 chamadas para zero.

Quando um agente vai mal em produção, a primeira reação de quase todo mundo é perguntar qual modelo usar. Construindo o agent-builder, aprendi que essa pergunta raramente é a certa.

A tese: falha de produção é falha de pilar

“Harness” vem de arnês, o chicote de fiação que liga um motor ao resto da máquina. Uso o termo para tudo que envolve o modelo e transforma capacidade bruta em agente confiável: o que ele vê, o que ele pode fazer, como se movimenta e o que o mantém sob controle.

A frase que guia o trabalho é esta:

O modelo define o teto de inteligência. O harness determina quanto desse teto chega ao usuário.

Daí sai uma regra de diagnóstico. Falha de produção quase sempre é falha de um pilar do harness, e quase nunca falta de inteligência do modelo. Um modelo menor num harness bom entrega mais que um modelo de ponta num harness ruim. Trocar de modelo para resolver um problema de contexto é dinheiro jogado fora.

O segundo princípio é contraintuitivo: mais não é melhor. Excesso de contexto enterra o sinal. Excesso de ferramentas confunde a escolha; um esquema com 60 ferramentas custa cerca de 27 mil tokens por passo, reenviados a cada volta do raciocínio. Loop sem freio queima dinheiro. Governança frouxa amplia o estrago quando algo dá errado. Por isso cada pilar trabalha com injeção condicional e tetos, nunca com “liga tudo que pode ser útil”.

O harness do OrganIA hoje tem cerca de 14.800 linhas de runtime, 21 posições de middleware, 13 blocos de prompt que entram por condição e 4 famílias de ferramenta. É ali, em volta do modelo, que está o trabalho.

Uma esteira só, para sete portas de entrada

A decisão de arquitetura mais importante não foi nenhum pilar. Foi garantir que todo caminho de execução desça pelo mesmo trilho.

Um agente pode ser acionado por chat, por rotina agendada, por webhook, por uma regra que disparou, por uma missão entre agentes, por tarefa em segundo plano ou pela retomada depois de uma aprovação humana. Sete portas. Uma esteira.

chat · agenda · webhook · regra · missão · 2º plano · retomada
                         │
                     [ borda ]          quem é o usuário, qual o input
                         │
                 [ orquestrador ]       segredos, ferramentas, memória
                         │
                 [ ferramentas ]        4 famílias, uma cadeia de proteção
                         │
                  [ montagem ]          prompt bloco a bloco + middlewares
                         │
                  [ execução ]          tetos, vigia de estagnação
                         │
               [ funil de saída ]       promessa × entrega, custo do run

Cada estágio recebe um artefato nomeado e não sabe de onde veio a chamada. A consequência prática: capacidade nova entra em um ponto e vale para todos os caminhos, sem ninguém precisar lembrar de replicar.

Aprendi do jeito caro: a retomada pós-aprovação era uma terceira cópia manual da montagem e divergiu da original seis vezes, em silêncio. Hoje a retomada reentra na esteira com o comando de retomada como input e não remonta nada.

Os quatro pilares, na prática

Cada pilar responde a uma pergunta e tem um jeito característico de falhar.

Pilar Pergunta Falhou quando
Contexto O que o modelo pode ver? A informação existia, mas não estava ali na hora da decisão: enterrada, velha ou ausente
Ferramentas O que o modelo pode fazer? A ação certa não estava exposta de forma compreensível, ou a ferramenta devolveu lixo
Ciclo Como o modelo se movimenta? Entrou em loop, parou cedo ou queimou recursos sem progresso
Governança O que mantém a autonomia sob controle? Restrito demais (não terminou) ou livre demais (agiu onde não devia)

Contexto

O system prompt do OrganIA não é um texto salvo no banco. Ele é remontado a cada conversa, bloco por bloco, e cada bloco tem uma condição para entrar. Um agente simples recebe três blocos. Um agente completo, conversando com uma pessoa que tem ficha e cadernos preenchidos, recebe treze.

Um exemplo do que isso permite: o bloco de contexto de tela (data, hora, quem fala, o que a pessoa está vendo) só existe no chat. Rotina, webhook e missão recebem vazio. Dizer ao modelo “o usuário está vendo X” quando ninguém está olhando é mentira operacional, e o agente agiria sobre uma tela que não existe. A honestidade, dentro de um harness, não é um aviso no prompt. É a ausência do dado.

A ordem dos blocos também é decisão de custo. O contexto de tela entra por último porque carrega a hora, que muda a cada minuto, e o cache de prefixo dos provedores vale até o primeiro caractere diferente. Com a hora no topo, os cerca de 86 mil caracteres seguintes seriam recobrados a cada minuto. Com a hora no fim, só o rabo muda. Medido nesta base: 76% dos tokens de entrada do chat vêm do cache.

Esse pilar tem tanto detalhe que escrevi um artigo só sobre ele, sobre engenharia de contexto.

Ferramentas

Ferramenta é como o agente sai do chat e mexe no mundo. O pilar tem três trabalhos: trazer origens diferentes para um formato só, proteger as chamadas de tudo que dá errado em produção e controlar o volume do que elas devolvem.

As quatro famílias (internas em Python, MCP, HTTP e sub-agente como função) entram por um resolvedor único e saem envelopadas na mesma cadeia de cinco proteções: preenche parâmetros fixos, corrige tipo errado, corta o que travou, separa erro definitivo de erro passageiro e captura o inesperado. Uma proteção nova escrita uma vez vale para as quatro famílias.

A cadeia só protege quem entra por ela: chamar a ferramenta pelo método interno pulou todas as camadas e quebrou os botões de ação dos painéis por duas semanas.

O controle de volume é o que mais muda a qualidade da resposta. Quando uma consulta devolve 3 mil linhas, jogar tudo no contexto é pedir para o modelo somar de cabeça. O resultado vira um conjunto consultável, o modelo recebe um resumo e um endereço, e as contas saem de ferramentas determinísticas de filtro, agrupamento e soma. Resultado cortado diz quanto mostrou. Resultado vazio diz o que existe no conjunto maior. O modelo para de afirmar “não existe” sobre algo que ele não leu.

Ciclo

Um agente pensa, chama ferramenta, lê, pensa de novo. Cada volta é um turno de modelo. O ciclo governa essas voltas: quantas podem acontecer, o que fazer quando uma falha, como perceber que o agente gira em falso e como garantir que ele termine.

São quatro tetos, porque cada um mede um eixo diferente de “gastar demais”:

Teto O que conta Que morte evita
Passos do grafo Voltas de raciocínio Run infinito por indecisão
Chamadas por run Total de ferramentas Exploração que nunca fecha
Repetição Mesma ferramenta além do que ela declara razoável Loop e efeito duplicado
Tempo sem sinal Minutos sem evento Passo que nunca retorna

O quarto nasceu de um run que ficou pendurado 68 minutos numa chamada de modelo estagnada, sem cobrar nada e sem terminar. Os outros três contavam passos, e aquele passo nunca voltou.

Um detalhe que me poupou recalibração manual para sempre. O dono do agente escolhe “profundidade de análise” e pensa em turnos. O LangGraph, por baixo, conta nós do grafo, e um turno custa cerca de seis nós porque cada middleware com gancho é um nó. Sem tradução, o preset “padrão” de 35 passos bancava uns 7 turnos, e um run legítimo de seis ferramentas morreu com a resposta final já gravada. Hoje um tradutor lê o custo por turno do grafo já compilado e multiplica o limite. Middleware novo encarece o turno, e o teto acompanha sozinho.

A outra mudança de mentalidade: a tarefa é a unidade de entrega, o run é só um turno dela. Antes do teto duro, o agente tem reserva para fechar o que já levantou. Quando o limite chega, a mensagem vem em linguagem de negócio. Em produção, um usuário chegou a ler run limit exceeded (121/120) com 22 KB de trabalho salvo do lado.

Governança

A pergunta que decide se uma plataforma de agentes entra numa empresa é: o que impede o agente de fazer o que não deve? A resposta não pode ser “pedimos no prompt”.

No OrganIA isso é infraestrutura. Ferramenta marcada como sensível pausa o grafo, o estado é salvo, e só quem pediu a ação pode aprová-la. O administrador vê todas e pode descartar uma, mas não aprova pela pessoa, porque a retomada roda com a identidade de quem aprova. Permissões são um catálogo de 33 itens com trilha de auditoria. Conexões podem ser do agente ou da pessoa, e no modo pessoa não existe recuo: o agente não manda e-mail “como ninguém”.

E todo trabalho concluído deixa um diário numa tabela que só aceita acréscimo. “Por que o agente fez isso?” vira consulta de segundos, não investigação de horas.

O servidor confere, o modelo não promete

Se eu tivesse que escolher um único padrão para levar para outra empresa, seria este.

Em produção, o agente escreveu “Aqui está o kanban” e o payload da resposta não tinha kanban nenhum. O funil de saída validava o formato e nunca comparava o texto com os blocos, tendo os dois na mão.

A tentação, quando o modelo mente sobre o que fez, é pedir com mais firmeza no prompt. Construímos mecanismos assim e removemos todos. Empurrar o modelo pelo contexto produz um relato melhor, não um trabalho melhor. E um relato melhor é mais difícil de detectar.

É proibido criar mecanismo cuja função seja convencer o modelo a se auto-relatar bem. O servidor confere o que foi dito contra o que existe.

Hoje são doze mecanismos nessa família, eram cinco em agosto. Alguns exemplos:

  • Promessa conferida: “aqui está o kanban” sem kanban é rebaixado com um aviso honesto.
  • Ata garantida: a ata da reunião é produzida pelo servidor a partir da transcrição, mesmo que o modelo não grave.
  • Etapa de plano conferida: só conclui se o banco confirma o resultado.
  • Link montado pelo servidor: o modelo só diz qual arquivo. Ele errou 1 caractere em 296, invisível a olho.
  • Bloco perdido declarado: antes, 31 respostas “com sucesso” tinham perdido 63 blocos visuais, 35 deles corretos, sem sinal nenhum.
  • Atribuição conferida: resposta que atribui a uma empresa o que veio de fonte de outra recebe aviso.

O viés é deliberado. Falso positivo custa mais que o bug, então o registro de promessas é fechado e qualquer dúvida faz o mecanismo recuar.

O que deu errado, e o número que mostrou

Cada mecanismo do harness nasceu de um incidente medido, não de uma ideia de arquitetura. Alguns que me ensinaram mais:

O cache que escondia o loop. O cache de resultados ficava por fora da guarda de loop na pilha de middlewares. Servia a repetição idêntica sem que o contador visse. Um agente repetiu a mesma consulta de memória 47 vezes numa pergunta trivial: 6,7 milhões de tokens em 10 minutos, e o freio achava que era a sétima. A regra que ficou: quem conta fica por fora de quem responde. A ordem dos middlewares não é detalhe.

A ferramenta antes do pré-requisito. A ferramenta de anotar na bancada de trabalho era oferecida antes de a bancada existir. O modelo leu “não chame de novo” 12 vezes e chamou de novo. Hoje ela só aparece quando a bancada existe. O modelo não chama o que não vê.

A fila que não bastava. O navegador da pessoa é um recurso único, e o modelo chegou a pedir 13 buscas em paralelo. A fila resolveu o atropelo, mas o grafo gravou 10 aprovações pendentes enquanto a plataforma registrou uma. A conversa ficou impossível de retomar. A segunda camada foi limitar a uma chamada de navegador por passo. Proteger o recurso não protege o que a concorrência produz rio abaixo.

O trabalhador sem freio. O trabalhador por trás do navegador, quando estourava o limite, jogava fora o que tinha achado: 4 de 32 chamadas em 90 dias, uma delas com o diretor procurado já localizado na página. Hoje todo grafo tem freio antes do teto e devolve o parcial.

A lista de nomes escrita à mão. Quanto cada ferramenta podia repetir num turno era decidido por quatro listas de nomes no código do freio. Houve cinco reincidências, duas com a mesma frase no comentário: “punido por obedecer”. Trocamos a lista por declaração: a ferramenta diz, onde nasce, se pode rodar uma vez, poucas, paginada ou por alvo. Antes de mudar, reclassificamos os 69 bloqueios reais de produção: 56 mantidos, 13 liberados, nenhum deles loop.

O “Saudável” que mentia. Dez consultas passaram a falhar por mudança de versão de API. Os valores padrão somaram 79,2 pontos e o veredito saiu “Saudável”, com zero avisos. A regra que nasceu: nunca pontuar o que não se mediu.

A documentação atrasada. Na auditoria de 14 de outubro, o próprio documento de arquitetura estava seis semanas atrás do código. Dizia que o primeiro ciclo autônomo “nunca rodou” quando já havia 294 conversas de rotinas agendadas em produção. Hoje um fiscal no CI recusa divergência entre a página e o código-fonte da documentação, e a convenção é que mudança em pilar atualiza o documento do pilar no mesmo PR.

Também mantenho uma lista de defeitos abertos, medidos e com causa conhecida. Um deles: o índice de skills não chega ao modelo em 6 de 8 agentes de instrução gerada, porque a regra que decide descartá-lo procura um texto que aparece em outro lugar das instruções. A análise do conserto está pronta. Escrevo isso aqui pelo mesmo motivo que escrevo no documento interno: descrever um mecanismo sem dizer onde ele não funciona ensina a confiar no que não acontece.

Os resultados

Medição Antes Depois
Releitura de material bruto (mesmo pedido) 26 chamadas 0
Duração (mesmo pedido) 17,3 min 8,4 min
Tokens (mesmo pedido) 2,09 M 1,26 M
Tarefa longa 121 chamadas, nada entregue 71 chamadas em 5,8 min, com entrega
Esquemas de ferramenta por chamada (Work Pilot) 20.747 tokens 6.250 tokens (−70%)
PDF de 76 páginas 365 s menos de 1 s
Leituras de página com “HTTP 403” cru 101 de 287 em 90 dias motivo legível e próximo passo decidido pelo servidor

76% dos tokens de entrada do chat vêm do cache do provedor; nas rotinas agendadas, de 40% a 58%. E o painel de custos, quando passou a cobrar cada parcela pelo preço real (cheia pelo preço cheio, cacheada pelo preço de cache), deixou de superestimar a entrada em cerca de 2,5 a 3 vezes. Na primeira conferência manual, a fórmula antiga dava 43% acima da fatura.

Como aplicar na sua empresa

Não precisa construir uma plataforma para usar a lente. Este é o checklist que eu usaria em qualquer projeto de agente em produção.

  1. Quando o agente errar, pergunte qual pilar falhou antes de perguntar qual modelo usar. A informação estava lá na hora da decisão? A ação certa estava exposta? Ele girou em falso? Foi barrado ou agiu onde não devia?
  2. Não suba o esforço de raciocínio para resolver alucinação sobre dado. Quase sempre é dado velho ou ferramenta não chamada. Pagar mais por token não conserta um dado que não estava lá.
  3. Uma esteira para todos os caminhos de execução. Se chat, rotina e webhook montam o agente cada um do seu jeito, eles vão divergir em silêncio.
  4. Todo bloco de prompt e toda ferramenta nascem com condição de entrada e teto. Se você não sabe dizer quando um bloco não deve entrar, ainda não entendeu o bloco.
  5. Ponha o que muda rápido no fim do prompt. Hora e estado de tela por último. Meça quanto vem do cache.
  6. Resultado grande vira referência, não texto. Conjunto consultável, resumo e endereço. As contas saem de ferramenta determinística.
  7. Pode sem destruir. Grave antes de apagar e escreva o ponteiro pensando em para onde ele empurra o modelo.
  8. Tenha mais de um teto, e um deles por tempo sem sinal. E deixe o agente pousar com o que já tem em vez de morrer com a resposta no bolso.
  9. Promessa da resposta é conferida pelo servidor. Se o texto diz que entregou, o payload precisa ter. Não tente resolver isso com instrução.
  10. Ação sensível pausa para aprovação de quem pediu, com o estado salvo e retomada exata.
  11. Registre o que o modelo recebeu em cada chamada. Sem isso, “por que ele fez isso?” é dedução.
  12. Mantenha a lista de defeitos abertos à vista. Documento que esconde a lacuna não serve para decidir nada.

Uma observação que generaliza bem: o que é do mecanismo não se conserta com instrução. Escrever “não faça isso” nas instruções não muda nada quando o modelo já leu a recusa e repetiu.

Para fechar

Construir um agente que vai bem numa demonstração é acessível hoje: um modelo, um prompt e algumas ferramentas. O difícil é o agente continuar certo no centésimo run, com dado real, cliente real e dinheiro real.

Essa parte não vem do modelo. Vem de uma esteira única, de blocos que entram por condição, de tetos que acompanham a arquitetura, de um servidor que confere o que foi prometido e de uma lista honesta do que ainda não funciona. Quase tudo nessa lista nasceu de um incidente que alguém mediu.

Por isso essa camada é difícil de copiar por quem ainda não teve os incidentes. Escrevo sobre ela para que você tenha alguns deles mais barato.

Experimentos ligadosEH-01Quando o agente falha, raramente é culpa do modelo17,3 → 8,4 minRodando16.10.2026EH-09Agente que usa sistemas sem integração13Rodando20.07.2026
● Lab Log

Um e-mail do lab a cada duas semanas.

O que testei, os números e o que deu errado. Sem spam. Dá para sair quando quiser.