Post

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.

Harness Engineering: criando ferramentas seguras e confiáveis para IA

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.

Esta postagem está licenciada sob CC BY 4.0 pelo autor.