Pular para conteúdo

Trabalho com agentes de IA — disciplina

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-25

Aplica-se a: todo repo em que um agente de IA trabalha.

O contexto de um agente de IA é recurso escasso e caro. Duas frentes cortam custo sem perder exatidão:

  • Input (o que entra no contexto) — corte a saída de comando na fonte (abaixo). O rtk é recomendado, opt-in de máquina (Ferramentas).
  • Output (o que o agente escreve) — estilo terso + carve-out verbatim.

Higiene de saída de comando

Saída de comando tem dois públicos: o terminal humano (progresso, spinner) e o agente (resultado e o que falhou). Corte o verboso antes de ele entrar no contexto:

  1. Test runner com reporter frugal, sempre: verde ≈ uma linha; vermelho = só as falhas.
  2. Ferramentas nativas de arquivo (ler, buscar, glob) em vez de cat/grep/find no shell.
  3. Flags de reporter na fonte (--quiet, --console=plain, -r failures-only) e git diff --stat antes do diff cheio. Com o rtk, comando bare: pipe fura o hook.
  4. UI de terminal não é saída de agente: nunca traga o progresso quando só precisa do resultado.
  5. Proxy de compressão é complemento, não substituto: ganha em saída volumosa e pode não cobrir a stack; se promete hook transparente, confira que está instalado.
Stack Comando frugal
Flutter flutter test -r failures-only · flutter analyze
Dart dart test -r failures-only
Java/Micronaut (Gradle) ./gradlew test --quiet --console=plain
Node npm test --silent
Docs (MkDocs) mkdocs build --strict -q
git git diff --stat antes do diff cheio; git log --oneline -n

Estilo terso (output)

Corte artigo, filler, gentileza, hedging. Fragmentos servem; termo técnico exato. Padrão: [coisa] [ação] [razão]. [próximo passo]. É regra de estilo — vale com ou sem ferramenta.

"Claro! Fico feliz em ajudar. O problema que você enfrenta provavelmente é…"

vira

"Bug no auth. Expiry usa <, devia <=. Fix:"

Intensidade: full (padrão), lite quando a revisão pede fluidez; ultra abrevia demais para revisão de spec e plano.

Status e fechamento — nomeie só o que falhou

  • Gate verde não se narra linha a linha: uma linha (gates ✓ (strict, frontmatter, nav, manifesto)); o que falhou vem com a saída.
  • Não re-descreva o que o diff ou o tool já mostram — diga a decisão e a pendência.
  • Não ecoe a escolha do usuário depois de uma pergunta — aja.
  • Sem preâmbulo de tool call.
  • A linha de feedback é literal: Feedback: nada a reportar, ou Feedback: candidato — <o quê> e a pendência em uma linha.

Verbatim obrigatório — o carve-out da casa

Terso corta prosa, nunca os deliverables que o fluxo precisa exatos:

  • conteúdo de documentação — o que vai para docs/ e o site sai em prosa normal, em português (constituição); terso é o chat;
  • código, nomes de API e CLI, tipos de commit, strings de erro;
  • a mensagem de commit pronta e a linha de feedback;
  • tabelas que carregam dado;
  • specs e planos .ia/, que outra skill lê.

O estilo entra por um hook SessionStart que injeta a regra — receita em Ferramentas. Pontual: caveman mode / normal mode.

Loop de verificação — servidor local pega porta efêmera

Servidor que sobe para conferir (debug, e2e local, preview de docs) não fixa porta: pede porta efêmera e lê a URL que o processo imprime. Porta chutada colide com processo vivo ou zumbi — ou o bind falha, ou responde outro servidor e você confere um build velho. Porta fixa inevitável: mate por porta antes de subir e confirme por curl o que está servido. Mecânica por stack em Java/Micronaut e Flutter.

No Windows, Hyper-V, WSL e Docker Desktop reservam faixas de porta TCP — bind numa delas falha mesmo sem nada ouvindo, e as faixas mudam a cada boot. Porta efêmera nunca cai numa reservada; para escolher uma fixa, consulte netsh interface ipv4 show excludedportrange protocol=tcp e fique fora.

Sonde toolchain com comando bare, um por chamada (java -version, python --version): o allow-list é por ferramenta, e comando composto (pipe, ;, ||, 2>&1) não casa regra nenhuma.

No Windows, o bash que um script chama do PowerShell é o stub do WSL: sem distro instalada, o subprocesso falha com execvpe(/bin/bash) failed e o script reporta falso vermelho. Script que roda bash por dentro (o testa-guardas-pipeline.py executa o decide assim) vai pelo Git Bash.

Tarefa longa em background — terminou é o marcador, não o pipe

O fim do stdout só chega quando morre o último processo que herdou o handle: um filho que ficou de pé (app que a suíte não derrubou, daemon Gradle órfão) segura o pipe aberto depois de o script sair.

  • Tarefa longa em background vai com saída redirecionada para arquivo, e o acompanhamento lê o arquivo.
  • "Terminou" é o marcador de fim da própria tarefa — um arquivo que o script grava por último (o FIM.txt da rodada no e2e-local) ou a linha final do log; nunca "o processo sumiu" ou "o pipe fechou".
  • Notificação que não chegou não prova tarefa viva. Marcador presente = acabou; log parado sem marcador = investigue.
  • O marcador é daquela execução — pasta por rodada, ou um id de run dentro dele.
  • Subagente roda gate longo em primeiro plano, com timeout explícito; passando disso, redireciona para arquivo e espera o marcador de fim no mesmo turno. Nunca encerra o turno esperando notificação: ela não chega a um subagente que já terminou.

Edição em lote por script — escreva BYTES, confira o numstat

Script que reescreve arquivo versionado lê e escreve bytes (read_bytes/write_bytes, ou open(..., newline="")). O que traduz no caminho corrompe o arquivo: write_text e open(..., "w") trocam o fim de linha pelo da plataforma, e no PowerShell 5.1 Set-Content/Out-File -Encoding utf8 gravam BOM — o javac quebra com illegal character ''. No PowerShell, escreva pela ferramenta Write do agente ou por [IO.File]::WriteAllText($p, $s, [Text.UTF8Encoding]::new($false)).

  • O git desliga a normalização de EOL no arquivo que tem um CR solitário (CR sem LF); nesse arquivo o flip vira diff do arquivo inteiro — o review afoga e o git blame do trecho morre.
  • O CR solitário costuma vir do próprio agente: a sequência \r escrita dentro de heredoc, sed ou replacement de regex vira o byte CR. Monte a barra em runtime (chr(92)) e confira os bytes em Python depois de escrever — grep -c num pipe não prova nada.
  • Antes de fechar: git diff --numstat. O número de linhas tem de ser plausível para a mudança feita. CRLF que quebra build é a outra face da classe, com cura própria no .gitattributes (constituição).

Auto-análise de uso (fechamento)

No fechamento de cada ciclo (/x-documentar):

  1. Medir — rtk gain, rtk discover (comando não coberto), rtk cc-economics; o lado output é qualitativo (fui terso? o carve-out ficou intacto?).
  2. Auto-corrigir — comando bare, ferramentas nativas de arquivo, output terso.
  3. Rotear o gap sistêmico — receita de stack que economiza vira linha de feedback para o central; comando verboso sem handler se envolve com rtk err/rtk summary, e só o que o invólucro não cobre vira issue no tracker do rtk.