跳到主要内容

Discord

Hermes Agent 可作为 bot 接入 Discord,让你通过私聊或服务器频道与 AI 助手对话。它会接收你的消息,通过完整的 Hermes Agent 流水线(包括工具、记忆和 reasoning)处理,并实时回复。支持文本、语音消息、文件附件和 slash commands。

在开始设置前,先说明大多数人最关心的一点:Hermes 进入你的服务器后会如何表现。

Hermes 的行为方式

ContextBehavior
DMs每条消息都回复,无需 @mention。每个 DM 拥有独立会话。
Server channels默认只有在 @mention bot 时才会回复;未提及时会忽略。
Free-response channels可通过 DISCORD_FREE_RESPONSE_CHANNELS 把某些频道设为无需 mention 的自由回复频道,或使用 DISCORD_REQUIRE_MENTION=false 全局关闭 mention 限制。此类频道会直接内联回复,不再自动新建 thread。
ThreadsHermes 会在同一 thread 中回复。除非该 thread 或其父频道已被设为自由回复,否则 mention 规则依然适用。thread 与父频道的会话历史彼此隔离。
Shared channels with multiple users默认会按用户隔离共享频道中的会话历史,确保安全且更清晰。
Messages mentioning other usersDISCORD_IGNORE_NO_MENTION=true(默认)时,如果一条消息只 @ 了别人却没有 @ bot,Hermes 会保持静默,避免误入别人的对话。
提示

如果你希望某个频道像普通 bot 帮助频道一样,让大家无需每次都 @ Hermes,也能直接聊天,把它加入 DISCORD_FREE_RESPONSE_CHANNELS 即可。

Discord 网关模型

Discord 上的 Hermes 不是一个无状态 webhook,而是完整运行在消息网关之上。每条入站消息通常会经过:

  1. 授权检查(DISCORD_ALLOWED_USERS
  2. mention / free-response 规则判断
  3. 会话查找
  4. transcript 加载
  5. 正常的 Hermes agent 执行流程(包括工具、记忆和 slash commands)
  6. 把响应投递回 Discord

因此,在繁忙服务器中的实际行为,既取决于 Discord 路由,也取决于 Hermes 的会话策略。

Discord 中的会话模型

默认情况下:

  • 每个 DM 是独立会话
  • 每个服务器 thread 都有独立会话命名空间
  • 共享频道中,每个用户在同一频道内也拥有自己的独立会话

也就是说,即使 Alice 和 Bob 都在 #research 里和 Hermes 对话,默认也会被视为两段互不干扰的独立会话。

这一行为由 config.yaml 控制:

group_sessions_per_user: true

如果你明确希望整个房间共享一段会话,可改为:

group_sessions_per_user: false

共享会话的含义是:

  • 用户会共享上下文增长和 token 成本
  • 某个人的长时间工具任务会影响其他人的上下文
  • 某个人正在运行的任务可能打断另一个人的后续消息

Interrupts and Concurrency

Hermes 会按 session key 跟踪正在运行的 agent。

在默认的 group_sessions_per_user: true 下:

  • Alice 打断自己的请求,只会影响她在该频道中的那段会话
  • Bob 可以在同一频道中继续聊天,不会继承 Alice 的历史,也不会打断 Alice 的运行

如果设置为 group_sessions_per_user: false

  • 整个房间共享同一个 running-agent 槽位
  • 不同人的后续消息会互相打断,或在同一个队列中排队

第 1 步:创建 Discord Application

  1. 打开 Discord Developer Portal 并登录
  2. 点击右上角 New Application
  3. 输入应用名称(例如 Hermes Agent
  4. 点击 Create

创建后,你会进入 General Information 页面。请记下 Application ID,稍后生成邀请链接时会用到。

第 2 步:创建 Bot

  1. 在左侧点击 Bot
  2. Discord 会自动为该应用创建一个 bot user,你可以自定义它的用户名
  3. Authorization Flow 部分:
    • Public Bot 设为 ON(推荐)
    • 保持 Require OAuth2 Code GrantOFF
提示

你可以在这个页面为 bot 设置自定义头像和 banner,这也是用户在 Discord 中看到的形象。

Private Bot Alternative

如果你希望 bot 保持私有(Public Bot = OFF),就不能使用 Installation 页中的 Discord Provided Link,必须改用第 5 步的手动 URL 方式邀请。

第 3 步:启用 Privileged Gateway Intents

这是整个设置过程中最关键的一步。如果没有启用正确的 intents,bot 即使连上 Discord,也看不到消息内容

Bot 页面向下滚动到 Privileged Gateway Intents,你会看到三个开关:

IntentPurposeRequired?
Presence Intent查看用户在线状态可选
Server Members Intent访问成员列表、解析用户名必需
Message Content Intent读取消息文本内容必需

请务必打开 Server Members Intent 和 Message Content Intent。

  • 没有 Message Content Intent,bot 虽然能收到消息事件,但消息文本是空的,也就是说它根本看不到你发了什么
  • 没有 Server Members Intent,bot 无法根据 allowlist 正确解析成员身份,也可能无法识别是谁在发消息
这是 Discord bot 无法工作的头号原因

如果你的 bot 在线,但永远不回复消息,那么几乎可以确定是 Message Content Intent 没开。回到 Developer Portal → 你的应用 → Bot → Privileged Gateway Intents,打开 Message Content Intent,然后点击 Save Changes

如果你的 bot 已加入 100 个以上服务器,Discord 会要求你通过验证流程后才能使用 privileged intents。对于个人使用场景,这通常不是问题。

第 4 步:获取 Bot Token

Bot 页面:

  1. Token 区域点击 Reset Token
  2. 如果你的 Discord 账号开启了双重验证,需要输入 2FA 代码
  3. Discord 会显示新的 token,立即复制
Token 只显示一次

如果遗失,只能重新生成。请不要公开分享 token,也不要提交到 Git。任何拿到这个 token 的人都能完全控制你的 bot。

第 5 步:生成邀请链接

你需要一个 OAuth2 URL 来把 bot 邀请进服务器。有两种方式:

Requires Public Bot

这种方式要求第 2 步中 Public BotON。如果你关闭了 Public Bot,请改用下面的手动 URL 方式。

  1. 点击左侧 Installation
  2. Installation Contexts 中启用 Guild Install
  3. Install Link 中选择 Discord Provided Link
  4. 在 Guild Install 的 Default Install Settings 中:
    • Scopes 勾选 botapplications.commands
    • Permissions 选择下方列出的权限

Option B: Manual URL

你也可以直接手动构造邀请链接:

https://discord.com/oauth2/authorize?client_id=YOUR_APP_ID&scope=bot+applications.commands&permissions=274878286912

把其中的 YOUR_APP_ID 替换成第 1 步记录下来的 Application ID。

Required Permissions

至少需要以下权限:

  • View Channels
  • Send Messages
  • Embed Links
  • Attach Files
  • Read Message History
  • Send Messages in Threads
  • Add Reactions

Permission Integers

LevelPermissions IntegerWhat's Included
Minimal117760View Channels、Send Messages、Read Message History、Attach Files
Recommended274878286912上述权限外加 Embed Links、Send Messages in Threads、Add Reactions

第 6 步:邀请到你的服务器

  1. 在浏览器中打开邀请链接
  2. Add to Server 下拉菜单里选择你的服务器
  3. 点击 Continue,然后 Authorize
  4. 如果需要,完成 CAPTCHA
信息

要把 bot 邀请进 Discord 服务器,你需要该服务器的 Manage Server 权限。如果下拉列表里看不到你的服务器,请让有管理员权限的人替你使用邀请链接。

授权完成后,bot 会出现在服务器成员列表中(在你启动 Hermes 网关前,它看起来会是离线状态)。

第 7 步:找到你的 Discord User ID

Hermes Agent 使用你的 Discord User ID 控制谁可以与 bot 交互。获取方法:

  1. 打开 Discord(桌面端或网页版)
  2. 进入 SettingsAdvanced,打开 Developer Mode
  3. 关闭设置
  4. 右键你自己的用户名(无论是在消息里、成员列表里还是个人资料里)→ Copy User ID

你的 User ID 看起来像 284102345871466496 这样的长数字。

提示

Developer Mode 也允许你同样复制 Channel IDServer ID。如果你想手动设置 home channel,就会用到 Channel ID。

第 8 步:配置 Hermes Agent

hermes gateway setup

选择 Discord,然后按提示粘贴 bot token 和你的 user ID。

Option B: Manual Configuration

把以下内容加入 ~/.hermes/.env

# Required
DISCORD_BOT_TOKEN=your-bot-token
DISCORD_ALLOWED_USERS=284102345871466496

# Multiple allowed users (comma-separated)
# DISCORD_ALLOWED_USERS=284102345871466496,198765432109876543

然后启动网关:

hermes gateway

几秒内 bot 就会在 Discord 上线。给它发一条消息测试,无论是私聊,还是它有权限看到的频道都可以。

提示

你也可以把 hermes gateway 作为后台进程或 systemd 服务运行,实现长期驻留。具体可参见部署文档。

Configuration Reference

Discord 的行为由两个文件控制:~/.hermes/.env 用于存放凭据和环境变量级开关,~/.hermes/config.yaml 用于结构化配置。当两边都设置了同一项时,环境变量优先。

Environment Variables (.env)

VariableRequiredDefaultDescription
DISCORD_BOT_TOKENYesDiscord Developer Portal 获取的 bot token
DISCORD_ALLOWED_USERSYes允许与 bot 交互的 Discord user ID 列表;如果它和 DISCORD_ALLOWED_ROLES 都没设置,网关会拒绝所有用户
DISCORD_ALLOWED_ROLESNo允许的 Discord role ID 列表。命中这些角色的成员会被授权,与 DISCORD_ALLOWED_USERS 是 OR 关系
DISCORD_HOME_CHANNELNobot 主动发送消息(cron 输出、提醒、通知)的频道 ID
DISCORD_HOME_CHANNEL_NAMENo"Home"home channel 在日志和状态输出中的显示名
DISCORD_COMMAND_SYNC_POLICYNo"safe"控制原生 slash commands 的启动同步策略
DISCORD_REQUIRE_MENTIONNotrue为 true 时,bot 只在被 @mention 的服务器频道中回复
DISCORD_FREE_RESPONSE_CHANNELSNo即使 DISCORD_REQUIRE_MENTION=true,这些频道里也无需 @mention
DISCORD_IGNORE_NO_MENTIONNotrue若消息只 @ 其他用户而没 @ bot,则保持静默
DISCORD_AUTO_THREADNotrue为 true 时,普通文本频道中的每次 @mention 都会自动创建 thread
DISCORD_ALLOW_BOTSNo"none"控制是否接受其他 Discord bots 的消息
DISCORD_REACTIONSNotrue是否在处理期间添加 👀 / ✅ / ❌ 表情反馈
DISCORD_IGNORED_CHANNELSNo永远不响应的频道,即使被 @mention 也忽略
DISCORD_ALLOWED_CHANNELSNo如果设置了,只允许在这些频道中响应
DISCORD_NO_THREAD_CHANNELSNo开启 auto-thread 时,这些频道中仍然直接内联回复,不创建 thread
DISCORD_REPLY_TO_MODENo"first"控制 reply-reference 的行为
DISCORD_ALLOW_MENTION_EVERYONENofalse是否允许 bot ping @everyone / @here
DISCORD_ALLOW_MENTION_ROLESNofalse是否允许 bot ping @role
DISCORD_ALLOW_MENTION_USERSNotrue是否允许 bot ping 单个用户
DISCORD_ALLOW_MENTION_REPLIED_USERNotruereply-reference 时是否 ping 被回复的原作者
DISCORD_PROXYNoDiscord 连接代理 URL
HERMES_DISCORD_TEXT_BATCH_DELAY_SECONDSNo0.6文本分块合并输出前的等待窗口
HERMES_DISCORD_TEXT_BATCH_SPLIT_DELAY_SECONDSNo0.1超长消息拆分后各块之间的发送延迟

Config File (config.yaml)

~/.hermes/config.yaml 中的 discord 段与上述环境变量相对应。它们作为默认值存在;如果等价的环境变量已设置,环境变量优先。

# Discord-specific settings
discord:
require_mention: true # Require @mention in server channels
free_response_channels: "" # Comma-separated channel IDs (or YAML list)
auto_thread: true # Auto-create threads on @mention
reactions: true # Add emoji reactions during processing
ignored_channels: [] # Channel IDs where bot never responds
no_thread_channels: [] # Channel IDs where bot responds without threading
channel_prompts: {} # Per-channel ephemeral system prompts
allow_mentions: # What the bot is allowed to ping (safe defaults)
everyone: false # @everyone / @here pings (default: false)
roles: false # @role pings (default: false)
users: true # @user pings (default: true)
replied_user: true # reply-reference pings the author (default: true)

# Session isolation (applies to all gateway platforms, not just Discord)
group_sessions_per_user: true # Isolate sessions per user in shared channels

Interactive Model Picker

在 Discord 中发送不带参数的 /model,Hermes 会打开一个基于下拉菜单的模型选择器:

  1. 大模型提供商(provider)选择:Select 下拉中显示可用的大模型提供商(provider)及模型数量
  2. 模型选择:随后显示该大模型提供商(provider)下的模型列表

选择器会在 120 秒后超时。只有授权用户(即 DISCORD_ALLOWED_USERS 中的用户)可以操作它。如果你已经知道模型名,也可以直接输入 /model <name>

Native Slash Commands for Skills

Hermes 会自动把已安装的技能注册为 原生 Discord Application Commands。这意味着它们会像内建命令一样出现在 Discord 的 / 自动补全菜单中。

  • 每个技能都会成为一个 Discord slash command(例如 /code-review/ascii-art
  • 技能命令接收一个可选的 args 字符串参数
  • Discord 每个 bot 最多支持 100 个 application commands;如果你的技能太多,超出的技能会被跳过,并在日志中给出警告
  • 技能会在 bot 启动时和 /model/reset/background 等内建命令一起注册

只要你使用 hermes skills install 安装了技能,下一次网关重启时,它们就会自动注册为 Discord slash commands。

Home Channel

你可以在任意 Discord 频道中执行 /sethome,把它设为 home channel,以便接收主动消息(如 cron 结果、提醒和通知)。

Using the Slash Command

在 bot 所在的任意 Discord 频道输入 /sethome,该频道就会成为 home channel。

Manual Configuration

把以下内容加入 ~/.hermes/.env

DISCORD_HOME_CHANNEL=123456789012345678
DISCORD_HOME_CHANNEL_NAME="#bot-updates"

把其中的 ID 替换成实际频道 ID(在开启 Developer Mode 后右键频道 → Copy Channel ID)。

Voice Messages

Hermes Agent 支持 Discord 语音:

  • 入站语音消息:会自动交给配置好的 STT 大模型提供商(provider)转写(本地 faster-whisper、Groq Whisper 或 OpenAI Whisper)
  • Text-to-speech:可通过 /voice tts 让 bot 在文字回复旁发送音频
  • Discord 语音频道:Hermes 还可以加入语音频道,监听用户讲话并在频道中回话

完整设置与使用说明见:

Forum Channels

Discord forum channels(type 15)不能直接发送普通消息,每一条内容都必须是一个 thread。Hermes 会自动检测 forum channel,并在需要发送内容时自动创建一个新的 thread post,因此 send_message、TTS、图片、语音消息和文件附件都能正常工作,无需 agent 特别处理。

  • 线程名 会从消息第一行推导(会移除 markdown 标题前缀,最长 100 字符)
  • 附件 会直接附着在新 thread 的起始消息上发送
  • 一次发送一次 thread:每次往 forum 发送都会新建一个 thread
  • 检测分三层:频道目录缓存、本地 probe 缓存,以及最后的 GET /channels/{id} 实时探测

如果 forum channel 是在 bot 启动后才新建的,可通过刷新频道目录(支持的平台可用 /channels refresh,或直接重启网关)让缓存重新同步。

Troubleshooting

Bot is online but not responding to messages

原因:Message Content Intent 未启用。

修复:回到 Developer Portal → 你的应用 → Bot → Privileged Gateway Intents,打开 Message Content Intent,点击保存,然后重启网关。

"Disallowed Intents" error on startup

原因:代码请求的 intents 在 Developer Portal 中没有打开。

修复:在 Bot 设置里启用所需的 privileged intents(至少是 Server Members Intent 和 Message Content Intent),然后重启。

Bot can't see messages in a specific channel

原因:bot 的角色没有权限查看该频道。

修复:在该频道设置中给 bot 的角色授予 View ChannelRead Message History

403 Forbidden errors

原因:bot 缺少必要权限。

修复:使用第 5 步中的正确邀请链接重新邀请,或在服务器角色设置中手动补齐权限。

Bot is offline

原因:Hermes 网关没有运行,或 token 不正确。

修复:检查 hermes gateway 是否正在运行;确认 .env 中的 DISCORD_BOT_TOKEN 正确;如果你最近重置过 token,请同步更新配置。

"User not allowed" / Bot ignores you

原因:你的 User ID 不在 DISCORD_ALLOWED_USERS 中。

修复:把你的 User ID 加入 DISCORD_ALLOWED_USERS,然后重启网关。

People in the same channel are sharing context unexpectedly

原因group_sessions_per_user 被关闭了,或者该场景下平台无法提供 user ID。

修复:在 ~/.hermes/config.yaml 中设置:

group_sessions_per_user: true

如果你本来就希望整个房间共享一段会话,可以保持关闭,但要预期共享 transcript 历史和打断行为。

Security

注意

务必设置 DISCORD_ALLOWED_USERS(或 DISCORD_ALLOWED_ROLES)来限制谁可以与 bot 交互。否则,出于安全考虑,网关默认会拒绝所有用户。只应授权你信任的人,因为被授权用户拥有 agent 的全部能力,包括工具调用和系统访问。

Role-Based Access Control

对于依赖角色管理的服务器(例如版主团队、支持团队或内部工具),可使用 DISCORD_ALLOWED_ROLES。它是逗号分隔的 role ID 列表,只要用户拥有其中任意一个角色,就会被授权。

# ~/.hermes/.env — works alongside or instead of DISCORD_ALLOWED_USERS
DISCORD_ALLOWED_ROLES=987654321098765432,876543210987654321

其语义如下:

  • 与用户 allowlist 是 OR 关系:只要 user ID 命中 DISCORD_ALLOWED_USERS,或拥有 DISCORD_ALLOWED_ROLES 中任意角色,即可通过授权
  • 自动启用 Members intent:设置 DISCORD_ALLOWED_ROLES 后,bot 会在连接时启用 Members intent,因为 Discord 只有这样才会下发成员角色信息
  • 使用 role ID,而不是角色名:在 Discord 中打开 User Settings → Advanced → Developer Mode ON,然后右键任意角色 → Copy Role ID
  • DM 回退:在私聊中,角色检查会扫描双方共同加入的服务器;只要用户在任意共同服务器中拥有允许角色,也会被授权

当管理团队经常变动时,这是更推荐的模式:新成员一旦被赋予相应角色,就立即获得权限,无需改 .env 或重启网关。

Mention Control

默认情况下,Hermes 会阻止 bot 触发 @everyone@here 和角色 mention,即使回复文本中出现了这些 token。这能防止不当 prompt 或原样回显用户内容时,不小心 ping 整个服务器。普通的单个用户 mention 和 reply-reference 仍保持启用,以保证日常对话正常工作。

你可以通过环境变量或 config.yaml 放宽这些默认限制:

# ~/.hermes/config.yaml
discord:
allow_mentions:
everyone: false # allow the bot to ping @everyone / @here
roles: false # allow the bot to ping @role mentions
users: true # allow the bot to ping individual @users
replied_user: true # ping the author when replying to their message
# ~/.hermes/.env — env vars win over config.yaml
DISCORD_ALLOW_MENTION_EVERYONE=false
DISCORD_ALLOW_MENTION_ROLES=false
DISCORD_ALLOW_MENTION_USERS=true
DISCORD_ALLOW_MENTION_REPLIED_USER=true
提示

除非你非常清楚为什么需要,否则请保持 everyonerolesfalse。LLM 很容易在看似正常的回复中生成 @everyone,如果没有这层保护,就会直接通知整个服务器。

更多部署安全信息,请参见 Security Guide