Profile 不是给同一 Agent 换一个昵称。它通过独立 HERMES_HOME 分开 config、Memory、Session、Skills、状态数据库、Gateway、日志和 Cron。真正的多环境验收要回答三件事:新 Profile 复制了什么、旧状态有没有泄漏、工具还能访问哪些宿主机文件。
本课创建 lab-alpha-731 与 lab-beta-732 两个临时 Profile。前者从当前配置轻量克隆,后者从 alpha 完整克隆。两个唯一金丝雀用于证明状态来源,不包含真实业务或 Secret。
本站验证范围: 2026-10-07 已在 Hermes v0.21.5 上完整实跑 P01–P12,实测与官方文档不一致的地方已在对应步骤标出,完整记录见文末。
下载实验材料
将每个未执行步骤保留为“待验证”。实际路径、命令输出和归档哈希应写入证据栏;不要记录 .env 内容、API Key、OAuth token 或真实个人资料。
先看清三种边界
| 边界 | Profile 会做什么 | Profile 不会做什么 |
|---|---|---|
| Hermes 状态 | 为 config、Memory、Session、Skills、Cron、Gateway PID/日志和数据库使用独立 HERMES_HOME | 不自动证明业务权限正确 |
| 工具起点 | 可用 terminal.cwd 指定启动目录 | 不会把 Profile 目录自动当工作目录 |
| 宿主机访问 | container backend 可用 profile home;host 可选 terminal.home_mode: profile | local backend 默认仍能按 OS 用户权限访问其他目录 |
SOUL.md 是提示,不是访问控制。让模型回答“我在哪个目录”也不是隔离证据;用工具实际读取路径和负例文件才算。
P01:盘点当前 Profile
hermes profile list
hermes profile show default
hermes dump
记录当前 active 标记、Profile ID、HERMES_HOME、模型、Gateway 状态与 Skill 数量。default 的内部 ID 永远是 default;对它执行 rename 只设置显示名,不改变命令、服务或 Cron 引用。
先检查实验名没有被占用:
hermes profile show lab-alpha-731
hermes profile show lab-beta-732
若名称已存在,停止实验并换一组明确的新名字,不使用 --force 覆盖。
P02:先写 Profile 合同
为 alpha 与 beta 各复制一份模板,写清 owner、用途、terminal.cwd、允许的 Tools/Skills、Memory 规则、Gateway/API/Cron 状态和删除日期。首轮约束为:
- 只在临时目录运行;
- Gateway、API 和 Cron 关闭;
- 不放生产凭据;
- 不访问两个 canary 文件之外的业务资料;
- 所有删除动作先 export。
Profile 的描述可供 Kanban orchestrator 路由,不能代替这份人工合同。
P03:用轻量 clone 创建 alpha
hermes profile create lab-alpha-731 --clone \
--description "Temporary profile isolation lab; no production actions"
hermes profile show lab-alpha-731
--clone 复制当前 Profile 的 config.yaml、.env、SOUL.md 与 Skills。实测 v0.21.5 还会复制 memories/MEMORY.md 和 USER.md(源码 _CLONE_SUBDIR_FILES),虽然创建提示和 --help 都只写了前四项;不复制的是 Session。来源 Profile 有不该带走的记忆时,克隆后先清理。由于 .env 会被复制,立即核对变量名和 provider 范围;不要把值打印到日志。实验 Profile 不需要的真实 Secret 应移除或轮换为测试凭据。
新建 Profile 默认生成 ~/.local/bin/lab-alpha-731 alias,也可以统一用:
hermes -p lab-alpha-731 doctor
hermes -p lab-alpha-731 dump
每条命令都带 -p 能减少 sticky default 切错环境的风险。-p 可以放在命令任意位置。
P04:建立固定工作目录
为两个 Profile 分别准备隔离测试目录:
<你的实验根目录>/alpha/profile-canary.txt = PROFILE-ALPHA-731
<你的实验根目录>/beta/profile-canary.txt = PROFILE-BETA-732
在 alpha 的 config.yaml 使用实际绝对路径:
terminal:
backend: local
cwd: /absolute/path/to/profile-lab/alpha
cwd: "." 表示 Hermes 启动时的目录,并不表示 Profile home。修改 SOUL.md 或 cwd 后开新 Session,避免旧 prompt 状态干扰判断。
P05:验证 cwd 正例与负例
在 alpha 新 Session 给出固定任务:
使用文件工具读取当前工作目录中的 profile-canary.txt,只返回文件内容和工具看到的绝对路径。不要搜索父目录。
预期只返回 PROFILE-ALPHA-731 和 alpha 路径。随后把明确的 beta canary 绝对路径作为负例读取。如果 local backend 能读到 beta,这不是 Profile 失效,而是证明 Profile 不构成文件系统沙箱;将结果记为 P05 的硬边界,而不是误写成“完全隔离”。需要强隔离时启用受控 container/sandbox,并重新跑负例。
P06:验证 Memory 与 Session 不继承
先在 alpha 新 Session 写入一个无害长期事实:
请申请写入长期记忆:实验代号是 PROFILE-ALPHA-731。
批准后再开一个 alpha 新 Session 查询;按 Memory 实验 记录 staged、approve 与新 Session 证据。当前 default Profile 不应凭空命中该唯一值。
--clone 的 beta 还没创建,因此 P06 只证明 alpha 与来源 Profile 的新 Memory/Session 分离。不要用“模型说不知道”作为唯一证据,同时检查 Profile 路径和 Session 列表。
P07:验证 Skills 与 Cron 的归属
hermes -p lab-alpha-731 skills list
hermes -p lab-alpha-731 cron list
hermes cron list
Skills 应来自 P03 的轻量 clone;alpha 的 Cron 应为空或只含你明确创建的本地测试项。Profile 文档明确:Cron 存在于各自 HERMES_HOME,不能让两个 Agent 并发指向同一 Profile,否则它们会同时写 Memory 和状态。
本课不创建 Cron。若需要验证,使用 Cron C01–C14 的 paused、local delivery 金丝雀,不能复制生产 job。
P08:从 alpha 完整 clone beta
hermes profile create lab-beta-732 \
--clone-from lab-alpha-731 --clone-all \
--description "Temporary clone-all boundary lab; no production actions"
hermes profile show lab-beta-732
当前 --clone-all 会复制 config、静态 API keys、SOUL、Memory、Skills 与 Plugins;明确排除 Session、state.db、backups、state-snapshots、checkpoints 以及 Cron jobs。旧资料中“完整状态会复制 Session/Cron”的说法已经过时。
OAuth 登录不会复制出第二套独立 token。共享 root auth 的 token refresh 会回写 root;需要独立 OAuth 身份时,在目标 Profile 内重新执行 hermes -p <name> auth add <provider>。
P09:证明 clone 后仍是两个身份
把 beta 的 cwd 改为 beta 实验目录,新开 Session 后检查:
- 能读取
PROFILE-BETA-732; - Session 列表不包含 alpha 历史;
- Cron 列表不包含 alpha job;
- clone 时已有的 alpha Memory 可出现;clone 后新增的 Memory 不应自动双向同步;
- Gateway PID、日志和状态路径不同。
外部 Memory provider 可能有自己的 scope;Honcho 在 Profile clone 时创建独立 AI peer,但可共享用户 workspace。启用第三方 provider 时应单独验证其 scoping,不能拿文件 Memory 结果外推。
P10:验证 sticky default 与 alias
hermes profile use lab-alpha-731
hermes profile list
hermes dump
hermes profile use default
hermes profile list
active * 应随 use 改变。切回 default 是本实验的硬门禁。Alias、-p 与 sticky default 都指向同一 Profile,但运维脚本应优先写显式 hermes -p <id>。
P11:导出并做恢复演练
hermes profile export lab-alpha-731
记录 tar.gz 路径、时间与 SHA-256。Export 会包含 Profile 配置、Memory、Skills、Cron、Plugins 等可迁移状态,并剥离 API Keys。它是恢复材料,不是凭据备份。
使用一个新名字导入,避免覆盖原 Profile:
hermes profile import ./lab-alpha-731.tar.gz --name lab-alpha-restore-731
hermes profile show lab-alpha-restore-731
核对 Memory canary、Skills 与合同;重新配置测试凭据后才能启动 Gateway/API。恢复验收完成后,先 export restore,再删除临时恢复 Profile。
P12:停止服务并删除实验 Profile
hermes -p lab-alpha-731 gateway status
hermes -p lab-beta-732 gateway status
hermes profile delete lab-alpha-restore-731
hermes profile delete lab-beta-732
hermes profile delete lab-alpha-731
hermes profile list
hermes profile use default
Delete 会停止对应 Gateway、移除 systemd/launchd 服务、alias 和全部 Profile 数据,并要求输入名称确认。默认 Profile 不能删除。列表中三个测试 ID 均消失、默认 Profile 恢复 active、实验目录和 export 按你的保留策略处理后,才算完成。
上生产前的四个硬门禁
- 一 Agent 一 Profile: 不让两个长期进程写同一个 HERMES_HOME。
- 一用途一合同: owner、cwd、工具、Memory、入口和停用方式可追责。
- Profile 不等于 sandbox: 用实际越界负例证明宿主机访问边界。
- 复制不等于备份: clone-all 排除历史和 Cron;需要恢复证据时使用 export 或 backup。
本站实测记录(2026-10-07,Hermes v0.21.5)
环境:macOS 26.4(Apple Silicon),Hermes v0.21.5(2026.9.24),模型 glm-5.3-flash(zai),测试 Profile aclab 及临时 Profile,均不连接消息平台;你的 default Profile 与正在运行的 Gateway 未改动。
为了验证”克隆是否复制 Memory”,我们先在来源 Profile aclab 的 MEMORY.md 写了一条金丝雀 ACLAB-SOURCE-MEM-730,再用 --clone-from aclab 创建 alpha。

| 步骤 | 实测结果 | 与教程一致 |
|---|---|---|
| P01 盘点 | default 为 active,Gateway running;两个实验名不存在 | ✅ |
| P03 轻量 clone | 复制了 config、.env、SOUL.md、61 个 Skills,还复制了插件 homeassistant;MEMORY.md 也被复制(含 ACLAB-SOURCE-MEM-730);Session 为 0 | ❌ Memory 部分不一致 |
| P05 cwd 正例 | 从别的目录启动,按 terminal.cwd 读到 PROFILE-ALPHA-731 | ✅ |
| P05 负例 | 用绝对路径读到了 beta 的 PROFILE-BETA-732 | ✅(证明 Profile 不是沙箱) |
| P06 Memory | staged → 批准 → alpha 新会话答出 PROFILE-ALPHA-731;aclab 与 default 记忆中没有 | ✅ |
| P07 | alpha 的 Cron 为空、Skills 60 个启用 | ✅ |
| P08 clone-all | Memory 复制;Session 0、无 state.db、Cron 不复制(提示原文:“excluding session history, cron jobs, backups, and snapshots”) | ✅ |
| P08 额外发现 | beta 的 terminal.cwd 仍指向 alpha 目录;TUI 输入历史 .hermes_history(含 /memory approve 命令)和 pending/ 也被复制 | 教程未提及 |
| P09 | beta 改 cwd 后读到自己的金丝雀;beta 新增 BETA-ONLY-734 后 alpha 中没有 | ✅ 不双向同步 |
| P10 | profile use 切换 ◆ 标记,dump 的 hermes_home 随之改变;已切回 default | ✅ |
| P11 导出 | 2.6 MB,不含 .env,含 Cron、Memory、输入历史 | ✅ |
| P11 导入 | 失败:Unsupported archive member type: …/skills/ego-browser | ❌ |
| P12 | 三个临时 Profile 删除,alias 清除,default 恢复 active | ✅ |
导入失败的原因:ego-browser 这个 Skill 是由另一个工具安装的符号链接。export 把链接原样打进归档,import 出于安全考虑拒绝符号链接,于是整个归档无法恢复。删掉链接后重新导出,导入成功:Memory 完整、.env 没有带过来(需要重新配置凭据)、暂停的 Cron 也恢复了。
这正是”复制不等于备份”的实例:导出成功不代表能恢复。用 find ~/.hermes/profiles/<名称>/skills -maxdepth 2 -type l 先查有没有链接 Skill;有的话,在导出前处理掉或另行记录安装方式,并且每次都做一次导入演练。
完成检查
- P01–P12 每一行都有实际命令、结果和证据位置。
- 你能准确说出
--clone、--clone-all、export 的资产差异。 - Memory、Session、Cron、Gateway 与 cwd 都完成正例和负例。
- 文件越界结果按真实 backend 记录,没有把 Profile 宣称为 sandbox。
- 三个临时 Profile 已删除,default 恢复 active,归档哈希已记录。
下一步用独立 Profile 完成 API Server A01–A14 上线实验。如果只需要消息入口,先完成 Gateway 四层验收。