跳到主要内容

同时运行多个网关

在单台机器上以托管服务的形式运行多个配置文件——每个配置文件拥有独立的机器人令牌(bot tokens)、会话和内存。本页涵盖操作层面的注意事项:如何同时启动所有网关、跨配置文件查看日志、防止主机进入睡眠状态,以及从常见的 launchd/systemd 问题中恢复。

如果你只运行一个 Hermes 代理,则无需阅读本页——请参阅配置文件了解基础知识。

何时使用此功能

当你有两个或更多需要同时在线的 Hermes 代理时,适合使用此设置。常见场景包括:

  • 一个 Telegram 机器人上的个人助理和另一个机器人上的编码代理
  • 每位家庭成员各一个代理,或每个 Slack 工作区各一个代理
  • 同一配置的沙盒环境与生产环境实例
  • 研究代理 + 写作代理 + 由 cron 驱动的机器人——每个都拥有隔离的内存和技能

每个配置文件已经拥有其各自的平台专属 LaunchAgent(ai.hermes.gateway-<name>.plist)或 systemd 用户服务(hermes-gateway-<name>.service)。本指南补充了集体管理这些服务的模式。

快速开始

# Create profiles (once)
hermes profile create coder
hermes profile create personal-bot
hermes profile create research

# Configure each
coder setup
personal-bot setup
research setup

# Install each gateway as a managed service
coder gateway install
personal-bot gateway install
research gateway install

# Start them all
coder gateway start
personal-bot gateway start
research gateway start

就是这样——三个独立的代理,各自运行在独立的进程中,在崩溃时和用户登录时自动重启。

一次性启动、停止或重启所有网关

CLI 提供了针对单个配置文件的生命周期命令。要对所有配置文件执行操作,可以将它们包裹在一个 shell 循环中。将以下代码片段放入 ~/.local/bin/hermes-gateways 并执行 chmod +x

#!/bin/sh
set -eu

# Add or remove profile names here as you create / delete profiles.
profiles="default coder personal-bot research"

usage() {
echo "Usage: hermes-gateways {start|stop|restart|status|list}"
}

run_for_profile() {
profile="$1"
action="$2"
if [ "$profile" = "default" ]; then
hermes gateway "$action"
else
hermes -p "$profile" gateway "$action"
fi
}

action="${1:-}"
case "$action" in
start|stop|restart|status)
for profile in $profiles; do
echo "==> $action $profile"
run_for_profile "$profile" "$action"
done
;;
list)
hermes gateway list
;;
*)
usage
exit 2
;;
esac

然后:

hermes-gateways start      # start every configured profile
hermes-gateways stop # stop every configured profile
hermes-gateways restart # restart all
hermes-gateways status # status across all
hermes-gateways list # delegates to `hermes gateway list`
提示

default 配置文件通过 hermes gateway <action>(不带 -p)进行定位,而不是 hermes -p default gateway <action>。上述包装脚本同时处理这两种形式。

管理单个配置文件

每个配置文件安装的快捷命令:

coder gateway run        # foreground (Ctrl-C to stop)
coder gateway start # start the managed service
coder gateway stop # stop the managed service
coder gateway restart # restart
coder gateway status # status
coder gateway install # create the LaunchAgent / systemd unit
coder gateway uninstall # remove the service file

这些命令等同于 hermes -p coder gateway <action>——当配置文件别名不在 PATH 中,或者你需要从脚本中动态定位配置文件时非常有用。

服务文件

每个配置文件都会安装具有唯一名称的服务,因此安装不会发生冲突:

平台路径
macOS~/Library/LaunchAgents/ai.hermes.gateway-<profile>.plist
Linux~/.config/systemd/user/hermes-gateway-<profile>.service

默认配置文件保留历史名称:ai.hermes.gateway.plist / hermes-gateway.service

查看日志

每个配置文件写入各自的日志文件:

# Default profile
tail -f ~/.hermes/logs/gateway.log
tail -f ~/.hermes/logs/gateway.error.log

# Named profile
tail -f ~/.hermes/profiles/<name>/logs/gateway.log
tail -f ~/.hermes/profiles/<name>/logs/gateway.error.log

同时流式传输所有配置文件的日志:

tail -f ~/.hermes/logs/gateway.log ~/.hermes/profiles/*/logs/gateway.log

CLI 还提供了一个结构化日志查看器:

hermes logs -f                  # follow default profile
hermes -p coder logs -f # follow one profile
hermes logs --help # filters, levels, JSON output

识别实际运行的进程

hermes profile list             # profiles + model + gateway state
hermes-gateways status # full status across every profile
launchctl list | grep hermes # macOS — PIDs and labels
systemctl --user list-units 'hermes-gateway-*' # Linux — units

编辑配置

每个配置文件将其配置保存在自己的目录中:

~/.hermes/profiles/<name>/
├── .env # API keys, bot tokens (chmod 600)
├── config.yaml # model, provider, toolsets, gateway settings
└── SOUL.md # personality / system prompt

默认配置文件直接使用 ~/.hermes/ 目录,包含相同的三个文件。

使用任意编辑器或通过 CLI 进行编辑:

hermes config set model.model anthropic/claude-sonnet-4    # default profile
coder config set model.model openai/gpt-5 # named profile

编辑 .envconfig.yaml 后,重启受影响的网关:

coder gateway restart
# or, for everything:
hermes-gateways restart

保持主机唤醒

网关进程可以全天运行,但操作系统在空闲时仍会尝试进入睡眠状态。有两种模式:

macOS — caffeinate

caffeinate 内置于 macOS 中,在其运行期间防止系统睡眠。无需安装。

caffeinate -dis                    # block display, idle, and system sleep
caffeinate -dis -t 28800 # same, auto-exit after 8 hours
caffeinate -i -w $(cat ~/.hermes/gateway.pid) & # awake while default gateway runs

# Persistent: run in background and forget
nohup caffeinate -dis >/dev/null 2>&1 &
disown

# Inspect / stop
pmset -g assertions | grep -iE 'caffeinate|prevent|user is active'
pkill caffeinate
标志效果
-d阻止显示器睡眠
-i阻止空闲系统睡眠(默认)
-m阻止磁盘睡眠
-s阻止系统睡眠(仅适用于连接电源的 Mac)
-u模拟用户活动(防止屏幕锁定)
-t NN 秒后自动退出
-w P当 PID P 退出时退出
合上盖子仍会使 Mac 睡眠

caffeinate 无法覆盖 MacBook 上由硬件控制的合盖睡眠。如需在合盖状态下运行,请更改“节能”/“电池”偏好设置,或使用第三方工具。

Linux — systemd-inhibitloginctl

# Inhibit suspend while a command runs
systemd-inhibit --what=idle:sleep --who=hermes --why="gateways running" \
sleep infinity &

# Allow user services to keep running after logout (recommended)
sudo loginctl enable-linger "$USER"

启用 lingering(持久化)后,你的 systemd 用户单元(包括 hermes-gateway-<profile>.service)将在 SSH 断开连接和重启后继续运行。

令牌冲突安全

每个配置文件必须为每个平台使用唯一的机器人令牌。如果两个配置文件共享 Telegram、Discord、Slack、WhatsApp 或 Signal 令牌,第二个网关将拒绝启动,并报出指明冲突配置文件的错误。

要审计令牌:

grep -H 'TELEGRAM_BOT_TOKEN\|DISCORD_BOT_TOKEN' \
~/.hermes/.env ~/.hermes/profiles/*/.env

更新代码

hermes update 拉取最新代码一次,并将新的捆绑技能同步到每个配置文件中:

hermes update
hermes-gateways restart

用户修改过的技能永远不会被覆盖。

故障排除

"Could not find service in domain for user gui: 501"

你在之前执行过 hermes gateway stop 之后,又运行了 hermes gateway start。CLI 的 stop 命令会执行完整的 launchctl unload,这会将服务从 launchd 的注册表中移除。CLI 在 start 时会捕获此特定错误,并自动重新加载 plist 文件(↻ launchd job was unloaded; reloading service definition)。服务将正常启动。无需修复。

崩溃后残留的 PID

如果某个配置文件的网关显示为 not running,但进程仍然存活:

ps -ef | grep "hermes_cli.*-p <profile>"
cat ~/.hermes/profiles/<profile>/gateway.pid
kill -TERM <pid> # graceful
kill -KILL <pid> # if that fails after a few seconds
<profile> gateway start

强制对单个服务进行硬重置

# macOS
launchctl unload ~/Library/LaunchAgents/ai.hermes.gateway-<profile>.plist
launchctl load ~/Library/LaunchAgents/ai.hermes.gateway-<profile>.plist

# Linux
systemctl --user restart hermes-gateway-<profile>.service

健康检查

hermes doctor                  # default profile
hermes -p <profile> doctor # one profile