Três agentes em uma sala, só o seu continua falando: silêncio por sala no Hermes

Imagine uma sala com você, dois colegas e três agentes, cada um responsável por uma fatia do trabalho. Um colega pergunta quem está acompanhando o deploy. Um dos agentes decide que a pergunta não é da sua alçada e responde com um NO_REPLY seco, exatamente como combinado. Você espera silêncio. Poucos segundos depois, o Hermes publica isto na sala:
⚠️ O modelo retornou apenas um marcador de silêncio para uma mensagem que precisava de resposta. Tente novamente ou reformule.
A mensagem não está errada — é uma proteção responsável. O problema é o que ela faz com a sala: transforma um repasse interno em um erro de sistema que todo mundo vê. Em uma sala multiagente, esse disparo errado se repete até ninguém mais querer usar a sala.
Silêncio é capacidade do modelo; permissão é política da sala
Duas coisas diferentes se misturam aqui. Primeiro, o modelo pode escolher não falar. O Hermes reconhece alguns marcadores de silêncio — NO_REPLY, [SILENT] — que significam “recebido, nada necessário de mim neste turno”. Segundo, se esse silêncio é aceitável de exibir. Isso é uma questão de política. Não deveria ser decidido unilateralmente pelo modelo, e também não deveria ser uma resposta global única.
Historicamente, o silêncio só era respeitado em casos estreitos: notificações internas, heartbeats agendados e mensagens que o adaptador já sabe que não eram dirigidas ao bot. Todo o resto — alguém mencionando o bot, uma pergunta direta em um canal de fórum — era tratado como falha se o modelo respondesse apenas com um marcador. O gateway então preenchia a lacuna com o aviso acima.
Esse padrão está certo. Peça ao seu agente em uma DM para rodar os testes e receba uma tela em branco: você não consegue dizer se ele está trabalhando, morto ou confuso. O aviso ao menos diz “tentou e não produziu nada”.
Em grupo, o padrão causa dano colateral. Salas mistas de humanos e agentes geram um fluxo constante de “vi, não precisa responder”. Por isso o Hermes adicionou um interruptor por sala.
Uma chave, uma sala
A configuração fica no config.yaml do perfil que atende aquela sala, no bloco channel_overrides que já existe:
platforms:
matrix:
channel_overrides:
"!exampleTeamRoom:example.org":
allow_silence: true
Três coisas para guardar:
- É um override de sala, não uma configuração de todo o perfil. As outras salas mantêm o comportamento antigo.
- Omitido,
nulloufalsesignificam “manter a política atual de resposta” — um humano pergunta, o modelo fica quieto e você ainda recebe o aviso. - As isenções existentes sobrevivem de qualquer forma: notificações internas, heartbeats agendados e mensagens sabidamente não endereçadas continuam em silêncio mesmo em uma sala com
allow_silence: false.
Reinicie o gateway depois de editar o arquivo, para que todo perfil que atende aquela rota pegue o novo valor.
Uma armadilha na ordem de busca
Overrides de sala resolvem exatamente como overrides de modelo: id exato do canal primeiro, depois id da thread, depois o canal pai ou o id do fórum. A primeira correspondência vence.
A armadilha é que “a primeira correspondência vence” inclui uma entrada que só define outra coisa. Configure model em uma thread e a entrada dessa thread corresponde primeiro — e, como ela não diz nada sobre allow_silence, o allow_silence: true da sala pai nunca se aplica. A thread volta silenciosamente para “precisa falar”. A correção não tem glamour: repita allow_silence na entrada da thread.
É o mesmo mecanismo dos overrides de modelo por chat; as duas chaves podem viver em uma única entrada. Só não escreva metade dela.
Silêncio não significa que nada aconteceu
Esta é a parte que as pessoas leem errado. Habilitar allow_silence não significa “agentes nesta sala podem desaparecer”. Isso governa apenas a entrega final:
- Não desfaz chamadas de ferramentas. Um comando que rodou, rodou.
- Não retira mensagens de progresso já enviadas. Atualizações no meio do turno continuam saindo.
- Não empurra o modelo para o silêncio. Permite o silêncio; nunca o incentiva.
Mais importante: resultados vazios, com falha, parciais ou interrompidos nunca ganham o direito de desaparecer. Um modelo não pode esconder uma execução quebrada atrás de um marcador. A checagem de saúde é explícita: apenas um turno concluído, sem marca de falha, parcial ou interrupção, conta com a permissão da sala.
Há um corolário sutil. Se o modelo escreveu uma resposta real, também chamou ferramentas apenas de manutenção (memória, lista de tarefas, gestão de skills, busca de sessão) e então encerrou o turno com um marcador seco, essa resposta é entregue — inclusive em salas que optaram pelo silêncio. Isso não é “não tinha nada a dizer”; é “disse, e depois errou o final”.
A recuperação de falhas segue o mesmo princípio: uma decisão de supressão só é respeitada se foi salva junto daquela resposta final exata. Se o processo cair antes disso, a salvaguarda de pergunta humana volta.
Quatro correções que vieram junto
Isso não foi um commit que apareceu sozinho. Alguns reparos tornaram o interruptor confiável:
- Ler blocos de plataforma de nível superior e falhar em segurança. Overrides podem viver diretamente sob
platforms.<name>; o loader agora lê os dois formatos e, quando não consegue resolver uma sala, volta à política padrão em vez de afrouxá-la. - Um recibo de silêncio com falha não é um erro. Se gravar o registro “este turno escolheu o silêncio” falhar, o turno não deve virar falha — é apenas uma nota.
- O perfil primário lê a própria configuração do gateway. O perfil que o próprio gateway atende resolve a partir da sua configuração, não do snapshot de inicialização.
- Marcadores de grupo no Telegram sobrevivem melhor. Um conjunto de correções mantém os marcadores de silêncio intactos em respostas a canais, posts de administradores anônimos, respostas a autores desconhecidos e notas de voz ou arquivos de áudio sem legenda em grupos, em vez de lê-los como “deveria ter respondido e não respondeu”.
As três primeiras tratam de não ler a política errado; a quarta, de não perder o marcador. Nenhuma delas aparece em um post de lançamento, e todas decidem se o interruptor funciona nas suas mãos.
Quando ligar e quando não ligar
Ligue em salas multiagente, canais de projeto mistos de humanos e agentes e salas de operação de alto volume — em qualquer lugar onde “o silêncio é a resposta correta” seja rotina.
Deixe desligado em DMs, triagem de suporte e qualquer canal onde uma pergunta de usuário precise de resposta. Ali o aviso ⚠️ não é ruído; é o único sinal de que algo quebrou. Desligá-lo silencia o alarme.
Se estiver em dúvida, habilite para uma sala e observe por uma semana. No pior caso, você perde a proteção daquela sala, não o gateway.
Para entender por que uma sala ficou quieta no nível da conexão, e não no da política, desconexões silenciosas e heartbeats cobre a outra metade — camada diferente, sintoma igual.