Chega de «parar no meio»: o max_turns do Hermes agora é ilimitado por padrão


Você conhece a sensação: você pede ao Hermes um trabalho de verdade — refatorar o repositório inteiro, processar milhares de arquivos em lote, montar um pipeline de dados do início ao fim — e ele está trabalhando, trabalhando, e de repente para. Não é um erro. Não é uma pergunta. Simplesmente… terminou. Metade da tarefa está pronta, o resto ficou lá parado.

Isso não era mágica, era um limite padrão rígido que o Hermes costumava ter: dentro de um único turno, o agent podia chamar ferramentas no máximo 500 vezes. Quinhentas parece muito, mas qualquer tarefa real — buscar, ler código, editar arquivos, rodar testes, corrigir bugs, rodar testes de novo — queima isso rapidinho. Pior: ele parava em silêncio. Você só notava o trabalho pela metade quando voltava na conversa.

Esse padrão acabou: a partir do branch main (pós-v0.20.4), o agent.max_turns é ilimitado por padrão. Este post explica o que mudou, por quê, e como definir um limite quando você realmente quiser um.

Primeiro: o que é o max_turns de verdade

O max_turns (também chamado de max iterations) limita quantas vezes o agent pode chamar ferramentas dentro de um turno — não quantos turnos você pode ter. Pense assim: você envia uma mensagem, o Hermes começa a trabalhar, e cada arquivo que ele lê, cada comando que ele executa, cada chamada de API conta como uma iteração. max_turns: 500 significava: neste turno ele pode fazer no máximo 500 unidades de trabalho e depois precisa parar e devolver o controle para você.

Nas versões antigas o padrão era 500. De sobra para o dia a dia de perguntas e respostas, mas para tarefas que exigem “ler o codebase → alterar dezenas de arquivos → rodar os testes → corrigir → rodar de novo”, 500 era um teto invisível. A tarefa batia no limite no meio do caminho e os passos restantes tinham que esperar um “continue” manual.

E piorava: se você escrevesse max_turns: none no seu config para expressar “sem limite”, o código antigo quebrava com um TypeError (issue #82813) — ou ignorava o valor silenciosamente. Às vezes não era só uma falha graciosa; podia derrubar cron jobs e o gateway.

O novo padrão: ilimitado, a menos que você opte por um limite

Esta mudança (PR #90708) inverte completamente o comportamento padrão:

Configuração Antes Agora
Não definido (padrão) limitado a 500 ilimitado
max_turns: none crash com TypeError ilimitado
max_turns: null / unlimited / inf / infinity / 0 / -1 crash ou ignorado ilimitado
max_turns: 200 limitado a 200 limitado a 200 (inalterado)

Em outras palavras: por padrão, uma tarefa agora roda até o fim — sem mais cortes silenciosos. Todas as grafias de “ilimitado” (none, null, unlimited, infinite, infinity, inf, , 0, -1, sem diferenciar maiúsculas de minúsculas e tolerante a espaços) agora são cidadãs de primeira classe, normalizadas por uma única função resolve_turn_limit(). Escreva como preferir — mesmo resultado, e sem crashes.

Se você realmente quiser um limite para algumas tarefas, um inteiro positivo continua funcionando exatamente como antes.

Como definir um limite quando você quiser um

Ilimitado é o padrão, mas não é certo para todo cenário — digamos, um cron job que roda a cada hora e você quer que ele faça uma quantidade limitada de trabalho para não gastar uma fortuna por acidente. Há três formas de definir um limite (da menor para a maior precedência):

1. Arquivo de configuração (config.yaml)

agent:
  max_turns: 200   # no máximo 200 chamadas de ferramentas por turno

2. CLI

hermes config set agent.max_turns 200

3. Variável de ambiente

export HERMES_MAX_ITERATIONS=200
hermes chat

As três passam pelo mesmo parser resolve_turn_limit(), então o comportamento é consistente onde quer que você defina.

Não confunda: goals.max_turns continua em 20

Uma coisa que não mudou: goals.max_turns mantém o padrão de 20.

O agent.max_turns governa os turnos de conversa comuns; o goals.max_turns governa o modo goal (você dá ao Hermes um objetivo de longo prazo e o deixa trabalhar autonomamente até concluir) — especificamente quantos ciclos de auto-continue ele pode rodar. O modo goal tem sua própria proteção de orçamento: ele pausa após 20 continuações e pede que você faça /goal resume ou limpe, para que um objetivo vago não queime dinheiro para sempre. O PR deixou esse campo deliberadamente intocado — cada configuração faz o seu trabalho.

Então: quer que tarefas longas parem de ser cortadas? Use o padrão ilimitado (nada para configurar). Quer um freio na caçada autônoma de objetivos? Ajuste o goals.max_turns.

Vale saber agora que é ilimitado

Com turnos ilimitados, duas coisas merecem atenção:

  • Consciência de custo: a tarefa roda até o fim, o que significa que ela continua chamando a API do modelo. Se você se preocupa com gastos, não dependa do max_turns como freio — use ferramentas mais precisas como agent.run_budget_seconds (um orçamento de tempo real que te avisa com 80% do tempo decorrido) ou o idle timeout do gateway (dispara apenas quando o agent fica completamente ocioso por um tempo). Esses são “freios graciosos” — muito melhores do que parar no meio da tarefa.
  • cron e gateway também ganham: como o agendador de cron e a configuração do gateway agora compartilham o mesmo resolver, o crash antigo ao escrever none na configuração do cron também foi corrigido. Tarefas longas de cron agora rodam até o fim de uma vez só.

Resumo

O agent.max_turns indo de “padrão 500” para “padrão ilimitado” é um conserto pragmático para a experiência de tarefas longas: deixe tarefas que devem terminar, terminarem; deixe quem quer limites, definir limites. A mudança está atualmente no branch main (mesclada após a v0.20.4) — quando a próxima versão oficial sair, um simples hermes update resolve.

Quer se aprofundar em como o Hermes lida com turnos e contexto? Confira nosso artigo aprofundado sobre tratamento de erros e recuperação, ou o guia de configuração para tarefas longas com configurações práticas que evitam que tarefas fiquem travadas.