你搭了一个 Hermes Agent。它跑起来了。然后客户问:"我能也装一个吗?"
独立创业者的优势在于一次构建,多次售卖。Hermes 内置的基于 profile 的隔离机制是多客户部署的正确基础,但 profile 本身并不是完整的安全边界。本文会讲清楚 profile 到底隔离了什么、哪里还需要补沙箱、以及看板如何让多团队协作保持有序。
什么是 Hermes Profile?
Profile 是一个完全独立的 agent 实例,拥有自己的 config.yaml、.env、SOUL.md、记忆存储、会话历史、技能、定时任务和网关状态。
hermes profile create acme # 现在你可以用:acme chat、acme gateway start、acme cron list
Profile 能隔离什么: Hermes 的状态。Profile A 无法读取 Profile B 的记忆、会话或定时任务。
Profile 不能隔离什么: 文件系统。在默认的 local 终端后端上,每个 profile 都以你的 OS 用户身份运行,拥有与你其他进程相同的文件访问权限。
Hermes Agent 能在一个服务器上支持多个客户吗?
能——但需要正确的安全护栏。
隔离的真实情况
| 层级 | Profile 能隔离吗? | 你还需要补充什么 |
|---|---|---|
| 记忆(SQLite DB) | 完全隔离 | 无需补充 |
| 会话 | 完全隔离 | 无需补充 |
| API 密钥(`.env`) | 完全隔离 | 无需补充 |
| Telegram Bot | Token 锁强制生效 | 每个运行的 gateway 配一个 token |
| 文件系统 | local 后端无法隔离 | terminal.cwd、Docker、SSH 或 Modal 后端 |
| 代码执行 | local 后端无法隔离 | Docker 沙箱、Modal 或 Singularity |
| 仪表板可见性 | 共享仪表板会在同一主机上暴露多个 profile 和看板工作 | 保持共享仪表板私有;面向客户的仪表板需要运行在单独隔离的 Hermes runtime 上,而不仅仅是 profile 级别的进程隔离 |
如果没有文件系统限制或沙箱,面向客户的会话可能访问主机用户账户下的所有文件。 面向客户的工作必须始终把 profile 和沙箱终端后端配对使用。
架构概览
external_users { # 外部客户
n1: circle label="客户 A 用户"
n2: circle label="客户 B 用户"
}
shared_host { # 共享主机环境
n3: rectangle label="反向代理"
n4: rectangle label="共享网关"
n5: rectangle label="管理仪表板"
n6: rectangle label="Profile: acme"
n7: rectangle label="Profile: beta"
n8: rectangle label="kanban.db"
n9: rectangle label="主机文件系统"
}
client_a_tools { # 客户 A 内部工具
n10: rectangle label="工程工具"
n11: rectangle label="支持工具"
n12: rectangle label="研究工具"
}
external_users.n1.handle(right) -> shared_host.n3.handle(left) [label="webhook"]
external_users.n2.handle(right) -> shared_host.n3.handle(left) [label="webhook"]
shared_host.n3.handle(right) -> shared_host.n4.handle(left)
shared_host.n4.handle(right) -> shared_host.n6.handle(left) [label="Token A"]
shared_host.n4.handle(bottom) -> shared_host.n7.handle(top) [label="Token B"]
shared_host.n4.handle(top) -> shared_host.n5.handle(bottom) [label="ops only"]
shared_host.n6.handle(right) -> client_a_tools.n10.handle(left) [label="/engineering"]
shared_host.n6.handle(right) -> client_a_tools.n11.handle(left) [label="/support"]
shared_host.n6.handle(bottom) -> client_a_tools.n12.handle(top) [label="/research"]
shared_host.n6.handle(bottom) -> shared_host.n8.handle(top) [label="shared board"]
shared_host.n7.handle(bottom) -> shared_host.n8.handle(top) [label="shared board"]
shared_host.n6.handle(bottom) -> shared_host.n9.handle(top) [label="local backend risk"]
shared_host.n7.handle(bottom) -> shared_host.n9.handle(top) [label="local backend risk"]
关键:仪表板问题
单个指向共享 Hermes runtime 的仪表板实例会在同一主机上展示多个 profile 的工作内容。
这不是面向客户的多租户门户,而是内部运营控制台。 Kanban 文档明确指出:Kanban 跨所有 Hermes profile 共享,存储在 ~/.hermes/kanban.db,任务设计上就是与 profile 无关的。
解决办法很简单:
- 把共享仪表板当作你的私有运营控制台。 永远不要给客户访问权限。
- 面向客户的仪表板需要为每个客户单独运行一个隔离的 Hermes runtime,而不仅仅是 profile 级别的进程隔离。实践中这意味着独立的安装、容器、虚拟机,或者至少是一个独立的 OS 用户/运行时边界。
- 给每个客户配独立子域名和认证(nginx 反向代理 + 基础认证或 OAuth)。永远不要让客户访问共享实例。
- 或者干脆不用仪表板 —— 很多独立开发者纯靠 Telegram 渠道运营,从不给客户暴露 Web UI。
规则很简单:一个客户可见的仪表板 = 一个隔离的 Hermes runtime。 如果客户需要更强的隔离,把他们迁移到独立主机或容器,配独立 Hermes 安装。
Hermes Profile 对多租户来说够安全吗?
Profile 是一个基础,不是完整方案。安全性取决于你在它周围加了什么。
最低安全检查清单
# 1. 新建 profile(不要 --clone 个人配置) hermes profile create client-x # 2. 限制工作空间 client-x config set terminal.cwd /var/hermes-clients/client-x # 3. 使用沙箱后端 client-x config set terminal.backend docker # 4. 设置独立的 bot token nano ~/.hermes/profiles/client-x/.env # TELEGRAM_BOT_TOKEN=789012:ABC-DEF-... # 5. 禁用客户不需要的工具集 client-x config set agent.disabled_toolsets '["flowzap","creative","media"]' # 6. 启动它的网关 client-x gateway start
为什么 --clone 有风险: 它会复制你的个人配置、API 密钥和记忆到新 profile。给客户用的一定要新建 profile。
Telegram Bot Token
每个运行的 gateway 都应该使用独立的 bot token。如果两个 profile 共享同一个 token,第二个 gateway 会被明确报错阻断。
ERROR: [Telegram] Bot token already in use by profile acme (PID X).
对于多部门客户,要么用一个 profile + 内部分流(更简单),要么创建多个 Telegram bot配独立 token。
架构选项:4 种部署模式
选项 1:单一客户,单一部门
external_actor { # 外部参与者
n1: circle label="客户用户"
}
hermes_runtime { # Hermes 运行时
n2: rectangle label="Telegram Bot"
n3: rectangle label="网关"
n4: rectangle label="Profile: client-x"
}
execution_sandbox { # 执行边界
n5: rectangle label="隔离工作空间"
}
external_actor.n1.handle(right) -> hermes_runtime.n2.handle(left) [label="message"]
hermes_runtime.n2.handle(right) -> hermes_runtime.n3.handle(left)
hermes_runtime.n3.handle(right) -> hermes_runtime.n4.handle(left) [label="routes"]
hermes_runtime.n4.handle(right) -> execution_sandbox.n5.handle(left) [label="executes code"]
适用于: 首个客户、概念验证、简单问答机器人。
选项 2:单一客户,多部门(内部分流)
一个 profile,一个 bot。SOUL.md 按前缀分流(/engineering、/support)。
team_users { # 客户入口
n1: circle label="团队用户"
}
entry_point { # Bot & 分流
n2: rectangle label="共享 Bot"
n3: rectangle label="网关"
n4: diamond label="前缀分流器"
}
hermes_profile { # 统一 Profile
n5: rectangle label="Profile: acme"
}
department_modes { # 内部逻辑
n6: rectangle label="工程模式"
n7: rectangle label="支持模式"
}
team_users.n1.handle(right) -> entry_point.n2.handle(left) [label="/eng 或 /support"]
entry_point.n2.handle(right) -> entry_point.n3.handle(left)
entry_point.n3.handle(right) -> entry_point.n4.handle(left)
entry_point.n4.handle(right) -> hermes_profile.n5.handle(left) [label="loads profile"]
hermes_profile.n5.handle(right) -> department_modes.n6.handle(left) [label="若 /eng"]
hermes_profile.n5.handle(right) -> department_modes.n7.handle(left) [label="若 /support"]
适用于: 一个客户,2-3 个团队共享一个聊天频道。
选项 3:多客户,独立 Bot(核心多租户)
每个客户拥有独立的 bot token、网关和隔离 profile。
external_tenants { # 外部租户
n1: circle label="客户 A 用户"
n2: circle label="客户 B 用户"
}
client_gateways { # 按 Token 的入口
n3: rectangle label="网关 A"
n4: rectangle label="网关 B"
}
hermes_profiles { # 隔离 Profile
n5: rectangle label="Profile: acme"
n6: rectangle label="Profile: beta"
}
execution_sandboxes { # 执行边界
n7: rectangle label="沙箱 A"
n8: rectangle label="沙箱 B"
}
external_tenants.n1.handle(right) -> client_gateways.n3.handle(left) [label="Token A"]
external_tenants.n2.handle(right) -> client_gateways.n4.handle(left) [label="Token B"]
client_gateways.n3.handle(right) -> hermes_profiles.n5.handle(left)
client_gateways.n4.handle(right) -> hermes_profiles.n6.handle(left)
hermes_profiles.n5.handle(right) -> execution_sandboxes.n7.handle(left) [label="Docker / Modal"]
hermes_profiles.n6.handle(right) -> execution_sandboxes.n8.handle(left) [label="Docker / Modal"]
适用于: 2+ 付费客户。每个人都从同一台服务器"拥有专属 bot"。
提示: 创建新 profile(hermes profile create client-x),不要 --clone。不继承 API 密钥,不产生跨客户记忆泄漏。
选项 4:完整多租户 + 多部门
client_users { # 外部参与者
n1: circle label="Acme 用户"
n2: circle label="Beta 用户"
}
entry_gateways { # 客户网关
n3: rectangle label="Acme 网关"
n4: rectangle label="Beta 网关"
}
hermes_profiles { # 分流 Profile
n5: diamond label="Acme 分流器"
n6: rectangle label="acme-eng"
n7: rectangle label="acme-support"
n8: rectangle label="beta"
}
execution_sandboxes { # 安全运行时
n9: rectangle label="Acme 沙箱"
n10: rectangle label="Beta 沙箱"
}
client_users.n1.handle(right) -> entry_gateways.n3.handle(left) [label="/eng 或 /support"]
client_users.n2.handle(right) -> entry_gateways.n4.handle(left) [label="general"]
entry_gateways.n3.handle(right) -> hermes_profiles.n5.handle(left)
hermes_profiles.n5.handle(right) -> hermes_profiles.n6.handle(left) [label="若 /eng"]
hermes_profiles.n5.handle(bottom) -> hermes_profiles.n7.handle(top) [label="若 /support"]
entry_gateways.n4.handle(right) -> hermes_profiles.n8.handle(left)
hermes_profiles.n6.handle(right) -> execution_sandboxes.n9.handle(left) [label="executes"]
hermes_profiles.n7.handle(right) -> execution_sandboxes.n9.handle(left) [label="executes"]
hermes_profiles.n8.handle(right) -> execution_sandboxes.n10.handle(left) [label="executes"]
从哪里开始
| 你的情况 | 先用这个 | 再升级到 |
|---|---|---|
| 首个客户,测试阶段 | 选项 1 | → 选项 2(多部门) |
| 一个客户,2+ 团队 | 选项 2 | → 选项 4(新客户) |
| 3+ 付费客户 | 选项 3 | → 选项 4(随客户增长) |
看板如何帮助多客户团队?
Hermes Kanban 是一个持久化任务板 —— 每个任务都是 SQLite 里的一行,每次交接都是任何 profile 都能查看和编辑的一行。从 v0.13.0 起,dispatcher 默认内嵌在网关中运行。
为每个客户使用独立看板,减少协作错误并保持工作分段。在 Hermes Kanban 中,看板是 Kanban 内部的硬隔离边界,而租户只是软过滤。
task_planner { # 规划器
n1: rectangle label="编排器"
}
shared_board { # 协调层
n2: rectangle label="共享 kanban.db"
}
specialized_workers { # 执行者
n3: rectangle label="研究员 A"
n4: rectangle label="研究员 B"
n5: rectangle label="写作者"
}
final_result { # 交付物
n6: circle label="交付成果"
}
task_planner.n1.handle(right) -> shared_board.n2.handle(left) [label="创建任务"]
shared_board.n2.handle(right) -> specialized_workers.n3.handle(left) [label="认领任务 1"]
shared_board.n2.handle(right) -> specialized_workers.n4.handle(left) [label="认领任务 2"]
specialized_workers.n3.handle(right) -> shared_board.n2.handle(right) [label="完成"]
specialized_workers.n4.handle(right) -> shared_board.n2.handle(right) [label="完成"]
shared_board.n2.handle(bottom) -> specialized_workers.n5.handle(top) [label="解锁写作者"]
specialized_workers.n5.handle(right) -> final_result.n6.handle(left) [label="发布"]
/kanban 斜杠命令在所有网关平台上都可用 —— Telegram、Discord、Slack、WhatsApp、Signal、Matrix、Mattermost、邮件和短信。
Hermes Agent v0.13.0 有什么变化?
截至 2026 年 5 月 7 日,最新的公开 Hermes Agent 版本是 v0.13.0。以下是最相关的更新:
- Kanban dispatcher 默认内嵌在网关中 —— 常规设置不再需要单独的守护进程。
- 多个 Kanban 看板 —— 按客户或项目实现干净的项目隔离。
- Profile 自动别名 —— 每个 profile 都变成自己的 CLI 命令。
- Token 锁定安全 —— 重复 bot token 会触发明确报错。
- 打包技能在
hermes update时同步到所有 profile。
分步指南:接入新客户
# 1. 新建 profile —— 不要 --clone hermes profile create client-x # 2. 限制工作空间并启用沙箱 client-x config set terminal.cwd /var/hermes-clients/client-x client-x config set terminal.backend docker # 3. 配置 bot token nano ~/.hermes/profiles/client-x/.env # TELEGRAM_BOT_TOKEN=789012:ABC-DEF-... # 4. 禁用客户不需要的打包工具集 client-x config set agent.disabled_toolsets '["flowzap","creative","media"]' # 注意:打包技能会在 hermes update 时自动同步。 # 自定义技能放在 ~/.hermes/profiles/client-x/skills/ 下,仅当你为该 profile 构建时才需要。 # 5. 启动网关 client-x gateway start
对于多部门客户,使用一个 profile + SOUL.md 分流,而不是硬抗 token 锁定。
~/.hermes/profiles/beta/SOUL.md → "Beta Corp agent。前缀 /engineering 用于工具访问。 前缀 /support 用于只读工单处理。"
什么能跑 vs. 什么会崩
| 场景 | 结论 |
|---|---|
| 3 个客户,每个 1 个部门,Docker 后端 | 能跑。Profile + 沙箱后端覆盖了 Hermes 状态 + 执行隔离。 |
| 1 个客户,5 个部门,共享 bot token | Token 锁定会阻断。使用内部分流或独立 bot。 |
| 两个 profile,同一个 token | 第二个网关拒绝启动。 |
| 每个客户使用不同后端(Docker vs local) | 能跑。按 profile 设置 terminal.backend。 |
| 通过 local 后端实现跨客户文件系统访问 | Profile 不隔离文件系统。使用 Docker。 |
| 看板任务出现在错误客户的看板里 | 为每个客户使用独立看板可降低此风险,因为看板是 Kanban 内部的硬隔离边界。 |
| 客户访问共享仪表板 | 共享仪表板仅供管理员。Kanban 在同一主机的 profile 间共享,因此面向客户的仪表板应运行在单独隔离的 Hermes runtime 上,而不是仅靠隔离的 HERMES_HOME。 |
用 --clone 从个人配置复制到客户 profile |
存在 API 密钥泄漏风险。创建新 profile。 |
核心结论
Hermes Agent 可以在一台服务器上支持多个客户,但安全的多租户部署取决于你如何配置执行环境。Profile 能很好地隔离 Hermes 状态;Docker、SSH、Modal、Daytona、Vercel Sandbox 或 Singularity 则提供面向客户工作所需的更强执行边界。如果你需要面向客户的仪表板,为每家公司使用独立隔离的 Hermes runtime;如果你留在共享主机上,保持仪表板私有,用消息渠道给客户访问。
参考资料
官方文档
社区与评论
