28 de junho de 2026•9 min de leitura
Harness Engineering: por que seu agente falha (e não é culpa do modelo)
Quando o agente entrega pela metade ou quebra o projeto, o problema costuma ser o harness — não o modelo. Veja os cinco subsistemas que fazem a diferença.
Para economizar seu tempo:
Harness é toda a infraestrutura fora dos pesos do modelo — aquilo que evita você pedir uma coisa, o agente entregar pela metade, quebrar o build e, na sessão seguinte, começar do zero como se nada tivesse acontecido.
Consiste em cinco subsistemas:
- Instruções —
AGENTS.md, regras do IDE,docs/ - Ferramentas — shell, leitura/escrita de arquivos
- Ambiente —
init.sh, versões, comando para rodar o projeto - Estado —
progress.md,feature_list.json, commits - Feedback — test, lint, build
Fiz a skill harness-modular para você implementar ou melhorar o harness no seu projeto agora mesmo. Instale com:
npx skills add ErikBarroso/skills@harness-modular -g -yDepois, peça ao agente para criar ou auditar o harness.
O restante deste artigo mostra como cada subsistema resolve uma causa real de falha.
Quando os modelos falham
Quando pedimos para o agente fazer algo e ele cria bugs, quebra testes, adiciona algo nada a ver ou entrega algo pela metade, logo pensamos que o modelo não é bom o suficiente e achamos que testar um mais caro vai resolver. Bom, talvez o problema não seja o modelo.
A Anthropic fez um teste usando o mesmo prompt ("crie um editor de jogos retrô 2D"), mesmo modelo (Opus 4.5), duas execuções. A primeira custou US$9 e 20 minutos; as principais funcionalidades do jogo não funcionaram. A segunda custou US$200 e o jogo ficou totalmente jogável.
Perceba que o modelo usado foi o mesmo. O que trouxe a diferença foi o harness. Vamos analisar alguns motivos:
1. Requisitos vagos
Se você pede algo muito vago, o agente precisa adivinhar. E adivinhar nada mais é do que sorte. Se ele errar, o retrabalho vai sair mais caro do que se você tivesse sido específico desde o início.
Subsistema que resolve: Instruções (AGENTS.md, docs/).
2. Convenções implícitas não documentadas
Você acha que seu código tem que ter early return, e suas rotas no plural, /products não /product , mas isso está apenas na sua cabeça. O agente não tem como seguir, porque ele simplesmente não faz ideia disso.
Subsistema que resolve: Instruções + Fonte de verdade no repositório.
3. Ausência de métodos de verificação
O agente vai considerar a task concluída quando ele achar que terminou. Se você não tiver um comando de verificação e não comunicar isso ao agente, ele vai escrever o código, revisar superficialmente e concluir.
A Anthropic observou um comportamento e o chamou de "ansiedade de contexto": quando o contexto está acabando, o agente acelera para terminar, pulando etapas de verificação e escolhendo soluções simples em vez das melhores.
Subsistema que resolve: Feedback (init.sh, lint, test, build).
4. Perda de estado entre sessões
Toda nova sessão começa do zero. O agente precisa redescobrir a organização do código, decisões tomadas, qual a próxima tarefa, como testar, buildar e rodar o projeto. Isso aumenta o número de falhas em tarefas maiores.
Subsistema que resolve: Estado (progress.md, feature_list.json, git log).
Ainda neste artigo, vamos ver como resolver cada um deles.
Primeiros passos no harness engineering
Primeiro de tudo: um arquivo na raiz do repositório chamado AGENTS.md. Se você usa Claude Code, o equivalente é CLAUDE.md. A função desse arquivo é dizer como operar o projeto.
Vai ser a primeira leitura que o agente faz em cada sessão. Então, ela deve conter um mapa do repositório, definition of done e restrições obrigatórias. Trate-o como um índice (~100 linhas), não enciclopédia.
Ele serve como mapa para a base de conhecimento do repositório, que ficará em uma pasta docs/:
AGENTS.md
docs/
├── design-docs/
│ ├── index.md
│ ├── core-beliefs.md
│ └── ...
├── generated/
│ └── db-schema.md
├── product-specs/
│ ├── index.md
│ ├── new-user-onboarding.md
│ └── ...
Cada documento de tópico deve ter entre 50 e 150 linhas, organizado por assunto dentro de docs/ ou ao lado do módulo correspondente. (Falaremos mais sobre isso na seção Fonte de verdade.)
Isso faz com que os agentes comecem com um ponto de entrada pequeno e sejam instruídos sobre onde procurar em seguida, em vez de serem sobrecarregados consumindo a janela de contexto.

Exemplo de AGENTS.md
# AGENTS.md
## Visão Geral do Projeto
API REST em TypeScript com Express.
## Antes de escrever código
1. Confirme o diretório com `pwd`.
2. Leia `progress.md` e `feature_list.json` (estado atual e feature ativa).
3. Revise commits recentes: `git log --oneline -5`.
4. Execute `./init.sh` (lint + build + test).
Se o baseline já estiver quebrado, corrija antes de implementar feature nova.
## Restrições obrigatórias
- Early return; evitar `else`.
- Rotas REST no plural (`/products`, não `/product`).
- Todas as APIs devem utilizar autenticação OAuth 2.0
## Documentos Temáticos
- Padrões de Design de API (`docs/api-patterns.md`) — Leitura obrigatória ao adicionar endpoints
- Regras de Banco de Dados (`docs/database-rules.md`) — Obrigatório ao modificar operações de banco
- Padrões de Teste (`docs/testing-standards.md`) — Referência ao escrever testes
## Definição de concluído
Uma feature só está concluída quando:
- o comportamento alvo foi implementado
- `./init.sh` passa (lint + build)
- requests relevantes do `test.http` do módulo foram exercitados
- `feature_list.json` atualizado com status + evidência
- `progress.md` atualizado ao fim da sessão
Não marque feature como `passing` só porque o código foi escrito.
## Fim de sessão
1. Atualizar `feature_list.json` (status + evidência).
2. Atualizar `progress.md` (o que foi feito, bloqueios, próximo passo).
3. Commit descritivo quando o repo estiver em estado seguro.
4. Próxima sessão deve conseguir rodar `./init.sh` imediatamente.Uma vez que tenhamos essa estrutura estabelecida, o agente vai:
- Identificar o diretório para que as alterações se limitem a ele
- Ler os logs de git e arquivos de progresso para saber o trabalho recente
- Ler o arquivo de funcionalidades para saber a próxima tarefa
- Executar
./init.shpara confirmar que a aplicação não está quebrada
Essa abordagem economiza tokens, já que o agente não precisa, a cada sessão, redescobrir o que fazer, como testar, rodar o app e qual contexto está ativo.
Fortalecendo seu harness
Existem mais alguns passos que você pode fazer para melhorar o harness.
init.sh
O init.sh é um script que o agente roda antes de alterar algo no projeto. Essa etapa valida que o projeto está saudável, passando em lint, build e tests.
Se o agente adiciona código em cima de um projeto já quebrado, o estrago pode ser maior. Então ele verifica o baseline, corrige se necessário, implementa a feature e roda o script de novo para garantir que nada quebrou.
Subsistema: Ambiente + Feedback.
feature_list.json
O feature_list.json diz quais features terminaram (com evidência) e quais são os próximos passos.
Apenas adicionar código não significa que uma task foi concluída. Para uma task ser considerada concluída, precisamos verificar que o comportamento foi aprovado. Toda tarefa precisa de um critério objetivo de conclusão. Se o agente não sabe o que significa "concluído", ele entrega coisas pela metade.
Não precisa ser complexo. A Anthropic recomenda JSON porque o modelo tende a alterar menos campos indevidamente do que em Markdown. Existem dois formatos comuns:
Formato A — comportamento + evidência (bom para APIs e fluxos verificáveis):
{
"id": "F03",
"behavior": "POST /cart/items with {product_id, quantity} returns 201",
"verification": "curl -X POST http://localhost:3000/api/cart/items -H 'Content-Type: application/json' -d '{\"product_id\":1,\"quantity\":2}' | jq .status == 201",
"state": "passing",
"evidence": "commit abc123, test output log"
}Formato B — steps + passes (bom para fluxos de UI ou checklists):
{
"category": "functional",
"description": "New chat button creates a fresh conversation",
"steps": [
"Navigate to main interface",
"Click the 'New Chat' button",
"Verify a new conversation is created",
"Check that chat area shows welcome state",
"Verify conversation appears in sidebar"
],
"passes": false
}No formato B, a ideia é o agente alterar apenas o campo passes, evitando mudar requisitos indevidamente.
Cada item deve ter escopo concluível em uma única sessão. "O usuário pode adicionar itens ao carrinho" é boa granularidade. "Implementar o carrinho de compras" é amplo demais. "Criar o campo name no modelo Cart" é detalhado demais.
Para evitar que o agente tente muitas features de uma vez ou considere o projeto concluído precocemente, o feature_list lista tudo que falta para entregar o escopo. A cada nova sessão, o agente sabe onde paramos e qual o próximo passo.
Subsistema: Estado + Feedback.
progress.md
O progress.md (ou claude-progress.md) registra o que foi feito na sessão: decisões tomadas, mudanças de regras, erros e como foram resolvidos.
Imagine um projeto onde engenheiros trabalham em turnos. Cada novo engenheiro assume sem saber o que aconteceu no turno anterior. É exatamente isso que acontece em projetos complexos que não cabem em uma única sessão, cada nova sessão começa sem memória do que ocorreu antes.
É aí que entra o progress.md. Ele registra as ações dos agentes para que a próxima sessão compreenda rapidamente o estado do trabalho, mesmo com janela de contexto vazia.
Subsistema: Estado.
Fonte de verdade
Decisões tomadas no Slack, reuniões, Jira e até na sua cabeça são comuns. Para nós humanos já é difícil consultar depois. Imagine para o agente.
A OpenAI afirma isso de forma direta: informações que não existem no repositório não existem para o agente.
O repositório precisa ser a fonte de verdade. Qualquer coisa que o agente não consiga enxergar, na prática, não existe.
Abra uma sessão completamente nova do agente no seu projeto (sem contexto verbal), permita que ele veja apenas o repositório e faça cinco perguntas:
- O que é este sistema?
- Como ele está organizado?
- Como eu executo isso?
- Como eu verifico isso?
- Qual é o progresso atual?
Se você não tiver o mínimo de harness, o agente nunca terá essas respostas — ou vai gastar muito mais contexto e tempo do que deveria.

Como desenhar um bom mapa
-
- O conhecimento vive ao lado do código: coloque um documento curto em cada diretório de módulo explicando responsabilidades e restrições. Quando o agente chega ao código, encontra as regras sem precisar procurar.
-
- Seja objetivo: se remover uma regra não altera a qualidade das decisões do agente, essa regra não deveria existir. Busque equilíbrio, nada demais, nem de menos.
-
- Atualize a doc junto com o código: cada vez que modificar o código, revise a documentação naquele diretório e atualize se necessário.
project/
├── AGENTS.md # Entrada: visão geral, comandos e restrições rígidas
├── src/
│ ├── api/
│ │ ├── ARCHITECTURE.md # Decisões arquiteturais da camada de API
│ │ └── ...
│ ├── db/
│ │ ├── CONSTRAINTS.md # Restrições com MUST / MUST NOT para operações críticas
│ │ └── ...
│ └── ...
├── PROGRESS.md # Progresso: concluído, em andamento, bloqueado
└── Makefile # Comandos padronizados: setup, teste, lint e verificação
Como manter o contexto vivo entre sessões?
Com progress.md + histórico do git, as próximas sessões sabem o progresso e o que foi feito.
Você também pode ter um decisions.md com registros de decisões importantes:
# Decisões de Design
## 15/01/2026: Utilizar Redis para cache de preferências do usuário
- **Motivo:** Alta frequência de leitura (praticamente todas as chamadas da API) e pequeno volume de dados.
- **Alternativa rejeitada:** *Materialized View* no PostgreSQL (a alta frequência de alterações não justifica o custo de manutenção).
- **Restrição:** TTL do cache de 5 minutos, com invalidação ativa sempre que ocorrer uma escrita.Você precisa testar na prática para comprovar que Harness Engineering não é algo a ignorar se quer trabalhar de forma séria com IA.
Já passamos da fase de culpar modelos e prompts. Lembre-se: se seu prompt falhar, veja isso como uma forma de perceber que seu harness tem defeitos.