sidebar_position: 4 title: “Slack” description: “Set up Hermes Agent as a Slack bot using Socket Mode”
Slack 设置
- 通过 Socket 模式将 Hermes Agent 作为机器人连接到 Slack。Socket 模式使用 WebSocket 而非公共 HTTP 端点,因此您的 Hermes 实例无需公开访问——它可以在防火墙后面、笔记本电脑上或私有服务器上运行。
-
::warning 传统 Slack 应用已弃用 基于 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 为您生成的清单文件。该文件会一次性声明所有内置的 slash 命令(如 /btw、 /stop、 /model 等)、所有必需的 OAuth 权限范围、所有事件订阅,并启用 Socket 模式。
方案 A:使用 Hermes 生成的清单文件(推荐)
- 生成清单文件:
hermes slack manifest --write
该操作会生成 ~/.hermes/slack-manifest.json 文件,并输出可直接粘贴的配置说明。
2. 访问 https://api.slack.com/apps,选择创建新应用 → 从应用清单创建。
3. 选择对应的工作空间,粘贴 JSON 内容,仔细检查后点击下一步 → 创建。
4. 直接跳至步骤 6:将应用安装到工作空间。该清单已自动处理了权限范围、事件及斜杠命令的相关配置。
方案 B:从零开始(手动创建)
- 访问 https://api.slack.com/apps
- 点击创建新应用
- 选择从零开始
- 输入应用名称(例如“Hermes Agent”),并选择对应的工作空间
- 点击创建应用
随后会进入应用的基本信息页面,接下来请按照以下步骤 2–6 操作。
步骤 2:配置机器人令牌的权限范围
在侧边栏中导航至功能 → OAuth 和权限。滚动到权限范围 → 机器人令牌权限范围,并添加以下项:
| 权限范围 | 用途 |
|---|---|
chat:write | 以机器人身份发送消息 |
app_mentions:read | 检测在频道中被@提及的情况 |
channels:history | 读取机器人所在公共频道的消息记录 |
channels:read | 列出并获取公共频道的信息 |
groups:history | 读取机器人被邀请加入的私密频道的消息记录 |
im:history | 读取直接消息的历史记录 |
im:read | 查看基本的直接消息信息 |
im:write | 打开并管理直接消息 |
mpim:history | 读取群组直接消息(多人直接消息)的历史记录 |
mpim:read | 查看基本的群组直接消息信息 |
users:read | 查询用户信息 |
files:read | 读取并下载附件,包括语音笔记/音频文件 |
files:write | 上传文件(图片、音频、文档) |
可选权限范围:
| 权限范围 | 用途 |
|---|---|
groups:read | 列出并获取私密频道的信息 |
步骤 3:启用 Socket 模式
Socket 模式允许机器人通过 WebSocket 连接,而无需使用公开 URL。
- 在侧边栏中,进入设置 → Socket 模式
- 将启用 Socket 模式切换为开启状态
- 系统会提示您创建一个应用级令牌:
- 为其命名,例如
hermes-socket(名称并无特殊要求) - 添加**
connections:write**权限范围 - 点击生成
- 为其命名,例如
- 复制该令牌——其开头为
xapp-。这就是您的SLACK_APP_TOKEN。
步骤 4:订阅事件
此步骤至关重要——它决定了机器人能够接收哪些类型的消息。
- 在侧边栏中,进入功能 → 事件订阅
- 将启用事件切换为开启状态
- 展开订阅机器人事件选项,然后添加以下项:
| 事件类型 | 是否必需 | 用途 |
|---|---|---|
message.im | 是 | 机器人可接收直接消息 |
message.mpim | 是 | 机器人可接收其被加入的群组直接消息中的内容 |
message.channels | 是 | 机器人可接收其被加入的公共频道中的消息 |
message.groups | 推荐 | 机器人可接收其被邀请加入的私密频道中的消息 |
app_mention | 是 | 防止在机器人被@提及时出现 Bolt SDK 错误 |
- 点击页面底部的保存更改
步骤 5:启用“消息”标签页
此步骤可让用户向机器人发送直接消息。若未启用,用户在尝试给机器人发直接消息时将会看到**“已关闭向此应用发送消息的功能”**的提示。
- 在侧边栏中,进入功能 → 应用主页
- 滚动到显示标签页选项
- 将消息标签页切换为开启状态
- 勾选**“允许用户通过消息标签页发送斜杠命令和消息”**
步骤 6:将应用安装到工作空间
- 在侧边栏中,进入设置 → 安装应用
- 点击安装到工作空间
- 查看权限设置后点击允许
- 授权完成后,您会看到一个以
xoxb-开头的机器人用户 OAuth 令牌 - 复制该令牌——这就是您的
SLACK_BOT_TOKEN。
步骤 7:查找白名单所需的用户 ID
Hermes 在构建白名单时使用的是 Slack 的成员 ID(而非用户名或显示名称)。
要查找成员 ID:
- 在 Slack 中点击用户的姓名或头像
- 点击查看完整资料
- 点击**⋮**(更多)按钮
- 选择复制成员 ID
成员 ID 的格式类似 U01ABC2DEF3。您至少需要拥有自己的成员 ID。
步骤 8:配置 Hermes
在您的 ~/.hermes/.env 文件中添加以下内容:
# Required
SLACK_BOT_TOKEN=xoxb-your-bot-token-here
SLACK_APP_TOKEN=xapp-your-app-token-here
SLACK_ALLOWED_USERS=U01ABC2DEF3 # Comma-separated Member IDs
# Optional
SLACK_HOME_CHANNEL=C01234567890 # Default channel for cron/scheduled messages
SLACK_HOME_CHANNEL_NAME=general # Human-readable name for the home channel (optional)
或者运行交互式设置流程:
hermes gateway setup # Select Slack when prompted
接着启动网关:
hermes gateway # Foreground
hermes gateway install # Install as a user service
sudo hermes gateway install --system # Linux only: boot-time system service
第 9 步:将机器人邀请到频道中
启动网关后,您需要将该机器人邀请到希望其响应的任意频道中:
/invite @Hermes Agent
该机器人不会自动加入频道,您必须逐一将其邀请到各个频道中。
hermes slack manifest --write
接下来在 Slack 中操作:
- 打开 https://api.slack.com/apps → 选择你的 Hermes 应用;
- 进入 Features → App Manifest → Edit;
- 粘贴
~/.hermes/slack-manifest.json文件中的新内容; - 点击 Save。如果权限范围或斜杠命令发生了变化,Slack 会提示你需要重新安装该应用。
旧版的 /hermes <subcommand> 方式仍然有效
为兼顾旧版配置文件的兼容性,你仍可以输入 /hermes btw run the tests — Hermes 会以与 /btw run the tests 相同的方式处理该命令。自由格式的提问也同样可行:/hermes what's the weather? 会被视为普通消息处理。
在主题回复中使用命令(使用 !cmd 前缀)
Slack 本身不允许在主题回复中使用原生斜杠命令——尝试在主题回复中输入 /queue,Slack 会回复 “/queue 不支持在主题回复中使用。抱歉!” 目前没有应用端的设置可以重新启用此功能,因为 Slack 也不会将这些命令传递给 Hermes。
作为变通方案,Hermes 会将开头的 ! 视为可在主题回复(以及其他任何地方)使用的替代命令前缀。你可以像发送普通主题回复一样输入 !queue、!stop、!model gpt-5.4 等命令——Hermes 会将其视为斜杠命令形式,并在同一主题回复中给出响应。
由于仅会检查第一个单词是否在已知命令列表中,像 !nice work 这样的普通消息会原封不动地传递给智能体。
需要用户确认的命令(如危险命令或 execute_code 的执行授权)通常会以交互式按钮的形式呈现。当无法显示按钮且 Hermes 转而使用文本提示时,它会指示用户回复 !approve 或 !deny——这两种形式在主题回复中同样有效。
进阶用法:仅输出斜杠命令数组
如果你是手动维护 Slack 配置文件,且仅需获取斜杠命令列表:
hermes slack manifest --slashes-only > /tmp/slashes.json
将该数组粘贴到您现有清单的 features.slash_commands 键中。
机器人的响应方式
了解 Hermes 在不同场景下的行为表现:
| 场景 | 行为 |
|---|---|
| 私信 | 机器人会回复每条消息——无需使用 @mention |
| 频道 | 机器人仅在被 @提及时才会回复(例如:@Hermes Agent 现在几点了?)。在频道中,Hermes 会在该消息对应的讨论串中回复。 |
| 讨论串 | 如果在现有讨论串中 @提及 Hermes,它会在同一讨论串中回复。一旦机器人已在某个讨论串中进入活跃会话,后续在该讨论串中的回复无需再 @提及——机器人会自动延续对话。 |
配置选项
除了第 8 步中要求的环境变量外,您还可以通过 ~/.hermes/config.yaml 自定义 Slack 机器人的行为。
讨论串与回复行为
platforms:
slack:
# Controls how multi-part responses are threaded
# "off" — never thread replies to the original message
# "first" — first chunk threads to user's message (default)
# "all" — all chunks thread to user's message
reply_to_mode: "first"
extra:
# Whether to reply in a thread (default: true).
# When false, channel messages get direct channel replies instead
# of threads. Messages inside existing threads still reply in-thread.
reply_in_thread: true
# Also post thread replies to the main channel
# (Slack's "Also send to channel" feature).
# Only the first chunk of the first reply is broadcast.
reply_broadcast: false
# Render agent messages as Slack Block Kit blocks (default: false).
# When true, the final agent message is sent with structured blocks —
# section headers, dividers, true nested lists (via rich_text), and
# native Block Kit tables — instead of flat mrkdwn text. A plain-text
# fallback is always sent alongside for notifications/accessibility.
# Tables exceeding Slack's limits (100 rows / 20 cols / 10k chars)
# gracefully fall back to aligned monospace.
rich_blocks: false
# Continuable-cron delivery surface (default: "thread").
# "in_channel" delivers a continuable cron job FLAT into the channel
# (no dedicated thread); pair with reply_in_thread: false (and
# require_mention: false) so a plain reply continues the job.
# See the cron guide → "Flat, in-channel continuation".
cron_continuable_surface: thread
| 键值 | 默认值 | 描述 |
|---|---|---|
platforms.slack.reply_to_mode | "first" | 多部分消息的线程模式:"off"、"first" 或 "all" |
platforms.slack.extra.reply_in_thread | true | 当设置为 false 时,频道中的消息将直接回复而非以线程形式发送。已存在线程内的消息仍会以线程形式回复。 |
platforms.slack.extra.reply_broadcast | false | 当设置为 true 时,线程回复也会同步发布到主频道。仅会广播第一部分内容。 |
platforms.slack.extra.rich_blocks | false | 当设置为 true 时,智能体发送的消息将以 Block Kit 块格式呈现(包括标题、分隔符、真正的嵌套列表以及原生表格)。同时仍会发送纯文本作为备用。超过 Slack 限制的表格将自动转换为对齐的等宽字体显示。无需重新安装应用,仅需在发送端进行设置即可。 |
platforms.slack.extra.cron_continuable_surface | "thread" | 可延续定时任务 的消息呈现方式。"thread" 模式为每次任务执行单独开启一个线程(默认值);"in_channel" 模式则将任务内容直接展示在频道时间轴中。若需通过普通频道回复来延续任务,需将 in_channel 与 reply_in_thread: false(以及 require_mention: false)一起使用。 |
会话隔离机制
# Global setting — applies to Slack and all other platforms
group_sessions_per_user: true
当设置为 true(默认值)时,共享频道中的每位用户都会拥有独立的对话会话。在 #general 频道中与 Hermes 交流的两位用户将拥有各自的对话历史和上下文。
若希望启用协作模式,让整个频道共用一个对话会话,则可将该值设置为 false。请注意,这意味着所有用户将共享上下文数据及令牌消耗,且任何一位用户执行 /reset 指令都会清除所有人的对话会话。
提及与触发行为
slack:
# Require @mention in channels (this is the default behavior;
# the Slack adapter enforces @mention gating in channels regardless,
# but you can set this explicitly for consistency with other platforms)
require_mention: true
# Prevent thread auto-engagement: only reply to channel messages that
# contain an explicit @mention. With this OFF (default), Slack can
# "auto-engage" — remembering past mentions in a thread and following
# up on bot-message replies, and resuming active sessions without a
# fresh mention. With strict_mention ON, every new channel message
# must @mention the bot before Hermes will respond.
strict_mention: false
# Custom mention patterns that trigger the bot
# (in addition to the default @mention detection)
mention_patterns:
- "hey hermes"
- "hermes,"
# Text prepended to every outgoing message
reply_prefix: ""
- :::提示 何时使用
strict_mention
在那些 Slack 默认的“机器人会记住该对话线程”功能令用户感到意外的高频工作空间中,可将此选项设置为true——例如,在一个漫长的技术支持对话线程中,机器人最初提供了帮助,而您希望除非再次被明确提及,否则它保持沉默。私信及正在进行的交互式会话则不受影响。 -
::
-
::信息
Slack 支持这两种模式:默认情况下,必须使用@mention才能启动对话,但您也可以通过config.yaml中的SLACK_FREE_RESPONSE_CHANNELS(以逗号分隔的频道 ID)或slack.free_response_channels来指定无需回应的特定频道。一旦机器人在某个对话线程中建立了活跃会话,后续的回复就无需再使用提及方式。在1:1 私信中,机器人始终无需提及即可响应。 -
::
-
::注意 群组私信(MPIM)属于共享空间,并非 1:1 私信
1:1 直接消息是与单个人的私人对话,因此无需提及即可触发响应。而**群组私信(MPIM/多人私信)**则是共享空间——多个人都可以看到并触发机器人响应——因此它遵循与频道相同的操作规则:require_mention、strict_mention、free_response_channels以及allowed_channels均适用。只有当真正被@mention时,机器人才会添加:eyes:/:white_check_mark:等表情反应。若希望机器人在特定的群组私信中自由响应,只需将其频道 ID(以G开头)添加到free_response_channels中即可。 -
::
频道白名单(allowed_channels)
可将机器人限制在指定的 Slack 频道范围内——当机器人被邀请加入众多频道,但仅需在少数几个频道中响应时,此功能非常有用。一旦设置此选项,来自列表之外频道的消息将被直接忽略,即便其中提到了该机器人。
1:1 私信不受此过滤规则限制,因此授权用户始终可以通过直接消息与机器人联系。而群组私信(MPIM)则不在例外之列——与频道一样,MPIM 必须被列入白名单(其 ID 以 G 开头),否则其消息也会被丢弃。
slack:
allowed_channels:
- "C0123456789" # #ops
- "C0987654321" # #incident-response
或通过环境变量(以逗号分隔):
SLACK_ALLOWED_CHANNELS="C0123456789,C0987654321"
行为规则:
- 空值/未设置 → 无限制(完全向后兼容)。
- 非空值 → 频道 ID 必须存在于指定列表中;否则,在执行其他任何限制条件(如提及要求、
free_response_channels等)之前,该消息将被直接丢弃。 - Slack 频道 ID 以
C(公共频道)、G(私有频道)或D(私信)开头。可通过 Slack 用户界面的“打开频道详情”→“关于”面板或 API 查阅这些信息。
另请参阅:管理员/用户斜杠命令分离。
未授权用户处理方式
slack:
# What happens when an unauthorized user (not in SLACK_ALLOWED_USERS) DMs the bot
# "pair" — prompt them for a pairing code (default)
# "ignore" — silently drop the message
unauthorized_dm_behavior: "pair"
您也可以为所有平台全局设置此参数:
unauthorized_dm_behavior: "pair"
在 slack: 下的特定平台设置会优先于全局设置生效。
语音转录
请翻译完整的输入内容,切勿提前终止。
# Global setting — enable/disable automatic transcription of incoming voice messages
stt_enabled: true
当设置为 true(默认值)时,传入的音频消息会在被智能体处理之前,先通过已配置的文本转语音服务进行自动转录。
完整示例
# Global gateway settings
group_sessions_per_user: true
unauthorized_dm_behavior: "pair"
stt_enabled: true
# Slack-specific settings
slack:
require_mention: true
unauthorized_dm_behavior: "pair"
# Platform config
platforms:
slack:
reply_to_mode: "first"
extra:
reply_in_thread: true
reply_broadcast: false
主页频道
请将 SLACK_HOME_CHANNEL 设置为 Hermes 用于发送定时消息、cron 任务结果以及其他主动通知的频道 ID。若需查找频道 ID,请按以下步骤操作:
- 在 Slack 中右键点击该频道名称
- 点击 查看频道详情
- 滚动到页面底部——频道 ID 即显示在那里
SLACK_HOME_CHANNEL=C01234567890
请确保该机器人已被邀请加入对应频道(使用命令 /invite @Hermes Agent)。
多工作区支持
Hermes 可通过单个网关实例同时连接多个 Slack 工作区。每个工作区都会使用独立的机器人用户 ID 进行身份验证。
配置方式
在 SLACK_BOT_TOKEN 中以逗号分隔的列表形式提供多个机器人令牌:
# Multiple bot tokens — one per workspace
SLACK_BOT_TOKEN=xoxb-workspace1-token,xoxb-workspace2-token,xoxb-workspace3-token
# A single app-level token is still used for Socket Mode
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
该文件是一个 JSON 对象,用于将团队 ID 与令牌条目进行映射:
{
"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 中发送语音消息:
- 接收端:语音/音频消息会自动使用配置好的文本转语音服务进行转写,可选服务包括本地的
faster-whisper、Groq Whisper(需提供GROQ_API_KEY)或 OpenAI Whisper(需提供VOICE_TOOLS_OPENAI_KEY)。 - 发送端:文本转语音生成的回复会以音频文件附件的形式发送。
每个频道的提示语
可为特定的 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(可通过频道详情页 → “关于” → 滚动到页面底部查看)。匹配频道中的所有消息都会作为临时的系统指令接收该提示词。
按频道绑定的技能
每当在特定频道或私信中开启新会话时,系统会自动加载对应技能。与每轮都会注入的频道专用提示词不同,按频道绑定的技能会在会话开始时以用户消息的形式注入——它将成为对话历史的一部分,后续轮次无需再次加载。
对于私信或具有特定用途的频道(如抽认卡工具、行业专属问答机器人、支持服务分流频道等),这种方式尤为理想,因为无需让模型自身的技能选择器在每次简短回复时都决定是否加载相应技能。
slack:
channel_skill_bindings:
# DM channel — always runs in "german-flashcards" mode
- id: "D0ATH9TQ0G6"
skills:
- german-flashcards
# Research channel — preload multiple skills in order
- id: "C01RESEARCH"
skills:
- arxiv
- writing-plans
# Short form: single skill as a string
- 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 命令邀请机器人 |
| 机器人不回复群组私信(多人私信) | 需添加 message.mpim 事件订阅以及 mpim:history(还需 mpim:read)权限范围,之后重新安装应用。若没有 message.mpim,即使一对一私信能正常发送,Slack 也不会将群组私信传递给机器人 |
| 在私信中出现“已禁用向此应用发送消息”的提示 | 在应用主页设置中启用消息标签页(参见第5步) |
| 出现“not_authed”或“invalid_auth”错误 | 重新生成机器人令牌和应用令牌,并更新 .env 文件 |
| 机器人能响应,但无法在频道中发布内容 | 使用 /invite @Hermes Agent 将机器人邀请至该频道 |
| 机器人可以聊天,但无法读取上传的图片/文件 | 需添加 files:read 权限,之后重新安装应用。当 Slack 返回权限/认证失败时,Hermes 现已在聊天界面中显示附件访问相关的诊断信息 |
出现 missing_scope 错误 | 在 OAuth 和权限设置中添加所需的权限范围,之后重新安装应用 |
| Socket连接频繁断开 | 检查网络状况;虽然 Bolt 会自动重连,但不稳定的连接会导致延迟 |
| 更改了权限范围或事件,但没有任何变化 | 每次更改权限范围或事件订阅后,都必须将应用重新安装到工作空间中 |
快速检查清单
如果机器人在频道中无法正常工作,请确认以下所有项:
- ✅ 已订阅
message.channels事件(适用于公共频道) - ✅ 已订阅
message.groups事件(适用于私密频道) - ✅ 已订阅
app_mention事件 - ✅ 已为公共频道添加
channels:history权限范围 - ✅ 已为私密频道添加
groups:history权限范围 - ✅ 在添加权限范围或事件后已重新安装应用
- ✅ 已使用
/invite @Hermes Agent将机器人邀请至该频道 - ✅ 在消息中已对机器人进行**@提及**
安全性
- :::warning
务必设置
SLACK_ALLOWED_USERS,填入授权用户的成员 ID。出于安全考虑,若未设置此参数,网关将默认拒绝所有消息。切勿共享机器人令牌——应将其视同密码对待。 - ::
- 令牌应存储在
~/.hermes/.env文件中(文件权限需设置为600) - 定期通过 Slack 应用设置轮换令牌
- 审核谁有权访问您的 Hermes 配置目录
- Socket 模式意味着不会暴露任何公共端点,从而减少了攻击面