Phase 14 - Lesson 37

Loops de Feedback em Tempo de Execução

Agentes que não veem a saída real do comando adivinham. Um executor de feedback captura stdout, stderr, código de saída e tempo em um registro estruturado que a próxima iteração pode ler. Assim, o agente reage a fatos em vez de reagir à sua própria previsão dos fatos.

Tipo: Build Idiomas: Python (stdlib) Pré-requisitos: Phase 14 · 32 (Minimal Workbench), Phase 14 · 35 (Init Script) Tempo: ~50 minutos

Objetivos de Aprendizado

  • Distinguir o feedback em tempo de execução da telemetria de observabilidade.
  • Construir um executor de feedback que envolve comandos do shell e persiste registros estruturados.
  • Truncar saídas grandes de forma determinística para que o loop permaneça dentro do limite de tokens.
  • Recusar o avanço do loop quando o feedback estiver ausente.

O Problema

O agente diz "executando testes agora." A mensagem seguinte diz "todos os testes passaram." A realidade é que nenhum teste foi executado. O agente imaginou a saída, ou executou o comando e nunca leu o resultado, ou leu o resultado e truncou silenciosamente a linha de falha.

Um executor de feedback elimina essa lacuna. Cada comando passa pelo executor. Cada registro contém o comando, o stdout e stderr capturados, o código de saída, a duração de tempo real e uma nota de uma linha do agente. O agente lê o registro na iteração seguinte. O portão de verificação lê os registros no final da tarefa.

O Conceito

flowchart LR
  Agent[Loop do Agente] --> Runner[run_with_feedback.py]
  Runner --> Shell[subprocess]
  Shell --> Capture[stdout / stderr / exit / duration]
  Capture --> Record[feedback_record.jsonl]
  Record --> Agent
  Record --> Gate[Portão de Verificação]

O que vai em um registro de feedback

Campo Por que isso importa
command Argv exato, sem surpresas de expansão do shell
stdout_tail Últimas N linhas, truncamento determinístico
stderr_tail Últimas N linhas, separado do stdout
exit_code O sinal inequívoco de sucesso
duration_ms Revela sondagens lentas e processos fora de controle
started_at Carimbo de data/hora para reprodução
agent_note Uma linha que o agente escreve sobre o que ele esperava

O truncamento é determinístico

Um log de 50 MB destrói o loop. O executor trunca o início e o fim com um marcador ...truncated N lines..., de forma determinística para que a mesma saída sempre produza o mesmo registro. Sem amostragem; as partes que o agente precisa ver (erro final, resumo final) ficam no fim (tail).

Feedback versus telemetria

A telemetria (Phase 14 · 23, convenções do OTel GenAI) é para operadores humanos que revisam execuções ao longo do tempo. O feedback é para a próxima iteração desta execução. Eles compartilham campos, mas vivem em arquivos diferentes com tempos de retenção diferentes.

Recusar avanço sem feedback

Se o executor falhar antes de capturar a saída, o registro conterá exit_code: null e error: <reason>. O loop do agente deve se recusar a declarar sucesso com um código de saída null. Sem saída, sem progresso.

Construa

code/main.py implementa:

  • run_with_feedback(command, agent_note) que envolve subprocess.run, captura stdout/stderr/exit/duration, trunca deterministicamente e anexa a feedback_record.jsonl.
  • Um pequeno carregador que transmite o JSONL para uma lista Python.
  • Uma demonstração que executa três comandos (sucesso, falha, lento) e imprime o último registro de cada comando.

Execute:

python3 code/main.py

Saída: três registros de feedback anexados a feedback_record.jsonl, o último de cada impresso em linha. Monitore o final do arquivo (tail) ao longo das reexecuções para ver o loop se acumular.

Padrões de produção no mundo real

Três padrões tornam o executor robusto o suficiente para ser implantado.

Ocultar na escrita, não na leitura. Qualquer registro que toque em stdout ou stderr pode vazar segredos. O executor realiza uma etapa de ocultação antes de anexar ao JSONL: remove linhas correspondentes a ^Bearer , password=, api[_-]?key=, AKIA[0-9A-Z]{16} (AWS), xox[baprs]- (Slack). A ocultação no momento da leitura é perigosa; o arquivo em disco é o que um invasor acessa. Realize auditorias nos padrões de ocultação trimestralmente em relação aos formatos de segredos observados no ambiente de execução de produção.

Política de rotação, não um único arquivo. Limite o feedback_record.jsonl a 1 MB por arquivo; no estouro, rotacione para .1, .2, descarte .5. O loop do agente lê apenas o arquivo atual, mantendo o custo de execução limitado. O armazenamento de artefatos de CI recebe o conjunto rotacionado completo. Sem rotação, o arquivo se torna o gargalo em cada chamada de carregamento.

ID de comando pai para cadeias de tentativa. Cada registro recebe um command_id; as tentativas carregam um parent_command_id apontando para a tentativa anterior. A lista de "tentativas fracassadas" do revisor (Phase 14 · 40) e a auditoria do portão de verificação seguem a cadeia. Sem esse vínculo, as tentativas parecem sucessos independentes e a auditoria esconde o histórico de falhas.

Use

Padrões de produção:

  • Ferramenta Bash do Claude Code. A ferramenta já captura stdout, stderr, exit e duration. O executor nesta lição é o equivalente agnóstico de framework para qualquer produto de agente.
  • Nós do LangGraph. Envolva qualquer nó de shell no executor para que o registro persista fora do estado do grafo.
  • Logs de CI. Transmita o JSONL para o armazenamento de artefatos de CI; revisores podem reproduzir qualquer comando sem reexecutar a sessão.

O executor é um invólucro fino que sobrevive a qualquer migração de framework porque ele é o dono do formato do registro.

Envie

outputs/skill-feedback-runner.md gera um run_with_feedback.py específico do projeto com o limite de truncamento adequado, um gravador JSONL conectado à bancada de trabalho (workbench) e um carregador que o agente lê a cada iteração.

Exercícios

  1. Adicione um campo cwd por registro para que o mesmo comando executado a partir de diretórios diferentes possa ser distinguido.
  2. Adicione uma etapa de ocultação que remova linhas correspondentes a ^Bearer ou password=. Teste em um registro de teste (fixture).
  3. Limite o tamanho total do feedback_record.jsonl em 1 MB rotacionando para os arquivos .1 e .2. Defenda a política de rotação.
  4. Adicione um parent_command_id para que as cadeias de tentativas sejam visíveis: qual comando produziu a entrada que o comando seguinte consumiu.
  5. Direcione o JSONL para uma pequena TUI que destaque o último código de saída diferente de zero. Liste oito recursos principais que a TUI deve mostrar para ser útil em uma revisão.

Termos-Chave

Termo O que as pessoas dizem O que realmente significa
Registro de feedback "Log de execução" Entrada estruturada em JSONL com comando, saída (stdout/stderr), código de saída, duração
Truncamento de cauda "Cortar o log" Captura determinística de início + fim para que os registros caibam no orçamento de tokens
Recusa em caso de nulo "Bloquear com dados ausentes" O loop não deve avançar quando exit_code for nulo
Nota do agente "Tag de expectativa" A previsão de uma linha que o agente escreve antes de ler o resultado
Divisão de telemetria "Dois arquivos de log" Feedback para a próxima iteração, telemetria para o operador

Leituras Adicionales

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).