一、背景与架构
1.1 需求场景
在某些复杂任务中,OpenClaw 主 agent 需要将子任务委托给外部 Hermes Agent 处理,例如:
- 让 Hermes 执行需要长期记忆的对话任务
- 利用 Hermes 的特定工具或技能
- 多 Agent 协作分工
1.2 实现原理
OpenClaw 通过 sessions_spawn 启动 Hermes 的 ACP 进程,ACP 是基于 JSON-RPC over stdio 的通信协议:
- 每次 sessions_spawn 会在本地启动一个 Hermes 进程
- 任务通过 stdin/stdout 传递,JSON-RPC 格式
- 任务完成后进程关闭,但 Hermes 自身有持久记忆系统,可以跨任务保持上下文
二、前置条件
2.1 运行环境
- OpenClaw:已安装并正常运行,系统级 systemd 服务
- Hermes Agent:已安装,路径 /root/.hermes/
- Python:Hermes Agent 的 venv 内置 Python 3
- 节点:Linux(本文档基于 root 用户 + systemd 环境)
2.2 依赖组件
| 组件 | 说明 |
|---|---|
| acpx 插件 | OpenClaw 的 ACP over stdio 插件,已内置在 OpenClaw 中 |
| Hermes ACP 适配器 | Hermes 自带的 hermes acp 命令 |
| hermes_session.py | 会话管理脚本(本文档提供) |
三、OpenClaw 配置步骤
3.1 编辑配置文件
编辑 /root/.openclaw/openclaw.json,添加以下三个配置块。参数说明见 3.2 节表格:
| 配置路径 | 值 |
|---|---|
| acp.enabled | true |
| acp.backend | "acpx" |
| plugins.entries.acpx.config.agents.hermes.command | /root/.hermes/hermes-agent/venv/bin/hermes acp |
| agents.list[].id | "hermes" |
| agents.list[].runtime.type | "acp" |
| agents.list[].runtime.acp.agent | "hermes" |
| agents.list[].runtime.acp.backend | "acpx" |
| agents.list[].runtime.acp.mode | "run" |
3.2 重启 Gateway 使配置生效
执行以下命令重启 Gateway:
systemctl restart openclaw-gateway
3.3 验证配置是否生效
重启后,等待约 30 秒让 Hermes 完成冷启动,然后发送测试消息:
| sessions_spawn | task: "你好,收到请回复" |
| runtime | "acp" |
| agentId | "hermes" |
| mode | "run" |
如果 Hermes 正常响应,说明配置已生效。
四、Session 管理方案
4.1 问题分析
ACP session 存在以下限制:
- mode="run":每次创建独立 session,任务结束后立即关闭,无法跨任务保持上下文
- mode="session":需要 thread=true 做会话绑定,在某些平台下不可用
4.2 解决思路
在 prompt 层实现上下文续接:
- 每次 Hermes spawn 完成后 → 记录其内部 session ID
- 下次发送相关任务时 → 在 prompt 里告诉 Hermes "请继续之前的 session"
- Hermes 自身有持久记忆 → 加载该 session 的历史,继续对话
4.3 核心脚本
会话管理脚本路径:/root/.openclaw/workspace/scripts/hermes_session.py
功能命令:
| 命令 | 用途 |
|---|---|
| decide "任务描述" | 判断应该创建新会话还是续接(返回 new 或 resume:id) |
| record 关键词 | spawn 返回后,记录当前活跃会话 |
| build-resume session_id 新任务 | 生成续接 prompt(decide 返回 resume 时使用) |
| touch | 更新活跃会话时间,防止 30 分钟过期 |
| status | 查看当前活跃会话和历史会话数 |
| reset | 清空所有会话状态 |
4.4 状态文件
路径:/root/.openclaw/workspace/hermes-session-state.json
| 字段 | 说明 |
|---|---|
| activeConversation.hermes_session_id | Hermes 内部 session ID |
| activeConversation.acp_session_key | ACP session key |
| activeConversation.last_topic | 最近一次会话主题 |
| activeConversation.message_count | 消息数量 |
4.5 自动决策逻辑
| 判断条件 | 行为 |
|---|---|
| 无活跃会话 | 创建全新会话(返回 new) |
| 任务相关(共享关键词 ≥1 个英文词 ≥3 字符,或共享 ≥2 个中文 bigram) | 续接已有会话(返回 resume:id) |
| 任务不相关 | 归档旧会话,创建新会话(返回 new) |
| 活跃会话闲置 >30 分钟 | 自动过期,创建新会话 |
五、调用流程与示例
5.1 标准调用流程(不相关任务)
| 步骤 | 操作 |
|---|---|
| 1 | python3 .../hermes_session.py decide "介绍一下快速排序" → 输出 new |
| 2 | sessions_spawn 发送正常提问(不加续接提示) |
| 3 | spawn 返回后:python3 .../hermes_session.py record "快速排序" |
5.2 续接场景(相关任务)
| 步骤 | 操作 |
|---|---|
| 1 | python3 .../hermes_session.py decide "快速排序的最坏情况是什么" → 输出 resume:xxx |
| 2 | python3 .../hermes_session.py build-resume xxx "新任务" → 生成续接 prompt |
| 3 | 将续接 prompt 拼到任务前面,执行 sessions_spawn |
| 4 | spawn 返回后执行 touch 更新活跃时间 |
5.3 关键参数说明
| 参数 | 可选值 | 说明 |
|---|---|---|
| mode | "run"(推荐) | 一次性任务,执行完退出 |
| mode | "session" | 持久会话,需要平台支持 thread 绑定 |
| runtime | "acp" | 固定值,声明使用 ACP 协议 |
| agentId | "hermes" | agents.list 中注册的 agent ID |
| resumeSessionId | ACP session key | 可选项;传了则续接指定 ACP session |
六、已知限制
当前架构是"主 agent 调用子 agent"模式,Hermes 只在收到调用时启动,任务结束后退出。Hermes 没有持续运行的监听循环,无法主动推送消息。
如果需要定时任务,可以由 OpenClaw 通过 cron 定时触发 Hermes,结果由 OpenClaw 转发给用户。
| 场景 | 耗时 |
|---|---|
| 冷启动(首次调用) | 约 30 秒 |
| 正常任务 | 约 16 秒 |
| 续接任务 | 同正常任务 |
七、文件路径参考
| 用途 | 路径 |
|---|---|
| OpenClaw 配置 | /root/.openclaw/openclaw.json |
| Session 管理脚本 | /root/.openclaw/workspace/scripts/hermes_session.py |
| Session 状态文件 | /root/.openclaw/workspace/hermes-session-state.json |
| Hermes 主目录 | /root/.hermes/ |
| Hermes Session 历史 | /root/.hermes/sessions/session_id.json |
| Hermes venv Python | /root/.hermes/hermes-agent/venv/bin/hermes |
| Skill 文档 | /root/.openclaw/workspace/skills/hermes-acp/SKILL.md |
八、快速参考
Shell 命令:
| hermes_session.py decide "任务描述" |
| hermes_session.py record "任务关键词" |
| hermes_session.py build-resume id "新任务" |
| hermes_session.py status |
| hermes_session.py reset |
sessions_spawn 调用:
| sessions_spawn({ task, runtime: "acp", agentId: "hermes", mode: "run" }) |
文章评论