sidebar_position: 30 title: “Hermes Relay” description: “Connect Hermes to messaging platforms through a relay connector that owns the platform credentials — enrollment, capabilities, config, and troubleshooting”
Hermes Relay(连接器)
:::warning 实验性功能
Relay目前仍处于实验阶段。在系统验证期间,其消息传输协议、认证机制及配置都可能随时变更,且不会提前发布弃用通知。
Hermes Relay本身并非聊天平台,而是一个连接器系统。它能够让您的网关对接一个或多个真实的消息平台(如Discord、Telegram、Slack、WhatsApp等),且无需持有任何平台的访问凭证。实际的平台机器人令牌和连接端口由另一个独立的服务——即“连接器”来管理。您的网关通过单个已认证的WebSocket与连接器建立连接,在握手阶段获取功能描述信息,之后便通过该连接通道交换标准化的消息事件(接收)及操作指令(发送)。
主要特点:
- 仅支持单向通信。网关从不开放入站端口。所有接收到的消息都会沿着网关发起连接的同一条WebSocket返回,因此该方案既可在NAT网络环境中使用,也适用于没有公网IP的服务器。
- 网关上不存储任何平台敏感信息。机器人令牌由连接器保管。经过认证的平台媒体地址会在连接器端重新处理,因此平台的访问凭证永远不会在网络上传输。
- 与具体平台无关。网关能够从握手阶段的描述信息中了解所对接平台的各项功能限制(如消息长度上限、Markdown格式支持、编辑/线程/流式传输功能以及支持的操作类型),而无需依赖硬编码的平台逻辑。
关于网关与连接器之间的正式接口规范,详见仓库中的文档 docs/relay-connector-contract.md。
何时使用 Relay
Relay 适用于由托管或共享的连接器服务负责管理平台端的部署场景——例如多租户托管环境,其中一个共享机器人负责处理多个用户的智能体请求;或是您不希望在网关机器上存储机器人令牌的场景。如果您直接运行自己的机器人,则应使用原生的平台适配器(Telegram、Discord 等)。
注册流程
自托管网关会使用每个网关专用的密钥向连接器进行身份验证。hermes gateway enroll 命令会使用该密钥来兑换一个一次性注册令牌(该令牌由连接器在为您的租户配置路由并生成网关配置时创建并提供)。
hermes gateway enroll \
--token <enrollment-token> \
--connector-url wss://connector.example.com/relay
功能说明:
-
从您现有的登录信息(位于
~/.hermes/auth.json)中获取最新的 Nous Portal 访问令牌——该令牌用于确认您所属的 Nous 组织(租户)。如果配置了gateway.idp.token_url,则会使用您自己的身份提供商(IdP),此时无需经过 Nous Portal,属于隔离式/自托管 IdP 的流程:若配置了client_id/client_secret,则会执行通用的 OAuth2 客户端凭据授权流程;若未配置任何参数,则该地址将被视为环境令牌端点(即简单的 GET 请求,响应体即为令牌——采用元数据服务器模式,例如 Domino’s 的$DOMINO_API_PROXY/access-token)。仅配置其中一种凭据将会导致错误。 -
通过 TLS 协议将注册令牌及网关 ID 发送到连接器的
/relay/enroll端点。 -
连接器会对令牌进行验证(包括签名、一次性使用规则以及租户匹配性),随后生成每个网关对应的密钥以及每个租户对应的传输密钥,并一次性返回这些密钥。
-
将上述凭据保存到
~/.hermes/.env文件中,包括GATEWAY_RELAY_ID、GATEWAY_RELAY_SECRET、GATEWAY_RELAY_DELIVERY_KEY(若已配置,则还会包含GATEWAY_RELAY_URL/GATEWAY_RELAY_WAKE_URL)。
之后请重启网关,以便其加载新的环境配置。
参数选项:
| 标志 | 描述 |
|---|---|
--token | 一次性注册令牌。也可通过 GATEWAY_RELAY_ENROLL_TOKEN 设置。 |
--connector-url | 连接器基础地址或中继地址(格式为 wss://…/relay 或 https://…)。也可通过 config.yaml 中的 GATEWAY_RELAY_URL 或 gateway.relay_url 设置。 |
--gateway-id | 该网关实例的稳定标识符(用于精细控制关闭机制)。默认值为 gw-<hostname>。 |
--wake-url | 可选地址,连接器可在空闲时收到缓冲任务时,通过该地址发送无载荷的 GET 请求来唤醒此网关。该值会以 GATEWAY_RELAY_WAKE_URL 的形式保存。即使未设置该参数,网关在下次重新连接时仍会处理缓冲消息。 |
配置说明
只要配置了连接器中继地址,中继功能就会自动启用——无需额外的功能标志。未设置该参数的部署环境也不会受到影响。
| 设置项 | 位置 | 含义 |
|---|---|---|
GATEWAY_RELAY_URL | 环境变量(~/.hermes/.env) | 连接器中继 WebSocket 地址。该设置启用中继平台功能。 |
gateway.relay_url | config.yaml 文件 | 与上述含义相同,采用配置文件形式(环境变量优先)。 |
GATEWAY_RELAY_ID | 环境变量 | 该网关实例的标识符(由 enroll 命令生成)。 |
GATEWAY_RELAY_SECRET | 环境变量 | 用于验证 WebSocket 升级请求的网关专用密钥(由 enroll 命令生成)。 |
GATEWAY_RELAY_DELIVERY_KEY | 环境变量 | 每个租户专用的消息传递密钥(由 enroll 命令生成;保留以兼容旧版本)。 |
GATEWAY_RELAY_WAKE_URL / gateway.relay_wake_url | 环境变量 / config.yaml 文件 | 用于唤醒处于空闲或暂停状态的网关的可选目标地址。 |
GATEWAY_RELAY_PLATFORMS | 环境变量 | 该网关通过单个连接支持的平台列表,各平台之间以逗号分隔(例如 discord,telegram)。该值通常由部署工具或编排系统自动设置。 |
GATEWAY_RELAY_BOT_IDS | 环境变量 | 各平台对应机器人标识的 JSON 映射表,例如 {"discord": {"botId": "…"}}。需与 GATEWAY_RELAY_PLATFORMS 配合使用。 |
gateway.idp.token_url | config.yaml 文件 | 当该设置被指定时,注册/配置过程将使用您自己的身份提供商而非 Nous Portal 进行身份验证:若同时设置了 gateway.idp.client_id/client_secret,则采用 OAuth2 客户端凭据机制;否则将使用系统默认的令牌获取接口(通过简单 GET 请求获取令牌,返回原始格式或 {"access_token": …} 格式)。 |
支持的功能特性
通过中继连接能够实现的功能,会在握手阶段进行协商确定:连接器会声明一份supported_ops列表,而网关仅会使用连接器明确声明的支持操作(较旧的连接器则会回退到传统的send/edit/typing/follow_up操作集)。各平台特有的功能标志(如基于编辑的流式传输、多线程功能、草稿流式传输、Markdown格式支持以及消息长度限制)也均来自握手阶段的描述信息。在完成上述协商后,该中继连接可支持以下功能:
- 文本消息与流式传输——当目标平台支持消息编辑时,可实现发送、回复以及基于编辑的渐进式流式传输;否则,传输方式将降级为每个消息段仅传输一条消息。
- 双向媒体传输——发送方的图片、语音、音频、视频及文档会被上传至连接器(或通过公共URL引用),随后附带字幕,通过各平台原有的上传通道进行传输。接收方的附件则会被转换为适用于智能体的文件形式;而经过身份验证的平台URL则会在连接器端重新托管,从而确保平台的访问凭证永远不会传递到网关。媒体文件的重新托管大小上限为25 MB,且有效期约为1小时。
- 原生交互式提示——执行审批、确认操作及问题澄清等功能将通过平台原生控件(Discord按钮、Telegram内联键盘、Slack Block Kit操作、WhatsApp按钮/列表消息)来呈现,而非采用编号文本作为替代方案。用户点击按钮后,系统会返回由实际操作者发送的经过身份验证的响应,因此网关的授权机制与处理文本回复时完全一致。提示的有效期由网关端统一管控。
- 反应确认流程——机器人用于显示处理状态的反应(工作中显示👀,处理完成后显示✅/❌)会通过中继机制传递。这类反应采用尽力而为的方式处理:即使某次反应发送失败,也不会导致当前轮次中断。
- 主题线程管理——可通过平台抽象层的
thread_create/thread_rename操作来创建转交主题线程或重命名主题线程(包括基于LLM生成的语义化重命名),并且系统设有防止覆盖保护机制,确保人工手动重命名能优先生效。具体功能支持情况因平台而异(例如Slack不支持重命名主题线程,WhatsApp则没有主题线程功能)。 - 输入中状态指示——在处理过程中,网关会通过连接器发送输入中/停止输入的状态信号。
- 聊天元数据——当相关功能被支持时,
get_chat_info查询请求会被转发至连接器处处理。 - 缓冲传输与唤醒机制——当网关处于空闲状态或断开连接时,连接器会持久存储传入的消息,并在重新连接后按顺序重新发送这些消息(采用确认机制,确保无丢失或重复)。如果已注册唤醒 URL,当有消息需要发送给处于休眠状态的网关时,连接器会自动发送请求进行唤醒。
该系统支持多平台接入:一个网关可通过单个中继连接同时为多个平台提供服务(例如 Discord 和 Telegram),每条出站消息都会被标记对应的目标平台。
故障排除
注册失败并返回 401 错误——连接器无法验证您的身份令牌。请使用 hermes auth add nous(或 hermes setup)重新登录后再试。
注册失败并返回 403 错误——注册令牌无效、已过期、已被使用,或属于其他租户。注册令牌为一次性使用,请向负责配置您租户路由的团队申请新的令牌。
“无法连接到连接器”——请检查连接器 URL。您可以输入 wss://…/relay 这样的连接地址,也可以输入 https://… 这样的基础地址;CLI 会自动在两者之间进行转换。
enroll 命令无法执行——您当前使用的是托管型安装环境,其中中继密钥由托管平台统一提供。仅自托管型网关才支持自行注册。
原本正常工作的中继平台突然显示为已禁用 —— 在成功完成握手之后出现代码为4401的WebSocket连接关闭,意味着网关的密钥已被撤销(例如相关实例已被移除)。此时网关会主动停止尝试重新连接,并将中继状态标记为已禁用,而不会继续重试。如果在任何成功握手之前就出现4401错误,则视为暂时的资源准备不足问题,系统会正常进行重试。
完成注册后没有任何变化 —— 网关在启动时会读取GATEWAY_RELAY_*相关配置。请尝试重启网关(使用命令hermes gateway restart)。
某些功能(如按钮、媒体内容、线程等) silently降级为纯文本显示 —— 您所使用的平台连接器在握手过程中的supported_ops列表中并未声明支持这些操作。为避免发送连接器无法处理的指令,网关会自动采用纯文本显示方式。