部署进阶:多 Profile 网关与托管
本教程共 25 篇 · 第 22 篇 · 更新于 2026-07-26 · 约 15 分钟阅读
22. 部署进阶:多 Profile 网关与托管
本节目标:掌握 Hermes Agent 在生产环境的部署模式—一台机器跑多个 Agent、把完整 Agent 打包成 Git 仓库分享给团队、管理员锁定关键配置、选择合适的终端后端实现空闲近零成本。
单个 Hermes Agent 跑起来不难,但当你需要同时运行多个 Agent、把它们分发给团队、或者在企业环境里统一管控配置时,就需要这一章的进阶部署能力了。
为什么需要多 Profile
一个 Profile 就是一个独立的 Agent 实例,有自己的记忆、技能、会话历史和 API Key。常见的多 Profile 场景:
- 一个 Telegram Bot 当个人助手,另一个当编程助手
- 每个家庭成员或每个 Slack 工作区一个 Agent
- 沙盒实例 + 生产实例分开
- 研究 Agent + 写作 Agent + 定时任务 Bot,各自隔离
每个 Profile 都有独立的目录结构:
~/.hermes/profiles/<name>/
├── .env # API Key、Bot Token(chmod 600)
├── config.yaml # 模型、提供商、工具集、网关设置
├── SOUL.md # 人格 / 系统提示
├── memories/ # 记忆
├── sessions/ # 会话历史
└── logs/ # 日志
各文件的详细含义参见 §04,这里不再赘述。默认 Profile 直接用 ~/.hermes/ 作为根目录。
一台机器跑多个网关
创建和配置 Profile
# 创建 Profile
hermes profile create coder
hermes profile create personal-bot
hermes profile create research
# 各自配置
coder setup
personal-bot setup
research setup
安装为系统服务
每个 Profile 可以注册为独立的后台服务,崩溃自动重启、登录自动启动:
# 安装服务
coder gateway install
personal-bot gateway install
research gateway install
# 启动
coder gateway start
personal-bot gateway start
research gateway start
服务文件的位置:
| 平台 | 路径 |
|---|---|
| macOS | ~/Library/LaunchAgents/ai.hermes.gateway-<profile>.plist |
| Linux | ~/.config/systemd/user/hermes-gateway-<profile>.service |
默认 Profile 用历史命名(不带 profile 后缀):ai.hermes.gateway.plist / hermes-gateway.service。
批量管理
CLI 本身只支持单 Profile 操作。要一次性管理所有 Profile,可以写个包装脚本:
#!/bin/sh
set -eu
profiles="default coder personal-bot research"
for profile in $profiles; do
echo "==> $1 $profile"
if [ "$profile" = "default" ]; then
hermes gateway "$1"
else
hermes -p "$profile" gateway "$1"
fi
done
然后:
hermes-gateways start # 启动所有
hermes-gateways stop # 停止所有
hermes-gateways status # 查看全部状态
Note默认 Profile 用
hermes gateway <action>(不带-p),不是hermes -p default gateway <action>。
查看日志
每个 Profile 写自己的日志:
# 默认 Profile
tail -f ~/.hermes/logs/gateway.log
# 命名 Profile
tail -f ~/.hermes/profiles/coder/logs/gateway.log
# 同时看所有 Profile 的日志
tail -f ~/.hermes/logs/gateway.log ~/.hermes/profiles/*/logs/gateway.log
CLI 也有结构化日志查看器:
hermes logs -f # 跟踪默认 Profile
hermes -p coder logs -f # 跟踪指定 Profile
Token 冲突保护
每个 Profile 必须用唯一的 Bot Token。如果两个 Profile 共用同一个 Telegram 或 Discord Token,第二个网关会拒绝启动并报出冲突的 Profile 名。
# 审计所有 Profile 的 Token
grep -H 'TELEGRAM_BOT_TOKEN\|DISCORD_BOT_TOKEN' \
~/.hermes/.env ~/.hermes/profiles/*/.env
多路复用:一个进程服务所有 Profile
上面是”一个进程一个 Profile”的模式,适合大多数场景。但在容器部署或 Profile 数量很多时,N 个进程、N 个端口、N 个 PID 文件会成为负担。
Hermes 提供了另一种选择:多路复用模式—默认 Profile 的网关成为唯一的入站进程,同时服务所有 Profile。
开启方式
hermes config set gateway.multiplex_profiles true
hermes gateway restart
什么变了
开启多路复用后,有几件事会不同:
1. 子 Profile 不能再启动自己的网关。 默认网关已经替它们服务了,再启动会报错。
2. HTTP 入站平台通过 URL 前缀路由。 子 Profile 的 Webhook 流量走 /p/<profile>/ 前缀:
# 默认 Profile
POST http://host:8644/webhooks/<route>
# coder Profile(同一个监听端口)
POST http://host:8644/p/coder/webhooks/<route>
3. 会话 Key 按 Profile 命名空间隔离。 每个 Profile 的会话存在 agent:<profile>:… 命名空间下,不会冲突。默认 Profile 保持原有的 agent:main:… 命名空间,不需要迁移。
4. 每个 Profile 仍然用自己的 Bot Token。 轮询/连接型平台(Telegram、Discord、Slack 等)每个 Profile 必须提供自己的 Token,不能两个 Profile 轮询同一个 Token。
什么没变
- 凭据隔离不变,甚至更严格:Profile 的 Key 只从自己的作用域解析,不会混入共享环境
- Kanban、技能、记忆、SOUL、模型路由 都按 Profile 独立工作
- 子进程(MCP 服务器、Kanban worker)只看到自己 Profile 的密钥
Profile 路由
当多个社区共用一个 Bot Token 时(比如一个 Discord Bot 服务多个服务器),可以用 profile_routes 把特定的服务器/频道路由到不同的 Profile:
gateway:
multiplex_profiles: true
profile_routes:
- name: acme-server
platform: discord
guild_id: "1234567890"
profile: acme
- name: acme-support
platform: discord
guild_id: "1234567890"
chat_id: "9876543210"
profile: acme-support
- name: tg-group
platform: telegram
chat_id: "-1001234567890"
profile: tg-profile
路由匹配按最具体优先(thread_id > chat_id > guild_id),所有声明的字段必须同时满足(AND 逻辑)。不匹配任何路由的消息留在默认 Profile。
Tip
profile_routes需要先开启gateway.multiplex_profiles: true,否则路由配置被忽略。
Profile 发行版:把整个 Agent 打包分享
什么是发行版
一个 Profile 发行版(Distribution)把完整的 Hermes Agent—人格、技能、定时任务、MCP 连接、配置—打包成一个 Git 仓库。任何人拿到仓库地址就能一条命令安装整个 Agent,更新也是一条命令,而他们自己的记忆、会话和 API Key 不受影响。
如果说 Profile 是本地 Agent,发行版就是可分享的 Agent。
仓库结构
my-research-agent/
├── distribution.yaml # 清单:名称、版本、环境变量需求
├── SOUL.md # Agent 的人格 / 系统提示
├── config.yaml # 模型、温度、推理、工具默认值
├── skills/ # 捆绑的技能
├── cron/ # 定时任务
├── mcp.json # MCP 服务器连接
└── .gitignore # 排除密钥和用户数据
清单文件 distribution.yaml
name: research-bot
version: 1.0.0
description: "自主研究助手,带 arXiv 和 Web 工具"
hermes_requires: ">=0.12.0"
author: "Your Name"
license: "MIT"
env_requires:
- name: OPENAI_API_KEY
description: "OpenAI API Key"
required: true
- name: SERPAPI_KEY
description: "SerpAPI Key for web search"
required: false
default: ""
安装和更新
安装方一行命令:
hermes profile install github.com/you/research-bot --alias
安装过程:
- 克隆仓库到临时目录
- 读取
distribution.yaml,显示清单和需要的环境变量 - 检查每个必需的环境变量是否已设置
- 确认后,把发行版文件复制到
~/.hermes/profiles/research-bot/ - 生成
.env.EXAMPLE,复制为.env填入自己的 Key --alias创建命令别名,可以直接research-bot chat
更新也是一行:
hermes profile update research-bot
更新时:
- 发行版拥有的文件(SOUL、技能、cron、mcp.json)被替换
config.yaml默认保留(你可能调过模型或温度),加--force-config可以重置- 用户数据永远不动:记忆、会话、auth.json、.env、日志
Warning安装/更新时的文件排除只保护安装方,不保护作者。 作者必须在
git add之前用.gitignore把.env、auth.json、memories/、sessions/等排除掉。
永远不进发行版的内容
安装器硬排除以下路径,即使作者不小心提交了也不会被复制:
auth.json— OAuth Token 和平台凭据.env— API Key 和密钥memories/— 对话记忆sessions/— 会话历史state.db*— 会话元数据logs/— 日志workspace/— 工作文件*_cache/— 缓存local/— 用户自定义命名空间
发行版拥有的 vs 用户拥有的
| 类别 | 路径 | 更新时 |
|---|---|---|
| 发行版拥有 | SOUL.md、skills/、cron/、mcp.json | 从新版本替换 |
| 配置覆盖 | config.yaml | 默认保留,--force-config 可重置 |
| 用户拥有 | memories/、sessions/、auth.json、.env、logs/ | 永不动 |
适用场景
个人跨机同步:你在笔记本上建了个研究助手,想在台式机上也有同样的 Agent。推到 Git 仓库,台式机一条命令安装,两台机器各自有各自的记忆,互不干扰。
团队共享:工程团队想要一个统一的 PR 审查 Bot,带特定 SOUL、技能和定时任务。负责人推到内部 Git 仓库,每个工程师一行命令安装,各自用自己的 API Key。负责人更新后,所有人一行命令拉新版。
社区发布:你做了一个有趣的 Agent(比如学术论文摘要、Minecraft 服务器管理),推到公开 GitHub 仓库,发个安装命令让任何人试用。
产品分发:你基于 Hermes 做了一个合规监控方案或客服系统,作为产品分发。客户一行命令安装,安装预览告诉他们需要哪些 Key,更新随你推新版自动到达。
Managed Scope:管理员锁定配置
在企业或团队部署中,IT 可能需要给每台机器统一锁定某些配置—比如强制用某个模型提供商、强制开启密钥脱敏、统一 API 端点地址。这就是 Managed Scope。
工作原理
Managed Scope 从系统级目录读取配置(默认 /etc/hermes),这些配置对普通用户不可覆盖:
/etc/hermes/
├── config.yaml # 管理配置层(覆盖 ~/.hermes/config.yaml)
└── .env # 管理环境层(覆盖 ~/.hermes/.env + shell 环境变量)
目录和文件归 root 所有(目录 0755,文件 0644):所有人可读,只有管理员可写。文件系统权限就是执行机制—普通用户能读但不能改。
优先级
对于 Managed Scope 指定的 Key,优先级从高到低:
| 层级 | config.yaml | .env |
|---|---|---|
| 1 | /etc/hermes/config.yaml(管理) | /etc/hermes/.env(管理) |
| 2 | ~/.hermes/config.yaml(用户) | ~/.hermes/.env(用户) |
| 3 | 内置默认值 | 已有的 shell 环境变量 |
合并是叶子级别的:锁定 model.default 不会冻结 model.* 的其他 Key。
Note对于它锁定的 Key,Managed Scope 故意覆盖 shell 环境变量。这是唯一一个”环境变量不覆盖 config.yaml”规则被反转的地方,且只对 Managed Scope 指定的 Key 生效。
设置 Managed Scope
sudo mkdir -p /etc/hermes
# 锁定一些配置
sudo tee /etc/hermes/config.yaml >/dev/null <<'YAML'
model:
provider: nous
security:
redact_secrets: true
YAML
sudo chmod 0755 /etc/hermes
sudo chmod 0644 /etc/hermes/config.yaml /etc/hermes/.env
用户尝试修改被锁定的值时,Hermes 拒绝并告知来源:
$ hermes config set model.default my/model
Cannot set 'model.default': it is managed by your administrator
(/etc/hermes/config.yaml) and cannot be changed.
安全边界
Warning当前的 Managed Scope 有明确的局限:
- 执行机制仅靠文件系统权限,有 root 权限的用户可以绕过
- 管理的
.env是全局可读的(0644),不要放高敏感密钥- Agent 自己的工具不会被硬性阻止修改被管理的环境变量值
它是面向普通用户的管理便利边界,不是不可逃逸的沙箱。
六种部署模式
Hermes Agent 支持从笔记本到云端的全场景部署。核心区别在于”Agent 进程在哪”和”终端命令在哪执行”。
| 模式 | Agent 在哪 | 命令在哪 | 适合场景 |
|---|---|---|---|
| 本地 CLI | 本机 | 本机 | 开发、个人日常 |
| 网关服务 | 本机/服务器 | 本机/服务器 | 24/7 Bot |
| Docker | 容器 | 容器内 | 隔离、CI/CD |
| SSH 远程 | 本机 | 远程服务器 | GPU 计算、大数据 |
| Modal | 本机 | Modal 云 VM | 无服务器、临时计算 |
| Daytona | 云端 | 云容器 | 完全云端 |
本地 CLI
最简单的方式,零配置:
hermes chat # 直接对话
hermes --tui # TUI 界面
hermes desktop # 桌面应用
网关服务
让 Agent 24/7 在线,随时响应消息平台的消息:
hermes gateway install && hermes gateway start # 注册并启动
hermes gateway status # 查看状态
hermes gateway stop # 停止
hermes gateway restart # 重启
hermes gateway uninstall # 卸载服务
Docker 容器
官方镜像支持多 Profile 网关,由 s6-overlay 管理进程:
docker pull nousresearch/hermes-agent:latest
docker run -d \
--name hermes \
-v ~/.hermes:/root/.hermes \
-e OPENROUTER_API_KEY=sk-or-... \
-e TELEGRAM_BOT_TOKEN=... \
nousresearch/hermes-agent:latest
Docker 内多 Profile 网关由 s6-overlay 自动监督。hermes profile create 会自动注册 s6 服务槽位,容器重启后自动恢复之前运行中的所有网关。
SSH 远程
Agent 在本地运行,所有终端命令在远程服务器上执行:
hermes config set terminal.backend ssh
hermes config set terminal.ssh_host user@your-gpu-server.com
hermes chat
典型场景:在本地发消息,让 Agent 在远程 GPU 服务器上训练模型。
Modal Serverless(空闲近零成本)
Agent 在 Modal 云沙箱(VM)中执行命令,空闲时几乎不产生费用:
hermes config set terminal.backend modal
这是 scale-to-zero 的核心方案:按需计费,适合偶发性的高强度计算任务。不用的时候不花钱,用的时候按量付费。
Daytona 托管工作区
Hermes 进程和终端沙箱都在云端,完全不依赖本地机器:
terminal:
backend: daytona
让主机不睡觉
网关进程能跑一整天,但操作系统空闲时还是会尝试休眠。
macOS:caffeinate
caffeinate 是 macOS 内置的,不需要安装:
# 阻止显示器、空闲和系统休眠
caffeinate -dis
# 8 小时后自动退出
caffeinate -dis -t 28800
# 持久后台运行
nohup caffeinate -dis >/dev/null 2>&1 &
disown
| 参数 | 效果 |
|---|---|
-d | 阻止显示器休眠 |
-i | 阻止空闲系统休眠(默认) |
-s | 阻止系统休眠(仅接通电源的 Mac) |
-t N | N 秒后自动退出 |
-w P | PID P 退出时跟着退出 |
Warning
caffeinate无法覆盖合盖休眠。合盖使用需要改节能/电池设置或用第三方工具。
Linux:systemd-inhibit 或 loginctl
# 挂起期间保持运行
systemd-inhibit --what=idle:sleep --who=hermes --why="gateways running" \
sleep infinity &
# 允许用户服务在登出后继续运行
sudo loginctl enable-linger "$USER"
开启 lingering 后,systemd 用户单元(包括 hermes-gateway-<profile>.service)在 SSH 断开和重启后继续运行。
更新代码
hermes update # 拉取最新代码,同步新捆绑技能到所有 Profile
hermes-gateways restart # 重启所有网关
用户修改过的技能永远不会被覆盖。
健康检查
hermes doctor # 默认 Profile
hermes -p coder doctor # 指定 Profile
hermes doctor 会报告当前 Profile 的配置状态、模型连通性、Managed Scope 锁定的 Key 数量等,是排障的第一步。