De headlinefeature van Hermes Agent v0.2.0 was geen modelintegratie of een skillsysteem. Het was de Multi-Platform Messaging Gateway — één enkel Hermes-proces dat tegelijkertijd op zeven chatplatforms luistert: Telegram, Discord, Slack, WhatsApp, Signal, e-mail (IMAP/SMTP) en Home Assistant. Tegen de release van 8 april was de lijst gegroeid naar dertien, met Matrix, Feishu, WeCom, Mattermost, DingTalk en sms (via Twilio) erbij.
Wat makkelijk over het hoofd te zien is: het bouwen van één Telegram-bot is niet zo moeilijk. Het bouwen van zeven gelijktijdige chatintegraties die één agent, één geheugen en één tool-register delen — dát is waar het architectuurwerk zit. Dit artikel loopt door hoe Hermes dat aanpakt.
De naïeve aanpak, en waarom die niet werkt
Als je "een AI-bot die antwoordt op Telegram én Discord" zou bouwen, is je eerste impuls om twee aparte bots neer te zetten. Elk met een eigen proces, een eigen database, een eigen state. Ze roepen allebei dezelfde taalmodel-API aan. De gebruiker op Telegram en de gebruiker op Discord krijgen conceptueel dezelfde agent, maar in de praktijk twee agents die niets van elkaar weten.
Dit is wat de meeste bestaande botprojecten doen, en het is op manieren slecht die pas na een tijdje zichtbaar worden:
- •Geheugen gaat uiteenlopen. Een gebruiker die op Telegram zegt dat hij allergisch is voor pinda's, heeft dat feit niet meer als hij op Discord een kookvraag stelt. De agent moet hetzelfde twee keer leren.
- •Tool-state drijft af. Een cronjob die via Slack is ingesteld, verschijnt niet als de gebruiker cron checkt via Telegram. Sessiegeschiedenis is gefragmenteerd. Autorisatietokens voor gedeelde resources (een Notion-integratie, bijvoorbeeld) moeten in elke bot apart worden geïnstalleerd.
- •Operationele overhead vermenigvuldigt. N bots betekent N processen, N services, N logstreams, N configbestanden, N plekken waar iets kapot kan gaan. De complexiteit groeit lineair met het aantal platforms.
- •Veiligheidsregels versplinteren. Als je in één bot het goedkeuringsbeleid voor gevaarlijke commando's aanscherpt, moet je eraan denken het bij de andere ook te doen. Beveiligingsdrift is de standaard.
Hermes kiest een andere weg: er is precies één agentproces, precies één sessiedatabase, precies één geheugenopslag, precies één tool-register. De platforms zijn adapters — dunne voordeuren die berichten heen en weer sluizen naar de gedeelde agent.
De opbouw van de gateway
Intern heeft de Hermes-gateway drie lagen.
Onderaan zit de agent zelf — dezelfde Hermes-kern die ook in CLI-modus draait. Hij weet niets van chatplatforms. Hij ontvangt berichten, draait zijn agentlus (LLM-aanroepen, tool-aanroepen, geheugenopvragingen, checkpoints) en produceert antwoorden. Zijn enige interface naar de buitenwereld is een queue-gebaseerde API.
In het midden zit de gateway-kern — sessiebeheer, gebruiker-/platformrouting, goedkeuringsdispatch, cronplanning, streaming, mediaverwerking. Dit is het deel dat "er kwam een bericht binnen op platform X van gebruiker Y in kanaal Z" vertaalt naar "een agentrun in sessie S met deze rechten." Het handelt ook gedeelde zaken af: rate limits, floodcontrole, duplicaatdetectie, inactiviteitstimeouts, routering van goedkeuringsknoppen, cross-platformstatus.
Bovenaan zitten de platformadapters. Eén per platform: een Telegram-adapter, een Discord-adapter, een Slack-adapter, enzovoort. De taak van een adapter is smal — verbinding maken met zijn platform (via polling, long-poll, WebSocket, webhook, of wat de SDK van het platform ook prefereert), binnenkomende platformeigen events vertalen naar het interne berichtenformaat van de gateway, en uitgaande antwoorden terugvertalen naar wat het platform verwacht (Markdown, MarkdownV2, mrkdwn, Discord rich embeds, Matrix HTML, Slack blocks, e-mail MIME).
De adapters zijn bewust klein gehouden. Een nieuw platform toevoegen (een communitycontributor voegde Mattermost toe in minder dan 300 regels Python in v0.4.0) is vooral een kwestie van de events van die SDK mappen naar het interne berichtenformaat van de gateway, en andersom.
Hoe sessies werken tussen platforms
Een Hermes-sessie is een gespreksthread met een eigen geheugenvenster, tool-state en lopende geschiedenis. Op één platform is de mapping natuurlijk — één sessie per Telegram-chat, één per Discord-kanaal, één per Slack-thread. Over platforms heen wordt het interessanter.
Standaard behandelt Hermes elke combinatie van platform en chat als een aparte sessie. Je Telegram-DM met de bot, je Slack-thread met de bot en je Discord-kanaal met de bot zijn drie afzonderlijke gesprekken met drie afzonderlijke contexten, maar ze delen allemaal hetzelfde langetermijngeheugen via de plugbare geheugenprovider (Honcho standaard vanaf v0.7.0). De informatie die je verwacht dat meegaat tussen sessies — "de gebruiker is allergisch voor pinda's", "de gebruiker heet Alice", "het project van de gebruiker heet Atlas" — reist mee op de geheugenlaag, terwijl de korttermijncontext van elk gesprek beperkt blijft tot het platform dat je op dat moment gebruikt.
Dit is het ontwerp dat dezelfde assistent op elk platform als dezelfde assistent laat aanvoelen, zonder dat elk bericht verandert in een verwarde globale broadcast.
Waarom gedeelde threadsessies ertoe doen
In v0.4.0 voegde Hermes een feature toe genaamd shared thread sessions standaard — in groepschats krijgt elke gebruiker een eigen sessie binnen dezelfde thread. Klinkt als een klein ding, maar het verandert alles voor iedereen die ooit een multi-userbot in een groep heeft geprobeerd.
Zonder sessies per gebruiker in een groepschat is elk bericht onderdeel van één gedeeld gesprek. Als Alice de bot een vraag stelt en Bob dertig seconden later een andere, dan is de context van de bot nu een warrige mix van allebei. Antwoorden raken verward. Alice' geheugen raakt vervuild met Bobs data. In gatewaymodus wordt het alleen maar erger naarmate er meer gebruikers bijkomen.
Met shared thread sessions hebben Alice en Bob elk hun eigen privésessie binnen de thread. Ze zien elkaars berichten in de zichtbare chat, maar de agent houdt per gebruiker aparte contexten en aparte geheugenschrijfacties bij. In v0.8.0 werd dit het standaardgedrag op alle gatewayplatforms. Het is het soort fix dat onzichtbaar is totdat je je gebrand hebt aan het alternatief — en dan wil je nooit meer terug.
Waar de gateway echt voor is
Als je lang genoeg naar de architectuur tuurt, houdt de gateway op eruit te zien als "een manier om bots op chatplatforms te draaien" en begint hij eruit te zien als wat hij werkelijk is: een coördinatielaag tussen mensen (in welke app ze ook zitten) en een enkele AI-assistent met gedeeld geheugen en gedeelde tools.
De chatplatforms zijn niet het product. Ze zijn de ingangen. Het product is de assistent die erachter zit, en het feit dat je nooit hoeft na te denken over welke ingang je gebruikt.
Dat is de feature die Hermes op dag één leverde. Al het andere is het verhaal van wat die coördinatielaag de volgende vier weken leerde.