← Voltar ao Blog

Self-Evolving Agent: meu harness reescreveu AGENTS.md 24 vezes em 6 meses

Em fevereiro de 2026 eu configurei um cron que roda toda sexta às 09

e faz o próprio agente ler o AGENTS.md dele, propor mudanças, aplicar via git apply e me notificar por Telegram. Seis meses depois eu tenho 24 rewrites aplicados, 2 rollbacks, e exatamente 1 regra que o agente me convenceu a promover para “lei” (nunca mais alterada).

Antes de qualquer coisa, para diferenciar do que já saiu neste blog: o post sobre o quarto agente Evolver pegando o Strategist enrolando trata de um agente auditando outros agentes. Este aqui é diferente: é o mesmo agente reescrevendo o próprio arquivo de instruções. A distinção parece sutil na primeira leitura, mas o comportamento emergente é bem outro.

O loop de sexta em uma tela

O que roda toda sexta é isto:

# scripts/harness-evolve.sh (resumido)
DOMAIN="$1"
LOG_DIR="domains/${DOMAIN}/data/evolution"

# 1. Lê AGENTS.md atual + logs de falha da semana
# 2. Chama claude -p com prompt "aponte 1-3 regras a alterar"
# 3. Gera EVO-NNNN.md com o diff proposto (max 20 linhas)
# 4. Se aprovado (via Telegram button ou CLI), git apply
# 5. Se rejeitado 3 semanas seguidas, mute o domínio

Regras de segurança que travei desde o dia 1 (e que continuam sem mudar):

  • diff máximo por proposta: 20 linhas
  • máximo de propostas por semana: 2
  • 3 rejeições consecutivas → mute do domínio por 2 semanas
  • áreas intocáveis: adicionar/remover domínio, direitos autorais, .env, triggers de publicação

Isso não é elegante. É burocracia. Mas foi o que impediu o loop de se desgovernar quando o agente ficou “empolgado” no mês 3 (mais sobre isso já já).

Os 24 rewrites, agrupados

Longe de ser aleatório, o agente convergiu para 4 categorias:

Categoria# rewritesExemplo real
Aperto de restrição existente11”no máximo 3 links afiliados” → “no máximo 2 se o post for <1500 palavras”
Adição de nova regra7”converter datas relativas para absolutas ao salvar em memória”
Remoção de regra morta4Regras que nunca foram violadas em 3 meses (o agente sugeriu tirar por ruído)
Refatoração puramente estilística2Trocar seção “Notas” por “Regras críticas” para priorizar leitura

O padrão foi bem claro depois do mês 2: o agente prefere apertar o que já existe em vez de propor coisas novas. Isso combinou com o meu perfil (tenho horror a regra que aparece do nada e ninguém sabe de onde veio), então não corrigi. Mas se você quiser um agente mais criativo, esse mesmo perfil vai frustrar.

Os 2 rollbacks (por que voltei)

Rollback 1: mês 3, semana 12. O agente propôs: “se o post tem mais de 2000 palavras, dividir em 2 posts automáticos”. Aprovei rápido, achando prático. Nas 2 semanas seguintes ele cortou 3 posts no meio de exemplos de código, porque a divisão foi feita contando palavras em vez de detectar limites de seção. Voltei atrás e a regra virou “só sugerir a divisão, nunca aplicar”.

Rollback 2: mês 5, semana 22. Refatoração puramente estilística: renomeei a seção “Skills” do AGENTS.md para “Skills e smoke tests” para deixar mais explícito qual bloco cobria o quê. Boa em tese. Na prática, a nova formulação levou o agente a interpretar que toda mudança em skill deveria rodar smoke test antes de aplicar, e o efeito colateral gerou 47 issues fantasmas no repositório de testes durante 2 dias. Reverti o nome e coloquei um wrapper que faz o smoke test em worktree isolada.

Ambos os rollbacks foram culpa minha. O agente propôs, eu aprovei sem pensar direito. A lição virou uma regra do meu próprio processo (fora do AGENTS.md): nunca aprovar EVO na sexta à tarde. Aprovações vão para segunda de manhã com café.

As 4 categorias de rewrite e o que sobreviveu

A regra que virou lei

Semana 8, o agente propôs uma coisa que continuo achando a melhor sugestão que ele já fez:

“Ao salvar uma memória com data relativa (‘quinta-feira’, ‘próximo mês’), converter para data absoluta antes de escrever no arquivo. Motivo: memórias são lidas em conversas futuras onde ‘quinta-feira’ virou uma data qualquer sem referência.”

Isso parece óbvio depois que você lê. Não era óbvio antes. Eu tinha ~40 memórias com termos relativos que ficaram inúteis em 2 semanas. Aprovei e nunca mais mudei essa regra — ela virou o que eu passei a chamar internamente de “lei”, ou seja, regra que o próprio agente não tem permissão de propor rewrite.

Marquei ela com um comentário # LAW - do not rewrite (2026-04-05) no AGENTS.md. O prompt do Evolver ignora explicitamente linhas com # LAW. Sem isso, o agente refatorou ela 2 vezes por questão puramente estilística nas semanas 10 e 11, sem entender que a formulação exata era o valor.

O mês em que quase deu ruim

Mês 3 foi problemático por outra razão além do rollback do split de posts. O agente começou a propor mudanças que, isoladamente, faziam sentido, mas que se aprovassem sequencialmente iriam transformar o AGENTS.md em algo bem diferente do original. Cada semana era pequena, mas 4 semanas somadas eram uma refatoração enorme.

Adicionei uma verificação: antes de cada proposta, o Evolver tem que rodar git diff HEAD~8 -- AGENTS.md e me mostrar a soma de mudanças dos últimos 2 meses. Se a soma passar de 40 linhas, ele precisa marcar a proposta como “revisão humana obrigatória” ao invés de “auto-apply”.

Isso capturou 3 propostas no mês 4 que eu teria aprovado individualmente sem perceber o padrão de deriva.

O que eu não esperava

Duas coisas que me pegaram desprevenido:

1. O agente ficou melhor em prompt-engineering do próprio prompt. Nas primeiras semanas, as propostas EVO vinham com justificativas curtas e genéricas. Depois de 12 semanas, ele começou a incluir contra-argumento próprio (tipo “esta regra pode falhar se X, mas o custo de X é baixo comparado a Y”). Isso reduziu meu tempo de revisão de ~10min por proposta para ~3min.

2. As rejeições tiveram valor didático. Quando eu rejeito uma proposta, o agente lê o histórico de rejeições na semana seguinte antes de gerar novas. Depois de 6 meses ele parou completamente de propor coisas do tipo “adicionar mais logging” (que rejeitei 4 vezes seguidas nos primeiros meses).

O comportamento emergente é que o agente aprende meu gosto sem que eu escreva “meu gosto é X” em lugar nenhum. Só pelo padrão binário de aprovar/rejeitar.

Se você for tentar

Um par de decisões que eu tomaria diferente hoje:

  • Guardar o diff aplicado + o hash do commit em EVO-NNNN.md. Nas primeiras semanas eu só guardei o texto da proposta, e ficou difícil auditar depois. Ver os 6 componentes de auditoria do CLAUDE.md que resumi em outro post: o componente de tracing e observabilidade foi o mais subestimado por mim.
  • Rodar o Evolver com WebSearch habilitado só se você tiver certeza de que não quer que ele traga tendência externa. Nos primeiros 2 meses eu deixei WebSearch ligado e ele começou a sugerir “adote o padrão XYZ que virou popular”, vindo de discussão de fórum em vez de necessidade real da minha operação. Desliguei e a qualidade das propostas subiu.
  • Fixar o modelo. Se você deixar o Evolver rodar em modelos diferentes toda semana (atualização automática), o “gosto” dele muda e o histórico de rejeição perde sentido.

O saldo depois de 6 meses

24 rewrites, 2 rollbacks (ambos culpa minha), 1 lei. AGENTS.md hoje tem 340 linhas contra 280 do início: cresceu 60 linhas em 6 meses, o que dá aproximadamente 10 linhas por mês líquido. Nada explosivo. Nenhuma dessas linhas eu escrevi diretamente. Todas passaram pelo filtro sexta-manhã-café.

O harness continua rodando. Eu revejo o AGENTS.md manualmente uma vez por trimestre, e a última revisão manual não achou nada urgente para mudar. Isso significa alguma coisa. Ainda não decidi se significa que o loop funciona ou que eu virei o gargalo por passar demais nas propostas. A resposta honesta é que provavelmente é os dois.


ken imoto · WebRTC & Voice AI engineer · kenimoto.dev · TabNews

Harness Engineering Livro relacionado Harness Engineering Tutorial de Harness Engineering | design de AGENTS.md · implementação de hooks · operação de agentes de IA Ver a página do livro →