Slack 设置

使用 Socket Mode 将 Hermes Agent 连接到 Slack 作为机器人。Socket Mode 使用 WebSocket 而非公共 HTTP 端点,因此您的 Hermes 实例无需公开访问——它可以在防火墙后、笔记本电脑上或私有服务器上工作。

:::warning 经典 Slack 应用已弃用 经典 Slack 应用(使用 RTM API)已于 2025 年 3 月完全弃用。Hermes 使用现代的 Bolt SDK 与 Socket Mode。如果您有旧的经典应用,必须按照以下步骤创建一个新的。 :::

概述

组件
Python 的 slack-bolt / slack_sdk(Socket Mode)
连接WebSocket — 无需公共 URL
所需认证令牌Bot Token(xoxb-)+ App-Level Token(xapp-
用户标识Slack 成员 ID(例如 U01ABC2DEF3

第 1 步:创建 Slack 应用

最快的方法是粘贴 Hermes 为您生成的清单(manifest)。它一次性声明了所有内置斜杠命令(/btw/stop/model、…)、所有必需的 OAuth 范围、所有事件订阅,并启用 Socket Mode。

选项 A:从 Hermes 生成的清单开始(推荐)

  1. 生成清单:
    hermes slack manifest --write
    这会写入 ~/.hermes/slack-manifest.json 并打印粘贴说明。
  2. 前往 https://api.slack.com/appsCreate New AppFrom an app manifest
  3. 选择您的工作区,粘贴 JSON 内容,审核,点击 NextCreate
  4. 跳到第 6 步:安装应用到工作区。清单已为您处理了范围、事件和斜杠命令。

选项 B:从头开始(手动)

  1. 前往 https://api.slack.com/apps
  2. 点击 Create New App
  3. 选择 From scratch
  4. 输入应用名称(例如 “Hermes Agent”)并选择您的工作区
  5. 点击 Create App

您将进入应用的基本信息页面。继续下面的第 2–6 步。


第 2 步:配置 Bot Token 范围

导航到侧边栏的 Features → OAuth & Permissions。滚动到 Scopes → Bot Token Scopes 并添加以下内容:

范围用途
chat:write以机器人身份发送消息
app_mentions:read检测在频道中何时被 @提及
channels:history读取机器人所在公共频道中的消息
channels:read列出和获取公共频道信息
groups:history读取机器人被邀请到的私密频道中的消息
im:history读取直接消息历史
im:read查看基本 DM 信息
im:write打开和管理 DM
users:read查找用户信息
files:read读取和下载附件文件,包括语音笔记/音频
files:write上传文件(图片、音频、文档)

:::caution 缺少范围 = 缺少功能 没有 channels:historygroups:history,机器人将无法接收频道中的消息——它只能在 DM 中工作。没有 files:read,Hermes 可以聊天但无法可靠地读取用户上传的附件。这些是最常被遗漏的范围。 :::

可选范围:

范围用途
groups:read列出和获取私密频道信息

第 3 步:启用 Socket Mode

Socket Mode 让机器人通过 WebSocket 连接,而非需要公共 URL。

  1. 在侧边栏中,进入 Settings → Socket Mode
  2. Enable Socket Mode 切换为 ON
  3. 系统会提示您创建一个 App-Level Token
    • 命名(例如 hermes-socket,名称无关紧要)
    • 添加 connections:write 范围
    • 点击 Generate
  4. 复制令牌——它以 xapp- 开头。这是您的 SLACK_APP_TOKEN

:::tip 您随时可以在 Settings → Basic Information → App-Level Tokens 下找到或重新生成应用级令牌。 :::


第 4 步:订阅事件

此步骤至关重要——它控制机器人可以看到哪些消息。

  1. 在侧边栏中,进入 Features → Event Subscriptions
  2. Enable Events 切换为 ON
  3. 展开 Subscribe to bot events 并添加:
事件必需?用途
message.im机器人接收直接消息
message.channels机器人在公共频道中接收消息
message.groups推荐机器人在被邀请的私密频道中接收消息
app_mention防止 Bolt SDK 在机器人被 @提及时报错
  1. 点击页面底部的 Save Changes

:::danger 缺少事件订阅是首要设置问题 如果机器人在 DM 中工作但在频道中不行,您几乎肯定忘记了添加 message.channels(用于公共频道)和/或 message.groups(用于私密频道)。没有这些事件,Slack 根本不会将频道消息传递给机器人。 :::


第 5 步:启用消息标签

此步骤启用对机器人的直接消息。没有它,用户在尝试 DM 机器人时会看到 “Sending messages to this app has been turned off”

  1. 在侧边栏中,进入 Features → App Home
  2. 滚动到 Show Tabs
  3. Messages Tab 切换为 ON
  4. 勾选 “Allow users to send Slash commands and messages from the messages tab”

:::danger 没有此步骤,DM 完全被阻止 即使有所有正确的范围和事件订阅,除非启用了消息标签,否则 Slack 将不允许用户向机器人发送直接消息。这是 Slack 平台的要求,而非 Hermes 配置问题。 :::


第 6 步:安装应用到工作区

  1. 在侧边栏中,进入 Settings → Install App
  2. 点击 Install to Workspace
  3. 审核权限并点击 Allow
  4. 授权后,您将看到一个以 xoxb- 开头的 Bot User OAuth Token
  5. 复制此令牌——这是您的 SLACK_BOT_TOKEN

:::tip 如果您稍后更改范围或事件订阅,您必须重新安装应用才能使更改生效。安装应用页面会显示一个横幅提示您这样做。 :::


第 7 步:为白名单查找用户 ID

Hermes 使用 Slack 成员 ID(而非用户名或显示名称)进行白名单。

查找成员 ID:

  1. 在 Slack 中,点击用户的名称或头像
  2. 点击 View full profile
  3. 点击 (更多)按钮
  4. 选择 Copy member ID

成员 ID 看起来像 U01ABC2DEF3。您至少需要您自己的成员 ID。


第 8 步:配置 Hermes

将以下内容添加到您的 ~/.hermes/.env 文件中:

# 必需
SLACK_BOT_TOKEN=xoxb-y...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 Mode 中,无论清单的 url 字段如何,Slack 都会通过 WebSocket 路由命令事件。

更新后刷新斜杠命令

当 Hermes 添加新命令时(例如 hermes update 之后),重新生成清单并更新您的 Slack 应用:

hermes slack manifest --write

然后在 Slack 中:

  1. 打开 https://api.slack.com/apps → 您的 Hermes 应用
  2. Features → App Manifest → Edit
  3. 粘贴 ~/.hermes/slack-manifest.json 的新内容
  4. Save。如果范围或斜杠命令发生变化,Slack 会提示重新安装应用。

旧版 /hermes <subcommand> 仍然有效

为向后兼容旧清单,您仍然可以键入 /hermes btw run the tests — Hermes 会像处理 /btw run the tests 一样路由它。自由形式的问题也可用:/hermes what's the weather? 被视为普通消息。

在线程内使用命令(!cmd 前缀)

Slack 本身会阻止线程回复中的原生斜杠命令——在线程中尝试 /queue,Slack 会回复 “/queue is not supported in threads. Sorry!” 没有应用侧设置可以重新启用它们;Slack 从未将它们传递给 Hermes。

作为解决方法,Hermes 识别前导的 ! 作为在线程中(以及任何其他地方)有效的替代命令前缀。键入 !queue!stop!model gpt-5.4 等作为普通线程回复——Hermes 将其视为与斜杠形式相同,并在同一线程中回复。

只有第一个令牌会对照已知命令列表进行检查,因此像 !nice work 这样的随意消息会原封不动地传递给 agent。

高级:仅输出斜杠命令数组

如果您手动维护 Slack 清单,只想要斜杠命令列表:

hermes slack manifest --slashes-only > /tmp/slashes.json

将该数组粘贴到您现有清单的 features.slash_commands 键中。


机器人如何回复

了解 Hermes 在不同上下文中的行为:

上下文行为
私信机器人回复每条消息——无需 @提及
频道机器人仅在 @提及 时回复(例如 @Hermes Agent what time is it?)。在频道中,Hermes 在附属于该消息的线程中回复。
线程如果您在现有线程中 @提及 Hermes,它会在同一线程中回复。一旦机器人在线程中有活跃会话,该线程中的后续回复不需要 @提及——机器人自然地跟随对话。

:::tip 在频道中,始终 @提及机器人以开始对话。一旦机器人在线程中活跃,您可以在该线程中回复而不提及它。在线程外,没有 @提及 的消息会被忽略,以防止繁忙频道中的噪音。 :::


配置选项

除了第 8 步中的必需环境变量外,您还可以通过 ~/.hermes/config.yaml 自定义 Slack 机器人行为。

线程和回复行为

platforms:
  slack:
    # 控制多部分回复的线程化方式
    # "off"   — 从不将回复线程化到原始消息
    # "first" — 第一个块线程化到用户消息(默认)
    # "all"   — 所有块线程化到用户消息
    reply_to_mode: "first"
 
    extra:
      # 是否在线程中回复(默认:true)。
      # 当为 false 时,频道消息获得直接频道回复而非线程。
      # 现有线程内的消息仍然在线程内回复。
      reply_in_thread: true
 
      # 也将线程回复发布到主频道
      #(Slack 的 "Also send to channel" 功能)。
      # 仅广播第一个回复的第一个块。
      reply_broadcast: false
默认值描述
platforms.slack.reply_to_mode"first"多部分消息的线程化模式:"off""first""all"
platforms.slack.extra.reply_in_threadtrue当为 false 时,频道消息获得直接回复而非线程。现有线程内的消息仍然在线程内回复。
platforms.slack.extra.reply_broadcastfalse当为 true 时,线程回复也会发布到主频道。仅广播第一个块。

会话隔离

# 全局设置 — 适用于 Slack 和所有其他平台
group_sessions_per_user: true

当为 true(默认)时,共享频道中的每个用户获得自己隔离的对话会话。在 #general 中与 Hermes 交谈的两个人将拥有独立的历史和上下文。

设为 false 如果您想要协作模式,整个频道共享一个对话会话。请注意这意味着用户共享上下文增长和 token 成本,并且一个用户的 /reset 会清除所有人的会话。

提及和触发行为

slack:
  # 在频道中要求 @提及(这是默认行为;
  # Slack 适配器无论如何都会在频道中强制执行 @提及 门控,
  # 但您可以显式设置以与其他平台保持一致)
  require_mention: true
 
  # 防止线程自动参与:仅回复包含显式 @提及 的频道消息。
  # 关闭此选项时(默认),Slack 可以 "auto-engage" —
  # 记住线程中的过去提及并跟进机器人消息的回复,
  # 并在没有新提及的情况下恢复活跃会话。
  # 开启 strict_mention 时,每条新的频道消息必须 @提及
  # 机器人,Hermes 才会回复。
  strict_mention: false
 
  # 触发机器人的自定义提及模式
  #(除了默认的 @提及 检测之外)
  mention_patterns:
    - "hey hermes"
    - "hermes,"
 
  # 附加到每条出站消息前的文本
  reply_prefix: ""

:::tip 何时使用 strict_mention 在繁忙的工作区中设置为 true,当 Slack 默认的”机器人记住这个线程”行为让用户感到意外时——例如,一个很长的技术支持线程,机器人帮助了开头,而您宁愿它保持静默,除非显式再次被 @。私信和活跃的交互式会话不受影响。 :::

:::info Slack 支持两种模式:默认情况下需要 @提及 才能开始对话,但您可以通过 SLACK_FREE_RESPONSE_CHANNELS(逗号分隔的频道 ID)或 config.yaml 中的 slack.free_response_channels 选择特定频道退出。一旦机器人在线程中有活跃会话,后续线程回复不需要提及。在私信中,机器人始终无需提及即可回复。 :::

频道白名单(allowed_channels

将机器人限制到固定的 Slack 频道集合——当机器人被邀请到许多频道但只应在少数频道中回复时很有用。设置后,来自不在此列表中的频道的消息会被静默忽略,即使机器人被 @提及

私信不受此过滤器影响,因此授权用户始终可以通过直接消息联系到机器人。

slack:
  allowed_channels:
    - "C0123456789"   # #ops
    - "C0987654321"   # #incident-response

或通过环境变量(逗号分隔):

SLACK_ALLOWED_CHANNELS="C0123456789,C0987654321"

行为:

  • 空/未设置 → 无限制(完全向后兼容)。
  • 非空 → 频道 ID 必须在列表中,否则消息在任何其他门控(提及要求、free_response_channels 等)运行之前被丢弃。
  • Slack 频道 ID 以 C(公共)、G(私密)或 D(DM)开头。通过 Slack UI 的”Open channel details” → “About”面板或 API 查找它们。

另请参阅:用户斜杠命令分拆

未授权用户处理

slack:
  # 当未授权用户(不在 SLACK_ALLOWED_USERS 中)DM 机器人时发生什么
  # "pair"   — 提示他们输入配对码(默认)
  # "ignore" — 静默丢弃消息
  unauthorized_dm_behavior: "pair"

您也可以为所有平台全局设置:

unauthorized_dm_behavior: "pair"

slack: 下的平台特定设置优先于全局设置。

语音转录

# 全局设置 — 启用/禁用传入语音消息的自动转录
stt_enabled: true

当为 true(默认)时,传入的音频消息会使用配置的 STT 提供商自动转录,然后再由 agent 处理。

完整示例

# 全局网关设置
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:

  1. 在 Slack 中右键点击频道名称
  2. 点击 View channel details
  3. 滚动到底部 — 频道 ID 显示在那里
SLACK_HOME_CHANNEL=C01234567890

确保机器人已被邀请到频道/invite @Hermes Agent)。


多工作区支持

Hermes 可以使用单个网关实例同时连接到多个 Slack 工作区。每个工作区使用其自己的机器人用户 ID 独立认证。

配置

SLACK_BOT_TOKEN 中提供多个机器人令牌作为逗号分隔的列表

# 多个机器人令牌 — 每个工作区一个
SLACK_BOT_TOKEN=xoxb-w...oken,xoxb-w...oken,xoxb-w...oken
 
# Socket Mode 仍使用单个应用级令牌
SLACK_APP_TOKEN=xapp-your-app-token

或在 ~/.hermes/config.yaml 中:

platforms:
  slack:
    token: "xoxb-w...oken,xoxb-w...oken"

OAuth 令牌文件

除了环境或配置中的令牌外,Hermes 还会从 OAuth 令牌文件加载令牌,位于:

~/.hermes/slack_tokens.json

该文件是一个 JSON 对象,将团队 ID 映射到令牌条目:

{
  "T01ABC2DEF3": {
    "token": "xoxb-w...here",
    "team_name": "My Workspace"
  }
}

来自此文件的令牌与通过 SLACK_BOT_TOKEN 指定的任何令牌合并。重复令牌会自动去重。

工作原理

  • 列表中的第一个令牌是主令牌,用于 Socket Mode 连接(AsyncApp)。
  • 每个令牌在启动时通过 auth.test 进行认证。网关将每个 team_id 映射到自己的 WebClientbot_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": |
      你是一个研究助手。专注于学术来源、
      引用和简洁的综合。
    "C02ENGINEERING": |
      代码审查模式。对边界情况和
      性能影响要精确。

键是 Slack 频道 ID(通过频道详情 → “About” → 滚动到底部查找)。匹配频道中的所有消息都会获得该提示作为临时系统指令注入。

每频道技能绑定

在特定频道或 DM 中开始新会话时自动加载技能。与每频道提示(在每轮注入)不同,技能绑定在会话开始时将技能内容作为用户消息注入——它成为对话历史的一部分,不需要在后续轮次中重新加载。

这对于具有专用目的的 DM 或频道(闪卡、特定领域的问答机器人、支持分类频道等)非常理想,在这些场景中您不希望模型的技能选择器在每个简短回复时决定是否加载。

slack:
  channel_skill_bindings:
    # DM 频道 — 始终以 "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.channelsmessage.groups 添加到事件订阅,重新安装应用,并使用 /invite @Hermes Agent 邀请机器人到频道
机器人在频道中不响应 @提及1) 检查 message.channels 事件已订阅。2) 机器人必须被邀请到频道。3) 确保 channels:history 范围已添加。4) 在范围/事件更改后重新安装应用
机器人忽略私密频道中的消息添加 message.groups 事件订阅和 groups:history 范围,然后重新安装应用并 /invite 机器人
私信中显示”Sending messages to this app has been turned off”在 App Home 设置中启用 Messages Tab(见第 5 步)
“not_authed” 或 “invalid_auth” 错误重新生成您的 Bot Token 和 App Token,更新 .env
机器人回复但无法在频道中发布使用 /invite @Hermes Agent 邀请机器人到频道
机器人可以聊天但无法读取上传的图片/文件添加 files:read,然后重新安装应用。Hermes 现在在 Slack 返回范围/认证/权限失败时在聊天中显示附件访问诊断信息。
missing_scope 错误在 OAuth & Permissions 中添加所需范围,然后重新安装应用
Socket 频繁断开检查您的网络;Bolt 会自动重连,但不稳定的连接会导致延迟
更改了范围/事件但没有任何变化在更改范围或事件订阅后,您必须重新安装应用到您的工作区

快速检查清单

如果机器人在频道中不工作,验证所有以下项目:

  1. message.channels 事件已订阅(用于公共频道)
  2. message.groups 事件已订阅(用于私密频道)
  3. app_mention 事件已订阅
  4. channels:history 范围已添加(用于公共频道)
  5. groups:history 范围已添加(用于私密频道)
  6. ✅ 应用在添加范围/事件后已重新安装
  7. ✅ 机器人已被邀请到频道(/invite @Hermes Agent
  8. ✅ 您在消息中 @提及了机器人

安全性

:::warning 始终设置 SLACK_ALLOWED_USERS 包含授权用户的成员 ID。没有此设置,网关将默认拒绝所有消息作为安全措施。切勿分享您的机器人令牌——将其视为密码。 :::

  • 令牌应存储在 ~/.hermes/.env 中(文件权限 600
  • 定期通过 Slack 应用设置轮换令牌
  • 审计谁可以访问您的 Hermes 配置目录
  • Socket Mode 意味着没有公共端点暴露——少了一个攻击面