Główną atrakcją Hermes Agent v0.2.0 nie była integracja modelu ani system skilli. Była nią Multi-Platform Messaging Gateway — jeden proces Hermes nasłuchujący jednocześnie na siedmiu platformach czatowych: Telegram, Discord, Slack, WhatsApp, Signal, email (IMAP/SMTP) i Home Assistant. Do wydania z 8 kwietnia lista urosła do trzynastu — doszły Matrix, Feishu, WeCom, Mattermost, DingTalk i SMS (przez Twilio).
To, co łatwo przeoczyć: zbudowanie jednego bota na Telegram nie jest specjalnie trudne. Zbudowanie siedmiu jednoczesnych integracji czatowych dzielących jednego agenta, jedną pamięć i jeden rejestr narzędzi — to jest właśnie ta robota architektoniczna. Ten wpis pokazuje, jak Hermes to robi.
Naiwne podejście i dlaczego nie działa
Gdybyś miał zbudować „bota AI, który odpowiada na Telegramie i Discordzie", pierwszy odruch to postawić dwa osobne boty. Każdy z własnym procesem, własną bazą danych, własnym stanem. Obydwa wywołują to samo API modelu językowego. Użytkownik na Telegramie i użytkownik na Discordzie dostają koncepcyjnie tego samego agenta, ale w praktyce dwóch agentów, którzy o sobie nie wiedzą.
Tak robi większość istniejących projektów botowych, i jest to kiepskie w sposób, który ujawnia się z opóźnieniem:
- •Pamięć się rozjeżdża. Użytkownik, który na Telegramie wspomniał, że ma alergię na orzechy, nie będzie miał tego faktu, gdy zada pytanie o gotowanie na Discordzie. Agent musi nauczyć się tego samego dwa razy.
- •Stan narzędzi dryfuje. Cronjob ustawiony przez Slacka nie pojawia się, gdy użytkownik sprawdzi crony przez Telegram. Historia sesji jest pofragmentowana. Tokeny autoryzacji do współdzielonych zasobów (na przykład integracja z Notion) trzeba instalować w każdym bocie osobno.
- •Narzut operacyjny się mnoży. N botów oznacza N procesów, N usług, N strumieni logów, N plików konfiguracyjnych, N miejsc, w których coś może się zepsuć. Złożoność rośnie liniowo z liczbą platform.
- •Reguły bezpieczeństwa się fragmentują. Jeśli w jednym bocie zaostrzysz politykę zatwierdzania niebezpiecznych poleceń, musisz pamiętać, żeby zrobić to samo w pozostałych. Dryf bezpieczeństwa to domyślny stan.
Hermes wybiera inną drogę: jest dokładnie jeden proces agenta, dokładnie jedna baza sesji, dokładnie jeden magazyn pamięci, dokładnie jeden rejestr narzędzi. Platformy to adaptery — cienkie drzwi wejściowe, które przesyłają wiadomości tam i z powrotem do współdzielonego agenta.
Budowa bramki
Wewnętrznie bramka Hermes ma trzy warstwy.
Na dole siedzi sam agent — ten sam rdzeń Hermes, który działa też w trybie CLI. Nic nie wie o platformach czatowych. Odbiera wiadomości, uruchamia swoją pętlę agenta (wywołania LLM, wywołania narzędzi, zapytania do pamięci, checkpointy) i produkuje odpowiedzi. Jego jedynym interfejsem ze światem zewnętrznym jest API oparte na kolejce.
W środku siedzi jądro bramki — zarządzanie sesjami, routing użytkowników/platform, dispatch zatwierdzeń, planowanie cronów, streaming, przetwarzanie mediów. To ta część, która tłumaczy „przyszła wiadomość na platformie X od użytkownika Y w kanale Z" na „uruchomienie agenta w sesji S z tymi uprawnieniami". Obsługuje też wspólne sprawy: rate limity, kontrolę zalewania, wykrywanie duplikatów, timeouty nieaktywności, routing przycisków zatwierdzeń, status międzyplatformowy.
Na górze siedzą adaptery platform. Jeden na platformę: adapter Telegram, adapter Discord, adapter Slack i tak dalej. Zadanie adaptera jest wąskie — połączyć się ze swoją platformą (przez polling, long-poll, WebSocket, webhook, lub cokolwiek preferuje SDK danej platformy), przetłumaczyć przychodzące natywne eventy na wewnętrzny format wiadomości bramki, i przetłumaczyć wychodzące odpowiedzi z powrotem na to, czego platforma oczekuje (Markdown, MarkdownV2, mrkdwn, Discord rich embeds, Matrix HTML, Slack blocks, email MIME).
Adaptery są celowo małe. Dodanie nowej platformy (kontrybutor społecznościowy dodał Mattermost w mniej niż 300 liniach Pythona w v0.4.0) to głównie kwestia zmapowania eventów SDK na wewnętrzny format wiadomości bramki i z powrotem.
Jak sesje działają między platformami
Sesja Hermes to wątek rozmowy z własnym oknem pamięci, stanem narzędzi i bieżącą historią. Na jednej platformie mapowanie jest naturalne — jedna sesja na czat Telegram, jedna na kanał Discord, jedna na wątek Slack. Między platformami robi się ciekawiej.
Domyślnie Hermes traktuje każdą kombinację platformy i czatu jako osobną sesję. Twój DM na Telegramie z botem, wątek na Slacku z botem i kanał na Discordzie z botem to trzy oddzielne rozmowy z trzema oddzielnymi kontekstami, ale wszystkie dzielą tę samą pamięć długoterminową przez wymiennego dostawcę pamięci (domyślnie Honcho od v0.7.0). Informacje, które oczekujesz, że przeniosą się między sesjami — „użytkownik ma alergię na orzechy", „użytkownik ma na imię Alice", „projekt użytkownika nazywa się Atlas" — podróżują warstwą pamięci, podczas gdy krótkoterminowy kontekst każdej rozmowy pozostaje ograniczony do platformy, z której aktualnie korzystasz.
To jest projekt, który sprawia, że ten sam asystent na każdej platformie zachowuje się jak ten sam asystent, nie zamieniając każdej wiadomości w zagmatwaną globalną transmisję.
Dlaczego współdzielone sesje wątkowe mają znaczenie
W v0.4.0 Hermes dodał funkcję zwaną shared thread sessions domyślnie — w czatach grupowych każdy użytkownik dostaje własną sesję w ramach tego samego wątku. Brzmi jak drobiazg, ale zmienia wszystko dla każdego, kto kiedykolwiek próbował uruchomić wieloużytkownikowego bota w grupie.
Bez sesji per użytkownik w czacie grupowym każda wiadomość jest częścią jednej wspólnej rozmowy. Kiedy Alice zadaje botowi pytanie, a Bob trzydzieści sekund później inne, kontekst bota staje się zagmatwaną mieszanką obojga. Odpowiedzi się plączą. Pamięć Alice zostaje zanieczyszczona danymi Boba. W trybie bramki z każdym kolejnym użytkownikiem jest tylko gorzej.
Przy shared thread sessions Alice i Bob mają każdy swoją prywatną sesję w ramach wątku. Widzą nawzajem swoje wiadomości w widocznym czacie, ale agent prowadzi osobne konteksty i osobne zapisy pamięci per użytkownik. W v0.8.0 stało się to domyślnym zachowaniem na wszystkich platformach bramki. To ten rodzaj poprawki, która jest niewidoczna, dopóki nie sparzyłeś się na alternatywie — a wtedy nigdy nie chcesz wracać.
Do czego bramka tak naprawdę służy
Jeśli wystarczająco długo przyglądasz się architekturze, bramka przestaje wyglądać jak „sposób na uruchamianie botów na platformach czatowych" i zaczyna wyglądać jak to, czym naprawdę jest: warstwa koordynacji między ludźmi (w jakiejkolwiek aplikacji się znajdują) a jednym asystentem AI ze współdzieloną pamięcią i współdzielonymi narzędziami.
Platformy czatowe nie są produktem. Są wejściami. Produktem jest asystent, który za nimi stoi, i fakt, że nigdy nie musisz myśleć o tym, którego wejścia użyć.
To jest ta funkcja, którą Hermes dostarczył w pierwszym dniu. Wszystko inne to historia tego, czego ta warstwa koordynacji nauczyła się przez następne cztery tygodnie.