Hermes-Studio 企业级分布式部署改造方案 Hermes-Agent 企业级分布式部署方案版本v1.0 | 适用场景多租户 / 多团队 / 规模化 AI Agent 平台基于 Hermes Studio 原生架构企业仅需扩展用户表 新增路由映射表即可落地一、方案概述1.1 背景与挑战Hermes Studio 原生采用单实例 SQLite架构适合个人或小团队使用。当企业需要将 AI Agent 能力开放给数十到数百名用户时单实例面临以下瓶颈瓶颈表现并发上限SQLite 写锁导致高并发下请求排队数据隔离所有用户共享同一数据库无法做会话隔离扩展困难无法水平扩容单点故障影响全员资源争抢某用户的大量 Agent 会话影响其他用户体验1.2 设计目标低成本 — 无中间件依赖不需要 Redis/MySQL/K8s纯 Docker SQLite 水平扩展 高可用 — 任一实例故障仅影响该实例用户全局兜底保证零中断 易落地 — 企业只需改两处用户表加一个字段 新增一张路由映射表 零侵入 — 不修改 Hermes Studio 源码通过反向代理层透明路由1.3 核心架构┌──────────────────────────────────────────┐ │ 企业后端 (Proxy Layer) │ │ │ ┌──────┐ HTTP/API │ ┌───────────────────────────────┐ │ │ 用户A │──────────────┼─►│ 路由决策引擎 │ │ └──────┘ │ │ ① 查用户绑定的实例 │ │ ┌────────────────┐ │ │ ② 未绑定 → 自动分配 │ │────►│ Hermes 实例 A │ ┌──────┐ HTTP/API │ │ ③ 都不可用 → 全局默认兜底 │ │ │ :30001 │ │ 用户B │──────────────┼─►│ │──┬──►│ SQLite (~20用户) │ └──────┘ │ └───────────────────────────────┘ │ └────────────────┘ │ │ ┌────────────────┐ ┌──────┐ HTTP/API │ │ │ Hermes 实例 B │ │ 用户C │──────────────┼─► ├──►│ :30002 │ └──────┘ │ │ │ SQLite (~15用户) │ │ │ └────────────────┘ │ │ ┌────────────────┐ │ │ │ Hermes 实例 C │ │ └──►│ :30003 │ │ │ SQLite (~10用户) │ │ └────────────────┘ └──────────────────────────────────────────┘关键设计决策一用户一实例每个用户的所有请求HTTP API WebSocket/SSE自动路由到固定实例实例自治每个 Hermes 实例独立运行拥有自己的 SQLite 数据库用户间数据天然隔离代理透明前端无需感知多实例所有请求通过企业后端统一代理转发二、数据库设计最小改动企业只需做两件事① 新增一张路由映射表 ② 用户表加一个外键字段2.1 新增表hermes_instances实例路由映射表CREATETABLEhermes_instances(idSERIALPRIMARYKEY,nameVARCHAR(100)NOTNULL,-- 实例名称如 hermes-prod-01base_urlVARCHAR(500)NOTNULLUNIQUE,-- 实例地址如 http://10.0.1.50:30001statusVARCHAR(20)NOTNULLDEFAULTactive,-- active 正常服务-- maintenance 维护中不分配新用户-- inactive 已下线max_usersINTEGERNOTNULLDEFAULT20,-- 最大承载用户数按 SQLite 并发能力设定priorityINTEGERNOTNULLDEFAULT100,-- 自动分配优先级数值越大越优先remarkTEXTDEFAULT,created_atTIMESTAMPDEFAULTNOW(),updated_atTIMESTAMPDEFAULTNOW());字段说明字段用途运维场景status控制实例生命周期下线前先改maintenance→ 迁移用户 → 再改inactivemax_users防止单实例过载根据服务器配置调整一般 15-30priority灰度发布新实例可设高优先级优先接收用户老实例逐步迁移2.2 用户表扩展字段ALTERTABLEusersADDCOLUMNhermes_instance_idINTEGERREFERENCEShermes_instances(id)ONDELETESETNULL;-- NULL 含义该用户未绑定实例走全局默认地址完全向下兼容设计原则hermes_instance_id允许为 NULL → 未绑定的老用户自动走全局默认实例零中断ON DELETE SET NULL→ 删除实例时用户自动回退到全局默认不会悬空不修改任何现有字段 → 对现有业务逻辑完全透明2.3 初始化迁移向下兼容-- 1. 将现有全局地址注册为第一个实例INSERTINTOhermes_instances(name,base_url,status,max_users,priority,remark)VALUES(hermes-prod-01,http://当前全局地址:30001,active,20,100,初始实例)ONCONFLICTDONOTHING;-- 2. 将已有 Hermes 凭证的用户绑定到初始实例UPDATEusersSEThermes_instance_id(SELECTidFROMhermes_instancesORDERBYidLIMIT1)WHEREhermes_usernameISNOTNULLANDhermes_instance_idISNULL;三、路由决策引擎3.1 路由优先级请求进入 │ ▼ ┌─────────────────────────────────┐ │ ① 用户已绑定实例 │ │ → YES → 查询实例 base_url │ │ → 实例存在且 active │ │ → YES → 路由到该实例 │ │ → NO → 降级到 ② │ │ → NO → 进入 ② │ └─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ ② 全局默认地址是否可用 │ │ → YES → 路由到全局默认实例 │ │ → NO → 返回 503 │ └─────────────────────────────────┘3.2 路由函数伪代码asyncdefget_remote_base(user,db)-str: 路由决策核心 — 每个代理请求的入口 返回该用户应该被转发到的 Hermes 实例地址 # 优先级 1用户绑定的实例ifuser.hermes_instance_id:instancedb.query(hermes_instances).get(user.hermes_instance_id)ifinstanceandinstance.statusactive:returninstance.base_url# 实例不存在或已下线降级# 优先级 2全局默认地址兜底returnGLOBAL_HERMES_BASE_URL3.3 Token 缓存隔离多实例场景下同一用户在不同实例上的认证 Token 不同缓存键需包含实例地址改前cache_key username 改后cache_key {base_url}::{username}这确保了用户切换实例后自动获取新 Token旧 Token 自然过期不同实例的 Token 互不干扰四、自动分配算法4.1 分配策略优先级加权最低负载新用户注册时系统自动选择最优实例算法流程 1. 查询所有 status active 的实例 2. 按 priority DESC 排序高优先级先考虑 3. 统计每个实例当前绑定的用户数 4. 过滤出 current_users max_users 的实例未满载 5. 在候选集中选 load_ratio current_users / max_users 最低的实例 6. 无可分配实例时返回 NULL用户走全局默认4.2 分配示例实例优先级当前用户最大用户负载比是否选中hermes-prod-01100182090%hermes-prod-02100122060%✅ 最低负载hermes-prod-0320052025%✅ 高优先级 低负载hermes-prod-041002020100%已满优先级为 200 的 hermes-prod-03 会被优先选中即使它的绝对负载不是最低。4.3 何时触发自动分配触发时机行为新用户注册自动分配一个可用实例管理员手动分配覆盖自动分配结果管理员清除绑定用户回退到全局默认五、Hermes Studio 实例部署5.1 单实例部署Docker每个 Hermes 实例是一个独立的 Docker 容器# 实例 A — 端口 30001dockerrun-d\--namehermes-prod-01\-p30001:3000\-v/data/hermes/instance-01:/app/data\--restartunless-stopped\hermes-studio:latest# 实例 B — 端口 30002dockerrun-d\--namehermes-prod-02\-p30002:3000\-v/data/hermes/instance-02:/app/data\--restartunless-stopped\hermes-studio:latest要点每个实例挂载独立的数据目录 → SQLite 文件互不干扰使用--restart unless-stopped保证进程级高可用同一台服务器可运行多个实例端口区分也可分布在不同服务器5.2 服务器规划低成本方案┌───────────────────────────────────────────────────────────────┐ │ 服务器 A (4C8G, 云服务器 ~¥200/月) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Hermes 实例 1 │ │ Hermes 实例 2 │ │ Hermes 实例 3 │ │ │ │ :30001 │ │ :30002 │ │ :30003 │ │ │ │ ≤20 用户 │ │ ≤20 用户 │ │ ≤20 用户 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Hermes 实例 4 │ │ Hermes 实例 5 │ │ Hermes 实例 6 │ │ │ │ :30004 │ │ :30005 │ │ :30006 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ 共承载 ~120 用户 │ └───────────────────────────────────────────────────────────────┘容量估算单实例 Hermes Studio 内存占用约 200-500MB取决于 Agent 数量和活跃度4C8G 服务器可安全运行 6-8 个实例每实例推荐 15-25 用户取决于使用频率单台服务器可承载 100-150 用户5.3 Docker Compose 模板推荐version:3.8services:hermes-01:image:hermes-studio:latestports:[30001:3000]volumes:[./data/instance-01:/app/data]restart:unless-stoppedenvironment:-HERMES_INSTANCE_NAMEhermes-prod-01hermes-02:image:hermes-studio:latestports:[30002:3000]volumes:[./data/instance-02:/app/data]restart:unless-stoppedenvironment:-HERMES_INSTANCE_NAMEhermes-prod-02hermes-03:image:hermes-studio:latestports:[30003:3000]volumes:[./data/instance-03:/app/data]restart:unless-stoppedenvironment:-HERMES_INSTANCE_NAMEhermes-prod-03# 按需增加更多实例...六、代理层改造要点代理层是企业后端与 Hermes 实例之间的桥梁负责将请求路由到正确的实例。6.1 需要改造的代理接口接口类型说明改造内容REST API 代理所有 Hermes CRUD 操作的透传_get_remote_base(user)替代硬编码地址WebSocket/SSE 代理Agent 对话的流式响应连接时使用用户实例地址建立上游连接认证代理Hermes 登录/Token 获取Token 缓存键加实例前缀MCP 工具调用Agent 工具链执行工具调用请求路由到用户实例6.2 代理层改造清单改前所有请求 → 同一地址 def get_remote_base() - str: return settings.HERMES_STUDIO_BASE_URL 改后按用户路由 async def get_remote_base(user, db) - str: if user.hermes_instance_id: instance await db.get(HermesInstance, user.hermes_instance_id) if instance and instance.status active: return instance.base_url return settings.HERMES_STUDIO_BASE_URL # 兜底6.3 所有调用点统一改造代理层中每个调用 Hermes 的位置都需要获取当前用户对象从 JWT/Session 中解析调用路由函数获取实例地址传递实例地址到下游 HTTP 客户端需要改造的典型调用点调用点改造方式通用 API 代理catch-all传入current_userdb调用get_remote_base流式对话代理从请求 Header 解析 JWT → 获取用户 → 路由认证代理路由到用户实例后登录Token 缓存键含实例地址WebSocket 代理用路由后的地址建立上游连接七、管理后台设计7.1 实例管理页面面向超级管理员提供完整的实例生命周期管理┌─────────────────────────────────────────────────────────────┐ │ Hermes 实例管理 [ 新增] │ ├─────────────────────────────────────────────────────────────┤ │ 名称 地址 状态 用户数 负载 操作 │ │ ─────────────────────────────────────────────────────────── │ │ hermes-prod-01 http://...:30001 ✅活跃 18/20 90% 编辑 │ │ hermes-prod-02 http://...:30002 ✅活跃 12/20 60% 编辑 │ │ hermes-prod-03 http://...:30003 维护 5/20 25% 编辑 │ │ hermes-prod-04 http://...:30004 ❌停用 0/20 0% 编辑 │ └─────────────────────────────────────────────────────────────┘功能列表功能说明新增实例填写名称、地址、最大用户数、优先级编辑实例修改状态活跃/维护/停用、调整容量上限删除实例前置校验实例下必须无用户才能删除查看用户查看某实例下绑定的所有用户列表预览分配模拟自动分配算法预览新用户会被分到哪个实例7.2 用户管理页面增强在现有的用户管理页面中Hermes 配置弹窗增加实例选择┌─────────────────────────────────┐ │ Hermes 账号配置 │ │ │ │ 用户zhangsan (张三) │ │ │ │ Hermes 实例 │ │ ┌─────────────────────────────┐│ │ │ hermes-prod-02 ││ ← 下拉选择 │ │ 12/20 用户 ✅活跃 ││ │ └─────────────────────────────┘│ │ 留空则使用全局默认实例 │ │ │ │ Hermes 账号[zhangsan ] │ │ Hermes 密码[•••••••• ] │ │ │ │ [取消] [保存] │ └─────────────────────────────────┘用户列表表格中可选展示实例名称列便于管理员一目了然。八、运维操作流程8.1 扩容新增 Hermes 实例Step 1 部署新实例 docker-compose 增加一个 service → docker compose up -d Step 2 注册到路由表 管理后台 → Hermes 实例管理 → 新增实例 填写名称、地址、端口、最大用户数、优先级 Step 3 自动生效 后续新注册用户会自动分配到新实例 无需重启任何服务8.2 迁移用户实例切换Step 1 管理员操作 用户管理 → 找到目标用户 → Hermes 配置 → 切换实例 → 保存 Step 2 即时生效 用户的下一次请求自动路由到新实例 Token 缓存自动刷新旧 Token 自然过期 Step 3 数据说明 ⚠️ 旧实例上的会话/消息数据不会自动迁移 这是 SQLite 方案的特性也是数据隔离的优势 如用户需要历史数据可保留旧实例一段时间供查阅8.3 下线实例退役Step 1 停止分配 将实例状态改为 maintenance不再接收新用户 Step 2 迁移用户 查看实例下的用户列表 → 逐个或批量迁移到其他实例 可通过管理后台操作也可直接更新数据库 Step 3 确认清空 确认实例下用户数为 0 Step 4 下线 将实例状态改为 inactive 或直接删除实例记录有用户时删除会被拒绝 Step 5 清理 docker compose 移除对应 service 可选备份并删除数据目录8.4 批量迁移脚本当需要大规模迁移时如服务器更换可通过 SQL 批量操作-- 将实例 A 的所有用户迁移到实例 BUPDATEusersSEThermes_instance_id(SELECTidFROMhermes_instancesWHEREnamehermes-prod-02)WHEREhermes_instance_id(SELECTidFROMhermes_instancesWHEREnamehermes-prod-01);九、高可用保障9.1 多层次容错层级 1 — 进程级 Docker restart: unless-stopped → 实例崩溃自动重启 层级 2 — 路由级 实例不可达时代理层返回明确的错误信息 管理员可将故障实例标记为 inactive → 用户切换到其他实例 层级 3 — 全局兜底 所有路由失败时降级到全局默认地址 保证至少有基础服务可用 层级 4 — 数据级 定期备份各实例的 SQLite 文件 单实例数据损坏不影响其他实例9.2 实例健康检查可选增强# 定时任务每 60 秒检测各实例健康状态asyncdefhealth_check():forinstanceinactive_instances:try:respawaithttpx.get(f{instance.base_url}/api/health,timeout5)ifresp.status_code!200:alert(f实例{instance.name}健康检查异常: HTTP{resp.status_code})excepthttpx.ConnectError:alert(f实例{instance.name}无法连接)# 可选自动将状态改为 maintenance9.3 监控指标指标采集方式告警阈值实例可用性/api/health探活连续 3 次失败用户负载比数据库统计 90%请求延迟代理层日志P99 10sSQLite 文件大小文件系统监控 500MB连接错误率代理层统计 5%十、安全设计10.1 网络隔离┌──────────────────────────────────────────────────┐ │ 公网 / 企业内网 │ │ ┌──────────┐ │ │ │ 前端应用 │ │ │ └─────┬────┘ │ │ │ 仅访问企业后端 │ │ ▼ │ │ ┌──────────────────┐ │ │ │ 企业后端 (代理层) │ ← 唯一入口JWT 认证 │ │ └─────┬────────────┘ │ │ │ 仅后端可访问 │ │ ▼ │ │ ┌──────────────────────────────┐ │ │ │ Hermes 实例集群 (内网/容器网) │ ← 不暴露公网 │ │ └──────────────────────────────┘ │ └──────────────────────────────────────────────────┘10.2 权限控制操作所需权限查看实例列表已登录用户查看实例详情已登录用户新增/编辑/删除实例超级管理员切换用户绑定的实例管理员查看实例下的用户管理员10.3 凭证管理每个用户在每个实例上有独立的 Hermes 账号/密码企业后端统一代管凭证前端不直接暴露Token 缓存在服务端按实例用户隔离代理转发时自动附加认证信息十一、成本估算11.1 基础设施成本用户规模服务器配置月成本约实例数1-20 人2C4G 云服务器¥100120-60 人4C8G 云服务器¥200360-120 人8C16G 云服务器¥4006120-200 人2×4C8G 云服务器¥40010200 人按需扩展线性增长N11.2 对比方案方案月成本复杂度数据隔离扩展性本方案多实例 SQLite¥200-400⭐ 极低✅ 天然隔离水平扩展单实例 MySQL¥300-500⭐⭐ 中等❌ 需开发需改 Hermes 源码K8s 共享存储¥1000⭐⭐⭐⭐ 高需设计弹性每用户独立部署¥极高⭐⭐⭐ 高✅运维成本大十二、落地检查清单Phase 1基础设施1 天确认当前 Hermes Studio 单实例运行正常确定新实例的部署服务器和端口规划通过 Docker Compose 部署第 2 个实例并验证可用性Phase 2数据库改造0.5 天创建hermes_instances路由映射表用户表新增hermes_instance_id字段执行初始化迁移将现有全局地址注册为实例验证现有用户不受影响向下兼容Phase 3代理层改造1-2 天实现路由决策函数get_remote_base(user, db)改造所有代理调用点REST/WebSocket/认证/MCPToken 缓存键加实例隔离测试不同用户路由到不同实例测试未绑定用户走全局默认Phase 4管理后台1 天实现实例 CRUD API实现自动分配算法 API前端实例管理页面用户配置弹窗增加实例选择Phase 5验证上线0.5 天管理员手动分配/切换实例 → 验证路由正确新用户注册 → 验证自动分配实例设为 maintenance → 验证不分配新用户实例宕机 → 验证降级到全局默认灰度发布先迁移少量用户到新实例观察十三、FAQQ1为什么不直接改 Hermes 源码换成 MySQL/PostgreSQL修改 Hermes 源码意味着每次官方更新都需要合并冲突维护成本极高。本方案在代理层做路由对 Hermes 零侵入可以随时升级 Hermes 版本。Q2用户切换实例后旧数据怎么办旧实例上的会话/消息数据保留在旧实例的 SQLite 中。企业可根据业务需求选择① 保留旧实例一段时间供查阅 ② 通过导出工具迁移关键数据 ③ 直接丢弃适合会话型场景。Q3能否做到实例间的负载均衡可以。自动分配算法在用户注册时选择最优实例实现了注册时均衡。如果需要运行时再均衡管理员可手动迁移用户。不建议做请求级负载均衡因为 SQLite 不支持跨实例数据共享。Q4单个实例最多支持多少用户取决于使用模式。一般建议 15-25 用户/实例。如果用户主要做轻量对话可以放宽到 30-40如果频繁使用复杂 Agent 工作流建议 10-15。Q5如何做到零停机升级① 部署新版本 Hermes 实例 ② 在路由表中注册新实例 ③ 逐步迁移用户到新实例 ④ 确认所有用户迁移完毕 ⑤ 下线旧实例。全程无需停机。Q6前端需要改动吗前端无需感知多实例。所有请求走企业后端代理代理层透明路由。可选优化前端从后端获取instance_url后直连实例需 CORS 配置减少代理层压力。十四、架构演进路线当前阶段本方案 未来可选演进 ───────────────── ───────────── 多实例 SQLite 代理路由 ──► 实例健康检查 自动故障转移 │ ├──► 实例用量看板 Grafana 监控 │ ├──► 实例自动扩缩容Docker API │ └──► 数据导出/迁移工具总结本方案以最小代价将 Hermes Studio 从单实例扩展为多实例分布式架构。企业仅需一张路由映射表 用户表一个字段 代理层路由改造即可实现低成本、高可用、数据隔离的企业级 AI Agent 平台。方案对 Hermes Studio 零侵入可随时跟随官方版本升级。