Slack 配置
通过 Socket 模式将 Hermes Agent 以机器人身份连接到 Slack。Socket 模式使用 WebSocket 而非公共 HTTP 端点,因此你的 Hermes 实例无需公网访问——可以在防火墙后、笔记本电脑或私有服务器上正常运行。
使用 RTM API 的经典 Slack 应用已于 2025 年 3 月完全弃用。Hermes 使用带有 Socket 模式的现代 Bolt SDK。如果你有旧版经典应用,必须按照以下步骤创建新的应用。
概览
| 组件 | 值 |
|---|---|
| 库 | Python 的 slack-bolt / slack_sdk(Socket 模式) |
| 连接 | WebSocket——无需公网 URL |
| 所需认证令牌 | 机器人令牌(xoxb-)+ 应用级令牌(xapp-) |
| 用户标识 | Slack 成员 ID(如 U01ABC2DEF3) |
步骤 1:创建 Slack 应用
最快的方式是粘贴 Hermes 为你生成的清单文件。它一次性声明了所有内置斜杠命令(/btw、/stop、/model 等)、所有必需的 OAuth 权限范围、所有事件订阅,并启用 Socket 模式。
方式 A:使用 Hermes 生成的清单(推荐)
- 生成清单:
这会将hermes slack manifest --write
~/.hermes/slack-manifest.json写入磁盘并打印粘贴说明。 - 访问 https://api.slack.com/apps → Create New App → From an app manifest
- 选择你的工作区,粘贴 JSON 内容,检查后点击 Next → Create
- 直接跳到步骤 6:将应用安装到工作区。清单已处理好权限范围、事件和斜杠命令。
方式 B:从头创建(手动)
- 访问 https://api.slack.com/apps
- 点击 Create New App
- 选择 From scratch
- 输入应用名称(如"Hermes Agent")并选择你的工作区
- 点击 Create App
你将跳转到应用的 Basic Information 页面。继续执行以下步骤 2–6。
步骤 2:配置机器人令牌权限范围
在侧边栏导航到 Features → OAuth & Permissions。滚动到 Scopes → Bot Token Scopes 并添加以下权限:
| 权限范围 | 用途 |
|---|---|
chat:write | 以机器人身份发送消息 |
app_mentions:read | 检测频道中的 @提及 |
channels:history | 读取机器人所在公共频道的消息 |
channels:read | 列出并获取公共频道信息 |
groups:history | 读取机器人受邀加入的私有频道消息 |
im:history | 读取私信历史记录 |
im:read | 查看基本私信信息 |
im:write | 开启和管理私信 |
users:read | 查找用户信息 |
files:read | 读取并下载附件,包括语音备忘录/音频 |
files:write | 上传文件(图片、音频、文档) |
没有 channels:history 和 groups:history,机器人将无法接收频道中的消息——只能在私信中工作。没有 files:read,Hermes 可以聊天,但无法可靠地读取用户上传的附件。这是最常遗漏的权限范围。
可选权限范围:
| 权限范围 | 用途 |
|---|---|
groups:read | 列出并获取私有频道信息 |
步骤 3:启用 Socket 模式
Socket 模式允许机器人通过 WebSocket 连接,无需公网 URL。
- 在侧边栏,前往 Settings → Socket Mode
- 将 Enable Socket Mode 切换为开启
- 系统会提示你创建应用级令牌:
- 名称可随意设置(如
hermes-socket) - 添加
connections:write权限范围 - 点击 Generate
- 名称可随意设置(如
- 复制令牌——以
xapp-开头,这是你的SLACK_APP_TOKEN
你可以在 Settings → Basic Information → App-Level Tokens 下随时查找或重新生成应用级令牌。
步骤 4:订阅事件
这一步至关重要——它控制机器人可以看到哪些消息。
- 在侧边栏,前往 Features → Event Subscriptions
- 将 Enable Events 切换为开启
- 展开 Subscribe to bot events 并添加:
| 事件 | 是否必需 | 用途 |
|---|---|---|
message.im | 是 | 机器人接收私信 |
message.channels | 是 | 机器人接收其加入的公共频道消息 |
message.groups | 推荐 | 机器人接收其受邀加入的私有频道消息 |
app_mention | 是 | 防止机器人被 @提及时出现 Bolt SDK 错误 |
- 点击页面底部的 Save Changes
如果机器人在私信中正常工作,但在频道中不工作,你几乎肯定是忘记添加了 message.channels(用于公共频道)和/或 message.groups(用于私有频道)。没有这些事件,Slack 根本不会将频道消息传递给机器人。
步骤 5:启用消息选项卡
此步骤允许用户向机器人发送私信。没有它,用户在尝试私信机器人时会看到**"发送消息到此应用已关闭"**。
- 在侧边栏,前往 Features → App Home
- 滚动到 Show Tabs
- 将 Messages Tab 切换为开启
- 勾选**"允许用户从消息选项卡发送斜杠命令和消息"**
即使配置了所有正确的权限范围和事件订阅,Slack 也不会允许用户向机器人发送私信,除非启用了消息选项卡。这是 Slack 平台的要求,不是 Hermes 的配置问题。
步骤 6:将应用安装到工作区
- 在侧边栏,前往 Settings → Install App
- 点击 Install to Workspace
- 检查权限并点击 Allow
- 授权后,你将看到一个以
xoxb-开头的机器人用户 OAuth 令牌 - 复制此令牌——这是你的
SLACK_BOT_TOKEN
如果你之后更改了权限范围或事件订阅,必须重新安装应用才能使更改生效。安装应用页面会显示横幅提示你这样做。
步骤 7:查找允许列表的用户 ID
Hermes 使用 Slack 成员 ID(而非用户名或显示名称)作为允许列表。
查找成员 ID:
- 在 Slack 中,点击用户的名称或头像
- 点击 View full profile
- 点击 ⋮(更多)按钮
- 选择 Copy member ID
成员 ID 看起来像 U01ABC2DEF3。至少需要你自己的成员 ID。
步骤 8:配置 Hermes
在 ~/.hermes/.env 文件中添加以下内容:
# 必需
SLACK_BOT_TOKEN=xoxb-your-bot-token-here
SLACK_APP_TOKEN=xapp-your-app-token-here
SLACK_ALLOWED_USERS=U01ABC2DEF3 # 逗号分隔的成员 ID
# 可选
SLACK_HOME_CHANNEL=C01234567890 # 定时消息的默认频道
SLACK_HOME_CHANNEL_NAME=general # 主频道的可读名称(可选)
或运行交互式设置:
hermes gateway setup # 在提示时选择 Slack
然后启动网关:
hermes gateway # 前台运行
hermes gateway install # 安装为用户服务
sudo hermes gateway install --system # 仅 Linux:启动时运行的系统服务
步骤 9:邀请机器人到频道
启动网关后,你需要邀请机器人到你希望它响应的任何频道:
/invite @Hermes Agent
机器人不会自动加入频道,必须逐一邀请它到每个频道。
斜杠命令
每个 Hermes 命令(/btw、/stop、/new、/model、/help 等)都是原生 Slack 斜杠命令——与它们在 Telegram 和 Discord 上的工作方式完全相同。在 Slack 中输入 /,自动补全选择器会列出所有 Hermes 命令及其描述。
底层实现:Hermes 附带生成的 Slack 应用清单(见步骤 1,方式 A),该清单将 COMMAND_REGISTRY 中的每个命令声明为斜杠命令。在 Socket 模式下,Slack 通过 WebSocket 路由命令事件,与清单的 url 字段无关。
更新后刷新斜杠命令
当 Hermes 添加新命令时(如 hermes update 后),重新生成清单并更新你的 Slack 应用:
hermes slack manifest --write
然后在 Slack 中:
- 打开 https://api.slack.com/apps → 你的 Hermes 应用
- Features → App Manifest → Edit
- 粘贴
~/.hermes/slack-manifest.json的新内容 - 保存。如果权限范围或斜杠命令有变化,Slack 会提示重新安装应用。
遗留的 /hermes <子命令> 仍然有效
为了与旧版清单的向后兼容性,你仍然可以输入 /hermes btw run the tests——Hermes 会以与 /btw run the tests 相同的方式路由它。自由形式的问题也有效:/hermes what's the weather? 会被视为普通消息。
进阶:仅导出斜杠命令数组
如果你手动维护 Slack 清单,只想要斜杠命令列表:
hermes slack manifest --slashes-only > /tmp/slashes.json
将该数组粘贴到你现有清单的 features.slash_commands 键中。
机器人的响应方式
了解 Hermes 在不同场景下的行为:
| 场景 | 行为 |
|---|---|
| 私信 | 机器人响应每条消息——无需 @提及 |
| 频道 | 机器人仅在被 @提及时响应(如 @Hermes Agent 现在几点?)。在频道中,Hermes 在该消息的线程中回复。 |
| 线程 | 如果你在现有线程中 @提及 Hermes,它会在同一线程中回复。一旦机器人在线程中有活跃会话,该线程中后续的回复不需要 @提及——机器人会自然地跟随对话。 |
在频道中,始终 @提及机器人来开始对话。一旦机器人在线程中活跃,你可以在该线程中回复而无需提及它。在线程外,没有 @提及的消息会被忽略,以防止在繁忙频道中产生噪音。
配置选项
除了步骤 8 中的必需环境变量外,你还可以通过 ~/.hermes/config.yaml 自定义 Slack 机器人行为。
线程与回复行为
platforms:
slack:
# 控制多部分响应的线程方式
# "off" — 永不将回复线程到原始消息
# "first" — 第一块线程到用户消息(默认)
# "all" — 所有块线程到用户消息
reply_to_mode: "first"
extra:
# 是否在线程中回复(默认:true)。
# 当为 false 时,频道消息获得直接频道回复而非线程。
# 现有线程中的消息仍然在线程中回复。
reply_in_thread: true
# 将线程回复也发布到主频道
# (Slack 的"同时发送到频道"功能)。
# 只有第一次回复的第一块会被广播。
reply_broadcast: false
| 键 | 默认值 | 描述 |
|---|---|---|
platforms.slack.reply_to_mode | "first" | 多部分消息的线程模式:"off"、"first" 或 "all" |
platforms.slack.extra.reply_in_thread | true | 当为 false 时,频道消息获得直接回复而非线程。现有线程中的消息仍在线程中回复。 |
platforms.slack.extra.reply_broadcast | false | 当为 true 时,线程回复也会发布到主频道。只有第一块被广播。 |
会话隔离
# 全局设置——适用于 Slack 和所有其他平台
group_sessions_per_user: true
当为 true(默认值)时,共享频道中的每个用户都有自己独立的对话会话。两个人在 #general 中与 Hermes 对话将有各自独立的历史记录和上下文。
设置为 false 可开启协作模式,使整个频道共享一个对话会话。注意这意味着用户共享上下文增长和 Token 消耗,一个用户的 /reset 会清除所有人的会话。
提及与触发行为
slack:
# 在频道中需要 @提及(这是默认行为;
# Slack 适配器无论如何都会在频道中强制执行 @提及门控,
# 但你可以显式设置以与其他平台保持一致)
require_mention: true
# 防止线程自动参与:只回复包含明确 @提及的频道消息。
# 关闭此选项(默认)时,Slack 可以"自动参与"——记住线程中的过去提及
# 并跟进机器人消息回复,以及无需新提及即可恢复活跃会话。
# 开启 strict_mention 时,每条新的频道消息必须 @提及机器人,Hermes 才会响应。
strict_mention: false
# 触发机器人的自定义提及模式
# (除了默认的 @提及检测之外)
mention_patterns:
- "hey hermes"
- "hermes,"
# 每条发出消息前面添加的文本
reply_prefix: ""
strict_mention在繁忙的工作区中将其设置为 true,可以避免 Slack 默认的"机器人记住此线程"行为让用户感到惊讶——例如,一个长期技术支持线程,机器人在开始时提供了帮助,而你希望它保持沉默,除非再次被明确提及。私信和活跃的交互会话不受影响。
Slack 支持两种模式:默认需要 @提及才能开始对话,但你可以通过 SLACK_FREE_RESPONSE_CHANNELS(逗号分隔的频道 ID)或 config.yaml 中的 slack.free_response_channels 选择特定频道退出此限制。一旦机器人在线程中有活跃会话,后续线程回复不需要提及。在私信中,机器人始终无需提及即可响应。
未授权用户处理
slack:
# 当未授权用户(不在 SLACK_ALLOWED_USERS 中)私信机器人时的处理方式
# "pair" — 提示他们输入配对码(默认)
# "ignore" — 静默丢弃消息
unauthorized_dm_behavior: "pair"
你也可以为所有平台全局设置:
unauthorized_dm_behavior: "pair"
slack: 下的平台特定设置优先于全局设置。
语音转录
# 全局设置——启用/禁用传入语音消息的自动转录
stt_enabled: true
当为 true(默认值)时,传入的音频消息会在被 Agent 处理之前使用配置的 STT 提供商自动转录。
完整示例
# 全局网关设置
group_sessions_per_user: true
unauthorized_dm_behavior: "pair"
stt_enabled: true
# Slack 特定设置
slack:
require_mention: true
unauthorized_dm_behavior: "pair"
# 平台配置
platforms:
slack:
reply_to_mode: "first"
extra:
reply_in_thread: true
reply_broadcast: false
主频道
将 SLACK_HOME_CHANNEL 设置为频道 ID,Hermes 会在此处发送定时消息、定时任务结果和其他主动通知。查找频道 ID:
- 在 Slack 中右键点击频道名称
- 点击 View channel details
- 滚动到底部——频道 ID 显示在那里
SLACK_HOME_CHANNEL=C01234567890
确保已邀请机器人到该频道(/invite @Hermes Agent)。
多工作区支持
Hermes 可以使用单个网关实例同时连接到多个 Slack 工作区。每个工作区使用其自己的机器人用户 ID 独立认证。
配置
在 SLACK_BOT_TOKEN 中以逗号分隔列表的形式提供多个机器人令牌:
# 多个机器人令牌——每个工作区一个
SLACK_BOT_TOKEN=xoxb-workspace1-token,xoxb-workspace2-token,xoxb-workspace3-token
# 单个应用级令牌仍用于 Socket 模式
SLACK_APP_TOKEN=xapp-your-app-token
或在 ~/.hermes/config.yaml 中:
platforms:
slack:
token: "xoxb-workspace1-token,xoxb-workspace2-token"
OAuth 令牌文件
除了环境变量或配置中的令牌外,Hermes 还从以下位置的 OAuth 令牌文件中加载令牌:
~/.hermes/slack_tokens.json
该文件是一个将团队 ID 映射到令牌条目的 JSON 对象:
{
"T01ABC2DEF3": {
"token": "xoxb-workspace-token-here",
"team_name": "My Workspace"
}
}
此文件中的令牌与通过 SLACK_BOT_TOKEN 指定的令牌合并。重复令牌会自动去重。
工作原理
- 列表中的第一个令牌是主令牌,用于 Socket 模式连接(AsyncApp)。
- 每个令牌在启动时通过
auth.test进行认证。网关将每个team_id映射到其自己的WebClient和bot_user_id。 - 当消息到达时,Hermes 使用正确的工作区特定客户端进行响应。
- 主
bot_user_id(来自第一个令牌)用于向后兼容那些期望单一机器人身份的功能。
语音消息
Hermes 支持 Slack 上的语音功能:
- 传入: 使用配置的 STT 提供商自动转录语音/音频消息:本地
faster-whisper、Groq Whisper(GROQ_API_KEY)或 OpenAI Whisper(VOICE_TOOLS_OPENAI_KEY) - 传出: TTS 响应以音频文件附件的形式发送
每频道提示词
为特定 Slack 频道分配临时系统提示词。提示词在每次交互时注入——永不保存到对话历史——因此更改立即生效。
slack:
channel_prompts:
"C01RESEARCH": |
You are a research assistant. Focus on academic sources,
citations, and concise synthesis.
"C02ENGINEERING": |
Code review mode. Be precise about edge cases and
performance implications.
键是 Slack 频道 ID(通过频道详情 → "About" → 滚动到底部找到)。匹配频道中的所有消息都会将提示词注入为临时系统指令。
每频道技能绑定
每当在特定频道或私信中开始新会话时,自动加载某个技能(Skill)。与每频道提示词(在每次交互时注入)不同,技能绑定在会话开始时将技能内容作为用户消息注入——它成为对话历史的一部分,后续交互无需重新加载。
这非常适合有专门用途的私信或频道(抽认卡、特定领域问答机器人、支持分类频道等),在这些场景下你不希望模型自己的技能选择器在每次简短回复时都决定是否加载。
slack:
channel_skill_bindings:
# 私信频道——始终以"german-flashcards"模式运行
- id: "D0ATH9TQ0G6"
skills:
- german-flashcards
# 研究频道——按顺序预加载多个技能
- id: "C01RESEARCH"
skills:
- arxiv
- writing-plans
# 简短形式:单个技能作为字符串
- id: "C02SUPPORT"
skill: hubspot-on-demand
注意事项:
- 绑定通过频道 ID 匹配。对于绑定频道中的线程消息,线程继承父频道的绑定。
- 技能仅在会话开始时加载(新会话或自动重置后)。如果你更改绑定,请运行
/new或等待会话自动重置以使其生效。 - 与
channel_prompts结合使用,可在技能指令之上提供每频道的语气/限制。
故障排除
| 问题 | 解决方案 |
|---|---|
| 机器人不响应私信 | 验证 message.im 是否在你的事件订阅中,且应用已重新安装 |
| 机器人在私信中工作,但在频道中不工作 | 最常见问题。 将 message.channels 和 message.groups 添加到事件订阅,重新安装应用,并使用 /invite @Hermes Agent 邀请机器人到频道 |
| 机器人不响应频道中的 @提及 | 1)检查是否订阅了 message.channels 事件。2)机器人必须被邀请到频道。3)确保添加了 channels:history 权限范围。4)更改权限范围/事件后重新安装应用 |
| 机器人忽略私有频道中的消息 | 添加 message.groups 事件订阅和 groups:history 权限范围,然后重新安装应用并 /invite 机器人 |
| 私信中出现"发送消息到此应用已关闭" | 在 App Home 设置中启用消息选项卡(见步骤 5) |
| "not_authed"或"invalid_auth"错误 | 重新生成机器人令牌和应用令牌,更新 .env |
| 机器人可以聊天但无法在频道中发布 | 使用 /invite @Hermes Agent 邀请机器人到频道 |
| 机器人可以聊天但无法读取上传的图片/文件 | 添加 files:read,然后重新安装应用。Hermes 现在会在聊天中显示 Slack 返回权限/认证失败时的附件访问诊断信息。 |
missing_scope 错误 | 在 OAuth & Permissions 中添加所需权限范围,然后重新安装应用 |
| Socket 频繁断开连接 | 检查你的网络;Bolt 自动重连,但不稳定的连接会导致延迟 |
| 更改了权限范围/事件但没有任何变化 | 在更改权限范围或事件订阅后,必须重新安装应用到你的工作区 |
快速检查清单
如果机器人在频道中不工作,请验证以下所有条件:
- ✅ 已订阅
message.channels事件(用于公共频道) - ✅ 已订阅
message.groups事件(用于私有频道) - ✅ 已订阅
app_mention事件 - ✅ 已添加
channels:history权限范围(用于公共频道) - ✅ 已添加
groups:history权限范围(用于私有频道) - ✅ 添加权限范围/事件后已重新安装应用
- ✅ 已邀请机器人到频道(
/invite @Hermes Agent) - ✅ 你在消息中**@提及**了机器人
安全
始终设置 SLACK_ALLOWED_USERS,填入授权用户的成员 ID。没有此设置,网关将默认拒绝所有消息作为安全措施。切勿分享你的机器人令牌——像密码一样对待它们。
- 令牌应存储在
~/.hermes/.env中(文件权限600) - 通过 Slack 应用设置定期轮换令牌
- 审计谁有权访问你的 Hermes 配置目录
- Socket 模式意味着不暴露公共端点——减少了一个攻击面