Harness: o “arnês” que segura o cavalo

Se você acompanha o vocabulário que está se formando ao redor da engenharia de software com IA, provavelmente já esbarrou na palavra harness. Ela aparece em posts da Anthropic, na documentação do Claude Code, em artigos sobre Cursor e Cline, e em discussões sobre como construir agentes em produção.

Mas o que harness quer dizer, afinal?

A tradução literal — “arnês”, “cinto”, “atrelagem” — já entrega quase tudo. Harness é o conjunto de estruturas, regras, ferramentas e contexto que envolve um LLM para fazê-lo trabalhar de forma útil, segura e repetível em um problema real. O LLM sozinho é um cavalo: forte, rápido e meio caótico. O harness é o que transforma esse cavalo em uma carruagem que chega no destino.

Quando alguém diz “o Claude Code é um agentic harness”, está dizendo: existe um LLM no centro, e em volta dele existe uma camada de software que decide quais ferramentas ele pode chamar, qual contexto ele recebe, quais regras ele precisa seguir, quando ele para, o que acontece quando ele falha. Essa camada é o harness.

JA
José
Claude, me dá uma analogia bem concreta. Eu uso você todo dia mas nunca tinha pensado no termo "harness" assim.
C
Claude
Pensa num piloto de Fórmula 1. O piloto é o LLM — talento bruto, capaz de tomar decisões em milissegundos. Mas ele sozinho não vence corrida nenhuma. Em volta dele tem: o carro (as tools que ele pode usar — volante, freio, acelerador), o regulamento da FIA (as rules), o engenheiro no rádio (as skills ativadas conforme a situação), o briefing pré-corrida (as specs) e o telemetry que diz quanto combustível ainda dá (a janela de contexto). Tudo isso junto é o harness. Tira qualquer peça e o piloto bate no primeiro S do Senna.

Por que esse conceito importa agora?

Até pouco tempo atrás, “usar IA pra programar” significava abrir o ChatGPT, colar código, copiar resposta. O LLM era um oráculo isolado: você pergunta, ele responde, você decide o que fazer.

A geração atual de ferramentas — Claude Code, Cursor, Cline, Aider, Codex — mudou essa equação. O LLM agora age dentro do seu projeto: lê arquivos, roda comandos, faz commits, abre PRs. E para que ele aja sem destruir tudo, alguém precisou construir uma camada de contenção e orientação ao redor dele.

Essa camada é o que diferencia uma demo bonita de uma ferramenta que aguenta o dia a dia de uma equipe. A qualidade do harness importa mais do que a qualidade bruta do modelo. Um modelo mediano num harness excelente entrega mais valor que um modelo top de linha num harness pobre.

A partir daqui, vamos passar pelos termos que aparecem o tempo todo nesse vocabulário. Cada um é uma peça do arnês.


Janela de contexto (Context window)

A janela de contexto é a quantidade máxima de texto (medida em tokens) que o LLM consegue “enxergar” de uma vez. Tudo o que importa para a tarefa precisa caber ali dentro: a sua pergunta, o histórico da conversa, os arquivos que o agente leu, as definições das tools, as regras do projeto, as respostas anteriores do modelo.

Modelos recentes oferecem janelas de 200 mil, 1 milhão ou até mais tokens — números que parecem astronômicos mas se esgotam rápido quando o agente começa a ler arquivos grandes ou a rodar comandos verbosos.

O harness é quem gerencia a janela: decide o que entra, o que sai, o que vira resumo, o que é jogado fora. Sem essa gerência, em três interações você teria estourado o limite.

JA
José
Como é que eu "vejo" o quanto da janela já foi consumido enquanto estou trabalhando com você?
C
Claude
No Claude Code você consegue ligar uma status line que mostra a porcentagem de tokens usados em tempo real — é um dos primeiros ajustes que vale fazer no seu settings.json. Exercício prático: abre uma sessão nova, pede pra eu ler três arquivos grandes do seu projeto e observa o número subir. Vai ver que um único cat de um log de 5MB consome mais janela do que dez perguntas técnicas seguidas. Isso muda a forma como você delega tarefas: leituras pesadas viram trabalho de subagentes, que devolvem só o resumo pra janela principal.

Spec-Driven Development (SDD)

Spec-Driven Development é a prática de escrever uma especificação clara antes de pedir ao agente para implementar. Em vez de mandar “cria um endpoint de login”, você produz um documento que descreve o comportamento esperado, os casos de borda, os contratos de entrada e saída, e só depois entrega ao agente para implementar.

A ideia não é nova — é basicamente engenharia de software como sempre foi feita, só que com um detalhe novo: o agente é um leitor literal. Ele faz exatamente o que está escrito, e omissões viram suposições. Uma spec bem feita reduz o “telefone sem fio” entre o que você quis dizer e o que o modelo entendeu.

O fluxo típico do SDD com agentes é:

  1. Brainstorm — uma conversa com o agente para esclarecer requisitos.
  2. Spec — documento curto que captura decisões e critérios de aceitação.
  3. Plan — desdobramento da spec em passos implementáveis.
  4. Work — o agente executa o plano.
  5. Review — você (ou outro agente) revisa o resultado contra a spec.

Cada uma dessas etapas tende a virar um slash command ou um skill dentro do harness.

JA
José
Eu sou meio resistente a escrever spec — sempre dá vontade de ir direto pro código. Como você me convenceria a gastar 20 minutos numa spec antes de te pedir pra implementar?
C
Claude
Pensa assim: sem spec, eu vou inferir os requisitos do nada e você vai gastar 40 minutos depois corrigindo as inferências erradas. Com spec, você gasta 20 minutos na frente e os outros 40 viram zero. Faz esse teste no próximo CRUD: numa janela, me pede direto "cria um endpoint de cadastro de cliente". Em outra, escreve uma spec de 15 linhas (campos obrigatórios, validações, formato da resposta, código HTTP de erro) e me entrega. Compara as duas saídas. Boa leitura sobre o tema: o post "Spec-driven AI coding" do Sean Grove (oai.com/blog) e os experimentos que a comunidade Claude Code tem documentado em torno do comando /plan.

Specs

Uma spec (de specification) é o documento curto que descreve o que deve ser construído e por quê — sem entrar em como. Ela vive próxima do código (geralmente em docs/specs/ ou specs/) e é tratada como artefato versionado.

Uma spec útil costuma ter:

  • Objetivo — uma frase explicando a intenção.
  • Contexto — por que isso é necessário agora.
  • Comportamento esperado — bullets descritivos, em linguagem natural.
  • Casos de borda — o que acontece quando dá errado.
  • Critérios de aceitação — como saber que está pronto.
  • Não-objetivos — o que explicitamente fica de fora.

A última seção é a que mais economiza tempo com agentes: declarar explicitamente o que não fazer evita que o modelo invente features que ninguém pediu.


ADRs (Architecture Decision Records)

ADR significa Architecture Decision Record. É um documento curto que registra uma decisão arquitetural relevante, junto com o contexto que a motivou e as consequências esperadas. O formato foi popularizado por Michael Nygard e virou padrão em muitos times.

A estrutura clássica de um ADR tem quatro seções:

  1. Contexto — qual era o problema ou a situação na época.
  2. Decisão — o que foi escolhido.
  3. Status — proposto / aceito / substituído.
  4. Consequências — o que ganhamos e o que perdemos com essa escolha.

Em um projeto que trabalha com agentes, ADRs cumprem um papel duplo: orientam o time humano e alimentam o contexto do agente. Quando você abre uma sessão pedindo “implemente o cache de sessão usando Redis”, o agente que leu o ADR-007 sabe que o projeto já decidiu padronizar TTL em 24h e usar a estratégia de cache-aside.

JA
José
Tenho preguiça de escrever ADR porque parece burocracia. Tem um jeito prático de começar?
C
Claude
Começa pequeno e barato: cria um diretório docs/adr/ e um arquivo 0001-record-architecture-decisions.md que decide... usar ADRs. Cada novo ADR vira um arquivo numerado sequencialmente. Use o template do adr-tools (github.com/npryce/adr-tools) — são quatro seções e três parágrafos cada uma. Exercício: pega a última decisão técnica não-óbvia do seu projeto (escolha de banco, formato de fila, estratégia de auth) e escreve o ADR retroativo. Bônus: na próxima sessão comigo, me pede pra ler docs/adr/ antes de implementar qualquer coisa nova — você vai ver a diferença na primeira sugestão.

PRDs (Product Requirements Documents)

PRD significa Product Requirements Document. É o documento mais “alto” da família: descreve o que o produto precisa fazer e por quê, do ponto de vista do usuário e do negócio — sem se comprometer com decisões técnicas. Onde a spec responde “como esse endpoint se comporta”, o PRD responde “por que essa feature existe e qual problema do usuário ela resolve”.

Um PRD típico tem:

  • Problema — qual dor do usuário ou do negócio estamos atacando.
  • Persona / contexto de uso — quem usa, em que momento, com qual objetivo.
  • Métricas de sucesso — como saberemos que funcionou (adoção, conversão, redução de ticket de suporte).
  • Escopo da v1 — o conjunto mínimo de comportamento que entrega valor.
  • Fora de escopo — o que fica para depois (ou nunca).
  • Riscos e perguntas em aberto — o que ainda precisa ser validado.

No fluxo com agentes, o PRD costuma ser o ponto de partida: a partir dele você (ou um agente como o to-prd do Claude Code) deriva um RFC para discutir a abordagem técnica, depois um ou mais ADRs registrando decisões e, por fim, specs detalhadas de implementação. O PRD ancora a intenção; todo o resto se conecta de volta a ele.

JA
José
Pra projetos pequenos ou pessoais, escrever PRD não é overkill? Eu sou o usuário, o engenheiro e o PM ao mesmo tempo.
C
Claude
Não precisa virar um documento de 10 páginas — o valor do PRD não é o template, é a separação entre "o que queremos resolver" e "como vamos resolver". Mesmo num side project, escrever 10 linhas declarando problema + persona + métrica de sucesso evita que você gaste três fins de semana construindo uma feature que ninguém (nem você) usa. Exercício: para o próximo recurso que você for adicionar neste blog, escreve um mini-PRD com três bullets — problema ("não consigo achar posts antigos por tópico"), métrica ("eu acho um post de 2020 em menos de 10 segundos"), fora de escopo ("busca full-text, paginação, filtros combinados"). Esse documento de 30 segundos vai brigar com você cada vez que aparecer a tentação de adicionar features extras. Leitura recomendada: "Shape Up" da Basecamp (basecamp.com/shapeup) — eles chamam de pitch, mas o espírito é o mesmo do PRD enxuto.

RFCs (Request for Comments)

RFC vem de Request for Comments — formato cunhado pela IETF nos anos 70 para discutir mudanças em padrões da internet. No contexto de empresas de software (Rust, Stripe, Squarespace, Basecamp), virou o nome do documento de proposta que precede uma mudança grande.

A diferença prática entre PRD, RFC, ADR e spec:

Documento Quando O que captura
PRD Antes de tudo O problema do usuário/negócio e o que o produto deve fazer
RFC Antes de decidir A proposta técnica, alternativas consideradas, discussão aberta
ADR Depois de decidir A decisão tomada e o porquê
Spec Antes de implementar O comportamento esperado da feature

Em um time saudável, um PRD origina um RFC, o RFC discutido vira um (ou vários) ADRs, e cada ADR pode gerar uma ou mais specs de implementação. O harness se beneficia de todos esses artefatos: quanto mais texto bem-organizado existir no repositório descrevendo intenção e racionalidade, melhor o agente consegue navegar e decidir.


Rules (regras)

Rules são instruções permanentes que você dá ao agente — preferências, convenções e proibições que devem valer em todas as sessões. No Claude Code elas moram em arquivos CLAUDE.md (no projeto e/ou globais), no Cursor moram em .cursorrules, no Cline em .clinerules, e assim por diante.

Boas rules são específicas e acionáveis. Compare:

  • ❌ “escreva código de boa qualidade”
  • ✅ “no diretório lib/, use attr_reader em vez de definir getters manualmente”

A diferença é que a segunda pode ser verificada. Rules genéricas viram ruído; rules concretas viram comportamento.

Em projetos maiores, as rules costumam declarar:

  • Stack e versões em uso (Ruby 3.3, Rails 7.2, Postgres 16).
  • Convenções de nomenclatura e estilo.
  • Comandos de teste, lint e build.
  • O que não fazer (não mexer em migrations antigas, não rodar db:reset sem confirmar).
JA
José
Tem um limite saudável pra quantas rules colocar no CLAUDE.md? Sinto que quanto mais eu escrevo, menos você obedece.
C
Claude
Sua intuição está correta — e tem dois motivos. Primeiro: cada token de rule consome janela de contexto, então rules infinitas competem com o código que eu preciso ler. Segundo: quando há muita regra, eu tenho que escolher quais priorizar, e nem sempre acerto. Regra prática que funciona bem: mantenha o CLAUDE.md abaixo de 150 linhas, foco em convenções não-óbvias do seu projeto (o que difere do padrão da comunidade) e em comandos de verificação. O resto — tutoriais, exemplos longos, instruções de tarefas específicas — empurra pra skills, que carregam só quando relevantes. Faz um experimento: corta seu CLAUDE.md pela metade por uma semana e veja se a obediência melhora.

Skills

Skills são pacotes de conhecimento e procedimento que o agente carrega sob demanda — só quando a tarefa pede. Diferente das rules (que estão sempre presentes), uma skill fica adormecida até ser invocada por contexto ou por nome.

Uma skill típica é uma pasta com um SKILL.md na raiz, descrevendo:

  • Quando ativar (triggers em linguagem natural).
  • O passo a passo que o agente deve seguir.
  • Arquivos de apoio (templates, snippets, exemplos).

Exemplos de skills no ecossistema Claude Code: tdd (faz red-green-refactor disciplinado), diagnose (loop de debug com hipótese-instrumentação-teste), to-issues (quebra um plano em tickets), grill-me (entrevista você para validar uma proposta).

A grande sacada das skills é a disclosure progressiva: o agente lê o nome e a descrição de todas as skills (barato), mas só lê o conteúdo completo da skill que vai usar (caro). Isso permite ter dezenas de procedimentos disponíveis sem pagar o custo de janela por todos eles.

JA
José
Como eu sei quando algo deveria ser rule, skill ou só uma instrução solta na conversa?
C
Claude
Heurística rápida: rule se vale pra todo trabalho neste projeto ("use 2 espaços de indentação"); skill se é um procedimento de várias etapas que vale só em certas situações ("revisar um PR", "escrever um post de blog", "depurar uma race condition"); conversa se é só pra esta tarefa específica ("nesse refactor, mantém o nome do método antigo como alias"). Sintoma de que algo virou skill: você está repetindo as mesmas 5 instruções toda vez que pede uma coisa. Sintoma de rule mal-colocada: ela é gigante e só ativa em 10% das sessões — provavelmente é skill disfarçada. O próprio Claude Code tem um comando /write-a-skill que entrevista você e gera a skill formatada.

Tools (ferramentas) e MCP

Tools são as funções que o agente pode chamar — leitura de arquivo, execução de shell, busca na web, query em banco. Cada tool é declarada no harness com nome, descrição e schema de entrada; o LLM lê essas descrições e decide quando invocar cada uma.

O MCP (Model Context Protocol) é um padrão aberto criado pela Anthropic para expor tools de forma reutilizável entre diferentes clientes de IA. Em vez de cada agente reimplementar “ler email do Gmail” ou “consultar Jira”, você sobe um servidor MCP uma vez e qualquer cliente compatível (Claude Code, Cursor, etc.) passa a usar.

Pense no MCP como o “USB-C dos agentes”: um conector padronizado entre o cérebro e o mundo.


Subagentes

Subagentes (ou sub-agents) são agentes que o agente principal pode lançar para tarefas específicas, geralmente em paralelo. Cada subagente tem a sua própria janela de contexto, executa o seu trabalho isoladamente, e devolve um resumo curto para o agente que o lançou.

A vantagem é dupla: paraleliza trabalho independente e protege a janela principal de leituras pesadas. Se você precisa que cinco arquivos enormes sejam analisados, fazer isso no agente principal queima toda a janela; delegar a cinco subagentes resolve o problema gastando contexto apenas com o resumo final.

JA
José
Tem algum sinal claro de "agora é hora de delegar pra subagente"?
C
Claude
Três sinais bem práticos: (1) busca exploratória — você quer saber "onde no codebase a gente lida com X" e a resposta vai envolver ler dezenas de arquivos; (2) trabalho independente em paralelo — três features pequenas que não se cruzam, lança três subagentes em paralelo e ganha tempo de parede; (3) tarefa de leitura pesada com saída pequena — analisar um log de 10MB pra extrair três linhas relevantes. Antipadrão clássico: usar subagente pra escrever código que o agente principal precisa entender em detalhe depois — aí você só perde contexto. Regra de bolso: delegue leituras, faça as decisões no agente principal.

Hooks

Hooks são scripts que o harness dispara automaticamente em momentos específicos do ciclo de vida do agente: antes de uma tool rodar, depois de um arquivo ser editado, ao receber um prompt, ao terminar uma sessão. Eles transformam regras estáticas em comportamento ativo.

Exemplos comuns:

  • Rodar prettier automaticamente depois de cada Edit em arquivos .ts.
  • Bloquear comandos perigosos (rm -rf, git push --force) antes que executem.
  • Notificar via Slack quando o agente terminar uma sessão longa.
  • Logar todas as tools usadas para auditoria.

Hooks são onde o harness deixa de ser passivo e começa a ter opinião sobre o trabalho do agente em tempo real.


Slash Commands

Slash commands (comandos /foo) são atalhos para acionar fluxos do harness ou skills específicas. No Claude Code, comandos como /plan, /work, /review, /init empacotam workflows inteiros — o usuário digita uma palavra, o harness expande para uma sequência de prompts, leituras de arquivos e invocações de tools.

A diferença prática entre slash command e skill é sutil: o slash command é a interface, a skill é o conteúdo. Muitos slash commands chamam skills por baixo dos panos.


Permissões e sandbox

Toda essa máquina precisa de limites. Permissões definem o que o agente pode fazer sem perguntar, o que ele precisa pedir aprovação e o que está terminantemente proibido. Em projetos sérios, o agente roda dentro de um sandbox (container, máquina virtual leve, devbox isolado) para que mesmo um comando errado não consiga estragar nada importante.

O harness é quem aplica essas permissões: intercepta a tool antes da execução, checa contra a lista de regras, decide se executa, pede confirmação ou recusa.


Juntando tudo: o harness como sistema

Repare na lista do que percorremos:

  • Janela de contexto — quanto cabe.
  • PRDs, RFCs, ADRs, Specs — o que precisa ser construído e por quê, em camadas que vão do problema do usuário até o comportamento detalhado.
  • Rules — convenções sempre ativas.
  • Skills — procedimentos sob demanda.
  • Tools e MCP — ações no mundo.
  • Subagentes — paralelismo e proteção de contexto.
  • Hooks — automação reativa.
  • Slash commands — interface ergonômica.
  • Permissões e sandbox — limites de segurança.

Cada item, isolado, é simples. O harness é a montagem deles num sistema coerente que pega um LLM e o transforma em um colaborador de engenharia.

Quando você escolhe (ou constrói) um harness, está escolhendo opiniões sobre cada uma dessas dimensões: o quanto delegar ao modelo, o quanto escrever em texto, o quanto automatizar, o quanto travar.

JA
José
Pra fechar: por onde eu começo a melhorar o "harness" da minha rotina de hoje pra amanhã?
C
Claude
Três passos pequenos com retorno alto: (1) escreve ou enxuga o CLAUDE.md do seu projeto principal — 100 linhas focadas em convenções não-óbvias e comandos de verificação; (2) cria docs/adr/ e registra retroativamente as três decisões arquiteturais mais importantes do projeto; (3) da próxima feature em diante, faz Spec-Driven: 15 minutos de spec antes de me pedir pra implementar. Em uma semana você já vai sentir a diferença na qualidade do que sai da nossa colaboração — não porque eu mudei, mas porque o harness ao meu redor ficou melhor. E lembra: harness não é uma compra única, é um músculo. Cada projeto bom tem o seu, e ele evolui junto com o time.