본문으로 건너뛰기

Telegram 설정

Hermes Agent는 Telegram에서 완전한 대화형 봇으로 동작합니다. 연결해 두면 어느 기기에서든 에이전트와 대화하고, 음성 메모를 보내 자동 전사를 받고, 예약 작업 결과를 받아 보며, 그룹 채팅에서도 에이전트를 사용할 수 있습니다. Telegram 연동은 python-telegram-bot 위에 구축되어 있으며 텍스트, 음성, 이미지, 파일 첨부를 지원합니다.

1단계: BotFather로 봇 만들기

모든 Telegram 봇에는 Telegram의 공식 봇 관리 도구인 @BotFather가 발급한 API 토큰이 필요합니다.

  1. Telegram을 열고 @BotFather를 검색하거나 t.me/BotFather로 이동합니다.
  2. /newbot을 보냅니다.
  3. 표시 이름을 정합니다. 예: "Hermes Agent". 이 이름은 자유롭게 정할 수 있습니다.
  4. 사용자 이름을 정합니다. 전역에서 고유해야 하며 bot으로 끝나야 합니다. 예: my_hermes_bot.
  5. BotFather가 API 토큰을 응답합니다. 형태는 다음과 같습니다.
123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
경고

봇 토큰은 반드시 비밀로 보관하세요. 이 토큰을 가진 사람은 누구나 봇을 제어할 수 있습니다. 유출되었다면 BotFather에서 /revoke로 즉시 폐기하세요.

2단계: Bot 사용자 경험 다듬기(선택)

다음 BotFather 명령은 사용자 경험을 개선합니다. @BotFather에게 메시지를 보낸 뒤 아래 명령을 사용하세요.

명령용도
/setdescription사용자가 대화를 시작하기 전에 보는 "What can this bot do?" 설명
/setabouttext봇 프로필 페이지에 보이는 짧은 소개
/setuserpic봇 아바타 업로드
/setcommands채팅의 / 버튼에 표시되는 명령 메뉴 정의
/setprivacy봇이 그룹 메시지 전체를 볼 수 있는지 제어. 3단계 참고

/setcommands의 시작점으로는 다음 구성이 유용합니다.

help - Show help information
new - Start a new conversation
sethome - Set this chat as the home channel

3단계: Privacy Mode 이해하기(그룹에서 특히 중요)

Telegram 봇에는 privacy mode가 있으며, 기본값은 enabled입니다. 그룹에서 봇을 사용할 때 문제가 생기는 가장 흔한 원인입니다.

Privacy mode가 ON이면 봇은 다음 메시지만 볼 수 있습니다.

  • / 명령으로 시작하는 메시지
  • 봇 자신의 메시지에 대한 직접 답장
  • 서비스 메시지(멤버 입장/퇴장, 고정 메시지 등)
  • 봇이 관리자인 채널의 메시지

Privacy mode가 OFF이면 봇은 그룹의 모든 메시지를 받습니다.

Privacy mode 끄기

  1. @BotFather에게 메시지를 보냅니다.
  2. /mybots를 보냅니다.
  3. 자신의 봇을 선택합니다.
  4. Bot Settings -> Group Privacy -> Turn off로 이동합니다.
경고

Privacy 설정을 바꾼 뒤에는 해당 봇을 그룹에서 제거한 뒤 다시 추가해야 합니다. Telegram은 봇이 그룹에 들어올 때의 privacy 상태를 캐시하므로, 제거 후 재추가하기 전까지 기존 그룹 멤버십에는 새 설정이 반영되지 않습니다.

Privacy mode를 끄는 대신 봇을 그룹 관리자로 승격해도 됩니다. 관리자 봇은 privacy 설정과 관계없이 모든 메시지를 받으므로, 전역 privacy mode를 바꾸지 않아도 됩니다.

4단계: 사용자 ID 찾기

Hermes Agent는 접근 제어에 숫자형 Telegram 사용자 ID를 사용합니다. 사용자 ID는 @username이 아니라 123456789 같은 숫자입니다.

방법 1(권장): @userinfobot에게 메시지를 보내세요. 즉시 사용자 ID를 알려 줍니다.

방법 2: @get_id_bot에게 메시지를 보냅니다. 이 방법도 신뢰할 수 있습니다.

다음 단계에서 필요하므로 이 숫자를 저장해 두세요.

5단계: Hermes 설정하기

hermes gateway setup

프롬프트가 나오면 Telegram을 선택합니다. 설정 마법사가 봇 토큰과 허용할 사용자 ID를 물어보고 필요한 설정을 작성합니다.

옵션 B: 수동 설정

~/.hermes/.env에 다음 값을 추가합니다.

TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
TELEGRAM_ALLOWED_USERS=123456789 # 여러 사용자는 쉼표로 구분

게이트웨이 시작

hermes gateway

몇 초 안에 봇이 온라인 상태가 됩니다. Telegram에서 메시지를 보내 정상적으로 응답하는지 확인하세요.

Docker 기반 터미널에서 생성한 파일 보내기

터미널 백엔드가 docker라면 Telegram 첨부 파일은 컨테이너 안이 아니라 게이트웨이 프로세스에서 전송된다는 점을 기억해야 합니다. 따라서 최종 MEDIA:/... 경로는 게이트웨이가 실행 중인 호스트에서 읽을 수 있어야 합니다.

흔한 실수는 다음과 같습니다.

  • 에이전트가 Docker 안에서 /workspace/report.txt에 파일을 씁니다.
  • 모델이 MEDIA:/workspace/report.txt를 출력합니다.
  • /workspace/report.txt는 호스트가 아니라 컨테이너 안에만 있으므로 Telegram 전달이 실패합니다.

권장 패턴은 호스트에서도 보이는 출력 디렉터리를 마운트하는 것입니다.

terminal:
backend: docker
docker_volumes:
- "/home/user/.hermes/cache/documents:/output"

그런 다음 다음처럼 사용합니다.

  • Docker 안에서는 /output/...에 파일을 씁니다.
  • MEDIA:에는 호스트에서 보이는 경로를 출력합니다. 예: MEDIA:/home/user/.hermes/cache/documents/report.txt

이미 docker_volumes: 섹션이 있다면 같은 목록에 새 마운트를 추가하세요. YAML에서 중복 키는 앞선 값을 조용히 덮어씁니다.

지원되는 MEDIA: 파일 확장자

게이트웨이는 에이전트 응답에서 MEDIA:/path/to/file 태그를 추출하고, 참조된 파일을 플랫폼 네이티브 첨부 파일로 보냅니다. 모든 게이트웨이 플랫폼에서 지원하는 확장자는 다음과 같습니다.

범주확장자
이미지png, jpg, jpeg, gif, webp, bmp, tiff, svg
오디오mp3, wav, ogg, m4a, opus, flac, aac
비디오mp4, mov, webm, mkv, avi
문서pdf, txt, md, csv, json, xml, html, yaml, yml, log
Officedocx, xlsx, pptx, odt, ods, odp
압축 파일zip, rar, 7z, tar, gz, bz2
전자책 / 패키지epub, apk, ipa

이 목록의 파일은 Telegram, Discord, Signal, Slack, WhatsApp, Feishu, Matrix처럼 네이티브 첨부를 지원하는 플랫폼에서는 첨부 파일로 전송됩니다. 네이티브 지원이 없는 플랫폼에서는 링크나 일반 텍스트 표시로 대체됩니다. 굵게 표시된 범주는 최근 릴리스에서 추가되었습니다. 예전처럼 모델이 here is the file: /path/to/report.docx라고 말하게 두었다면, 이제 MEDIA:/path/to/report.docx로 바꾸면 네이티브 파일 전달을 사용할 수 있습니다.

Webhook 모드

기본적으로 Hermes는 롱 폴링으로 Telegram에 연결합니다. 게이트웨이가 Telegram 서버로 outbound 요청을 보내 새 업데이트를 가져오는 방식입니다. 로컬 환경이나 항상 켜져 있는 서버에는 잘 맞습니다.

클라우드 배포(Fly.io, Railway, Render 등)에서는 webhook 모드가 비용 면에서 더 효율적입니다. 이런 플랫폼은 inbound HTTP 트래픽이 오면 정지된 머신을 자동으로 깨울 수 있지만, outbound 연결만으로는 깨울 수 없습니다. 폴링은 outbound 방식이므로 폴링 봇은 잠들 수 없습니다. Webhook 모드는 방향을 뒤집어 Telegram이 봇의 HTTPS URL로 업데이트를 push하게 하므로, 메시지가 없을 때는 머신을 재울 수 있습니다.

폴링(기본값)Webhook
방향Gateway -> Telegram(outbound)Telegram -> Gateway(inbound)
적합한 환경로컬, 상시 실행 서버자동 wake가 있는 클라우드 플랫폼
설정추가 설정 없음TELEGRAM_WEBHOOK_URL 설정
유휴 비용머신이 계속 실행되어야 함메시지 사이에는 머신 sleep 가능

설정

~/.hermes/.env에 다음 값을 추가합니다.

TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 32)" # 필수
# TELEGRAM_WEBHOOK_PORT=8443 # 선택 사항, 기본값 8443
변수필수설명
TELEGRAM_WEBHOOK_URLTelegram이 업데이트를 보낼 공개 HTTPS URL입니다. URL path는 자동으로 추출됩니다. 위 예시에서는 /telegram입니다.
TELEGRAM_WEBHOOK_SECRET(TELEGRAM_WEBHOOK_URL 설정 시)Telegram이 모든 webhook 요청에 다시 보내는 검증용 secret token입니다. 이 값이 없으면 게이트웨이가 시작을 거부합니다. GHSA-3vpc-7q5r-276h를 참고하세요. openssl rand -hex 32로 생성합니다.
TELEGRAM_WEBHOOK_PORT아니요Webhook 서버가 listen하는 로컬 포트입니다. 기본값은 8443입니다.

TELEGRAM_WEBHOOK_URL이 설정되면 게이트웨이는 polling 대신 HTTP webhook 서버를 시작합니다. 설정하지 않으면 polling 모드를 사용하므로 이전 버전과 동작이 같습니다.

클라우드 배포 예시(Fly.io)

  1. Fly.io app secret에 환경 변수를 추가합니다.
fly secrets set TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
fly secrets set TELEGRAM_WEBHOOK_SECRET=$(openssl rand -hex 32)
  1. fly.toml에서 webhook 포트를 노출합니다.
[[services]]
internal_port = 8443
protocol = "tcp"

[[services.ports]]
handlers = ["tls", "http"]
port = 443
  1. 배포합니다.
fly deploy

게이트웨이 로그에 [telegram] Connected to Telegram (webhook mode)가 보여야 합니다.

Proxy 지원

Telegram API가 차단되어 있거나 트래픽을 proxy로 보내야 한다면 Telegram 전용 proxy URL을 설정하세요. 이 값은 일반 HTTPS_PROXY / HTTP_PROXY 환경 변수보다 우선합니다.

옵션 1: config.yaml(권장)

telegram:
proxy_url: "socks5://127.0.0.1:1080"

옵션 2: 환경 변수

TELEGRAM_PROXY=socks5://127.0.0.1:1080

지원하는 scheme은 http://, https://, socks5://입니다.

이 proxy는 기본 Telegram 연결과 fallback IP transport 모두에 적용됩니다. Telegram 전용 proxy가 없으면 게이트웨이는 HTTPS_PROXY / HTTP_PROXY / ALL_PROXY 또는 macOS 시스템 proxy 자동 감지로 fallback합니다.

Home Channel

Telegram 채팅(DM 또는 그룹)에서 /sethome 명령을 사용하면 해당 채팅을 home channel로 지정할 수 있습니다. 예약 작업(cron job)은 결과를 이 채널로 보냅니다.

~/.hermes/.env에서 수동으로 설정할 수도 있습니다.

TELEGRAM_HOME_CHANNEL=-1001234567890
TELEGRAM_HOME_CHANNEL_NAME="My Notes"

그룹 채팅 ID는 음수입니다. 예: -1001234567890. 개인 DM 채팅 ID는 사용자 ID와 같습니다.

음성 메시지

수신 음성(Speech-to-Text)

Telegram에서 보낸 음성 메시지는 Hermes에 설정된 STT provider로 자동 전사되어 대화에 텍스트로 주입됩니다.

  • local은 Hermes가 실행 중인 머신에서 faster-whisper를 사용합니다. API key가 필요 없습니다.
  • groq는 Groq Whisper를 사용하며 GROQ_API_KEY가 필요합니다.
  • openai는 OpenAI Whisper를 사용하며 VOICE_TOOLS_OPENAI_KEY가 필요합니다.

발신 음성(Text-to-Speech)

에이전트가 TTS로 오디오를 생성하면 Telegram 네이티브 voice bubble로 전달됩니다. Telegram 안에서 둥근 형태로 바로 재생되는 그 형식입니다.

  • OpenAI와 ElevenLabs는 Opus를 네이티브로 생성하므로 추가 설정이 필요 없습니다.
  • Edge TTS(기본 무료 provider)는 MP3를 출력하므로 Opus 변환을 위해 ffmpeg가 필요합니다.
# Ubuntu/Debian
sudo apt install ffmpeg

# macOS
brew install ffmpeg

ffmpeg가 없으면 Edge TTS 오디오는 일반 오디오 파일로 전송됩니다. 재생은 가능하지만 voice bubble이 아니라 직사각형 플레이어를 사용합니다.

TTS provider는 config.yamltts.provider 키에서 설정합니다.

Group Chat 사용

Hermes Agent는 Telegram 그룹 채팅에서도 동작하지만 몇 가지 조건을 이해해야 합니다.

  • Privacy mode는 봇이 어떤 메시지를 볼 수 있는지 결정합니다. 3단계를 참고하세요.
  • TELEGRAM_ALLOWED_USERS는 그룹에서도 적용됩니다. 허용된 사용자만 봇을 trigger할 수 있습니다.
  • telegram.require_mention: true를 설정하면 일반 그룹 대화에는 응답하지 않게 할 수 있습니다.
  • telegram.require_mention: true일 때 그룹 메시지는 다음 경우에만 허용됩니다.
    • 봇 메시지에 대한 답장
    • @botusername mention
    • /command@botusername 형식. Telegram 봇 메뉴 명령이 봇 이름을 포함하는 형태입니다.
    • telegram.mention_patterns에 설정한 정규식 wake word와 일치
  • telegram.ignored_threads를 사용하면 특정 Telegram 포럼 topic에서는 Hermes가 항상 조용히 있게 할 수 있습니다. 그룹이 자유 응답이나 mention 기반 응답을 허용하더라도 이 설정이 먼저 적용됩니다.
  • telegram.require_mention을 설정하지 않거나 false로 두면, Hermes는 기존 open-group 동작을 유지하고 볼 수 있는 일반 그룹 메시지에 응답합니다.

문제 해결: DM에서는 되지만 그룹에서는 안 되는 경우

봇이 private chat에서는 응답하지만 그룹에서는 조용하다면, 아래 gate를 순서대로 확인하세요.

  1. Telegram 전달: BotFather privacy mode를 끄거나, 봇을 관리자로 승격하거나, 봇을 직접 mention하세요. Telegram이 봇에게 전달하지 않은 그룹 메시지에는 Hermes가 응답할 수 없습니다.
  2. Privacy 변경 후 재입장: BotFather privacy 설정을 바꾼 뒤에는 봇을 그룹에서 제거하고 다시 추가하세요. 기존 멤버십에는 이전 전달 동작이 유지될 수 있습니다.
  3. Hermes 인증: 보낸 사람이 TELEGRAM_ALLOWED_USERS 또는 TELEGRAM_GROUP_ALLOWED_USERS에 있는지 확인하거나, TELEGRAM_GROUP_ALLOWED_CHATS로 그룹 채팅을 허용하세요.
  4. Mention 필터: telegram.require_mention: true라면 일반 그룹 대화는 무시됩니다. Slash command, 봇에게 하는 답장, @botusername mention, 설정된 mention_patterns match 중 하나여야 합니다.

Telegram group과 supergroup의 채팅 ID가 음수인 것은 정상입니다. 채팅 단위 인증을 쓰는 경우 보낸 사람 allowlist가 아니라 TELEGRAM_GROUP_ALLOWED_CHATS에 그 ID를 넣으세요.

그룹 trigger 설정 예시

~/.hermes/config.yaml에 다음을 추가합니다.

telegram:
require_mention: true
mention_patterns:
- "^\\s*chompy\\b"
ignored_threads:
- 31
- "42"

이 예시는 일반 direct trigger에 더해 @mention이 없어도 chompy로 시작하는 메시지를 허용합니다. Telegram topic 3142의 메시지는 mention 및 자유 응답 검사보다 먼저 항상 무시됩니다.

mention_patterns 참고사항

  • 패턴은 Python 정규식을 사용합니다.
  • 매칭은 대소문자를 구분하지 않습니다.
  • 패턴은 텍스트 메시지와 미디어 caption 모두에 대해 확인됩니다.
  • 잘못된 정규식 패턴은 봇을 종료시키지 않습니다. 게이트웨이 로그에 warning을 남기고 무시됩니다.
  • 메시지 시작에서만 매칭하고 싶다면 ^로 anchor하세요.

Private Chat Topics(Bot API 9.4)

Telegram Bot API 9.4(2026년 2월)는 Private Chat Topics를 도입했습니다. 이제 봇은 supergroup 없이도 1:1 DM 채팅 안에 forum-style topic thread를 만들 수 있습니다. 이 기능을 사용하면 하나의 Hermes DM 안에서 서로 격리된 여러 작업 공간을 운영할 수 있습니다.

사용 사례

여러 장기 프로젝트를 동시에 진행한다면 topic으로 context를 분리할 수 있습니다.

  • "Website" topic - 운영 웹 서비스 작업
  • "Research" topic - 문헌 검토와 논문 탐색
  • "General" topic - 잡다한 작업과 빠른 질문

각 topic은 고유한 conversation session, history, context를 가지며 서로 완전히 격리됩니다.

설정

사전 조건

설정 파일에 topic을 추가하기 전에, 사용자가 봇과의 DM 채팅에서 Topics mode를 켜야 합니다.

  1. Telegram에서 Hermes 봇과의 private chat을 엽니다.
  2. 상단의 봇 이름을 눌러 chat info를 엽니다.
  3. Topics를 켭니다. 채팅을 forum으로 바꾸는 toggle입니다.

이 작업을 하지 않으면 Hermes는 시작 시 The chat is not a forum을 로그에 남기고 topic 생성을 건너뜁니다. 이 값은 Telegram 클라이언트 측 설정입니다. 봇은 이 설정을 프로그래밍 방식으로 켤 수 없습니다.

~/.hermes/config.yamlplatforms.telegram.extra.dm_topics 아래에 topic을 추가합니다.

platforms:
telegram:
extra:
dm_topics:
- chat_id: 123456789 # 내 Telegram 사용자 ID
topics:
- name: General
icon_color: 7322096
- name: Website
icon_color: 9367192
- name: Research
icon_color: 16766590
skill: arxiv # 이 topic에서 skill 자동 load

필드:

필드필수설명
nameTopic 표시 이름
icon_color아니요Telegram icon color code(integer)
icon_custom_emoji_id아니요Topic icon용 custom emoji ID
skill아니요이 topic의 새 session에서 자동 load할 skill
thread_id아니요Topic 생성 후 자동으로 채워집니다. 수동으로 설정하지 마세요.

동작 방식

  1. Gateway startup 때 Hermes는 아직 thread_id가 없는 각 topic에 대해 createForumTopic을 호출합니다.
  2. 생성된 thread_idconfig.yaml에 자동 저장됩니다. 이후 restart에서는 API call을 건너뜁니다.
  3. 각 topic은 격리된 session key에 매핑됩니다. 형식은 agent:main:telegram:dm:{chat_id}:{thread_id}입니다.
  4. 각 topic의 메시지는 독립적인 conversation history, memory flush, context window를 가집니다.

Skill binding

skill field가 있는 topic은 그 topic에서 새 session이 시작될 때 해당 skill을 자동 load합니다. 대화 시작 시 /skill-name을 입력하는 것과 같은 방식입니다. Skill content가 첫 메시지에 주입되고, 이후 메시지는 conversation history에서 이를 참조합니다.

예를 들어 skill: arxiv가 있는 topic은 idle timeout, daily reset, manual /reset 등으로 session이 reset될 때마다 arxiv skill이 미리 load됩니다.

Config 밖에서 만든 topic, 예를 들어 Telegram API를 수동 호출해 만든 topic도 forum_topic_created service message가 도착하면 자동으로 발견됩니다. 게이트웨이 실행 중 config에 topic을 추가할 수도 있으며, 다음 cache miss 때 반영됩니다.

Multi-session DM mode(/topic)

ChatGPT 스타일의 multi-session DM입니다. 하나의 봇 안에서 여러 병렬 대화를 운영합니다. 위의 operator-curated extra.dm_topics와 달리 이 모드는 user-driven입니다. Config도, 미리 선언한 topic name도 필요 없습니다. End user가 /topic으로 모드를 켠 뒤 Telegram + 버튼을 눌러 원하는 만큼 topic을 만들 수 있고, 각 topic은 완전히 독립된 Hermes session이 됩니다.

/topic 하위 명령

형식컨텍스트효과
/topicRoot DM, 아직 enabled 아님BotFather capability를 확인하고 multi-session mode를 켜며 pinned System topic을 만듭니다.
/topicRoot DM, 이미 enabled상태를 보여 줍니다. Restore 가능한 unlinked session도 나열합니다.
/topicTopic 내부현재 topic의 session binding을 보여 줍니다.
/topic help어디서나Inline usage를 표시합니다.
/topic offRoot DMMulti-session mode를 끄고 이 chat의 모든 topic binding을 지웁니다.
/topic <session-id>Topic 내부이전 Telegram session을 현재 topic으로 restore합니다.

허가된 사용자(TELEGRAM_ALLOWED_USERS / platform auth config allowlist)만 /topic을 실행할 수 있습니다. 허가되지 않은 sender는 activation 대신 거부 응답을 받습니다.

DM Topics와 Multi-session DM mode 비교

extra.dm_topics(config-driven)/topic(user-driven)
누가 활성화하는가Operator가 config.yaml에서 활성화End user가 /topic을 보내 활성화
Topic listConfig에 선언한 고정 set사용자가 자유롭게 생성/삭제
Topic namesOperator가 선택사용자가 선택. Hermes session title에 맞춰 자동 rename
Root DM behavior변경 없음. 일반 chatSystem lobby가 됨. Non-command message는 거부
Primary use case선택적 skill binding이 있는 영구 workspaceAd-hoc parallel session
PersistenceConfig의 extra.dm_topicsSQLite table telegram_dm_topic_mode, telegram_dm_topic_bindings

두 기능은 같은 봇에서 공존할 수 있습니다. 사용자의 DM에서는 /topic을 쓰고, extra.dm_topics는 다른 chat의 operator-declared topic을 계속 관리할 수 있습니다.

사전 조건

@BotFather에서 자신의 봇을 열고 Bot Settings -> Threads Settings로 이동합니다.

  1. Threaded Mode를 켭니다. has_topics_enabled를 활성화합니다.
  2. 사용자가 topic을 만들 수 없도록 막지 마세요. allows_users_to_create_topics가 켜져 있어야 합니다.

사용자가 처음 /topic을 실행하면 Hermes는 getMe를 호출해 두 flag를 확인합니다. 둘 중 하나라도 꺼져 있으면 Hermes는 BotFather Threads Settings page screenshot을 보내고 어떤 toggle을 켜야 하는지 설명합니다. 사전 조건이 충족되기 전에는 activation이 일어나지 않습니다.

활성화 흐름

Root DM에서 다음을 보냅니다.

/topic

Hermes는 다음을 수행합니다.

  1. getMe().has_topics_enabledallows_users_to_create_topics를 확인합니다.
  2. 둘 다 true이면 이 DM에 multi-session topic mode를 켭니다.
  3. Status/command용 System topic을 만들고 pin합니다(best-effort).
  4. 사용자가 restore할 수 있는 이전 unlinked Telegram session 목록을 응답합니다.

Activation 후 root DM은 lobby가 됩니다. 일반 prompt는 All Messages를 가리키는 안내와 함께 거부됩니다. /status, /sessions, /usage, /help 같은 system command는 root에서도 계속 동작합니다.

새 topic 만들기(end-user flow)

  1. Telegram에서 봇 DM을 엽니다.
  2. 봇 interface 상단의 All Messages를 누르고 아무 메시지나 보냅니다.
  3. Telegram이 그 메시지를 위한 새 topic을 만듭니다.
  4. Hermes가 그 topic 안에서 응답합니다. 이제 이 topic은 standalone session입니다.

모든 topic은 고유 conversation history, model state, tool execution, session ID를 가집니다. Isolation key는 agent:main:telegram:dm:{chat_id}:{thread_id}이며, config-driven DM topics와 동일합니다.

Topic 자동 rename

Hermes가 첫 exchange 이후 auto-title pipeline으로 topic의 session title을 생성하면 Telegram topic 자체도 그 title에 맞춰 rename됩니다. 예를 들어 "New Topic"이 "Database migration plan"이 됩니다. Rename은 best-effort입니다. 실패는 log에 남지만 session을 깨뜨리지 않습니다.

Topic 안에서 /new 사용

현재 topic의 session만 reset합니다. 새 session ID와 fresh history를 만들고, 다른 topic에는 영향을 주지 않습니다. Hermes는 병렬 작업이 목적이라면 /new보다 All Messages에서 새 topic을 만드는 것이 보통 더 적합하다는 reminder를 응답합니다.

이전 session restore

Topic 안에서 다음을 보냅니다.

/topic <session-id>

그러면 현재 topic이 fresh session 대신 기존 Hermes session에 bind됩니다. Topic mode를 켜기 전에 시작했던 대화를 계속하고 싶을 때 유용합니다. 제약은 다음과 같습니다.

  • 대상 session은 같은 Telegram user의 것이어야 합니다.
  • 대상 session은 이미 다른 topic에 bind되어 있으면 안 됩니다.

Hermes는 session title로 확인 메시지를 보내고, context를 위해 마지막 assistant message를 replay합니다.

Session ID를 찾으려면 root DM에서 argument 없이 /topic을 보내세요. Hermes가 해당 사용자의 unlinked Telegram session을 나열합니다.

Topic 안에서 /topic만 입력한 경우

현재 topic의 binding을 보여 줍니다. Session title, session ID, /new를 쓸지 새 topic을 만들지에 대한 hint가 포함됩니다.

내부 동작

  • Activation은 state.dbtelegram_dm_topic_mode(chat_id, user_id, enabled, ...)에 저장됩니다.
  • 각 topic binding은 telegram_dm_topic_bindings(chat_id, thread_id, session_id, ...)에 저장되며 session_idON DELETE CASCADE가 걸려 있습니다. Session pruning이 일어나면 topic binding도 자동으로 정리됩니다.
  • Topic-mode SQLite migration은 opt-in입니다. Gateway startup이 아니라 첫 /topic 호출 때 실행됩니다. 사용자가 이 profile에서 /topic을 실행하기 전까지 state.db는 변경되지 않습니다.
  • Inbound DM message마다 (chat_id, thread_id) binding을 조회합니다. 있으면 SessionStore.switch_session()으로 메시지를 bound session에 route하여 session-key-to-session-id mapping이 disk에서 일관되게 유지되도록 합니다.
  • Topic 안의 /new는 binding row를 새 session ID로 다시 씁니다. 다음 message는 fresh session으로 이어집니다.
  • extra.dm_topics에 선언된 topic은 자동 rename되지 않습니다. Multi-session mode가 켜져 있어도 operator가 정한 이름을 보존합니다.
  • Forum-enabled DM에서 pinned top의 General topic은 Telegram이 message_thread_id=1로 전달하든 thread_id 없이 전달하든 root lobby로 취급합니다.
  • Root-lobby reminder는 chat당 30초에 1회로 rate-limit됩니다. 사용자가 topic mode가 켜진 것을 잊고 root에 prompt 10개를 입력해도 응답 10개가 오지 않습니다.
  • BotFather setup screenshot은 chat당 5분에 1회 전송으로 rate-limit됩니다. Threads Settings가 아직 꺼져 있는 상태에서 /topic을 반복해도 같은 이미지를 계속 upload하지 않습니다.
  • Topic 안에서 시작한 /background &lt;prompt&gt;는 결과를 같은 topic으로 전달합니다. Background session은 owning topic의 auto-rename을 trigger하지 않습니다.
  • /topic 자체도 bot의 user authorization check를 거칩니다. Unauthorized DM은 activation 대신 refusal을 받습니다.

Multi-session mode 비활성화

Root DM에서 /topic off를 보냅니다. Hermes는 row를 off로 바꾸고, 해당 chat의 (thread_id -> session_id) binding을 지우며, root DM을 일반 Hermes chat으로 되돌립니다. Telegram에 이미 존재하는 topic은 삭제되지 않습니다. 독립 session으로 gate되지 않을 뿐입니다. 나중에 /topic을 다시 실행하면 mode를 다시 켤 수 있습니다.

많은 chat을 한 번에 reset하는 등 수동 cleanup이 필요하다면 row를 직접 제거할 수 있습니다.

sqlite3 ~/.hermes/state.db \
"UPDATE telegram_dm_topic_mode SET enabled = 0 WHERE chat_id = '<your_chat_id>'; \
DELETE FROM telegram_dm_topic_bindings WHERE chat_id = '<your_chat_id>';"

Hermes downgrade

/topic이 도입되기 전 Hermes 버전으로 downgrade하면 이 기능은 단순히 동작하지 않습니다. telegram_dm_topic_modetelegram_dm_topic_bindings table은 state.db에 남아 있지만 older code가 무시합니다. DM은 native per-thread isolation으로 돌아갑니다. 각 message_thread_id는 여전히 build_session_key를 통해 고유 session을 가지므로, 기존 Telegram topic은 병렬 session으로 계속 동작합니다. Root DM은 더 이상 lobby가 아니며 예전처럼 agent에게 메시지가 들어갑니다. 다시 upgrade하면 multi-session mode는 이전 상태 그대로 재활성화됩니다.

Group Forum Topic Skill Binding

Topics mode가 켜진 supergroup, 즉 forum topic이 있는 그룹은 이미 topic별 session isolation을 제공합니다. 각 thread_id가 고유 conversation에 매핑됩니다. 다만 DM topic skill binding처럼 특정 그룹 topic에 메시지가 도착할 때 skill을 자동 load하고 싶을 수 있습니다.

사용 사례

여러 workstream을 위한 forum topic이 있는 team supergroup 예시입니다.

  • Engineering topic - software-development skill 자동 load
  • Research topic - arxiv skill 자동 load
  • General topic - skill 없이 general-purpose assistant

설정

~/.hermes/config.yamlplatforms.telegram.extra.group_topics 아래에 topic binding을 추가합니다.

platforms:
telegram:
extra:
group_topics:
- chat_id: -1001234567890 # Supergroup ID
topics:
- name: Engineering
thread_id: 5
skill: software-development
- name: Research
thread_id: 12
skill: arxiv
- name: General
thread_id: 1
# skill 없음 - general purpose

Fields:

필드필수설명
chat_idSupergroup의 numeric ID입니다. -100으로 시작하는 음수입니다.
name아니요사람이 읽기 위한 topic label입니다. 정보용입니다.
thread_idTelegram forum topic ID입니다. t.me/c/&lt;group_id&gt;/&lt;thread_id&gt; link에서 볼 수 있습니다.
skill아니요이 topic의 새 session에서 자동 load할 skill

동작 방식

  1. 매핑된 group topic에 message가 도착하면 Hermes가 group_topics config에서 chat_idthread_id를 조회합니다.
  2. 일치하는 entry에 skill field가 있으면 그 skill을 session에 자동 load합니다. DM topic skill binding과 동일합니다.
  3. skill key가 없는 topic은 session isolation만 적용합니다. 기존 동작과 같습니다.
  4. 매핑되지 않은 thread_idchat_id는 조용히 통과합니다. Error도 skill load도 없습니다.

DM Topics와의 차이

DM TopicsGroup Topics
Config keyextra.dm_topicsextra.group_topics
Topic creationthread_id가 없으면 Hermes가 API로 topic 생성Admin이 Telegram UI에서 topic 생성
thread_id생성 후 자동 입력수동 입력 필요
icon_color / icon_custom_emoji_id지원적용 안 됨. Admin이 appearance 제어
Skill binding지원지원
Session isolation지원지원. Forum topic에는 이미 built-in

Topic의 thread_id를 찾으려면 Telegram Web 또는 Desktop에서 topic을 열고 URL을 확인하세요. https://t.me/c/1234567890/5에서 마지막 숫자 5thread_id입니다. Supergroup의 chat_id는 group ID 앞에 -100을 붙인 값입니다. 예: group 1234567890 -> -1001234567890.

최근 Bot API 기능

  • Bot API 9.4(2026년 2월): Private Chat Topics. 봇이 createForumTopic으로 1:1 DM chat 안에 forum topic을 만들 수 있습니다. Hermes는 이 기능을 두 가지로 사용합니다. Operator-curated Private Chat Topics(config-driven, fixed topic list)와 user-driven Multi-session DM mode(/topic으로 활성화, 사용자가 topic을 제한 없이 생성)입니다.
  • Privacy policy: Telegram은 이제 봇에 privacy policy가 있기를 요구합니다. BotFather의 /setprivacy_policy로 설정하세요. 설정하지 않으면 Telegram이 placeholder를 자동 생성할 수 있습니다. Public-facing bot이라면 특히 중요합니다.
  • Bot API 9.5(2026년 3월): sendMessageDraft 기반 native streaming. Hermes는 Telegram의 native streaming-draft API를 사용해 private chat에서 에이전트 답변이 token 단위로 들어오는 animated preview를 렌더링합니다. 느린 모델에서 legacy editMessageText polling path가 만들던 per-edit jitter를 줄입니다.

Streaming transport(gateway.streaming.transport)

Streaming이 켜져 있으면(gateway.streaming.enabled: true) Hermes는 네 가지 transport 중 하나를 선택합니다.

동작
auto(기본값)지원되는 chat(현재 Telegram DM)에서는 native draft streaming을 사용하고, 그 외에는 legacy edit-based path를 사용합니다. Draft frame이 실패하면 graceful fallback합니다.
draftNative draft를 강제합니다. Chat이 draft를 지원하지 않으면, 예를 들어 group/topic에서는 downgrade를 log에 남기고 edit으로 fallback합니다.
edit모든 chat type에서 legacy progressive editMessageText polling을 사용합니다.
offStreaming을 완전히 끕니다. Progressive update 없이 final reply만 보냅니다.

~/.hermes/config.yaml 예시:

gateway:
streaming:
enabled: true
transport: auto # auto | draft | edit | off

auto(기본값)로 DM에서 보이는 것: 에이전트가 reply를 생성하는 동안 Telegram은 token-by-token으로 업데이트되는 animated draft preview를 보여 줍니다. Reply가 끝나면 일반 message로 전달되고 draft preview는 client에서 자연스럽게 사라집니다. Draft에는 message id가 없으므로 chat history에는 최종 답변만 남습니다.

Group, supergroup, forum topic은 어떻게 되나? Telegram은 sendMessageDraft를 private chat(DM)으로 제한합니다. 게이트웨이는 나머지 chat type에서 자동으로 edit-based path로 fallback합니다. 이전과 같은 UX입니다.

Draft frame이 실패하면? 일시적 network error, server-side rejection, 오래된 python-telegram-bot 설치 등 어떤 실패든 해당 response의 나머지 stream은 edit-based path로 전환됩니다. 다음 response에서는 다시 새로 시도합니다.

Telegram MarkdownV2에는 네이티브 표 문법이 없습니다. Pipe table을 그대로 넘기면 backslash-escaped noise처럼 보입니다. Hermes는 Markdown 표를 자동으로 normalize합니다.

  • 작은 표row-group bullet로 펼칩니다. 각 row가 column heading 아래 읽기 쉬운 bullet list가 됩니다. 2-4개 column과 짧은 cell에 적합합니다.
  • 크거나 넓은 표는 aligned column을 가진 fenced code block으로 fallback합니다. 내용이 무너지지 않게 하기 위함입니다. 에이전트가 Telegram에서는 표보다 문장형 follow-up을 선호하도록 one-line prompt hint도 추가합니다.

설정할 것은 없습니다. Adapter가 message마다 적절한 fallback을 선택합니다. 예전의 "항상 code-block" 동작을 원한다면 config.yaml에서 telegram.pretty_tables: false로 table normalization을 끌 수 있습니다. 기본값은 true입니다.

Link previews. Telegram은 봇 message 안의 URL에 link preview를 자동 생성합니다. 긴 /tools 출력이나 link가 많은 에이전트 reply에서 preview를 숨기고 싶다면 다음을 설정하세요.

gateway:
platforms:
telegram:
extra:
disable_link_previews: true

켜져 있으면 Hermes는 모든 outgoing message에 Telegram의 LinkPreviewOptions(is_disabled=True)를 붙입니다. 오래된 python-telegram-bot version에서는 legacy disable_web_page_preview parameter로 fallback합니다.

Group Allowlisting

Telegram group과 forum chat에는 서로 독립적인 두 gate를 설정할 수 있습니다.

  • Sender user IDs(group_allow_from / TELEGRAM_GROUP_ALLOWED_USERS) - group/forum message에만 적용되는 sender-scoped allowlist입니다. 특정 사용자가 group에서 봇을 호출할 수 있게 하되, TELEGRAM_ALLOWED_USERS에 넣어 DM access까지 주고 싶지는 않을 때 사용합니다.
  • Chat IDs(group_allowed_chats / TELEGRAM_GROUP_ALLOWED_CHATS) - chat-scoped allowlist입니다. 이 group/forum의 모든 member가 봇과 상호작용할 수 있습니다. Team/support bot처럼 group membership 자체가 access signal인 경우 유용합니다.
gateway:
platforms:
telegram:
extra:
# Global access(DM + groups). 여기의 사용자는 항상 봇을 invoke할 수 있습니다.
allow_from:
- "123456789"
# Group/forum에서만 허용되는 sender ID. DM access를 부여하지 않습니다.
group_allow_from:
- "987654321"
# 전체 group/forum. 모든 member가 authorized됩니다.
group_allowed_chats:
- "-1001234567890"

동등한 env var는 다음과 같습니다.

TELEGRAM_ALLOWED_USERS="123456789"
TELEGRAM_GROUP_ALLOWED_USERS="987654321"
TELEGRAM_GROUP_ALLOWED_CHATS="-1001234567890"

동작:

  • TELEGRAM_ALLOWED_USERS는 모든 chat type(DM, group, forum)에 적용됩니다.
  • TELEGRAM_GROUP_ALLOWED_USERS는 listed sender를 group/forum에서만 authorize합니다. TELEGRAM_ALLOWED_USERS에 없으면 이 사용자는 봇에게 DM을 보낼 수 없습니다.
  • TELEGRAM_GROUP_ALLOWED_CHATS의 chat은 sender와 무관하게 그 chat의 모든 member를 authorize합니다.
  • 어느 항목에든 *를 쓰면 모든 sender/chat을 허용합니다.
  • 이 설정은 기존 mention/pattern trigger 위에, 그리고 group_topics + ignored_threads 위에 layer됩니다.

PR #17686 이전 설정에서 migration

이 분리 전에는 TELEGRAM_GROUP_ALLOWED_USERS가 유일한 knob였고, 사용자들이 여기에 chat ID를 넣었습니다. 하위 호환성을 위해 TELEGRAM_GROUP_ALLOWED_USERS 안의 chat-ID-shaped value, 즉 -로 시작하는 값은 여전히 chat ID로 인정되며 deprecation warning이 한 번 log됩니다. Migration은 다음과 같습니다.

# Old (still works, but deprecated)
TELEGRAM_GROUP_ALLOWED_USERS="-1001234567890"

# New
TELEGRAM_GROUP_ALLOWED_CHATS="-1001234567890"

Slash Command 접근 제어

기본적으로 allowed user는 모든 slash command를 실행할 수 있습니다. Allowlist를 admin(모든 slash command 접근)과 regular user(명시적으로 허용한 command만 접근)로 나누려면 platform의 extra block에 allow_admin_fromuser_allowed_commands를 추가하세요.

gateway:
platforms:
telegram:
extra:
# 기존 allowlist(변경 없음)
allow_from:
- "123456789" # admin
- "555555555" # regular user
- "777777777" # regular user

# NEW - admin은 모든 slash command를 사용할 수 있습니다(built-in + plugin).
allow_admin_from:
- "123456789"

# NEW - non-admin allowed user는 여기 나열한 slash command만 실행할 수 있습니다.
# /help와 /whoami는 사용자가 자신의 접근 권한을 확인할 수 있도록 항상 허용됩니다.
user_allowed_commands:
- status
- model
- history

# 선택: group용 admin/command list를 별도로 둡니다.
group_allow_admin_from:
- "123456789"
group_user_allowed_commands:
- status

동작:

  • 특정 scope(DM 또는 group)의 allow_admin_from에 있는 사용자는 live registry를 통해 등록된 모든 slash command를 실행할 수 있습니다. Built-in command와 plugin-registered command를 모두 포함합니다.
  • allow_from에는 있지만 allow_admin_from에는 없는 사용자는 user_allowed_commands에 나열된 command와 항상 허용되는 최소 command인 /help, /whoami만 실행할 수 있습니다.
  • Plain chat, 즉 slash가 아닌 일반 message는 영향을 받지 않습니다. Non-admin user도 에이전트와 정상 대화할 수 있지만 임의 command를 trigger할 수는 없습니다.
  • Backward compat: 특정 scope에 allow_admin_from이 설정되어 있지 않으면 그 scope의 slash command gating은 비활성화됩니다. 기존 설치는 변경 없이 계속 동작합니다.
  • DM admin status는 group admin status를 의미하지 않습니다. 각 scope는 별도 admin list를 가집니다.
  • group_allow_admin_from만 설정되어 있으면 DM scope는 backward-compat을 위해 unrestricted mode로 남습니다.

/whoami를 사용하면 active scope, 자신의 tier(admin / user / unrestricted), 실행 가능한 slash command를 확인할 수 있습니다.

Interactive Model Picker

Telegram chat에서 argument 없이 /model을 보내면 Hermes가 모델 전환용 interactive inline keyboard를 보여 줍니다.

  1. Provider selection - 사용 가능한 각 provider와 model count를 button으로 보여 줍니다. 예: "OpenAI (15)", 현재 provider에는 "✓ Anthropic (12)"처럼 표시됩니다.
  2. Model selection - paginated model list를 보여 줍니다. Prev/Next navigation, provider로 돌아가는 Back, Cancel button을 제공합니다.

현재 model과 provider는 상단에 표시됩니다. 모든 navigation은 같은 message를 in-place edit하는 방식으로 진행되어 chat이 지저분해지지 않습니다.

정확한 model name을 알고 있다면 /model &lt;name&gt;을 직접 입력해 picker를 건너뛸 수 있습니다. /model &lt;name&gt; --global을 입력하면 변경 사항을 session 전체에 persist할 수 있습니다.

DNS-over-HTTPS Fallback IPs

일부 제한된 network에서는 api.telegram.org가 unreachable IP로 resolve될 수 있습니다. Telegram adapter에는 fallback IP mechanism이 있어, 올바른 TLS hostname과 SNI를 유지하면서 alternative IP로 connection을 재시도합니다.

동작 방식

  1. TELEGRAM_FALLBACK_IPS가 설정되어 있으면 그 IP를 직접 사용합니다.
  2. 그렇지 않으면 adapter가 DNS-over-HTTPS(DoH)로 Google DNSCloudflare DNS를 조회하여 api.telegram.org의 alternative IP를 찾습니다.
  3. DoH가 반환한 IP 중 system DNS result와 다른 IP를 fallback으로 사용합니다.
  4. DoH도 차단되어 있으면 hardcoded seed IP(149.154.167.220)를 마지막 수단으로 사용합니다.
  5. Fallback IP가 한 번 성공하면 "sticky"가 됩니다. 이후 request는 primary path를 먼저 재시도하지 않고 그 IP를 직접 사용합니다.

설정

# Explicit fallback IPs (comma-separated)
TELEGRAM_FALLBACK_IPS=149.154.167.220,149.154.167.221

또는 ~/.hermes/config.yaml에 설정합니다.

platforms:
telegram:
extra:
fallback_ips:
- "149.154.167.220"

보통은 직접 설정할 필요가 없습니다. DoH auto-discovery가 대부분의 restricted-network 상황을 처리합니다. TELEGRAM_FALLBACK_IPS 환경 변수는 network에서 DoH까지 차단된 경우에만 필요합니다.

Proxy 지원

회사 network처럼 internet 접근에 HTTP proxy가 필요한 환경에서는 Telegram adapter가 표준 proxy environment variable을 자동으로 읽고 모든 connection을 proxy로 route합니다.

지원 변수

Adapter는 다음 environment variable을 순서대로 확인하고, 처음 설정된 값을 사용합니다.

  1. HTTPS_PROXY
  2. HTTP_PROXY
  3. ALL_PROXY
  4. https_proxy / http_proxy / all_proxy(lowercase variants)

설정

게이트웨이를 시작하기 전에 환경에 proxy를 설정합니다.

export HTTPS_PROXY=http://proxy.example.com:8080
hermes gateway

또는 ~/.hermes/.env에 추가합니다.

HTTPS_PROXY=http://proxy.example.com:8080

이 proxy는 primary transport와 모든 fallback IP transport에 적용됩니다. 추가 Hermes 설정은 필요 없습니다. 환경 변수가 있으면 자동으로 사용합니다.

노트

이 섹션은 Hermes가 Telegram connection에 사용하는 custom fallback transport layer를 다룹니다. 다른 곳에서 쓰는 표준 httpx client는 proxy env var를 원래부터 native로 존중합니다.

Message Reactions

봇은 처리 상태를 시각적으로 보여 주기 위해 메시지에 emoji reaction을 달 수 있습니다.

  • 👀 봇이 메시지 처리를 시작했을 때
  • ✅ response가 성공적으로 전달되었을 때
  • ❌ 처리 중 error가 발생했을 때

Reaction은 기본적으로 disabled입니다. config.yaml에서 켭니다.

telegram:
reactions: true

또는 환경 변수로 설정합니다.

TELEGRAM_REACTIONS=true
노트

Discord에서는 reaction이 누적되지만, Telegram Bot API는 한 번의 call에서 bot reaction 전체를 교체합니다. 👀에서 ✅ 또는 ❌로의 전환은 원자적으로 일어납니다. 둘을 동시에 보지는 않습니다.

Group에서 봇이 reaction을 추가할 permission이 없다면 reaction call은 조용히 실패하고 message processing은 정상적으로 계속됩니다.

Per-Channel Prompts

특정 Telegram group이나 forum topic에 ephemeral system prompt를 배정할 수 있습니다. Prompt는 매 turn runtime에 주입되며 transcript history에는 저장되지 않습니다. 그래서 변경 사항이 즉시 반영됩니다.

telegram:
channel_prompts:
"-1001234567890": |
You are a research assistant. Focus on academic sources,
citations, and concise synthesis.
"42": |
This topic is for creative writing feedback. Be warm and
constructive.

Key는 chat ID(group/supergroup) 또는 forum topic ID입니다. Forum group에서는 topic-level prompt가 group-level prompt보다 우선합니다.

  • Group -1001234567890 안의 topic 42 메시지 -> topic 42의 prompt 사용
  • Topic 99 메시지에 explicit entry가 없음 -> group -1001234567890 prompt로 fallback
  • Entry가 없는 group의 메시지 -> channel prompt 적용 안 함

Numeric YAML key는 자동으로 string으로 normalize됩니다.

문제 해결

문제해결 방법
봇이 전혀 응답하지 않음TELEGRAM_BOT_TOKEN이 올바른지 확인하세요. hermes gateway log에서 error를 확인하세요.
봇이 "unauthorized"라고 응답User ID가 TELEGRAM_ALLOWED_USERS에 없습니다. @userinfobot으로 다시 확인하세요.
봇이 group message를 무시Privacy mode가 켜져 있을 가능성이 큽니다. 끄거나(3단계) 봇을 group admin으로 만드세요. Privacy 변경 후에는 봇을 제거했다가 다시 추가해야 합니다.
Voice message가 전사되지 않음STT가 사용 가능한지 확인하세요. Local transcription에는 faster-whisper를 설치하고, cloud provider를 쓰려면 ~/.hermes/.envGROQ_API_KEY / VOICE_TOOLS_OPENAI_KEY를 설정하세요.
Voice reply가 bubble이 아니라 file로 옴ffmpeg를 설치하세요. Edge TTS Opus 변환에 필요합니다.
Bot token revoked/invalidBotFather에서 /revoke/newbot 또는 /token으로 새 token을 생성하고 .env를 업데이트하세요.
Webhook이 update를 받지 못함TELEGRAM_WEBHOOK_URL이 public에서 접근 가능한지 확인하세요(curl로 테스트). Platform/reverse proxy가 URL의 inbound HTTPS traffic을 TELEGRAM_WEBHOOK_PORT로 설정한 local listen port에 route하는지 확인하세요. 외부 port와 local port가 같은 숫자일 필요는 없습니다. SSL/TLS가 켜져 있어야 합니다. Telegram은 HTTPS URL에만 전송합니다. Firewall rule도 확인하세요.

실행 승인

에이전트가 위험할 수 있는 command를 실행하려고 하면 chat에서 승인을 요청합니다.

⚠️ This command is potentially dangerous (recursive delete). Reply "yes" to approve.

승인하려면 "yes" 또는 "y"를, 거부하려면 "no" 또는 "n"을 답하세요.

Interactive Prompts(clarify)

에이전트가 clarify tool을 호출해 접근 방식을 고르라고 묻거나, task 후 feedback을 받거나, 중요한 결정 전에 확인을 요청하면 Telegram은 질문을 inline keyboard button으로 렌더링합니다.

Which framework should I use for the dashboard?

[1. Next.js] [2. Remix] [3. Astro] [Other (type answer)]

Button을 눌러 답하거나, Other를 눌러 free-form response를 입력할 수 있습니다. Other를 누른 뒤 다음에 보내는 메시지가 답변으로 사용됩니다. 선택지가 없는 open-ended clarify call은 button 없이 다음 메시지를 그대로 capture합니다.

응답 timeout은 ~/.hermes/config.yamlagent.clarify_timeout으로 설정합니다. 기본값은 600초입니다. Timeout 안에 응답하지 않으면 에이전트는 sentinel message로 unblock되고, 멈춰 있지 않고 상황에 맞게 진행합니다.

보안

경고

봇과 상호작용할 수 있는 사용자를 제한하려면 반드시 TELEGRAM_ALLOWED_USERS를 설정하세요. 이 값이 없으면 게이트웨이는 안전을 위해 기본적으로 모든 사용자를 거부합니다.

봇 token을 공개적으로 공유하지 마세요. 유출되었다면 BotFather의 /revoke command로 즉시 폐기하세요.

자세한 내용은 Security documentation을 참고하세요. 사용자 authorization을 더 동적으로 관리하려면 DM pairing도 사용할 수 있습니다.