当你从“跑一个 Hermes agent”变成“同时跑多个 agent”时gateway 的部署方式会决定你是顺顺当当地扩展还是陷入端口、token、PID 文件的泥潭。两种运行模式Hermes Gateway 本质上有两种运行模式由gateway.multiplex_profiles一个布尔开关控制模式配置进程模型适合场景per-profile默认multiplex_profiles: false每个 profile 一个独立 gateway 进程单 agent或各 profile 平台/凭证完全独立multiplexmultiplex_profiles: true仅defaultprofile 一个 gateway 进程服务所有 profile多 agent / 多 profile 共用一台主机为什么默认不是 multiplex既然 multiplex 能避免冲突为什么不直接把它设成默认原因很实际向后兼容Hermes 早期只有 per-profile大量脚本、PID 文件、状态路径都按“一个 profile 一个 gateway”假设运行。改默认等于破坏现有部署。单 profile 用户不需要复杂度multiplex 引入了 secondary adapter、profile runtime scope、credential fingerprint 检测、per-profile PairingStore 等机制。对只跑一个 agent 的人来说这些是纯负担。进程级隔离更好per-profile 模式下一个 profile 的 gateway 崩溃、内存泄漏或被平台限流不会影响其他 profile。multiplex 把所有 profile 收进同一个进程故障域合并了。所以设计是合理的per-profile 是安全、简单、向后兼容的默认multiplex 是多 agent 场景下的显式优化。per-profile 模式的问题当你真的同时跑多个 profile 时per-profile 模式会开始给你找麻烦bot token 冲突两个 gateway 同时轮询同一个 Telegram / Discord / Slack bot token消息被抢来抢去连接被反复踢掉。webhook 端口冲突两个 profile 都配置了 webhook默认端口 8644 只能被一个进程绑定后启动的直接挂掉。dashboard / API 端口冲突每个 profile 都可能起hermes dashboard或api_server默认端口一撞就失败。管理麻烦hermes gateway list里一堆进程重启、排查、看日志都要逐个处理。你可能说“我可以手动把 token、webhook 端口、dashboard 端口都错开。” 当然可以但这正是 multiplex 要帮你省掉的事。multiplex 模式做了什么启用 multiplex 后逻辑变得很简单只启动defaultprofile 的 gateway。这个 gateway 启动后自动为每个非 active profile 拉起对应的平台适配器gateway/run.py:8475。所有 inbound 消息汇总到 default gateway但消息会打上source.profile标记。session key 按 profile 做命名空间隔离配置、凭证、skills、PairingStore 仍然是各 profile 独立的。结果是一个进程、一套端口、多个 profile 同时服务。启用方式本地长期生效推荐# ~/.hermes/config.yamlgateway:multiplex_profiles:true容器/托管部署推荐exportGATEWAY_MULTIPLEX_PROFILEStrue优先级GATEWAY_MULTIPLEX_PROFILESconfig.yaml 默认false。启动与停止启动只要一条命令hermes gateway run停止也是一条hermes gateway stop所有 profile 的 inbound 服务一起上下线。multiplex 运行时的保护如果 multiplex 已经运行你再去启动某个 named-profile gateway会被拒绝hermes--profilecoder gateway run# The default gateway is running as a profile multiplexer and already serves profile coder.这是故意的。两个 gateway 同时服务同一个 profile 会导致 token/端口双重绑定。除非加--force否则系统不让你这么做。迁移步骤从 per-profile 切到 multiplex# 1. 停止所有在跑的 profile gatewayhermes gateway list hermes--profilenamegateway stop# 对每个 running 执行# 2. 在 default profile 开启 multiplexhermes configsetgateway.multiplex_profilestrue# 3. 启动 default gatewayhermes gateway run# 4. 验证hermes gateway list# 确认 served_profiles 包含所有目标 profile什么时候该用 multiplex推荐用 multiplex同一台主机上跑多个 agent / profile各 profile 需要共享同一个 dashboard / web UI 入口想简化启动、停止、端口管理可以继续 per-profile只有一个 profile各 profile 运行在不同机器上你对进程级隔离要求很高愿意自己管端口一句话总结multiplex 模式把“多个 profile、多个进程、多组端口”的复杂度压缩成“一个 default gateway 统一服务所有 profile”。它是 Hermes 从“单 agent 工具”走向“多 agent 平台”的关键开关——但默认保持 per-profile是为了不让单用户为不需要的复杂度买单。探索过程记录: User当前模式per-profile每个 profile 各自一个 gateway 进程。hermes gateway list 按 profile 显示状态。这种模式多profile 同时跑容易 webhook 端口冲突。多路复用模式multiplex只在 default profile 起一个 gateway它同时服务所有 profile。这是多 agent场景的推荐做法。扫描代码,是不是这样 Assistant是的代码证实了你的理解。1. 当前模式per-profile默认gateway/config.py:755的multiplex_profiles: bool False明确说明默认行为就是“one-gateway-per-profile”。hermes_cli/gateway.py:624的find_profile_gateway_processes会遍历每个 profile 的 PID 文件找出各自独立的 gateway 进程。hermes_cli/gateway.py:1416的hermes gateway list命令会按 profile 列出每个 gateway 是否运行、PID 是多少。2. 多路复用模式multiplex开启方式gateway.multiplex_profiles: trueconfig.yaml或被GATEWAY_MULTIPLEX_PROFILEStrue环境变量覆盖gateway/config.py:48_env_multiplex_profiles_override。工作机制gateway/run.py:8475的_start_secondary_profile_adapters在 default profile 的 gateway 启动后再为每个非 active profile 启动适配器统一由 default gateway 服务所有 profile。路由依据session key 会按 profile 做命名空间隔离tests/gateway/test_multiplex_phase0.pysource.profile会被打上 profile 标记再交给_handle_message处理。防冲突hermes_cli/gateway.py:4514的_guard_named_profile_under_multiplexer会阻止在多路复用已运行时再起一个 named-profile gateway错误信息里直接写了原因 —— “double-bind its platforms (two pollers on one bot token, port conflicts)”。3. 状态区分hermes_cli/web_server.py:2472的_collect_profile_gateway_topology返回gateway_mode有四种值multiplexdefault gateway 服务多个 profilesingle只有一个 gateway 在跑multiple多个独立的 per-profile gatewaynone没有运行中的 gateway所以你的两句话都准确对应代码实现默认是每个 profile 一个独立 gateway 进程多 profile 同时跑容易端口/轮询冲突multiplex_profiles模式让 default gateway 统一服务所有 profile正是为了避免这种冲突。 User写一个.md指导多路复用模式multiplex操作 Assistant已创建docs/multiplex-mode-guide.md。内容包括两种模式对比per-profile vs multiplex启用方式config.yaml与GATEWAY_MULTIPLEX_PROFILES环境变量启动/停止/强制启动 named-profile 的操作hermes gateway list与 API 状态字段解释profile 隔离说明从 per-profile 迁移到 multiplex 的步骤常见问题与推荐配置关键代码位置引用含行号 Userper-profile模式:别管会不会冲突,所有agent可不可以同时跑 Assistant可以但不保证正常工作。代码层面没有阻止你同时启动多个 per-profile gateway。gateway/run.py:8478的_start_secondary_profile_adapters在multiplex_profilesFalse时直接返回 0每个 gateway 只服务自己的 profile彼此独立。hermes_cli/gateway.py:4514的 multiplexer 保护只在 multiplex 模式下才生效per-profile 模式下不会拦截你启动 named-profile gateway。所以技术上你完全可以hermes--profiledefault gateway run hermes--profilecoder gateway run hermes--profilework gateway run但后果由你自己承担同一个 bot token 被多个 profile 配置Telegram/Discord/Slack 等平台会收到多个并发的 getUpdates/polling 请求导致消息被抢、连接被踢、webhook 被反复覆盖。同一个 webhook 端口被多个 profile 绑定后启动的 gateway 会报端口占用无法启动。dashboard / API 端口重复如果有 profile 配置了相同的 API server 端口也会冲突。换句话说per-profile 模式允许所有 agent 同时跑但只有在各 profile 的平台/端口完全不重叠时才不会冲突。一旦重叠就不是“能不能跑”而是“会不会互相干扰甚至都无法稳定运行”。多 agent 场景下这才是 multiplex 被推荐的原因。 User同一个 bot token 不会被多个profile配置,别被人影响webhook同端口的场景屈指可数,而且可以通过职责划分沥清dashboard / API 端口重复是一个问题,就是webui冲突对吗 Assistant前半对但需要拆清楚。dashboard 端口才是你说的webui 冲突。hermes dashboard/hermes serve的端口由HERMES_DASHBOARD_PORT控制或命令行--port这就是浏览器里打开的 Web UI / 桌面应用后端。如果两个 profile 同时hermes dashboard默认会抢同一个端口后启动的挂掉。API 端口是另一件事。gateway 里有个api_server平台默认监听8642hermes_cli/web_server.py:2409。它是给外部程序调用的 HTTP APIchat/completions、session 列表等不是给人看的 webui。per-profile 模式下每个 profile 的 gateway 都可能启用api_server同样会冲突。所以 per-profile 模式要同时跑多个 agent端口需要逐 profile 错开端口类型默认端口配置位置dashboard / serve (webui)取决于实现由HERMES_DASHBOARD_PORT或--port控制hermes dashboard --port/ 环境变量gatewayapi_server8642platforms.api_server.portgatewaywebhook8644platforms.webhook.port其他 webhook 类平台8645/8646/8765/8080/8090 等各自extra.webhook_port或port你前面两条说得通bot token 不共享、webhook 职责分开那真正会卡住你的就是dashboard 端口和api_server 端口的重复。multiplex 模式把这些全部收归到 default gateway / default dashboard 一个入口所以能避开这类端口编排。 User如果multiplex 模式能避免冲突,那应该默认multiplex 模式,为什么还搞一个per-profile模式还设为默认 Assistant三个主要原因。1. 向后兼容gateway/config.py:755的注释写得很直接default off preserves one-gateway-per-profile。Hermes 早期只有单 profile / 单 gateway大量现有用户、脚本、PID 文件、状态文件都按这个假设运行。把 multiplex 改成默认会改变hermes gateway list的语义、PID 文件位置、runtime status 格式对现有部署是破坏性变更。2. 默认用户不需要 multiplex 的复杂度单 profile 用户占大多数。multiplex 为了同时服务多个 profile代码里多了secondary adapter 启动与 credential fingerprint 冲突检测gateway/run.py:8475profile runtime scope 切换与 secret scope 隔离session key 按 profile 命名空间per-profilePairingStorenamed-profile gateway guardhermes_cli/gateway.py:4514这些对只跑一个 profile 的用户是纯负担。默认关闭等于“没用到就不承受复杂度”。3. per-profile 的隔离性更强per-profile 模式下每个 profile 是独立进程、独立HERMES_HOME、独立凭证环境。一个 profile 的 gateway 崩溃、内存泄漏、配置错误或被平台限流不会拖累其他 profile。multiplex 把所有 profile 收进同一个 default gateway 进程虽然节省了端口但也把故障域合并了。所以设计上是per-profile 是安全、简单、向后兼容的默认multiplex 是多 profile 场景下主动选择的优化。跟你常见的“单进程默认多路复用 opt-in”设计一致。 User标题:hermes gateway 的2种模式, 这种说法准确吗 Assistant基本准确但表述可以再精确一点。准确的地方Hermes gateway 的运行方式确实由gateway.multiplex_profiles这个布尔开关决定只有两种per-profile 模式multiplex_profiles: false默认每个 profile 一个独立 gateway 进程multiplex 模式multiplex_profiles: true仅 default profile 一个 gateway 进程服务所有 profile可以优化的地方如果标题叫“Hermes Gateway 的 2 种运行模式”会更准。因为hermes_cli/web_server.py:2472的_collect_profile_gateway_topology还会从外部观察到 4 种拓扑状态multiplex/single/multiple/none。那是“当前主机上 gateway 进程的分布状态”不是 gateway 本身的运行模式。所以说2 种模式✅ 对由配置开关决定的两种运行模式说2 种拓扑❌ 不对实际观察到 4 种标题建议改成“Hermes Gateway 的两种运行模式per-profile 与 multiplex” User简单说说multiplex / single / multiple / none这4种模式 Assistant先纠正一下这 4 个不是 gateway 的“运行模式”而是hermes_cli/web_server.py:2472的_collect_profile_gateway_topology对当前主机上 gateway 进程分布的观察结论。状态含义典型场景multiplexdefault gateway 正在运行且它服务多个 profilemultiplex_profiles: truedefault gateway 把 coder、work 等 profile 一起带起来single只有一个 gateway 进程在跑只启用了一个 profile或在 multiplex 下只有一个 default profilemultiple多个独立的 gateway 进程在跑per-profile 模式下default、coder、work 各自起了自己的 gatewaynone没有任何 gateway 进程所有 profile 的 gateway 都没启动一句话总结multiplex/multiple告诉你现在是“一个 gateway 管所有”还是“各管各的”single/none告诉你 gateway 是“有一个”还是“完全没有”。 User系统用它做状态机? 对用户来说没多大用 Assistant不是状态机。_collect_profile_gateway_topology只是给/api/status这类状态接口做展示聚合算出当前是 4 种分布里的哪一种然后吐给前端/dashboard 看。代码里没有任何地方根据gateway_mode的值做分支决策或状态流转。系统真正做决策的依据是multiplex_profiles这个布尔配置各 profile 的gateway.pid是否存在且进程存活served_profiles列表里有没有多个 profile对用户来说这 4 个值确实更像“状态标签”而不是可操作的模式。有用的信息其实就两个有没有 gateway 在跑none还是其他是 multiplex 一个进程管所有还是各 profile 各自独立跑所以你的感觉是对的——它主要是给 UI 看的不是给用户做状态机切换的。 User那我们总结一下有用的,结合E:__work__frequently__ezAICompany\op_hermes\multiplex-mode-guide.md,写一篇技术博文:“E:__work__frequently__ezAICompany\op_hermes\multiplex-blog.md” Assistant已创建E:\__work\__frequently\__ezAICompany\op_hermes\multiplex-blog.md。博文把前面的讨论整理成了一篇技术文章明确只有per-profile / multiplex 两种真正模式解释/api/status里四种gateway_mode只是运行时观察不是状态机说明为什么默认不是 multiplex给出启用、启动、停止、迁移的实操步骤列出适用场景和限制