实战:团队 Telegram 助手
Hermes 实战教程第3篇:团队 Telegram 助手。给整个团队配一个 AI。
实战:团队 Telegram 助手
兄弟们,今天咱们来点硬核又实用的——把 Hermes Agent 接进 Telegram,搞一个团队都能用的智能助手。别慌,全程不用写代码,跟着点几下就行。
💡 懒人福音:如果你用的是 dashboard 或桌面应用,直接打开 Messaging → Telegram 页面,点 Create with QR 按钮,扫码(或点开链接)就行——Hermes 会自动帮你创建机器人、识别你的 Telegram 用户 ID,把
TELEGRAM_BOT_TOKEN和TELEGRAM_ALLOWED_USERS写进你配置的.env,然后重启网关。想自己动手的,接着往下看。
第一步:找 BotFather 要个“机器人身份证”
Telegram 里所有机器人都是 @BotFather 管的。操作超简单:
- 打开 Telegram,搜 @BotFather(或者直接访问 t.me/BotFather)
- 发送
/newbot - 给它起个显示名,比如 “Hermes Agent”
- 再起个唯一的用户名,必须以
bot结尾,比如my_hermes_bot - BotFather 会回你一串 API Token,长这样:
123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
⚠️ 这串 Token 就是机器人的命根子,谁拿到谁就能控制你的机器人。万一泄露了,赶紧回 BotFather 用
/revoke吊销重来。
第二步:给机器人“化妆”(可选但推荐)
想让队友用得舒服?给 BotFather 发这些命令:
| 命令 | 作用 |
|---|---|
/setdescription |
设置机器人开场白 |
/setabouttext |
个人主页简介 |
/setuserpic |
上传头像 |
/setcommands |
设置 / 菜单命令 |
/setprivacy |
控制群聊消息可见性 |
推荐用 /setcommands 设置一组基础命令:
help - Show help information
new - Start a new conversation
sethome - Set this chat as the home channel
第三步:在线状态指示(小彩蛋)
Telegram 机器人没有“在线绿点”,但我们可以曲线救国——用简介文字显示状态。在 ~/.hermes/config.yaml 里加:
gateway:
platforms:
telegram:
extra:
status_indicator: true
status_online: "🟢 Online"
status_offline: "🔴 Offline"
这样网关一连接,机器人简介就显示“🟢 Online”,正常关闭时变“🔴 Offline”。注意:只有干净退出才会变 Offline,直接杀进程的话状态会卡住。另外这个简介是全局的(所有用户都能看到),不是每个聊天单独显示,而且默认关闭,因为它会改动机器人的全局资料。
第四步:冷启动时别丢消息(可选)
默认情况下,网关冷启动时会丢掉 Telegram 服务器上堆积的待处理消息(第一次 start_polling 时 drop_pending_updates=True)。这对 7×24 常开的服务器挺合适——重启就当清理旧账。但如果你是把 Hermes 跑在会关机的机器上(比如晚上关掉的台式机),那离线期间别人发的消息就会在下次开机时被悄悄扔掉,没日志、没重试。
想让这些积压消息在启动时按顺序补上,就把它关掉:
platforms:
telegram:
extra:
drop_pending_on_cold_boot: false
几点提醒:默认是 true,不设就是老行为;网络抖动导致的 watcher 重连(进程还活着)永远保留队列,跟这个开关无关;崩溃后补发的队列可能重放一条已经处理过一半的消息,Telegram 的 offset 一般能挡住,但长时间离线期间发的时效性命令会在开机时执行。
第五步:重复消息去重(可选)
Telegram 偶尔会把同一条 update_id 重复投递过来,Hermes 会在消息批处理、命令/媒体处理、群历史写入和插件观察者之前就把重复的 update_id 拦掉。这个检查按接收适配器 + 数字 bot ID 划分作用域,不按文本或 message_id 去重——所以一条真正的新编辑(带新的 update ID)照样能处理。
这是一层有界的内存保护,不是“精确一次”的保证:
- 适配器记住最近 4096 条已完成的准入记录,不设过期时间。正在处理的 update 会一直保持“已认领”状态,直到分发和它调度的 PTB handler 任务(包括非阻塞的原生插件和注册的错误回调)跑完。
- 同一个适配器重连会保留这份历史;但淘汰、适配器替换或进程重启都可能让旧 update 再次进来——磁盘上不写任何重放账本。
- 准备阶段失败或被取消、且还没交接出去的话,会释放认领;一旦 update 进入批处理/暂存队列、网关分发、观察者或原生插件,之后再出错也不会重新打开。原生插件自己负责自己的部分副作用,所以进入它们的 update 或注册的错误回调会被保守地视为“已交接”。PTB 自己的异常日志不算交接。未缓存的静态贴纸视觉分析也算交接:取消 await 也撤不回已经提交的辅助模型请求。交接前被捕获的准备错误仍可重试;主动拒绝则是终态。
- 释放认领只是允许后续再投递,并不会主动向 Telegram 请求重发。轮询确认和 agent 是否跑完是两码事。这个检查不会重试失败的回复,也挡不住下游组件自己重复干活。
怀疑遇到迟到的重放时,把两次出现的 bot/profile、chat/topic、update_id、update 类型、message_id 和实际接收时间都对比一下——编辑可以复用 message_id,而消息的发送时间戳不等于接收时间。
第六步:命令菜单优化(团队必备)
默认命令菜单上限 60 个,够用但可能不够“顺手”。想让你团队的常用命令排前面?这样配:
platforms:
telegram:
extra:
command_menu:
max_commands: 60
priority_mode: prepend # prepend | append | replace
priority:
- my_plugin_command
- songsee
priority_mode 三种玩法:
prepend:你的命令排最前append:你的命令排最后replace:完全用你的列表
重点来了:以前技能命令总是被优先裁剪,现在只要在 priority 里点名,保证有菜,不会被挤掉。Telegram 本身最多允许 100 条命令,但命令太多容易发送失败,所以 Hermes 默认取 60 条保稳,配置值会被限制在 1..100 之间;想看完整命令列表用 /commands。
第七步:隐藏大招——内联搜索
/ 菜单有上限,但 Telegram 的内联模式没有!在任意聊天框输入 @你的机器人名 加关键词,就能实时搜索所有命令和技能:
@my_hermes_bot plan → 找到 /plan
@my_hermes_bot plan migrate → 直接发送带参数的命令
@my_hermes_bot pdf → 搜到所有跟 pdf 相关的技能
第一个词用来过滤目录,后面的内容会作为参数带进发送的命令里。点一下结果,命令就会以普通消息的形式发出去,走标准命令通道(带命令前缀的消息即使开了隐私模式也能到达机器人)。
注意:内联模式默认关闭,得去 @BotFather 发 /setinline 开启(随便设个占位提示文字,比如 Search commands and skills...)。而且只有通过你网关白名单的人才能看到结果,外人搜到的永远是空列表,隐私安全有保障。
第八步:并发处理,别让一个慢请求拖垮全群
团队场景里最怕的就是“一个人卡住,全群陪跑”。现在 Hermes 把不同聊天的消息改成并发处理了——某个聊天里遇到超长的模型重试、大文件下载,不会再拖住其他聊天。同一个聊天里的消息仍然按到达顺序一条条来,不会乱。
跨聊天的并发池默认是 32,填了非法值会打一条警告并回退到默认值:
platforms:
telegram:
extra:
max_concurrent_updates: 32 # 设为 1 就恢复成完全串行处理
第九步:澄清问题别干等(超时可配)
机器人有时候会反问你一句(比如“你要发到哪个频道?”),然后等你回复。这个等待时间现在可以配了,在 ~/.hermes/config.yaml 里改 agent.clarify_timeout(默认 3600 秒,也就是一小时)。如果你一直不回,agent 不会傻等,会带着 "outcome": "timed_out" 自己往下走、随机应变。不想回答某个问题时,直接回 skip 跳过就行。
最后一步:隐私模式
群聊里机器人默认只看被 @ 的消息。想让它“眼观六路”?在 BotFather 用 /setprivacy 关掉隐私模式即可。不过建议团队场景保持默认,省得被刷屏。
💡 小技巧:不想关隐私模式,也可以把机器人提升为群管理员——管理员机器人无视隐私设置,永远能收到所有消息。
进阶:让机器人“潜水观察”但不乱插嘴
想要 OpenClaw / 元宝那种群聊效果——机器人能看到普通群消息,但只在被直接触发时才回应?这样配:
telegram:
allowed_chats:
- "-1001234567890"
group_allowed_chats:
- "-1001234567890"
require_mention: true
observe_unmentioned_group_messages: true
开启后,来自白名单群/话题的未 @ 消息会作为“观察到的上下文”追加到共享会话记录里,但不会触发 agent。之后在同一个群/话题里 @ 机器人、回复机器人或命中配置的触发词时,就能用上这些上下文。allowed_chats 决定机器人在哪里回应,group_allowed_chats 授权用于观察上下文的共享群会话,所以这个模式下两个列表填一样的 chat ID。这个功能同样要求 Telegram 把普通群消息投递给网关,所以还是得关隐私模式或把机器人设为群管理员。
进阶:DM 话题模式下根消息怎么处理
开了 /topic 话题模式后,有些 Telegram 客户端会把你在根 DM(General / All Messages)里发的消息投递过来,却不带 message_thread_id。默认情况下 Hermes 把它当成“续聊”,回复到你最近活跃的那个话题里(lobby recovery)。
想让每条根 DM 消息都开一个全新会话,就打开 dm_topic_auto_transfer:
gateway:
platforms:
telegram:
extra:
dm_topic_auto_transfer: true # 默认 false
开启后,根 DM 里的普通消息会让 Hermes 新建一个话题(自动改名前叫 “Hermes Chat”),在那里开新会话并把回复发进该话题。根 DM 里输入的斜杠命令仍算 lobby 命令,不会创建话题。如果建话题失败(比如 BotFather 里把 Threaded Mode 关了),Hermes 会回退到默认行为,回复到你最近活跃的话题。这个开关只在 /topic 模式开启时才有意义。顶层的 telegram.extra.dm_topic_auto_transfer 键(桌面设置里显示的那个)同样生效。
进阶:多机器人同群,防止“无限套娃”
群里放了多个 Hermes 机器人时,如果开了 TELEGRAM_ALLOW_BOTS=all,两个机器人互相回复引用可能无限循环——因为对机器人的回复总能通过 require_mention 这道门。把 telegram.bots_require_mention: true(环境变量 TELEGRAM_BOTS_REQUIRE_MENTION)打开就能堵住这条路:来自其他机器人的消息只有明确 @ 本机器人才会触发回应,人类回复不受影响。
另外还有一个机器人循环守卫,会统计每个允许机器人发言的聊天(TELEGRAM_ALLOW_BOTS 设为 mentions 或 all):5 分钟内某个聊天里机器人消息达到 20 条,接下来 10 分钟该聊天的机器人消息会被丢弃,并记录一条警告;人类消息永远不计数、不丢弃。配置在 config.yaml:
gateway:
bot_loop_guard:
enabled: true # false 关闭守卫
max_events: 20 # 每个聊天每个窗口的机器人消息数
window_seconds: 300
cooldown_seconds: 600
注意:如果某个正经机器人确实需要 5 分钟内往一个聊天发超过 20 条消息,也会触发守卫,这种情况把 max_events 调高即可。
搞定!现在你的团队可以在 Telegram 里随时 @ 机器人干活了——发语音自动转文字、定时任务结果推送、群聊协作,全都能玩。快去试试吧!
📖 官方文档
本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/messaging/telegram