将 Desktop 连接到多个 Hermes 实例
把你拥有的每一个 Hermes 后端 —— 本地运行时、位于局域网或 VPS 上的远程网关、SSH 主机,以及 Hermes Cloud 实例 —— 都注册到一个桌面应用中,并同时使用它们上面的智能体。连接是持久的:每个已注册的网关按需拨号连接自己的后端和 WebSocket,当你切换到另一个网关时,后台智能体仍会继续流式输出。
这是 同时运行多个网关在桌面端的补充篇:那一页讲的是如何在一台机器上托管多个网关;这一页讲的是一个桌面应用如何与多台机器通信。
在哪里找到它
一切都位于统一的 设置 → 网关 页面(较早的版本中分为 网关 和 连接 两个独立页面;遗留的“连接”深度链接会重定向到这里)。有三条路径可以到达该页面:
- 设置 → 网关 —— 页面本身(按 Cmd/Ctrl+,,然后在设置导航栏中点 网关)。连接注册表是该页面的一个区块,位于机器级别的连接模式控件下方。
- 侧边栏配置档栏 —— 栏最右端的插头按钮 (提示文字:"连接另一个 Hermes 网关……")会直接深度链接到 网关页面。它始终可见,即使你还没有创建 第二个配置档或第二个连接。
- 命令面板 —— 按 Cmd/Ctrl+K,然后输入 Gateways(也可以 匹配 connections、add gateway、remote、ssh、instances)。
网关注册表
设置 → 网关 中的 已注册网关 区块管理着一个具名的 Hermes 网关列表。它的简介说得很直白:"管理此设备以及它能够通过远程、SSH 或 Cloud 连接访问的每一个 Hermes 网关。" 每一条目就是一个连接:
| 类型 | 它是什么 | 认证 |
|---|---|---|
| 本地 | "由此应用管理的 Hermes 运行时。" | 自动 |
| 远程网关 | "可通过 HTTP(S) 访问的 Hermes 网关 —— 局域网、Tailscale 或互联网。" | 会话令牌或 OAuth |
| SSH | "通过 SSH 访问的 Hermes 安装。" 应用会为你打开隧道并启动仪表盘 | SSH 密钥 + 采纳的令牌 |
| Hermes Cloud | "通过你的 Hermes Cloud 账户发现的托管实例。" | 门户登录 |
值得了解的规则:
- 每一个连接都需要一个唯一的设备名称("Homelab"、"Work laptop")。这个名称会出现在该实例出现的所有地方 —— 名册徽标、句柄、更新结果。唯一性不区分大小写,所以
Homelab和homelab不能共存。 - 本地条目由应用管理(它带有一个 应用托管 标签),且不能被移除。移除任何其他连接会拆除其所有活动后端和隧道;实例本身不受影响。
- 始终有一个连接是 主连接(其所在行上有标签):对于那些未指明网关的多网关调用,它是注册表中的回退连接。设为主连接 不会切换当前 Sessions 工作区;移除主连接会回退到本地条目。
- 启动时,返回到上次使用的网关上的 Sessions 控制应用完全重启后 Sessions 打开哪个网关。它默认关闭,所以 Sessions 打开在 主连接 上。打开它可恢复到最近一次成功连接的网关。切换失败不会被记住,已移除或不可用的已保存网关会回退到主连接。
- 测试 会探测连接自身的 HTTP 和 WebSocket 两条链路,所以测试通过(出现 "可访问" 提示)意味着聊天会真正可用 —— 而不仅仅是主机能被 ping 通。
- 保存时重复项会被拒绝:本地条目永远只有一个;远程和 Cloud 条目按规范化后的 URL 去重(去除首尾空白、去掉末尾斜杠、转为小写 —— 并且在两个类型之间联合去重,所以一个 Cloud 条目和一个远程条目不能指向同一个 URL);SSH 条目按规范化后的
user@host:port加远程配置档去重。 - Cloud 条目通常来自网关页面顶部的 Hermes Cloud 登录/发现流程 —— 添加连接编辑器中的 Hermes Cloud 类型会把你怎么去那里指出来。
在 Sessions 侧边栏中切换网关。配置档、聊天、消息收发和定时任务都保持在该网关的范围内;应用管理的窗口后端仍由上述连接模式控件选择。主连接 是注册表中的回退项,不会切换当前工作区。
组织会话分组
在 Sessions 侧边栏的视图菜单中,查看所有配置档时选择 Gateway & profile。每个 gateway 都有自己的可折叠区块,其中的配置档子区块包含各自的会话。两个都有 default 配置档的 gateway 会保持各自独立。Gateway 标题以保存的连接名开头;配置档标题显示配置档名称。
使用 gateway 或配置档区块的菜单可以进行 重命名分组、重置名称、上移 或 下移 操作。重命名只改变侧边栏标签,不会改变 gateway 或配置档本身。Gateway 作为完整区块重新排序,配置档在其所属 gateway 内部重新排序。拖拽区块的前导图标即可重新排序,或将焦点移到该拖拽手柄上,用空格键、方向键,再按空格键来放置。名称、顺序和折叠状态都会在这台桌面上被记住。折叠某个 gateway 会保留其配置档各自的折叠状态。每个配置档的新建会话操作会针对其所属 gateway 上的该配置档。
当门户发现处于登出状态时,Hermes Cloud 面板还会列出 已保存的 Cloud gateway。Use gateway 会选择已有的已保存连接而不改变默认 gateway;Active in this window 则标识当前使用的那个。添加新实例时使用其友好的 Cloud 名称,而现有的自定义连接名则保持不变。已保存的连接仍然需要有效的 gateway 认证;请从已注册的连接控件管理登录。
逐步添加连接
- 打开 设置 → Gateways,滚动到连接注册表(或点击配置档栏中的插头图标)。
- 点击 添加连接。
- 选择类型:本地、Hermes Cloud、远程 gateway 或 SSH。(当应用管理的本地条目存在时——这几乎是常态——本地 会被禁用;Hermes Cloud 会引导你进入上方的 cloud 登录/发现流程。)
- 填写字段:
- 名称 — 必填,唯一;它是此实例出现处所显示的“设备名”(占位符:
Homelab)。最多 64 个字符。 - 仅远程 gateway:
- Gateway URL — 正在运行的
hermes serve后端的基 URL,例如http://homelab.lan:9119。反向代理路径前缀也可以。 - 认证 — 选择 会话令牌 或 OAuth:
- 会话令牌 — 粘贴远程 gateway 的仪表盘会话令牌。编辑时,“留空以保留已保存的令牌。”
- OAuth — 通过 Nous Portal 浏览器流程登录;无需粘贴令牌。
- Gateway URL — 正在运行的
- 仅 SSH:
- SSH 主机 — 一个复合字段,格式为
user@host:22(user 和端口可选)。将使用你的 SSH 密钥;应用会通过隧道获取仪表盘令牌。
- SSH 主机 — 一个复合字段,格式为
- 名称 — 必填,唯一;它是此实例出现处所显示的“设备名”(占位符:
- 点击 保存连接(或 取消)。
- 在新行上点击 测试,等待出现 "Reachable"。
之后可以用铅笔按钮编辑任何非本地条目,或用垃圾桶按钮将其移除——移除会请求确认,并提醒你 “实例本身不受影响——你随时可以重新添加。”
hermes serve 进程除非后端确实已在另一台机器上启动并可访问,否则这里的一切都无法工作。桌面应用会连接到它;它不会替你启动它(SSH 连接除外,此时应用会按需通过隧道启动仪表盘)。后端侧的设置——认证服务商、绑定到非回环地址以及 Tailscale 指南——请参阅连接到远程后端。
从单连接设置迁移
支持注册表的版本首次启动时会自动导入你现有的设置:全局连接模式以及设置 → Gateway 中任何按配置档的旧版覆盖项,都会变成具名的注册表条目(按 URL/主机去重)。(较新版本不再在 Gateways 设置页提供按配置档的覆盖项——gateway 连接是机器级别的,配置档则从你所连接的 gateway 中发现。)旧设置文件保持原样,因此同一台机器上运行的旧版本仍可正常工作。如果迁移后的名称发生冲突,会加上后缀(Homelab 2)。
跨网关的智能体
每个已注册连接上的每个 配置档 都是一个智能体。多网关界面(以及内置的 Bot Mode 名单)呈现的是这份合并名册:
- 当同名配置档存在于多个网关上时,其标识会通过
@名称-设备消除歧义 — 你 Homelab 上的research呈现为@research-homelab,而跨所有网关唯一的配置档则保留其裸名称。 - 列举是即时完成的,但套接字是惰性的:应用通过 REST 列出智能体,而不会逐一拨打每个网关的 WebSocket。不可达的网关按行报错,而不是破坏整个名册;SSH 连接保持按需连接,直到你首次在其上打开智能体(不会有意外的隧道)。
- 打开一个智能体会拨通它自己的网关 — 聊天、会话和记忆都存在于拥有该配置档的机器上,恰如你直接使用该实例一样。
每个 (连接, 配置档) 对都拥有自己的后端和套接字,并与本地按配置档划分的后端采用相同的空闲回收机制进行池化 — 后台智能体在你查看另一个网关时仍持续推送流。
批准按钮会回传到拥有该会话的后端,而不是当前选中的配置档。对于本地次要配置档,即使缓存的会话绑定缺失,Desktop 也可以使用传递请求的那个套接字。已保存的会话归属仍然优先,而删除或重命名该本地配置档会清除这个临时的路由,而不是重连一个已废弃的后端。
切换与作用域
侧边栏底部遵循一个层级:网关 → 配置档 → 会话。网关是机器或托管后端;配置档是存在于某个网关上的隔离 Hermes 智能体。
- 只注册一个网关时,不会添加网关控件。纯本地 Desktop 保持原有的配置档栏和键盘操作流程。
- 注册多个网关时,侧边栏显示一个具名网关选择器。其设备、云、网络或终端图标标识连接类型;配置档头像仍然是分隔线后的独立控件。同一个选择器可从两个网关扩展到更大的集群,而不会把后端变成类似配置档的图标,也不会把配置档操作挤出轨栏。
- 选择某个网关会恢复该处最后使用的配置档。主页胶囊返回其默认配置档,图层胶囊显示此网关上的所有配置档。Cmd/Ctrl+1–9 继续在当前网关内切换配置档。
- 注册多个网关时,配置档栏是一条集群栏:每个已注册网关的配置档都位于同一条带上,每组以其网关的类型图标(设备、网络、终端、云)打头 — 与网关选择器使用的图标相同。当前网关的方块外观与单网关 Desktop 完全一致;其他网关的方块变暗("静息")。悬停一个静息方块会显示其机器名(
omer · 此设备),因此不同机器上两个同名配置档绝不会看起来一样。 - 点击静息方块执行的切换与网关选择器相同,落到确切的
(网关, 配置档):目标拨通过程中该方块旋转,前一个网关保持显示直到目标应答,目标失效时点击会以消息方式失败,而不是让窗口处于半切换状态。无论哪个网关处于活动状态,各组都保持注册顺序,因此方块绝不会在点击它的指针下移动。右键点击静息方块会提供切换至、颜色、重命名、编辑 SOUL.md 和删除,全部在方块自己的网关上执行;删除确认会指出机器名。 - 上次列举时无法到达的网关会保留其方块,图标上标有琥珀色圆点 — 沉睡的机器仍然是你的。同一个后端的两次注册会合并为一个组。集群中超过十三个方块后,该条带会折叠为一个按网关分区的菜单。
- 只有开启设置 → 网关 → 启动时,返回上次使用网关上的会话时,选定的网关才会在退出并重启后保留。该偏好设置和网关 id 存放在应用的用户数据注册表中,因此替换或更新应用包不会重置它们。
- 当前网关上超过十三个配置档时,其头像条会折叠为一个具名配置档选择器。因此大型网关和配置档集合可以并存,而不会改变网关 → 配置档 → 会话模型。
- 此设备仍然是一等网关,即使某个远程连接是 Primary。它可以在远程中断期间保持本地会话可用,但应用不会称其为"离线模式":所选模型或工具可能仍需要互联网访问。
- 会话列表、消息渠道、定时任务、设置、文件和记忆全部以活动的
(网关, 配置档)为作用域。从 Telegram 网关切换到 Signal 网关,不会把前一个网关的渠道组或会话留在侧边栏中。 - 仅显示切换器会读取 Electron 的本地连接注册表。远程网关只在被选中时才打开;没有定期的集群轮询。
- 悬停智能体会预热其后端,使切换不必付出冷启动的代价。
- 能力页面(Skills / Tools / MCP)具有匹配的作用域:其 配置中 选择器列出合并名册中的每个
(配置档, 设备)智能体,选择一个会读写那台机器的 Skills、工具集和 MCP 服务器,而不会切换会话工作区。Hub 安装、环境变量键和 MCP 设置都落到所选智能体的后端。MCP 标签页的热重载到活动会话按钮仅对窗口所连接网关上的智能体显示;其他机器上的编辑会在其下次会话时生效。
在设置 → 网关中添加、测试、重命名或移除网关。配置档操作旁的插头按钮是该单一管理页面的快捷方式,而不是第二个添加流程。
会话与 Bot 模式
会话有意一次只展示一个活动网关:这使文件、工具、渠道、定时任务和会话历史保持在同一个易于理解的执行上下文中。多配置档导航栏只会扩大选择器的范围——每次点击之后,工作区仍然只属于一个确切的 (gateway, profile)。Bot 模式承担不同的职责,可以展示联合名册,按网关分组,这样用户就能从同一个界面打开 NAS 上的一个智能体和 VPS 上的另一个智能体。打开某个 bot 仍然会激活其确切的 (gateway, profile) 路由。
直接 @ 提及 bot 和委托默认仍限制在网关本地。跨越后端边界会改变文件系统、凭据、工具和信任上下文,因此跨网关执行应当是一道显式的桥接,而不是共用同一个 Desktop 窗口带来的意外副作用。
同时更新所有实例
Settings → Gateways → Update all instances(在注册了多个连接后显示)会并行向每个符合条件的连接派发 hermes update:
- Local 通过应用自身的更新管道进行更新(与 Settings → Updates 流程相同)。
- Remote 和 SSH 连接会被通知通过各自的后端自行更新——更新在那台机器上运行。
- Hermes Cloud 实例会被跳过,并显示 "Managed by Hermes Cloud" 说明:平台负责管理它们的版本。
每个实例独立上报,因此一个无法连接的机器永远不会阻塞整个批次。对外部管理更新的后端(Docker、Nix)会按行礼貌地以自己的消息拒绝。
不过你很少需要这个 Settings 按钮:一旦存在多个更新目标,应用常规的更新入口(About 面板上的 Update now、⌘K Update Hermes、更新就绪提示)会自动执行相同的扇出——先更新活动后端,然后是其他所有符合条件的网关,最后才是桌面应用本身。参见桌面指南中的更新。
安全说明
- 令牌存放位置。 远程网关会话令牌(以及按网关基础 URL 为键的原生登录 OAuth 令牌)存储于应用的用户数据目录中,为仅属主可读(0600)的文件,位于 Electron 主进程中;渲染进程和插件永远看不到令牌字节。
- 可选的钥匙串加密。 默认情况下令牌不会经过操作系统钥匙串——尤其是在 macOS 上,Electron 的
safeStorage会把每个应用一个的密钥存入登录钥匙串,而钥匙串被锁定或损坏会导致每次启动时弹出密码提示。如果你希望在文件权限之上再增加静态加密,请开启 Settings → Gateway → "Encrypt saved secrets with the OS keychain";已存储的密文会被就地重新加密(macOS 上为 Keychain,Windows 上为 DPAPI,Linux 上为会话钥匙串后端)。再次关闭则会将其解密还原。 - 注册表文件(应用用户数据目录下的
connections.json)保存标签、URL 和主机——密文只会出现在加密信封内部。 - 插件 SDK 的
host.connections()有意只返回标签、类型和主 id——绝不返回令牌材料。
插件作者须知
Desktop 插件 SDK 直接暴露多网关接口:
host.connections()—— 已注册的连接列表(标签、类型、主标识;绝不包含令牌字节)。host.agents()—— 联合名册:每个(gateway, profile)一行,附带预计算的@name-device句柄。host.ensureAgent(connectionId, profile)—— 激活某个智能体的网关,使后续host.request调用命中其后端。host.warmAgent(connectionId, profile)—— 触发后即忘的套接字预热(悬停意图)。
这四个接口都会进行特性检测:在较旧的 Desktop 构建中它们不存在,插件应回退到单网关的 profiles.list 流程。Bot 模式的多网关名册就是参考实现。
故障排查
- "Connection test failed" —— 本机无法通过该 URL 访问后端。检查远程主机上
hermes serve是否在运行、端口是否开放,以及(对于令牌认证)令牌是否为最新。修复后重新运行 Test。 - 某个智能体显示出来但无法打开 —— 对其连接运行 Test。HTTP 通过而 WebSocket 阶段失败,通常意味着代理、防火墙或网关的认证/来源防护阻止了
/api/ws。 - 名册中缺少某个远程网关 —— 其后端宕机或无法访问;名册会将其列在网关项下并附上错误。SSH 连接在首次使用前显示为按需连接——这是设计使然,并非故障。
- "Update Hermes Desktop to chat with agents on other connections" —— 该应用早于多连接技术栈;请更新桌面应用本身。
- 设备名重复 —— 不可能;名称在保存时强制唯一。如果迁移的名称发生冲突,会被加上后缀(
Homelab 2)。 - "Could not save the connection" —— 最常见的原因是缺少 Name、名称已被占用,或 Gateway URL / SSH host 格式错误;错误消息会指出具体违反项。