Trois agents dans une room, seul le vôtre continue de parler : le silence par room dans Hermes

Imaginez une room avec vous, deux collègues et trois agents qui possèdent chacun une part du travail. Un collègue demande qui surveille le déploiement. Un agent juge que la question ne le concerne pas et répond par un simple NO_REPLY, exactement comme convenu. Vous vous attendez au silence. Quelques secondes plus tard, Hermes publie ceci dans la room :
⚠️ Le modèle n’a renvoyé qu’un marqueur de silence pour un message qui attendait une réponse. Réessayez ou reformulez.
Le message n’est pas faux — c’est un filet de sécurité responsable. Le problème, c’est ce qu’il fait à la room : il transforme une passation interne en erreur système visible de tous. Dans une room multi-agents, ce faux déclenchement se répète jusqu’à ce que plus personne n’ait envie d’utiliser la room.
Le silence est une capacité du modèle ; la permission est une politique de room
Deux choses différentes se confondent ici. Premièrement, le modèle peut choisir de ne pas parler. Hermes reconnaît quelques marqueurs de silence — NO_REPLY, [SILENT] — qui signifient « reçu, rien n’était attendu de moi ce tour-ci ». Deuxièmement, il faut décider si ce silence est acceptable à afficher. C’est une question de politique. Elle ne doit pas être tranchée unilatéralement par le modèle, et elle ne doit pas non plus être une réponse globale unique.
Historiquement, le silence n’était honoré que dans des cas étroits : notifications internes, heartbeats planifiés, et messages dont l’adaptateur savait déjà qu’ils ne s’adressaient pas au bot. Tout le reste — quelqu’un qui mentionne le bot, une question directe dans un canal de forum — était traité comme une panne si le modèle répondait par un marqueur seul. La gateway comblait alors le vide avec l’avertissement ci-dessus.
Ce défaut est le bon. Demandez à votre agent en DM de lancer les tests et recevez un écran vide : vous ne pouvez pas savoir s’il travaille, s’il est mort ou s’il est perdu. L’avertissement dit au moins « il a essayé et n’a rien produit ».
Dans un groupe, le défaut cause des dégâts collatéraux. Les rooms mixtes humains/agents génèrent un flux constant de « vu, pas de réponse nécessaire ». Hermes a donc ajouté un interrupteur au niveau de la room.
Une clé, une room
Le réglage vit dans le config.yaml du profil qui sert cette room, sur le bloc channel_overrides existant :
platforms:
matrix:
channel_overrides:
"!exampleTeamRoom:example.org":
allow_silence: true
Trois choses à retenir :
- C’est un override de room, pas un réglage à l’échelle du profil. Les autres rooms gardent l’ancien comportement.
- Omis,
nulloufalsesignifient tous « garder la politique de réponse actuelle » — un humain pose une question, le modèle reste silencieux, et vous recevez quand même l’avertissement. - Les exemptions existantes survivent quoi qu’il arrive : notifications internes, heartbeats planifiés et messages non adressés restent silencieux même dans une room qui déclare
allow_silence: false.
Redémarrez la gateway après avoir modifié le fichier, pour que chaque profil servant cette route prenne la nouvelle valeur.
Un piège dans l’ordre de résolution
Les overrides de room se résolvent exactement comme les overrides de modèle : identifiant de canal exact d’abord, puis identifiant de thread, puis le canal parent ou l’identifiant de forum. Le premier qui correspond gagne.
Le piège, c’est que « le premier qui correspond gagne » inclut une entrée qui ne définit qu’autre chose. Configurez model sur un seul thread et cette entrée de thread correspond en premier — et comme elle ne dit rien de allow_silence, le allow_silence: true de la room parente ne s’applique jamais. Le thread retombe discrètement sur « doit parler ». Le correctif est peu élégant : répétez allow_silence dans l’entrée du thread.
C’est le même mécanisme que les overrides de modèle par conversation ; les deux clés peuvent vivre dans une seule entrée. Simplement, n’en écrivez pas la moitié.
Le silence ne signifie pas qu’il ne s’est rien passé
C’est la partie que les gens lisent de travers. Activer allow_silence ne veut pas dire « les agents de cette room peuvent disparaître ». Cela ne régit que la livraison finale :
- Cela n’annule pas les appels d’outils. Une commande qui a tourné a tourné.
- Cela ne retire pas les messages de progression déjà envoyés. Les mises à jour en cours de tour partent toujours.
- Cela n’incite pas le modèle au silence. Cela autorise le silence ; cela ne l’encourage jamais.
Plus important : les résultats vides, en échec, partiels et interrompus n’obtiennent jamais le droit de disparaître. Un modèle ne peut pas cacher une exécution cassée derrière un marqueur. Le contrôle de santé est explicite : seul un tour terminé sans indicateur d’échec, de partialité ou d’interruption compte sur la permission de la room.
Il y a un corollaire subtil. Si le modèle a écrit une vraie réponse, a aussi appelé des outils purement administratifs (mémoire, liste de tâches, gestion des skills, recherche de sessions), puis a terminé le tour sur un marqueur seul, cette réponse est livrée — y compris dans les rooms qui ont opté pour le silence. Ce n’est pas « rien à dire » ; c’est « je l’ai dit, puis j’ai raté la conclusion ».
La reprise après crash suit le même principe : une décision de suppression n’est honorée que si elle a été enregistrée pour cette réponse finale exacte. Un crash avant ce point et la protection des questions humaines revient.
Quatre correctifs livrés en même temps
Ce n’était pas un commit apparu seul. Une poignée de réparations a rendu l’interrupteur digne de confiance :
- Lire les blocs de plateforme de premier niveau et échouer en sécurité. Les overrides peuvent vivre directement sous
platforms.<name>; le chargeur lit désormais les deux formes et, quand il ne peut pas résoudre une room, retombe sur la politique par défaut au lieu de l’assouplir. - Un accusé de réception de silence en échec n’est pas une erreur. Si l’écriture de l’enregistrement « ce tour a choisi le silence » échoue, le tour ne doit pas devenir un échec — ce n’est qu’une note.
- Le profil principal lit la configuration propre à la gateway. Le profil que la gateway sert elle-même se résout depuis sa propre configuration, pas depuis l’instantané de lancement.
- Les marqueurs de groupe Telegram survivent mieux. Une série de correctifs préserve les marqueurs de silence pour les réponses aux canaux, les publications d’administrateurs anonymes, les réponses à des auteurs inconnus et les notes vocales ou fichiers audio sans légende dans les groupes, au lieu de les lire comme « aurait dû répondre mais ne l’a pas fait ».
Les trois premiers visent à ne pas mal lire la politique ; le quatrième à ne pas perdre le marqueur. Aucun n’apparaît dans une note de lancement, et tous décident si l’interrupteur fonctionne entre vos mains.
Quand l’activer, quand ne pas le faire
Activez-le dans les rooms multi-agents, les canaux de projet mixtes humains/agents et les rooms d’exploitation à fort volume — partout où « le silence est la bonne réponse » est la norme.
Laissez-le désactivé dans les DM, à l’accueil du support et dans tout canal où une question d’utilisateur doit recevoir une réponse. Là, l’avertissement ⚠️ n’est pas du bruit ; c’est le seul signal que quelque chose a cassé. Le désactiver, c’est couper l’alarme.
Si vous hésitez, activez-le pour une room et observez pendant une semaine. Au pire, vous perdez le filet de sécurité de cette room, pas la gateway.
Pour comprendre pourquoi une room est devenue silencieuse au niveau de la connexion plutôt que de la politique, déconnexions silencieuses et heartbeats traite l’autre moitié — autre couche, même symptôme.