Hermes 게이트웨이 아키텍처 — 같은 코어가 텔레그램·디스코드에서 도는 법
대화 루프 심층 글에서 agent/ 코어 루프를 추적했다. 이번에는 같은 코어가 텔레그램·디스코드·슬랙에서 어떻게 도는지 — 게이트웨이 계층을 따라간다. 로컬 소스(AppData\Local\hermes\hermes-agent)를 직접 열어 확인했다. (이 글의 초안은 설치된 Hermes 에이전트가 직접 작성했다.)
TL;DR: 플랫폼별 로직은
plugins/platforms/<name>/(텔레그램은adapter.py+telegram_network.py+plugin.yaml)에 격리되고, 발송 추상화는gateway/delivery.py의DeliveryRouter(deliver/_deliver_to_platform/_deliver_local)가 맡는다. 프로필(격리된 설정/세션/메모리) 라우팅은gateway/profile_routing.py의ProfileRoute가 담당. 즉 코어는 하나, 차이는 플러그인+라우터 다.
1. 플랫폼은 플러그인으로 분리
흥미로운 점: 텔레그램은 gateway/platforms/가 아니라 plugins/platforms/telegram/ 에 있다.
$ ls plugins/platforms/telegram/
__init__.py
adapter.py # 에이전트 코어 ↔ 텔레그램 메시지 변환
plugin.yaml # 플러그인 메타(이름/권한/진입점)
telegram_ids.py # chat/user id 파싱
telegram_network.py # 네트워크(폴링/웹훅) 전송
즉 채널 연동은 코어가 아니라 플러그인이다. gateway/platforms/는 base.py(공통 베이스)와 ADDING_A_PLATFORM.md(신규 플랫폼 추가 가이드)만 두고, 실제 구현은 plugins/로 나뉜다. 핵심은 agent/를 건드리지 않고 채널을 추가할 수 있다는 것 — 개방형 확장 모델.
2. 발송 추상화 — DeliveryRouter
에이전트 응답이 사용자에게 가는 경로는 gateway/delivery.py의 DeliveryRouter가 추상화한다.
$ grep -nE "def (route|deliver|_deliver|send|resolve)" gateway/delivery.py
74: async def send(
92: def resolve_delivery_transport(
318: async def deliver(
393: def _deliver_local(
460: async def _deliver_to_platform(
resolve_delivery_transport(92): 대상(chat_id 등)을 보고 어느 전송 방식인지 결정deliver(318): 진입점 — 로컬(터미널/TUI)인지 플랫폼인지 분기_deliver_local(393): 로컬 표시_deliver_to_platform(460): 플랫폼 어댑터(adapter.py)로 위임
즉 에이전트 코어는 “답을 만들었다”까지만 책임지고, 어디로 보낼지는 DeliveryRouter가 결정한다. CLI·데스크톱·텔레그램이 같은 deliver()를 쓰되 내부 분기만 다르다.
3. 프로필 라우팅 — 격리 경계
여러 프로필(독립 설정/세션/메모리)을 쓸 때 어느 프로필이 메시지를 받는지는 gateway/profile_routing.py가 정한다.
$ grep -nE "class ProfileRoute|def (parse_profile_routes|match_profile_route)" gateway/profile_routing.py
51: class ProfileRoute:
105: def parse_profile_routes(raw):
154: def match_profile_route(
ProfileRoute(51)가 라우팅 규칙 하나를, match_profile_route(154)가 들어온 메시지를 규칙과 매칭해 적절한 프로필로 보낸다. 메모리에 저장한 “프로필별 격리” 원칙이 코드 레벨에서 이 클래스로 구현된다.
4. 전체 흐름
사용자(텔레그램) → plugins/platforms/telegram/adapter.py (수신 변환)
→ gateway/profile_routing.ProfileRoute (프로필 매칭)
→ agent/conversation_loop.run_conversation() (코어 루프)
→ agent/model_tools.handle_function_call() (툴 실행)
→ gateway/delivery.DeliveryRouter.deliver() (발송 결정)
→ _deliver_to_platform → telegram/adapter.py (송신 변환)
→ 사용자(텔레그램)
핵심: 가운데 agent/ 세 줄만 빼면 나머지는 모두 플랫폼/라우팅 계층이다. 코어는 플랫폼을 모른다.
마무리
Hermes의 멀티플랫폼은 “거대한 분기문”이 아니라 플러그인 격리(plugins/platforms/)+발송 추상화(DeliveryRouter)+프로필 라우팅(ProfileRoute) 로 풀린다. 그래서 설치기 글에서 본 “터미널·데스크톱·메신저가 같은 에이전트 코어” 문구가 코드 레벨에서 성립한다. 소스 트리 투어(A) → 대화 루프(B) → 게이트웨이(C)로 이어진 이 3부작은, Hermes가 “모듈 경로로 읽히는 에이전트”임을 보여준다.
참고
관련글 목록
- 에이전트는 어떻게 '배우고' 고치는가 — 기억·스킬·피드백 루프의 실제 구조
- Hermes 파이프라인에 OKF 지식 번들 올리기
- Hermes Agent 설치부터 설정까지 - Windows에서 시작하기
- 오픈소스 가드레일 모델과 온프레미스 에이전트 파이프라인 구성
- 구글 OKF(Open Knowledge Format)는 RAG를 대체하나?
- Claude Code로 제안서 작성 파이프라인 만들기
- RAG & AI 에이전트 주간 연구 동향 (2026-07-12 ~ 07-19)
- 나디르 위성영상 캡셔닝을 위한 오픈웨이트 멀티모달 모델 비교
- 위성 영상 처리: 멀티모달 LLM vs 이미지 임베딩 모델
- Caller/Executor 패턴으로 멀티 에이전트 구성하기
- OpenRouter 무료 모델을 API로 사용하기
- PaperBanana - 문장으로 아키텍처 다이어그램 그리기
- AI TOOLS