Harness Engineering: criando ferramentas seguras e confiáveis para IA
Crie um ambiente reproduzível para agentes com permissões explícitas de ferramentas, comandos confiáveis, instruções do repositório e integrações MCP opcionais.
Um modelo pode sugerir uma mudança no código. Um agente de programação também precisa de ferramentas para ler arquivos, fazer a mudança, executar verificações e ver os resultados. Esse conjunto de ferramentas e controles é o seu harness.
Harness Engineering é o projeto desse ambiente: ferramentas disponíveis, permissões e retorno das verificações. Um harness pode apoiar edição, testes e outras ações. Não existe uma arquitetura única para todos os agentes.
Context Engineering trata das informações disponíveis para o agente. Harness Engineering trata do que ele pode fazer e de como essas ações são executadas.
Separe os controles do ambiente de execução das instruções do projeto
Duas camadas úteis são:
| Camada | Responsabilidades | Exemplos |
|---|---|---|
| Ambiente de execução da plataforma | Acionar ferramentas, gerenciar sessões e impor limites configurados | Editor de arquivos, terminal, ambiente isolado, política de aprovação |
| Ambiente do projeto | Permitir a repetição das tarefas de desenvolvimento e explicar convenções locais | Scripts para compilar e testar, dependências fixadas, dados de teste, instruções do repositório |
O limite entre elas depende do produto e da implantação. Ambiente isolado, restrições de rede e requisitos de aprovação dependem da configuração; não estão presentes em todo agente de programação. Verifique as permissões reais do ambiente usado.
Uma instrução como “não escreva em produção” orienta o modelo. Credenciais sem acesso a produção oferecem um controle separado e aplicável pelo sistema.
flowchart LR
accTitle: Ciclo de execução das ferramentas do agente
accDescr: O modelo propõe uma ação, o ambiente de execução verifica as permissões e uma ferramenta executa no ambiente configurado. O status e um resumo do resultado retornam ao modelo.
Model["Modelo propõe uma ação"] --> Runtime["Ambiente verifica as permissões"]
Runtime --> Tool["Ferramenta executa no ambiente configurado"]
Tool --> Result["Status de saída e retorno limitado"]
Result --> Model
Associe cada regra importante a um feedback observável
Em Harness engineering for coding agent users, Birgitta Böckeler distingue instruções que orientam o trabalho de verificações que examinam o resultado. Um harness de projeto também permite verificar se as expectativas de engenharia foram atendidas.
No exemplo de checkout, associe uma orientação a uma verificação:
| Orientação | Mecanismo de feedback | Julgamento que ainda é necessário |
|---|---|---|
| O serviço de preços calcula o desconto | Regras de dependência impedem que a interface web use detalhes internos desse serviço | Revisar fórmulas duplicadas que essas regras não detectam |
| Preserve a cotação aceita | Casos de teste comparam os valores da API, da interface e do banco de dados | Confirmar que os resultados esperados representam a intenção do produto |
| Siga os limites de módulos existentes | Verificações estruturais detectam dependências proibidas ou ciclos | Avaliar se os limites ainda fazem sentido para a próxima alteração |
Execute verificações rápidas e relevantes durante a edição; depois, repita na integração contínua (CI) as verificações exigidas para a alteração integrada. Use uma revisão por modelo quando a pergunta exigir interpretação e forneça evidências para uma pessoa revisar. Passar em verificações determinísticas confirma apenas as propriedades codificadas nelas; passar por uma revisão de modelo fornece um julgamento falível. Nenhum dos dois substitui os critérios de aceitação.
Torne acionável o feedback sobre manutenção
No artigo complementar Maintainability sensors for coding agents, Böckeler experimenta análise automática de código, regras de dependência, análise de acoplamento e testes de mutação. Uma lição prática é explicar como reagir a uma constatação, em vez de retornar uma pontuação sem contexto.
Para uma regra de dependência ilustrativa, retorne um diagnóstico como este:
1
2
3
4
Violação: web/checkout importa pricing/internal/discountRules.
Limite: web consome o contrato publicado da cotação.
Próxima etapa: inspecione o cliente de pricing e reutilize sua operação de cotação.
Se o limite precisar mudar, registre o motivo para revisão.
Mantenha exceções e alterações de limites visíveis nas mudanças do código. Revise-as antes de aceitar um resultado aprovado: um agente pode silenciar um alerta útil afrouxando a regra. Examine também as concessões entre regras. Dividir um componente longo em várias partes pode reduzir a contagem de linhas e, ao mesmo tempo, aumentar o acoplamento e o número de parâmetros entre componentes.
Comece com um problema de manutenção observado e uma verificação pequena. Acompanhe se ela ajuda nas alterações seguintes; indicadores melhores, por si só, não demonstram que ficou mais fácil manter o sistema. Para uma abordagem de arquitetura sobre verificações contínuas de qualidade, consulte os capítulos 2, “Fitness Functions”, e 4, “Automating Architectural Governance”, de Building Evolutionary Architectures.
Faça os comandos funcionarem sem configuração pessoal do shell
Uma falha comum é um comando funcionar no terminal de uma pessoa desenvolvedora, mas falhar na automação. O agente pode usar outro shell, diretório de trabalho, ambiente ou modo de inicialização.
No Bash, os modos interativo e de login afetam quais arquivos de inicialização são lidos; uma execução não interativa geralmente não lê ~/.bashrc automaticamente. Alguns arquivos .bashrc também retornam imediatamente quando o shell não é interativo. A questão é o modo do shell, não apenas a existência de uma janela de terminal. Consulte as regras de arquivos de inicialização do Bash.
Executar todos os comandos com bash -i -c pode introduzir atalhos e comportamentos específicos da máquina. Prefira uma configuração documentada do ambiente de execução e comandos que funcionem tanto no CI quanto localmente.
Para um projeto Node ilustrativo com lockfile e scripts de pacote existentes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# AGENTS.md
## Configuração
- Execute os comandos a partir da raiz do repositório.
- Use a versão do Node declarada em .node-version.
- Instale as dependências fixadas com npm ci.
- Os testes unitários usam dados de teste locais e não precisam de serviços externos.
## Verificação
- Verificação de tipos: npm run typecheck
- Testes unitários, uma execução: npm run test:ci
- Lint: npm run lint
- Build de produção: npm run build
## Convenções de edição
- Siga o código ao redor e mantenha as alterações no escopo solicitado.
- Regenere os arquivos em generated/ usando npm run generate.
- Informe as verificações que não puderam ser executadas e o motivo.
Esses comandos pressupõem que os scripts correspondentes existem. Substitua-os por comandos verificados no seu repositório, incluindo a inicialização e o encerramento de serviços quando necessário. Mantenha as definições autoritativas dos comandos em scripts para que pessoas, agentes e CI usem a mesma implementação.
Use MCP quando ajudar na conectividade
O Model Context Protocol (MCP) padroniza como clientes descobrem e chamam ferramentas disponibilizadas por servidores. Ele pode conectar um agente a um inspetor de esquemas de dados, sistema de tarefas ou ferramenta de navegador. Ainda são necessários um cliente compatível, os recursos suportados e a configuração apropriada. A especificação de ferramentas do MCP descreve descoberta, chamadas e comunicação de erros.
MCP não torna um servidor seguro nem garante que o acesso ao banco de dados seja somente leitura. Imponha acesso somente leitura por meio de credenciais e configuração do servidor. Da mesma forma, a descrição de uma ferramenta não prova que sua implementação esteja livre de efeitos colaterais.
Use ferramentas de terminal ou uma ferramenta de linha de comando (CLI) quando já resolverem o problema. Um ciclo de feedback não exige MCP; exige execução confiável e resultados observáveis.
Empacote fluxos repetidos como skills
Uma skill (pacote reutilizável de instruções e recursos) pode reunir instruções, scripts e modelos de arquivo para uma tarefa recorrente, como gerar um cliente a partir de um contrato de API. O formato Agent Skills usa um arquivo de entrada SKILL.md, com recursos adicionais carregados conforme necessário pelas ferramentas compatíveis.
Uma skill torna os procedimentos reutilizáveis. Ela não garante que o agente siga todas as etapas nem que o procedimento continue correto. Versione os scripts, verifique as saídas e atualize as instruções quando as convenções do projeto mudarem.
Exemplo: uma ferramenta delimitada para verificar o checkout
Para a funcionalidade de desconto em andamento, uma equipe poderia disponibilizar verify_checkout com o contrato abaixo. É uma ferramenta ilustrativa que a equipe precisaria implementar; não é um comando interno dos agentes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tool: verify_checkout
inputs:
run_id: identificador de um ambiente descartável alocado
suite: enum [discount-valid, discount-expired, checkout-no-code]
candidate_manifest: referência imutável a commits de repositórios e digests de imagens
execution:
timeout_seconds: 120
prerequisites: revisões candidatas implantadas; serviços prontos; dados de teste preparados
side_effects: cria cotações e pedidos sintéticos somente nesta execução
concurrency: rejeita uma segunda invocação ativa para a mesma execução e suite
outputs:
status: passed | failed | invalid_arguments | environment_unavailable | timed_out
executed_cases: lista de verificações nomeadas
assertions: valores esperados e observados para cada verificação
elapsed_ms: duração medida
artifact_refs: referências a logs e registros detalhados da execução sem dados sensíveis
cleanup_status: completed | pending | failed
O executor valida o conjunto de verificações e o registro das revisões candidatas. Também confirma quem controla o ambiente, impõe o limite de tempo e fornece as credenciais fora dos argumentos da ferramenta. Ele precisa comparar as revisões implantadas com o registro, em vez de repetir as revisões solicitadas como se fossem evidência. Guarde os registros completos sem dados sensíveis mesmo quando o modelo receber apenas um resumo limitado.
| Resultado | Resposta do agente |
|---|---|
| invalid_arguments: conjunto de verificações desconhecido | Corrija a chamada usando o esquema de entrada da ferramenta; não edite o código da aplicação |
| environment_unavailable: pricing não ficou pronto | Inspecione as evidências de configuração e restabeleça o pré-requisito dentro do limite |
| failed: total exibido difere do persistido | Use os valores das verificações e o código-fonte candidato para diagnosticar a implementação |
| timed_out: navegador parou de responder | Inspecione o registro da execução e o estado de limpeza antes de outra invocação |
| passed sem casos executados | Considere o resultado uma evidência de verificação inválida |
Um limite de tempo excedido não demonstra que nenhum pedido foi criado. O executor deve preparar dados de teste isolados para outra tentativa ou redefinir os dados anteriores depois de confirmar o encerramento. Nunca repita uma mutação sem verificar só porque a ferramenta não retornou uma resposta final.
Projete resultados de ferramentas que ajudem no diagnóstico
O resultado útil de um comando inclui o diretório de trabalho, o status de saída, o tempo decorrido e a saída relevante. Preserve logs completos como artefatos quando o modelo receber apenas um resumo. Diferencie “o teste falhou” de “o executor de testes não conseguiu iniciar”.
Defina timeouts para comandos que possam travar e garanta que processos filhos cujo tempo se esgotou sejam encerrados. Separe permissões de build local das credenciais de implantação. Para mutações em sistemas compartilhados, explicite o escopo permitido e registre o que aconteceu.
A escolha do modelo é outra decisão de configuração. Compare modelos candidatos em tarefas representativas, incluindo conclusão bem-sucedida, esforço de revisão, latência e custo total. A capacidade de contexto, por si só, não demonstra adequação.
Um bom primeiro harness é modesto: uma configuração reproduzível, algumas verificações confiáveis e permissões ajustadas à tarefa. O próximo artigo explica como definir o comportamento que essas ferramentas devem ajudar a entregar: Spec-Driven Development.