RLM 2027 · Capítulo 25 de 30 · 13 min
Montar o harness que roda de madrugada com estado, checkpoint e retomada
Grave o estado de cada pergunta, retome um lote noturno interrompido do ponto exato da queda e prove por SQL que nenhuma chamada foi paga duas vezes.
Este capítulo faz parte do curso gratuito RLM 2027.
Com a pergunta a US$ 0,41 e 93 acertos em 120, a Veredas parou de rodar perguntas uma a uma durante o expediente. Helena juntou as 400 perguntas do mês, tiradas dos relatórios de condicionantes dos clientes, num lote que roda de madrugada com quatro trabalhadores em paralelo e ninguém olhando. Na primeira noite de teste, o servidor reiniciou para uma atualização no meio do lote. A pergunta da manhã foi direta: quanto disso pagamos duas vezes?
Ao fim, você monta um harness que guarda o estado de cada pergunta num banco SQLite e retoma o lote do ponto exato da queda. Depois prova, com uma consulta, que nenhuma chamada ao modelo foi cobrada duas vezes. SQLite: banco de dados inteiro num único arquivo, que já vem com o Python. Também passa a separar a carga da noite da avaliação que decide se o sistema melhorou.
Harness é o programa que cerca o modelo e o põe para trabalhar, como o arreio que liga o cavalo à carroça. Ele reúne o laço que chama o modelo, as ferramentas, o estado gravado e as regras de parada. Com alguém olhando, o harness pode ser frouxo, porque a pessoa nota a resposta estranha e roda de novo. De madrugada, cada decisão dessa pessoa precisa estar escrita: o que fazer quando o provedor recusa, quando o processo morre, quando a mesma pergunta chega duas vezes.
O horizonte de tarefa medido pelo METR
cerca de 50 min
Horizonte de 50% do Claude 3.7 Sonnet
Duração de tarefa humana que o modelo completa com 50% de sucesso
cerca de 7 meses
Tempo para o horizonte dobrar desde 2019
Tarefas de software; a tendência pode ter acelerado em 2024
89 dias
Dobra desde 2024 na Time Horizon 1.1
Suíte refeita com 228 tarefas, janeiro de 2026
17 h
Claude Mythos Preview, versão inicial
A página avisa que medidas acima de 16 h não são confiáveis
Fonte: METR, arXiv 2503.14499 (v4, julho de 2026); Time Horizon 1.1 (janeiro de 2026); página de horizontes, atualizada até setembro de 2026
O METR define horizonte de tarefa como a duração, medida pelo tempo de um especialista humano, das tarefas que o modelo completa com 50% de sucesso. A página viva do instituto mostra 17 horas para o Claude Mythos Preview e avisa que medidas acima de 16 horas não são confiáveis com a suíte atual. A página deixou de ser atualizada em setembro de 2026, e o FAQ dela corrige a leitura comum: o número mede a dificuldade da tarefa, e não por quanto tempo o agente trabalha sozinho.
Para a Veredas, isso muda o lugar do risco. Cada pergunta dura cerca de dois minutos e faz, na execução comum da trilha de custo, cerca de 25 chamadas: 7 turnos do raiz e 18 subchamadas. O que dura a noite inteira é a operação: 400 tarefas, perto de 10 mil chamadas, quatro processos e um provedor que às vezes recusa. Quem falha de madrugada costuma ser o harness, e é nele que este capítulo mexe.
A Anthropic chegou à mesma conclusão por outro caminho. Em dezembro de 2024, o texto Building effective agents separava workflows, em que o código define o caminho, de agentes, em que o modelo dirige o próprio processo. E recomendava padrões simples e componíveis. O lote da Veredas junta os dois: um workflow fixo (pegar a próxima pergunta, rodar, gravar) com um agente recursivo dentro de cada passo.
Em novembro de 2025, a empresa descreveu o desafio central dos agentes de longa duração: cada sessão nova começa sem memória da anterior. A resposta foi separar um agente inicializador, que prepara o ambiente uma vez, de um agente de código que avança uma funcionalidade por sessão. O inicializador escreve uma lista de mais de 200 funcionalidades em JSON, cada uma com um campo de aprovação. Cria também um arquivo de progresso e o primeiro commit (versão registrada no git, como salvar o jogo com nome).
Onde cada harness guarda o que a próxima sessão precisa saber
| Harness ou ferramenta | Onde fica o estado | O que isso vira na Veredas |
|---|---|---|
| Anthropic, agentes de longa duração (nov/2025) | Lista de funcionalidades em JSON, arquivo de progresso e commits | Tabela de tarefas com estado e resposta |
| Anthropic, compilador C com 16 agentes (fev/2026) | Repositório git comum e um arquivo de bloqueio por tarefa em current_tasks/ | Reserva da tarefa com dono e prazo |
| Anthropic, Managed Agents (abr/2026) | Sessão como log que só cresce, separada do harness e do sandbox | Tabela de chamadas, que só recebe linhas novas |
| Hermes Agent 0.21.6, Nous Research (out/2026) | Skills, memória curada e agenda cron | O agendamento noturno do lote |
| Temporal | Histórico de eventos de cada execução | Chamadas já pagas reaproveitadas na retomada |
| LangGraph | Checkpointers por thread e stores de longo prazo | Checkpoint por pergunta; memória fora do lote |
Fonte: Anthropic Engineering (nov/2025 a abr/2026); repositório NousResearch/hermes-agent; documentação do Temporal e do LangGraph
Dois defeitos motivaram aquele desenho: o agente tentava fazer tudo de uma vez e ficava sem contexto no meio, ou via trabalho feito e declarava o projeto pronto antes da hora. A lista fechada impede o segundo; o commit com mensagem descritiva e o arquivo de progresso dizem à sessão seguinte onde está. No lote da Veredas, a lista são as 400 tarefas, o progresso é a tabela de estados e o commit é o checkpoint de cada pergunta.
Os textos de engenharia da Anthropic em 2026 levaram o desenho a dias de trabalho. No compilador C de fevereiro, 16 agentes rodavam em contêineres, cada um num laço sem fim sobre um repositório git comum. Foram quase 2.000 sessões e US$ 20.000 de API para um compilador de 100 mil linhas, números da própria empresa. O autor recomenda rodar o laço num contêiner, nunca na máquina de trabalho. E relata um agente que encerrou o próprio laço com pkill -9 bash (comando que mata processos pelo nome).
Do mesmo texto vem a frase que vale para qualquer lote noturno: o verificador da tarefa precisa ser quase perfeito, senão o agente resolve o problema errado. O harness de março separou quem avalia de quem produz, porque o agente que julga o próprio trabalho tende a elogiá-lo com confiança.
Como o harness de longa duração ganhou forma, de 2024 a 2026
- 12/2024Concluído
Anthropic, Building effective agents
Workflow com caminho no código; agente que dirige o próprio processo.
- 11/2025Concluído
Anthropic, harness para agentes de longa duração
Inicializador, lista de funcionalidades, arquivo de progresso e commits.
- 02/2026Concluído
Compilador C com 16 agentes em paralelo
Quase 2.000 sessões e US$ 20.000, números da própria Anthropic.
- 03/2026Concluído
Planejador, gerador e avaliador separados
Quem avalia deixa de ser quem produz.
- 04/2026Concluído
Managed Agents
Sessão em log, harness e sandbox trocáveis um sem o outro.
- 10/2026Agora
Hermes Agent 0.21.6
Skills, memória curada e cron para rodar sem supervisão.
Fora da Anthropic, o Hermes Agent, da Nous Research, mostra a peça que faltava: o relógio. A versão 0.21.6, de 8 de outubro de 2026, traz skills (procedimentos em arquivo que o agente cria e reaproveita) e memória curada pelo próprio agente. Traz ainda um cron embutido: agenda de tarefas repetidas, como um despertador de dias úteis. A descrição de agente que se aprimora é do próprio projeto. O cron põe o agente para rodar de madrugada; o resto deste capítulo é o que precisa existir em volta dele.
Execução durável é a garantia de que um programa longo sobrevive a quedas: o progresso fica gravado e, depois de um reinício, ele continua do ponto em que estava, como um jogo salvo a cada fase. O Temporal faz isso com um histórico de eventos por execução; ao reiniciar, refaz o caminho lendo o histórico, sem repetir as atividades que já terminaram. O LangGraph oferece checkpointers, que gravam o estado do grafo a cada passo de uma thread, isto é, de uma execução com estado próprio.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
A documentação do LangGraph aponta duas armadilhas que valem para qualquer harness. O MemorySaver, que guarda o estado só na memória do processo, não sobrevive a um reinício, justamente o evento que o checkpoint deveria cobrir. E os checkpoints crescem sem limite se ninguém os poda. Na Veredas, o estado vai para um arquivo em disco, e cada lote fechado é arquivado com data e apagado da base ativa depois de 90 dias.
Cada tarefa do lote está sempre em um estado, e só algumas passagens valem. Pendente vai a rodando quando um trabalhador a reserva. Rodando grava checkpoint a cada chamada paga e termina em concluído ou cai em falhou. Falhou volta como retomado, que lê o último checkpoint e devolve a tarefa a rodando sem repetir o que já foi pago. Depois de três tentativas, a tarefa fica em falhou e espera uma pessoa. No código, retomado é a volta de rodando para pendente, na partida da vaga ou quando a reserva vence.
Idempotência é a propriedade de uma operação que, repetida, não muda o resultado, como apertar duas vezes o botão do elevador. Ela importa porque a fila entrega cada tarefa pelo menos uma vez, e não exatamente uma vez. A chave de idempotência da Veredas é lote:pergunta:versão, por exemplo 2026-11:215:v3: a mesma pergunta, no mesmo lote e na mesma versão do programa, tem uma resposta gravada e uma cobrança por chamada.
A reentrega nasce do jeito como a fila se protege de trabalhador morto. Ao pegar uma tarefa, o trabalhador grava o próprio nome e um prazo de dez minutos, uma reserva com validade, como a mesa guardada até certa hora. Se o prazo vence sem a tarefa terminar, outro trabalhador pode pegá-la. Isso cobre a queda e cria a duplicação: um trabalhador lento, mas vivo, e outro que pegou a mesma tarefa depois do prazo. Sem idempotência, a pergunta sai paga e respondida duas vezes.
Veredas: o que a queda na pergunta 215 custa em cada desenho
Recomeçar o lote do zero
Coluna a evitar
- As 214 perguntas prontas rodam de novo
- 5.360 chamadas pagas em dobro, US$ 87,90
- Respostas antigas sobrescritas sem registro
- Nenhuma prova do que mudou entre as rodadas
Retomar do checkpoint
Coluna recomendada
- As 214 prontas são puladas pelo estado
- As 10 chamadas já feitas da 215 vêm da tabela
- 0 chamada paga em dobro; 10.000 no total
- Cada resposta ligada a uma chave e a uma versão
O checkpoint por pergunta resolve as 214 perguntas prontas; falta a que estava no meio. A Veredas guarda também cada chamada ao modelo, com a chave da pergunta e um número de sequência. Na retomada, o harness refaz a pergunta 215 do começo, mas as chamadas já pagas saem da tabela, como no histórico do Temporal. O raiz recebe as mesmas respostas, escreve o mesmo código e o REPL chega ao mesmo ponto sem custo. Isso vale enquanto o código gerado não sortear valores nem ler o relógio, um arquivo ou um serviço que mude entre as execuções.
O lote noturno é carga operacional: perguntas reais, sem gabarito, cobradas no orçamento do mês. As 120 perguntas de Helena são avaliação: têm resposta de referência e decidem se uma mudança entra. Resposta da noite não vira nota, porque ninguém a conferiu; pergunta de avaliação não entra no lote, porque a memória do agente a veria e o conjunto retido deixaria de ser retido. A avaliação roda em outro banco, com chave de API própria, a US$ 49,20 por rodada (120 × 0,41), só quando algo muda.
Simular a noite da Veredas: queda na pergunta 215 e retomada
Python 3.8 ou mais novo, sem instalar nada. O provedor é simulado: cada chamada custa US$ 0,0164, e 25 chamadas dão os US$ 0,41 da pergunta média.
Passo 1: Criar o banco com as três tabelas
Tarefa guarda o estado; chamada é o checkpoint fino; fatura imita o registro do gateway, sem chave única.
Deu certo quando: O arquivo lote-veredas.db aparece na pasta e as três tabelas existem.
Erro comum: Deixar o Python abrir transações implícitas e esquecer o commit; aqui cada instrução grava na hora.
Passo 2: Enfileirar as 400 perguntas com a chave de idempotência
Deu certo quando: Rodar a carga duas vezes deixa 400 linhas na tabela de tarefas, e não 800.
Erro comum: Usar INSERT comum: a segunda carga falha ou, sem chave primária, duplica a fila.
Passo 3: Rodar python lote.py --cair, com a queda simulada na pergunta 215
Deu certo quando: O programa para com a mensagem da queda; 214 tarefas concluídas e 1 rodando.
Erro comum: Simular a queda com try/except dentro do laço, o que esconde a queda em vez de reproduzi-la.
Passo 4: Rodar python lote.py de novo, sem a queda
Deu certo quando: O lote recomeça pela 215 e termina com 400 tarefas concluídas.
Erro comum: Reiniciar com outro nome de vaga: a tarefa só volta à fila quando o prazo de dez minutos vence.
Passo 5: Conferir pela fatura, e não pela tabela de chamadas
Deu certo quando: A consulta de duplicadas volta vazia; a fatura soma 10.000 chamadas e US$ 164,00.
Erro comum: Provar pela tabela de chamadas: a chave primária já impede repetição ali, e a prova fica circular.
No fim você tem: Um lote que pode cair e voltar sem pagar de novo nenhuma chamada já gravada, com a prova em quatro consultas.
import os, sqlite3, sys, time
TRABALHADOR = os.environ.get("TRABALHADOR", "noite-1") # um nome fixo por vaga, de noite-1 a noite-4
PRECO = 0.0164 # US$ por chamada simulada: 25 chamadas x 0,0164 = US$ 0,41
db = sqlite3.connect("lote-veredas.db", isolation_level=None) # cada instrução grava na hora
db.executescript("""
CREATE TABLE IF NOT EXISTS tarefa (
chave TEXT PRIMARY KEY, -- lote:pergunta:versão
pergunta_id INTEGER NOT NULL,
estado TEXT NOT NULL DEFAULT 'pendente', -- pendente, rodando, concluída, falhou
dono TEXT, prazo REAL, -- quem reservou e até quando
tentativas INTEGER NOT NULL DEFAULT 0, resposta TEXT);
CREATE TABLE IF NOT EXISTS chamada ( -- checkpoint fino: cada chamada já paga
chave TEXT, seq INTEGER, saida TEXT, PRIMARY KEY (chave, seq));
CREATE TABLE IF NOT EXISTS fatura ( -- imita o registro do gateway: sem chave única
chave TEXT, seq INTEGER, custo_usd REAL);
""")
def provedor(chave, seq, prompt): # no harness real, a chamada ao modelo
db.execute("INSERT INTO fatura VALUES (?, ?, ?)", (chave, seq, PRECO))
return f"saída {seq} de {chave}"
def chamar(chave, seq, prompt):
feita = db.execute("SELECT saida FROM chamada WHERE chave = ? AND seq = ?",
(chave, seq)).fetchone()
if feita: # paga antes da queda: reaproveita
return feita[0]
saida = provedor(chave, seq, prompt)
db.execute("INSERT OR IGNORE INTO chamada VALUES (?, ?, ?)", (chave, seq, saida))
return saidaO laço do lote faz três coisas em torno de cada pergunta. Na partida, devolve à fila o que esta vaga deixou rodando; antes de cada reserva, devolve as vencidas ou marca falhou após três tentativas. Depois reserva a próxima pendente com uma única instrução de UPDATE, que só vale se a tarefa ainda estiver pendente; se outro trabalhador chegou antes, a contagem de linhas vem zero e ele segue. Ao terminar as 25 chamadas, grava a resposta e o estado concluído, só se a reserva ainda for sua.
def devolver(condicao, valor): # retomada: rodando volta à fila
db.execute(f"""UPDATE tarefa SET estado = CASE WHEN tentativas >= 3
THEN 'falhou' ELSE 'pendente' END
WHERE estado = 'rodando' AND {condicao}""", (valor,))
def rodar_lote(cair_em=None):
devolver("dono = ?", TRABALHADOR) # o que esta vaga deixou rodando
while True:
devolver("prazo < ?", time.time()) # reservas vencidas de qualquer vaga
t = db.execute("""SELECT chave, pergunta_id FROM tarefa
WHERE estado = 'pendente' ORDER BY pergunta_id""").fetchone()
if not t:
break
chave, pid = t
if not db.execute("""UPDATE tarefa SET estado = 'rodando', dono = ?, prazo = ?,
tentativas = tentativas + 1
WHERE chave = ? AND estado = 'pendente'""",
(TRABALHADOR, time.time() + 600, chave)).rowcount:
continue # outro trabalhador pegou antes
for seq in range(1, 26): # 7 turnos do raiz + 18 subchamadas
if pid == cair_em and seq == 11:
sys.exit(f"queda simulada na pergunta {pid}, chamada {seq}")
saida = chamar(chave, seq, f"pergunta {pid}")
db.execute("""UPDATE tarefa SET estado = 'concluída', resposta = ?
WHERE chave = ? AND dono = ?""",
(saida, chave, TRABALHADOR)) # checkpoint, só se a reserva é sua
db.executemany("INSERT OR IGNORE INTO tarefa (chave, pergunta_id) VALUES (?, ?)",
[(f"2026-11:{p}:v3", p) for p in range(1, 401)])
rodar_lote(cair_em=215 if "--cair" in sys.argv else None) # python lote.py --cair; depois semA prova vem da tabela que o harness não controla. No sistema real, a fatura é o registro do gateway ou o extrato de uso do provedor, e não tem chave única: se uma chamada fosse paga duas vezes, apareceria duas vezes ali. As quatro consultas abaixo rodam no mesmo arquivo, depois das duas execuções, e cada comentário mostra o que voltou na simulação.
-- 1. Chamadas pagas mais de uma vez (precisa voltar vazio)
SELECT chave, seq, COUNT(*) AS vezes
FROM fatura GROUP BY chave, seq HAVING COUNT(*) > 1; -- nenhuma linha
-- 2. Estado final do lote
SELECT estado, COUNT(*) FROM tarefa GROUP BY estado; -- concluída | 400
-- 3. O que a noite custou
SELECT COUNT(*) AS chamadas, ROUND(SUM(custo_usd), 2) AS usd
FROM fatura; -- 10000 | 164.0
-- 4. A pergunta que caiu: duas tentativas, uma cobrança por chamada
SELECT t.tentativas, COUNT(f.seq) AS cobradas
FROM tarefa t JOIN fatura f ON f.chave = t.chave
WHERE t.pergunta_id = 215; -- 2 | 25Veredas: a noite simulada com queda na pergunta 215
400 de 400
Tarefas concluídas
Retomada a partir da pergunta 215
0
Chamadas pagas em dobro
Consulta 1 volta sem nenhuma linha
US$ 164,00
Fatura da noite
10.000 chamadas, igual a 400 × 0,41
US$ 87,90
O que recomeçar do zero custaria a mais
214 × 25 + 10 = 5.360 chamadas × 0,0164
Fonte: Veredas Ambiental, cenário ilustrativo; simulação com provedor de custo fixo por chamada
A prova tem limites que entram no runbook, o roteiro escrito do que fazer em cada situação de operação. Entre a resposta do provedor e a gravação na tabela existe uma janela: se o processo morre exatamente ali, uma chamada fica paga e sem registro, no máximo uma por trabalhador. Com quatro trabalhadores, até quatro tarefas ficam em rodando na queda.
Há uma segunda janela. Um trabalhador lento e outro que pegou a mesma tarefa depois do prazo podem pagar a mesma chamada ao mesmo tempo; o prazo de reserva precisa passar da pergunta mais longa. A conferência diária compara a tabela de chamadas com o extrato do provedor e mostra essa diferença, em vez de escondê-la.
O curso Agentes de IA autônomos mostra o mesmo checkpoint em LangGraph e no Claude Agent SDK, com memória e monitoramento. Rode o lote de 400 com a queda na pergunta 215 e depois sem ela, e compare as duas faturas. Está pronto quando a consulta de duplicadas volta vazia, as duas faturas somam 10.000 chamadas e US$ 164,00 e a pergunta 215 mostra duas tentativas e 25 cobranças. Com o lote retomando sozinho, o passo seguinte é decidir quem pode pará-lo e quanto ele pode gastar.
Seu caderno neste capítulo
Abrir o caderno completoSelecione um trecho do capítulo para destacar ou anotar. Nos vídeos e áudios, use Anotar este momento. No teclado, selecione com Shift e as setas e use Alt+Shift+D para destacar ou Alt+Shift+N para anotar.
Salvo neste navegador. Entre na sua conta para levar o caderno a outros aparelhos.
Entre na sua conta para compartilhar o que aprendeu e convidar alguém para estudar com você.
Conexões deste capítulo
Veja o que estudar antes e para onde seguir depois, explore os conceitos e compare abordagens em outros cursos. Sugestões marcadas como “sugerido pelo grafo” vêm dos assuntos em comum, não do índice do curso.
Estude antes
- Primeiro Workflow no n8nsugerido pelo grafoApresenta o conceito “Workflow”, usado em “Montar o harness que roda de madrugada com estado, checkpoint e retomada”.
- CursoVídeo com IA: Claude Code, Codex e ElevenLabssugerido pelo grafo4 capítulos de “RLM 2027” usam conceitos apresentados em “Vídeo com IA: Claude Code, Codex e ElevenLabs”.
- CursoSkills de IA com Vibecoding e Terminalsugerido pelo grafo2 capítulos de “RLM 2027” usam conceitos apresentados em “Skills de IA com Vibecoding e Terminal”.
- CursoSetup Completo: do zero ao Claude Codesugerido pelo grafo3 capítulos de “RLM 2027” usam conceitos apresentados em “Setup Completo: do zero ao Claude Code”.
Conceitos deste capítulo
O mesmo assunto em outros cursos
- Prompt Engineering para ExecutivosManter um agente de horas no rumo sem estourar a janelaExaminar conexões de Manter um agente de horas no rumo sem estourar a janela
- Agentes de código para executivosReconhecer reward hacking pelos casos documentados de 2024 a 2026Examinar conexões de Reconhecer reward hacking pelos casos documentados de 2024 a 2026
- Frontends com VibecodingConstruir as cenas do orquestrador, do paralelismo e do robôExaminar conexões de Construir as cenas do orquestrador, do paralelismo e do robô
- Do Agile ao Agentic Operating ModelGastar modelo caro só onde ele paga e isolar agentes paralelosExaminar conexões de Gastar modelo caro só onde ele paga e isolar agentes paralelos
Voltar ao capítulo anterior: Decidir quando treinar pesos e quando a memória basta
Leve uma ideia para a prática
Escolha uma atividade no painel e volte a este curso quando quiser.
Atividades e evolução ficam reunidas no painel da sua conta.
Capítulos vizinhos em RLM 2027
- 23Distribuir o crédito numa árvore de chamadas: resultado, processo ou verificador
- 24Decidir quando treinar pesos e quando a memória basta
- 25Montar o harness que roda de madrugada com estado, checkpoint e retomada
- 26Governar o agente contínuo com portões, orçamento, interruptor e relatório de plantão
- 27Ler 2027 por sinais observáveis em vez de apostar numa previsão