Hermes 多 Profile 机制深度解析

折腾 Hermes 也有一段时间了,从一开始的单一 agent 用着挺爽,到后来发现需求越来越多,一个 agent 根本不够用。

你想想看,你白天写代码需要一个 coding assistant,晚上想搞个研究 bot 帮你盯 arXiv 论文,周末还想弄个写作助手帮你整理笔记。这三个场景的模型选择、记忆体系、技能树完全不一样,硬塞到一个 agent 里,迟早会精神分裂。

Profile 机制就是为了解决这个问题而生的。

什么是 Profile

坦率的讲,Profile 就是 Hermes 的多实例隔离方案。

每个 Profile 是一个完全独立的 Hermes agent,有自己的

  • config.yaml — 模型、provider、工具集、所有配置
  • .env — API keys、bot tokens
  • SOUL.md — 人格设定和系统提示
  • skills/ — 独立的技能树
  • sessions/ — 独立的会话历史
  • memory — 独立的记忆体系
  • logs/ — 独立的日志
  • cron jobs — 独立的定时任务
  • gateway state — 独立的聊天平台接入状态

这些文件全部隔离在各自的目录里,互不干扰。

底层实现其实挺巧妙的。Hermes 代码里有 119+ 个地方通过 get_hermes_home() 来解析路径,Profile 机制通过设置 HERMES_HOME 环境变量,让所有这些路径自动指向对应 Profile 的目录。

默认 Profile 就是 ~/.hermes 本身,自定义 Profile 在 ~/.hermes/profiles/<name>/

创建 Profile 的四种姿势

空白创建

最干净的方式,从零开始配置

hermes profile create coder

这会创建一个空的 ~/.hermes/profiles/coder/ 目录,你需要自己跑一遍 coder setup 来配置模型、API key 这些。

克隆配置

如果你已经有一个调好的 Profile,想基于它的配置创建一个新的,但 skills、sessions、memory 这些不要

hermes profile create research --clone

这会把 ~/.hermes/config.yaml.env 复制过去,但其他状态文件都是空的。适合「我想换个模型但其他配置差不多」的场景。

完整克隆

连 skills、memory、sessions 一起复制

hermes profile create backup --clone-all

这个我一般在做重大配置调整之前用,先完整克隆一份当备份,改炸了还能回滚。

从指定 Profile 克隆

hermes profile create dev --clone-from coder

coder Profile 克隆配置到新的 dev Profile。适合你有多个 Profile,想基于某个特定 Profile 创建新实例的场景。

使用 Profile 的三种方式

命令别名

创建 Profile 的时候会自动生成一个命令别名

coder chat              # 等同于 hermes -p coder chat
coder gateway start     # 启动 coder 的 gateway
coder config set model.default anthropic/claude-sonnet-4

这个别名是写到 PATH 里的 wrapper script,用起来跟原生 hermes 命令没区别。我自己最常用的就是这种方式,打字少。

-p 参数

不想用别名或者在脚本里动态指定 Profile

hermes -p coder chat
hermes -p research gateway start

适合在 CI/CD 或者自动化脚本里用,Profile 名字可以作为变量传入。

Sticky Default

如果你某段时间主要用某个 Profile,可以把它设为默认

hermes profile use coder

之后直接 hermes chat 就会用 coder Profile,不用再打 -p
想切回去就 hermes profile use default
使用 cat ~/.hermes/active_profile 查看当前活跃的profile。

默认 Profile 和自定义 Profile 的区别

说到这个,很多人刚接触 Profile 机制会有个疑问,默认 Profile 和自定义 Profile 到底有啥区别?

其实吧,从技术实现上看,它们没有本质区别。都是同样的目录结构,同样的配置文件格式,同样的命令接口。

唯一的区别是路径

  • 默认 Profile 是 ~/.hermes/
  • 自定义 Profile 是 ~/.hermes/profiles/<name>/

默认 Profile 就是你最初安装 Hermes 时的 ~/.hermes 目录,不需要迁移,现有安装直接就能用。自定义 Profile 是后来创建的,放在 profiles/ 子目录下。

另外一个小区别是服务命名

  • 默认 Profile 的 systemd 服务叫 hermes-gateway.service
  • 自定义 Profile 叫 hermes-gateway-<name>.service

这是为了向后兼容,早期版本只有默认 Profile,服务名没有后缀。

但从我自己的使用体验来看,这两者在功能上完全对等。你完全可以把默认 Profile 当成一个「特殊的自定义 Profile」来理解。

多 Profile 的应用场景

配置完了,来聊聊实际使用。我自己目前跑了三个 Profile,每个对应不同的使用场景。

场景一,角色分离

这是最基础的用法。不同 Profile 扮演不同角色

# 编程助手
hermes profile create coder
coder config set model.default anthropic/claude-sonnet-4
echo "你是一个专注的编程助手,擅长代码审查和调试。" > ~/.hermes/profiles/coder/SOUL.md

# 研究助手
hermes profile create research
research config set model.default openai/gpt-4-turbo
echo "你是一个研究助手,擅长论文检索和文献综述。" > ~/.hermes/profiles/research/SOUL.md

# 写作助手
hermes profile create writer
writer config set model.default anthropic/claude-3-opus
echo "你是一个技术写作助手,擅长把复杂概念讲清楚。" > ~/.hermes/profiles/writer/SOUL.md

每个 Profile 有自己的 SOUL.md 来定义人格,有自己的 skills 来定义能力边界。coder 装了 debugging 和 development-workflow 技能,research 装了 research-workflow 技能,writer 装了 qiye-writer 技能。

互不干扰,各司其职。

场景二,项目隔离

如果你同时参与多个项目,每个项目有自己的技术栈和约定,可以用 Profile 来隔离

hermes profile create project-a
project-a config set terminal.cwd /path/to/project-a
project-a config set model.default anthropic/claude-sonnet-4

hermes profile create project-b
project-b config set terminal.cwd /path/to/project-b
project-b config set model.default openai/gpt-4-turbo

terminal.cwd 设置工作目录,这样每个 Profile 启动后自动 cd 到对应项目。配合项目根目录的 AGENTS.mdCLAUDE.md,agent 会自动加载项目约定。

这个方案比在同一个 agent 里反复切换工作目录要干净得多。

场景三,模型对比

有时候你想对比不同模型在同一个任务上的表现,可以创建多个 Profile,每个用不同的模型

hermes profile create test-claude
test-claude config set model.default anthropic/claude-sonnet-4

hermes profile create test-gpt4
test-gpt4 config set model.default openai/gpt-4-turbo

hermes profile create test-local
test-local config set model.default ollama/llama3
test-local config set model.base_url http://localhost:11434

然后给它们同样的任务,对比输出质量。我自己用这个方法来测试新模型,决定要不要把主力 Profile 切过去。

场景四,沙盒和生产

同一个配置,跑两个实例,一个用于测试,一个用于生产

hermes profile create staging --clone production
staging config set model.default openai/gpt-4-turbo-preview
staging config set terminal.cwd /path/to/staging

staging 克隆了 production 的所有配置,但工作目录和模型不同。你可以在 staging 里随便折腾,确认没问题了再把配置同步到 production。

多 Profile 协作

单个 Profile 各自为战已经很强了,但 Hermes 还提供了多 Profile 协作的机制。

Kanban 工作队列

这是 Hermes 的多 agent 协作核心。一个 SQLite 数据库作为共享看板,多个 Profile 作为 worker 领取任务

# 初始化看板
hermes kanban init

# 创建任务
hermes kanban create "实现用户登录模块" --assign coder

# 查看任务状态
hermes kanban list

coder Profile 会自动领取分配给它的任务,完成后标记为 done。你可以在看板上看到所有任务的状态、进度、评论。

这个机制适合把一个大任务拆解成多个子任务,分配给不同的 Profile 并行处理。比如一个 Profile 负责后端 API,一个负责前端 UI,一个负责测试用例。

delegate_task 子 agent

如果你不想搞这么重,可以用 delegate_task 在当前 Profile 里临时 spawn 子 agent

# 在 coder Profile 的会话里
delegate_task(
    goal="实现用户登录的单元测试",
    context="后端 API 已经完成,使用 pytest,测试文件在 tests/test_auth.py",
    toolsets=["terminal", "file"]
)

子 agent 有独立的会话和终端,但共享父 agent 的进程。适合临时拆分一个子任务,不需要长期运行。

Profile Distributions

如果你调教出了一个很好用的 Profile,想分享给别人或者在多台机器上同步,可以把它打包成 distribution

# 导出
hermes profile export coder  # 生成 coder.tar.gz

# 导入
hermes profile import coder.tar.gz

或者更进一步,把 Profile 发布到 git 仓库

hermes profile install github.com/you/research-bot --alias

别人一行命令就能安装你的整个 agent 配置,包括 SOUL、skills、cron jobs、MCP 连接。credentials、memory、sessions 这些敏感数据不会打包,留在本地。

多 Profile 接入聊天平台

这块是我觉得 Hermes 设计得最优雅的地方。

单 Profile 对应单 Bot

每个 Profile 运行自己的 gateway 进程,有自己的 bot token

# coder Profile 的 .env
TELEGRAM_BOT_TOKEN=111111:AAA...

# research Profile 的 .env
TELEGRAM_BOT_TOKEN=222222:BBB...

启动各自的 gateway

coder gateway start       # 启动 coder 的 Telegram bot
research gateway start    # 启动 research 的 Telegram bot

这样你就有两个独立的 Telegram bot,一个负责编程,一个负责研究。用户在 Telegram 里 @ 不同的 bot,消息会路由到对应的 Profile。

飞书、Discord、Slack 这些平台也是同样的逻辑。每个 Profile 用自己的 bot token,运行独立的 gateway 进程。

Token Lock 安全机制

如果你不小心让两个 Profile 用了同一个 bot token,第二个 gateway 会拒绝启动,并报错告诉你哪个 Profile 冲突了。

这个机制防止了消息路由混乱。坦率的讲,我第一次配置的时候确实犯过这个错,复制 .env 的时候忘了改 token,结果启动第二个 gateway 的时候直接报错。看到错误信息的那一刻我就知道,这个设计是真的贴心。

多 Profile 群聊

如果你想让多个 Profile 在同一个群聊里协作,有几种方案。

方案一,多 bot 同群

把多个 bot 拉到同一个群里,每个 bot 对应一个 Profile

coder gateway start
research gateway start
writer gateway start

在 Telegram 群里 @coder 问编程问题,@research 问研究问题,@writer 让它帮你润色文章。每个 bot 只响应 @ 自己的消息。

方案二,单 bot + Profile 切换

如果不想搞这么多 bot,可以用一个 bot,通过命令切换 Profile

# 在 bot 的对话里
/profile coder    # 切换到 coder Profile
/profile research # 切换到 research Profile

但这个方案有个问题,切换 Profile 之后,之前的会话上下文就丢了。适合「我现在要用不同角色处理一个任务」的场景,不适合长期并行。

方案三,Kanban 协作群

创建一个专门的协作群,多个 bot 都在群里,通过 Kanban 看板协调任务

# 在群里发消息
@coder 实现登录模块
@research 调研 OAuth2 最佳实践
@writer 整理成技术文档

每个 bot 领取自己的任务,完成后在看板上更新状态。你可以在群里看到整个协作过程。

飞书接入实战

说到飞书接入,我自己踩了不少坑,这里分享一下完整流程。

方式一,交互式配置(推荐)

不想手动编辑配置文件的话,Hermes 提供了交互式向导,一步步引导你完成配置

hermes -p coder gateway setup

运行后会进入一个命令行交互界面,流程大概是这样的

  1. 选择接入渠道 — 列表里会有 Telegram、Discord、飞书、Slack 等选项,选「飞书」
  2. 创建飞书应用 — CLI 会生成一个二维码或链接,用手机飞书扫码,直接跳转到飞书开放平台的应用创建页面。这一步省去了你自己去开放平台找入口、填表单的麻烦
  3. 自动获取凭证 — 应用创建完成后,App ID 和 App Secret 会自动回填到 CLI 里,不需要你手动复制粘贴
  4. 配置事件订阅 — CLI 会提示你确认 webhook 回调地址,一般会自动生成本地监听地址。如果你用了反向代理或者 ngrok,在这里填公网可达的 URL
  5. 权限确认 — 飞书应用需要开通消息收发等权限,CLI 会列出需要的权限清单,提醒你逐一开通
  6. 写入配置 — 所有信息确认后,CLI 自动把凭证写入 ~/.hermes/profiles/coder/.env

整个过程基本不用碰配置文件,对新手很友好。配置完之后直接启动

coder gateway start

方式二,手动编辑配置

如果你更喜欢掌控每一步,或者交互式向导出了问题,也可以手动配置。

首先你需要在飞书开放平台创建一个应用,获取 App ID 和 App Secret。然后在 Hermes 里配置

# 编辑 Profile 的 .env
nano ~/.hermes/profiles/coder/.env

添加飞书的配置

FEISHU_APP_ID=cli_xxx
FEISHU_APP_SECRET=xxx
FEISHU_VERIFICATION_TOKEN=xxx
FEISHU_ENCRYPT_KEY=xxx

然后启动 gateway

coder gateway start

Hermes 会自动处理飞书的事件订阅和消息路由。你可以在飞书里 @ 这个 bot,它会用 coder Profile 的配置来响应。

如果你想让多个 Profile 接入飞书,每个 Profile 需要创建独立的飞书应用,获取各自的 App ID 和 Secret。然后在各自的 .env 里配置,启动各自的 gateway。

这块需要注意的是,飞书的应用审核比较严格,创建多个应用可能会触发审核。我自己的做法是先用一个应用测试,确认配置没问题了再创建其他应用。

持久化服务

如果你希望 gateway 在后台持续运行,重启后自动恢复,可以把它安装为系统服务

coder gateway install       # 创建 systemd 服务
coder gateway start         # 启动服务

每个 Profile 的服务名是独立的

  • 默认 Profile 是 hermes-gateway.service
  • coder Profile 是 hermes-gateway-coder.service
  • research Profile 是 hermes-gateway-research.service

它们互不影响,可以独立启停。

在 WSL2 里用 systemd 需要注意,确保 /etc/wsl.conf 里配置了 systemd=true,否则服务会在 WSL 重启后丢失。

批量管理

Profile 多了之后,逐个启停很麻烦。可以写个脚本来批量管理

#!/bin/sh
profiles="default coder research writer"

for profile in $profiles; do
    if [ "$profile" = "default" ]; then
        hermes gateway "$1"
    else
        hermes -p "$profile" gateway "$1"
    fi
done

保存为 hermes-gateways,加上执行权限

chmod +x hermes-gateways
./hermes-gateways start    # 启动所有 Profile
./hermes-gateways stop     # 停止所有 Profile
./hermes-gateways restart  # 重启所有 Profile

我自己把这个脚本放在 ~/.local/bin/ 里,用起来很方便。

查看日志和状态

多 Profile 运行的时候,排查问题需要看日志。每个 Profile 的日志在自己的目录下

# 默认 Profile
tail -f ~/.hermes/logs/gateway.log

# coder Profile
tail -f ~/.hermes/profiles/coder/logs/gateway.log

想同时看所有 Profile 的日志

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

查看 Profile 状态

hermes profile list    # 列出所有 Profile 及其状态

这个命令会显示每个 Profile 的模型、gateway 运行状态、最后活跃时间。

更新和维护

hermes update 会拉取最新代码,并自动同步新 bundled skills 到所有 Profile

hermes update
# → Code updated (12 commits)
# → Skills synced: default (up to date), coder (+2 new), research (+2 new)

用户修改过的 skills 不会被覆盖,只有 bundled skills 会同步。

更新完之后重启所有 gateway

./hermes-gateways restart

踩坑记录

说到这个,我分享几个自己踩过的坑。

坑一,工作目录混淆

一开始我以为 Profile 目录就是工作目录,结果发现 agent 执行命令的时候还是在 ~ 下。后来才搞明白,Profile 目录是 Hermes 的状态目录,工作目录由 terminal.cwd 控制。

如果你希望某个 Profile 默认在特定项目目录下工作,需要显式设置

coder config set terminal.cwd /absolute/path/to/project

注意必须是绝对路径,cwd: "." 在 local backend 下表示「Hermes 启动时的目录」,不是 Profile 目录。

坑二,Token 冲突

前面提到过,两个 Profile 用了同一个 bot token,第二个 gateway 会拒绝启动。排查方法

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

这个命令会列出所有 Profile 的 token,一眼就能看出哪个重复了。

坑三,WSL2 下服务丢失

WSL2 重启后 systemd 服务没了。原因是 /etc/wsl.conf 里没有配置 systemd=true

解决方法

sudo nano /etc/wsl.conf

添加

[boot]
systemd=true

然后在 PowerShell 里重启 WSL

wsl --shutdown

重新进入 WSL 后,systemd 服务就会自动恢复。

总结

回过头来看,Hermes 的 Profile 机制设计得真的很优雅。

它不是简单地在同一个 agent 里加个「角色切换」功能,而是从底层就做了完全隔离。每个 Profile 是一个独立的 agent,有自己的状态、配置、记忆、技能树。这种设计虽然占用更多磁盘空间,但换来了真正的隔离性和灵活性。

多 Profile 协作的 Kanban 机制也很有想象力。把任务拆解、分配、追踪这些项目管理概念引入到 AI agent 体系里,让多个 agent 能像一个团队一样协作。

接入聊天平台这块,单 Profile 对应单 bot 的设计很直观,多 Profile 群聊的方案也很灵活。你可以根据自己的需求选择最合适的方案。

如果你也在折腾 AI agent,强烈推荐试试 Profile 机制。它能让你的 agent 体系从「单兵作战」升级到「团队协作」,打开很多新的可能性。


如果你也有类似的折腾经历,欢迎交流。
原文链接 https://qiyec.site/archives/hermes-multi-profile-deep-dive