Hermes vs OpenClaw:基于源码的 Agent Loop 全面分析
作者:吴佳浩
撰稿时间:2026-6-7
最后更新:2026-6-10
声明 :本文所有结论均来自俺对两个仓库源码的分析和测(转载请注明出处 吴佳浩Alben)
Hermes:
github.com/NousResearch/hermes-agentOpenClaw:
github.com/openclaw/openclaw
引言
Hermes和OpenClaw的对比文章视频很多,但大多数停留在功能层面:支持哪些模型、有哪些工具、是否支持多Agent。
真正决定一个Agent系统上限的,其实不是工具数量,而是Agent Loop本身。
从学术谱系来看,两者都源于姚顺雨等人在2022年提出的ReAct(Reason + Act)范式:让大模型在推理(Thought)与行动(Action)之间循环迭代,通过工具调用获取外部信息,再将Observation反馈回下一轮推理。
然而,当ReAct从论文走向工程落地之后,两条完全不同的演化路线出现了。
Hermes选择继续强化Agent本身------记忆、技能、学习、长期成长;OpenClaw则选择强化Agent运行环境------会话、调度、流式事件、生命周期与可靠性。
前者试图回答:
"Agent如何变得越来越聪明?"
后者试图回答:
"Agent如何在生产环境中稳定运行数千次甚至数万次任务?"
这也是为什么,同样是Agent Loop,两者最终演化出了完全不同的架构形态。
一、两个项目的真实起源
#mermaid-svg-1Om6nO0AbJ8rVVXf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1Om6nO0AbJ8rVVXf .error-icon{fill:#552222;}#mermaid-svg-1Om6nO0AbJ8rVVXf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1Om6nO0AbJ8rVVXf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1Om6nO0AbJ8rVVXf .marker.cross{stroke:#333333;}#mermaid-svg-1Om6nO0AbJ8rVVXf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1Om6nO0AbJ8rVVXf p{margin:0;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge{stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section--1 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section--1 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section--1 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section--1 text{fill:#ffffff;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth--1{stroke-width:17;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:#ffffff;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-0 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-0 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-0 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-0 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-0{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-0{stroke-width:14;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-1 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-1 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-1 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-1 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-1{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-1{stroke-width:11;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-2 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-2 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-2 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-2 text{fill:#ffffff;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-2{stroke-width:8;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:#ffffff;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-3 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-3 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-3 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-3 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-3{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-3{stroke-width:5;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-4 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-4 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-4 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-4 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-4{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-4{stroke-width:2;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-5 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-5 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-5 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-5 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-5{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-5{stroke-width:-1;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-6 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-6 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-6 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-6 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-6{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-6{stroke-width:-4;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-7 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-7 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-7 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-7 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-7{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-7{stroke-width:-7;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-8 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-8 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-8 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-8 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-8{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-8{stroke-width:-10;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-9 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-9 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-9 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-9 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-9{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-9{stroke-width:-13;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-10 rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-10 path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-10 circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-10 text{fill:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .node-icon-10{font-size:40px;color:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge-depth-10{stroke-width:-16;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-1Om6nO0AbJ8rVVXf .lineWrapper line{stroke:black;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled circle,#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:lightgray;}#mermaid-svg-1Om6nO0AbJ8rVVXf .disabled text{fill:#efefef;}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-root rect,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-root path,#mermaid-svg-1Om6nO0AbJ8rVVXf .section-root circle{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-1Om6nO0AbJ8rVVXf .section-root text{fill:#ffffff;}#mermaid-svg-1Om6nO0AbJ8rVVXf .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-1Om6nO0AbJ8rVVXf .edge{fill:none;}#mermaid-svg-1Om6nO0AbJ8rVVXf .eventWrapper{filter:brightness(120%);}#mermaid-svg-1Om6nO0AbJ8rVVXf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 2025-11-24 OpenClaw 前身Clawdbot 发布 作者 PeterSteinberger(奥地利,vibecoder) TypeScript,本地Gateway +消息平台集成 2026-01-27 Clawdbot → Moltbot 应 Anthropic商标投诉改名 2026-01-30 Moltbot →OpenClaw 开始病毒式传播 2026-02-14 Steinberger 加入OpenAI 成立非营利基金会接管项目 2026-02 Hermes Agent 发布 NousResearch出品,Python 重写 定位「在 OpenClaw基础上填补记忆短板」 内置 hermes clawmigrate 迁移工具 两个项目的诞生时间线
关键背景:OpenClaw 的 VISION.md 明确写道:
"OpenClaw started as a personal playground to learn AI and build something genuinely useful: an assistant that can run real tasks on a real computer."
而 Hermes 的发布文章则直接写明:
"OpenClaw...Its limitation, as users noted publicly, is that memory between sessions requires manual setup. Hermes was built to solve that gap."
这不是两个竞争者,而是一个明确的继承与扩展关系。
二、技术栈对比:语言差异决定了执行模型
| Hermes | OpenClaw | |
|---|---|---|
| 主语言 | Python 83%(主逻辑)TypeScript 13%(TUI / Web) | TypeScript(Node.js 22+) |
| 并发模型 | 同步线程模型 concurrent.futures + threading.Lock |
原生异步模型 async/await + Event Loop |
| 包管理 | uv + pip | pnpm monorepo |
| 安装方式 | `curl ... | bash`(Shell Installer)或 PowerShell |
| LLM 客户端层 | auxiliary_client.py(264KB)--- 统一 LLM 调用抽象 |
pi-ai(Mario Zechner 作品)--- 多 Provider 抽象 + 流式事件归一化 |
| Agent Loop 层 | AIAgent 类(run_agent.py,6933 行) |
pi-agent-core(Mario Zechner 作品)--- Agent Loop + 工具执行 + 事件系统 |
| Agent Runtime 层 | agent/ 子包(prompt_builder、context_compressor、display 等) |
pi-coding-agent --- 完整 Runtime(文件工具、JSONL session、压缩、扩展) |
| CLI / TUI 层 | hermes_cli/ + hermes_tui/ |
pi-tui --- Terminal UI |
| Gateway 层 | Gateway(Python 实现) | OpenClaw Gateway --- 在 pi-* 层次之上构建的多渠道 + Hook 系统 |
OpenClaw 的架构层次
pi-ai → LLM 多 provider 抽象,流式事件归一化
pi-agent-core → Agent Loop,工具执行,事件系统
pi-coding-agent → 完整 Agent Runtime(文件工具、JSONL session、压缩、扩展)
pi-tui → Terminal UI
─────────────────────────
OpenClaw Gateway → 在以上层次之上构建的 Gateway + 多渠道 + Hook 系统
这不是简单的语言偏好问题。Python 的 GIL 和同步模型天然倾向于 while 循环 + ThreadPool;Node.js 的 Event Loop 天然倾向于事件驱动 + 异步流。两个系统的执行模型差异,根源在语言选择,不只是设计哲学。
三、仓库规模的真实对比
Hermes Agent 代码规模(agent/ 目录核心文件)
| 文件 | 大小 | 职责 |
|---|---|---|
run_agent.py |
6,933 行 / 335KB | 主入口,AIAgent 类(不是 15k+) |
agent/agent_runtime_helpers.py |
~110KB | Agent Runtime 辅助函数 |
agent/agent_init.py |
~88KB | Agent 初始化 |
agent/auxiliary_client.py |
~264KB | LLM 统一调用抽象 |
agent/anthropic_adapter.py |
~102KB | Anthropic 原生 SDK 适配 |
agent/prompt_builder.py |
~19KB | System Prompt 组装 |
agent/context_compressor.py |
~22KB | 上下文压缩引擎 |
agent/tool_guardrails.py |
~18KB | 工具循环检测护栏 |
agent/background_review.py |
~31KB | 后台自我回顾(Memory Nudge) |
agent/display.py |
~20KB | CLI 展示(spinner、diff 渲染、Tool Preview) |
agent/model_metadata.py |
~21KB | 模型元数据、上下文长度探测 |
agent/iteration_budget.py |
~3.4KB | 迭代预算计数器 |
agent/tool_dispatch_helpers.py |
~17KB | 工具并发调度 |
agent/bedrock_adapter.py |
~50KB | AWS Bedrock 适配 |
tools/registry.py |
--- | 22 个工具模块的自注册注册表 |
OpenClaw 代码规模
| 层级 | 说明 |
|---|---|
src/ 核心 |
TypeScript,数十个子系统 |
packages/ 工作区 |
pnpm monorepo |
extensions/ 插件 |
渠道适配器等 |
| 58,209 commits | 约为 Hermes 的 5.2 倍 |
Commit 数量差异(11,158 vs 58,209)是最直观的迭代深度指标。OpenClaw 的迭代密度远高于 Hermes,这符合「更早诞生、更大社区、更长演化时间」的事实。
四、共同骨架:两者都实现了同一个 ReAct 循环
#mermaid-svg-MNk9mlmGM4wZHpej{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MNk9mlmGM4wZHpej .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MNk9mlmGM4wZHpej .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MNk9mlmGM4wZHpej .error-icon{fill:#552222;}#mermaid-svg-MNk9mlmGM4wZHpej .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MNk9mlmGM4wZHpej .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MNk9mlmGM4wZHpej .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MNk9mlmGM4wZHpej .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MNk9mlmGM4wZHpej .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MNk9mlmGM4wZHpej .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MNk9mlmGM4wZHpej .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MNk9mlmGM4wZHpej .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MNk9mlmGM4wZHpej .marker.cross{stroke:#333333;}#mermaid-svg-MNk9mlmGM4wZHpej svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MNk9mlmGM4wZHpej p{margin:0;}#mermaid-svg-MNk9mlmGM4wZHpej .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MNk9mlmGM4wZHpej .cluster-label text{fill:#333;}#mermaid-svg-MNk9mlmGM4wZHpej .cluster-label span{color:#333;}#mermaid-svg-MNk9mlmGM4wZHpej .cluster-label span p{background-color:transparent;}#mermaid-svg-MNk9mlmGM4wZHpej .label text,#mermaid-svg-MNk9mlmGM4wZHpej span{fill:#333;color:#333;}#mermaid-svg-MNk9mlmGM4wZHpej .node rect,#mermaid-svg-MNk9mlmGM4wZHpej .node circle,#mermaid-svg-MNk9mlmGM4wZHpej .node ellipse,#mermaid-svg-MNk9mlmGM4wZHpej .node polygon,#mermaid-svg-MNk9mlmGM4wZHpej .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MNk9mlmGM4wZHpej .rough-node .label text,#mermaid-svg-MNk9mlmGM4wZHpej .node .label text,#mermaid-svg-MNk9mlmGM4wZHpej .image-shape .label,#mermaid-svg-MNk9mlmGM4wZHpej .icon-shape .label{text-anchor:middle;}#mermaid-svg-MNk9mlmGM4wZHpej .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MNk9mlmGM4wZHpej .rough-node .label,#mermaid-svg-MNk9mlmGM4wZHpej .node .label,#mermaid-svg-MNk9mlmGM4wZHpej .image-shape .label,#mermaid-svg-MNk9mlmGM4wZHpej .icon-shape .label{text-align:center;}#mermaid-svg-MNk9mlmGM4wZHpej .node.clickable{cursor:pointer;}#mermaid-svg-MNk9mlmGM4wZHpej .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MNk9mlmGM4wZHpej .arrowheadPath{fill:#333333;}#mermaid-svg-MNk9mlmGM4wZHpej .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MNk9mlmGM4wZHpej .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MNk9mlmGM4wZHpej .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MNk9mlmGM4wZHpej .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MNk9mlmGM4wZHpej .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MNk9mlmGM4wZHpej .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MNk9mlmGM4wZHpej .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MNk9mlmGM4wZHpej .cluster text{fill:#333;}#mermaid-svg-MNk9mlmGM4wZHpej .cluster span{color:#333;}#mermaid-svg-MNk9mlmGM4wZHpej div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MNk9mlmGM4wZHpej .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MNk9mlmGM4wZHpej rect.text{fill:none;stroke-width:0;}#mermaid-svg-MNk9mlmGM4wZHpej .icon-shape,#mermaid-svg-MNk9mlmGM4wZHpej .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MNk9mlmGM4wZHpej .icon-shape p,#mermaid-svg-MNk9mlmGM4wZHpej .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MNk9mlmGM4wZHpej .icon-shape .label rect,#mermaid-svg-MNk9mlmGM4wZHpej .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MNk9mlmGM4wZHpej .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MNk9mlmGM4wZHpej .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MNk9mlmGM4wZHpej :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} tool_calls
text
用户输入
组装 Prompt
系统提示词 + 工具 Schema
调用 LLM
响应类型?
执行工具
追加工具结果到历史
生成最终回复
持久化 Session
返回用户
两者入口对称:
| Hermes | OpenClaw | |
|---|---|---|
| 主入口 | agent.chat() / agent.run_conversation() |
runEmbeddedPiAgent() |
| 立即返回 | 阻塞等待最终回复 | { runId, acceptedAt } 立即返回 |
| 结果获取 | 函数返回值 | agent.wait RPC 轮询 lifecycle end |
| 核心位置 | run_agent.py: AIAgent |
src/agents/pi-embedded-runner/run.ts |
五、执行模型:同步 while vs 异步事件流
Hermes:同步 while 循环 + 可中断 HTTP
工具 后台线程(HTTP) AIAgent 用户 工具 后台线程(HTTP) AIAgent 用户 #mermaid-svg-SXv6eLAMk9QAAvup{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SXv6eLAMk9QAAvup .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SXv6eLAMk9QAAvup .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SXv6eLAMk9QAAvup .error-icon{fill:#552222;}#mermaid-svg-SXv6eLAMk9QAAvup .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SXv6eLAMk9QAAvup .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SXv6eLAMk9QAAvup .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SXv6eLAMk9QAAvup .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SXv6eLAMk9QAAvup .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SXv6eLAMk9QAAvup .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SXv6eLAMk9QAAvup .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SXv6eLAMk9QAAvup .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SXv6eLAMk9QAAvup .marker.cross{stroke:#333333;}#mermaid-svg-SXv6eLAMk9QAAvup svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SXv6eLAMk9QAAvup p{margin:0;}#mermaid-svg-SXv6eLAMk9QAAvup .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-SXv6eLAMk9QAAvup text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-SXv6eLAMk9QAAvup .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-SXv6eLAMk9QAAvup .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-SXv6eLAMk9QAAvup .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-SXv6eLAMk9QAAvup .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-SXv6eLAMk9QAAvup #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-SXv6eLAMk9QAAvup .sequenceNumber{fill:white;}#mermaid-svg-SXv6eLAMk9QAAvup #sequencenumber{fill:#333;}#mermaid-svg-SXv6eLAMk9QAAvup #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-SXv6eLAMk9QAAvup .messageText{fill:#333;stroke:none;}#mermaid-svg-SXv6eLAMk9QAAvup .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-SXv6eLAMk9QAAvup .labelText,#mermaid-svg-SXv6eLAMk9QAAvup .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-SXv6eLAMk9QAAvup .loopText,#mermaid-svg-SXv6eLAMk9QAAvup .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-SXv6eLAMk9QAAvup .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-SXv6eLAMk9QAAvup .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-SXv6eLAMk9QAAvup .noteText,#mermaid-svg-SXv6eLAMk9QAAvup .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-SXv6eLAMk9QAAvup .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-SXv6eLAMk9QAAvup .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-SXv6eLAMk9QAAvup .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-SXv6eLAMk9QAAvup .actorPopupMenu{position:absolute;}#mermaid-svg-SXv6eLAMk9QAAvup .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-SXv6eLAMk9QAAvup .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-SXv6eLAMk9QAAvup .actor-man circle,#mermaid-svg-SXv6eLAMk9QAAvup line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-SXv6eLAMk9QAAvup :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 主线程 wait:响应 / interrupt_event / 超时 alt并发安全 \& 多工具含 clarify 等交互工具 althas tool_calls纯文本 loopwhile True(同步) agent.chat("...")threading.Thread 发起 HTTPresponseThreadPoolExecutor(最多8线程)顺序执行结果(按原始顺序重排)追加 tool 消息,continue持久化 session返回 final_response
源码中有精细的并发判断逻辑(_should_parallelize_tool_batch()):
python
# 永不并发的工具(交互式)
_NEVER_PARALLEL_TOOLS = frozenset({"clarify"})
# 可安全并发的只读工具(来自 agent/tool_dispatch_helpers.py,已验证)
_PARALLEL_SAFE_TOOLS = frozenset({
"ha_get_state", "ha_list_entities", "ha_list_services",
"read_file", "search_files", "session_search",
"skill_view", "skills_list", "vision_analyze",
"web_extract", "web_search",
})
# 路径作用域工具:检查路径是否重叠才决定是否并发
_PATH_SCOPED_TOOLS = frozenset({"read_file", "write_file", "patch"})
# 注意:_MAX_TOOL_WORKERS(ThreadPoolExecutor max_workers)在 run_agent.py
# 中使用,不是模块级常量;MCP 工具并发通过 _is_mcp_tool_parallel_safe() 单独判断
还有专门的 _SafeWriter 类包装 stdout/stderr,防止 daemon 模式下 broken pipe 崩溃------这是生产化运行的细节。
OpenClaw:异步事件流 + 会话串行化
模型 pi-agent-core Pi-Agent Runtime 会话 Queue Gateway RPC 客户端(任意渠道) 模型 pi-agent-core Pi-Agent Runtime 会话 Queue Gateway RPC 客户端(任意渠道) #mermaid-svg-62Cw1TtfxsOwIdlJ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-62Cw1TtfxsOwIdlJ .error-icon{fill:#552222;}#mermaid-svg-62Cw1TtfxsOwIdlJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-62Cw1TtfxsOwIdlJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-62Cw1TtfxsOwIdlJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-62Cw1TtfxsOwIdlJ .marker.cross{stroke:#333333;}#mermaid-svg-62Cw1TtfxsOwIdlJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-62Cw1TtfxsOwIdlJ p{margin:0;}#mermaid-svg-62Cw1TtfxsOwIdlJ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-62Cw1TtfxsOwIdlJ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-62Cw1TtfxsOwIdlJ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-62Cw1TtfxsOwIdlJ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-62Cw1TtfxsOwIdlJ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-62Cw1TtfxsOwIdlJ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-62Cw1TtfxsOwIdlJ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-62Cw1TtfxsOwIdlJ .sequenceNumber{fill:white;}#mermaid-svg-62Cw1TtfxsOwIdlJ #sequencenumber{fill:#333;}#mermaid-svg-62Cw1TtfxsOwIdlJ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-62Cw1TtfxsOwIdlJ .messageText{fill:#333;stroke:none;}#mermaid-svg-62Cw1TtfxsOwIdlJ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-62Cw1TtfxsOwIdlJ .labelText,#mermaid-svg-62Cw1TtfxsOwIdlJ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-62Cw1TtfxsOwIdlJ .loopText,#mermaid-svg-62Cw1TtfxsOwIdlJ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-62Cw1TtfxsOwIdlJ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-62Cw1TtfxsOwIdlJ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-62Cw1TtfxsOwIdlJ .noteText,#mermaid-svg-62Cw1TtfxsOwIdlJ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-62Cw1TtfxsOwIdlJ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-62Cw1TtfxsOwIdlJ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-62Cw1TtfxsOwIdlJ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-62Cw1TtfxsOwIdlJ .actorPopupMenu{position:absolute;}#mermaid-svg-62Cw1TtfxsOwIdlJ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-62Cw1TtfxsOwIdlJ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-62Cw1TtfxsOwIdlJ .actor-man circle,#mermaid-svg-62Cw1TtfxsOwIdlJ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-62Cw1TtfxsOwIdlJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} opt工具调用 loopAgent Loop(异步事件驱动) agent RPC(带 sessionKey){ runId, acceptedAt }(立即)入队(全局 Queue + 会话 Channel 串行化)runEmbeddedPiAgent({ sessionId, sessionKey,provider, model, prompt, timeoutMs,bashElevated, abortSignal, ... })构建 Pi 会话,订阅事件流式请求token 流text_delta / thinking_delta 事件stream: "assistant"实时推送(各渠道适配)tool start/update/end 事件stream: "tool"工具进度实时可见lifecycle: { phase: "end", payload, usage }最终结果
runEmbeddedPiAgent 的真实参数签名(来自源码):
typescript
runEmbeddedPiAgent({
sessionId: string,
sessionKey: string, // 会话串行化 key
sessionFile: string, // JSONL 转录文件路径
workspaceDir: string,
agentDir: string,
config: OpenClawConfig,
prompt: string,
timeoutMs: number, // 默认 600,000ms(600秒)
runId: string,
provider?: string,
model?: string,
bashElevated?: {
enabled: boolean,
allowed: string[],
defaultLevel: string
},
abortSignal?: AbortSignal, // 外部可取消
})
注意:timeoutMs 默认值是 600 秒(10 分钟),不是 48 小时。
六、工具注册机制:自注册 vs 集中注册
Hermes:自注册式 Registry + Agent 级拦截
#mermaid-svg-mDAqjgXmL40PKL5U{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mDAqjgXmL40PKL5U .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mDAqjgXmL40PKL5U .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mDAqjgXmL40PKL5U .error-icon{fill:#552222;}#mermaid-svg-mDAqjgXmL40PKL5U .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mDAqjgXmL40PKL5U .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mDAqjgXmL40PKL5U .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mDAqjgXmL40PKL5U .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mDAqjgXmL40PKL5U .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mDAqjgXmL40PKL5U .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mDAqjgXmL40PKL5U .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mDAqjgXmL40PKL5U .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mDAqjgXmL40PKL5U .marker.cross{stroke:#333333;}#mermaid-svg-mDAqjgXmL40PKL5U svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mDAqjgXmL40PKL5U p{margin:0;}#mermaid-svg-mDAqjgXmL40PKL5U .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mDAqjgXmL40PKL5U .cluster-label text{fill:#333;}#mermaid-svg-mDAqjgXmL40PKL5U .cluster-label span{color:#333;}#mermaid-svg-mDAqjgXmL40PKL5U .cluster-label span p{background-color:transparent;}#mermaid-svg-mDAqjgXmL40PKL5U .label text,#mermaid-svg-mDAqjgXmL40PKL5U span{fill:#333;color:#333;}#mermaid-svg-mDAqjgXmL40PKL5U .node rect,#mermaid-svg-mDAqjgXmL40PKL5U .node circle,#mermaid-svg-mDAqjgXmL40PKL5U .node ellipse,#mermaid-svg-mDAqjgXmL40PKL5U .node polygon,#mermaid-svg-mDAqjgXmL40PKL5U .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mDAqjgXmL40PKL5U .rough-node .label text,#mermaid-svg-mDAqjgXmL40PKL5U .node .label text,#mermaid-svg-mDAqjgXmL40PKL5U .image-shape .label,#mermaid-svg-mDAqjgXmL40PKL5U .icon-shape .label{text-anchor:middle;}#mermaid-svg-mDAqjgXmL40PKL5U .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mDAqjgXmL40PKL5U .rough-node .label,#mermaid-svg-mDAqjgXmL40PKL5U .node .label,#mermaid-svg-mDAqjgXmL40PKL5U .image-shape .label,#mermaid-svg-mDAqjgXmL40PKL5U .icon-shape .label{text-align:center;}#mermaid-svg-mDAqjgXmL40PKL5U .node.clickable{cursor:pointer;}#mermaid-svg-mDAqjgXmL40PKL5U .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mDAqjgXmL40PKL5U .arrowheadPath{fill:#333333;}#mermaid-svg-mDAqjgXmL40PKL5U .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mDAqjgXmL40PKL5U .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mDAqjgXmL40PKL5U .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mDAqjgXmL40PKL5U .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mDAqjgXmL40PKL5U .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mDAqjgXmL40PKL5U .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mDAqjgXmL40PKL5U .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mDAqjgXmL40PKL5U .cluster text{fill:#333;}#mermaid-svg-mDAqjgXmL40PKL5U .cluster span{color:#333;}#mermaid-svg-mDAqjgXmL40PKL5U div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mDAqjgXmL40PKL5U .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mDAqjgXmL40PKL5U rect.text{fill:none;stroke-width:0;}#mermaid-svg-mDAqjgXmL40PKL5U .icon-shape,#mermaid-svg-mDAqjgXmL40PKL5U .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mDAqjgXmL40PKL5U .icon-shape p,#mermaid-svg-mDAqjgXmL40PKL5U .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mDAqjgXmL40PKL5U .icon-shape .label rect,#mermaid-svg-mDAqjgXmL40PKL5U .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mDAqjgXmL40PKL5U .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mDAqjgXmL40PKL5U .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mDAqjgXmL40PKL5U :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 工具执行时
model_tools.py 启动时发现
todo/memory/delegate/session_search
普通工具
import tools.web_tools
import tools.terminal_tool
import tools.delegate_tool
...22个模块
tools/registry.py
registry.register() 触发
get_tool_definitions()
按 toolset 过滤 schema
传给 LLM API
handle_function_call()
registry.dispatch()
Agent 级工具?
AIAgent 直接拦截处理
修改内部状态
工具 Handler
执行并返回结果
Agent 级工具 :todo、memory、delegate_task、session_search、skill_manage 等工具不走 registry dispatch,而是由 AIAgent 直接拦截、修改内部状态------这使它们能操作 Agent 的内存、技能、子任务等核心状态。
OpenClaw:Provider 插件化 + 工具事件化
#mermaid-svg-f4JrksrIklgahy5i{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-f4JrksrIklgahy5i .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-f4JrksrIklgahy5i .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-f4JrksrIklgahy5i .error-icon{fill:#552222;}#mermaid-svg-f4JrksrIklgahy5i .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-f4JrksrIklgahy5i .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-f4JrksrIklgahy5i .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-f4JrksrIklgahy5i .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-f4JrksrIklgahy5i .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-f4JrksrIklgahy5i .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-f4JrksrIklgahy5i .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-f4JrksrIklgahy5i .marker{fill:#333333;stroke:#333333;}#mermaid-svg-f4JrksrIklgahy5i .marker.cross{stroke:#333333;}#mermaid-svg-f4JrksrIklgahy5i svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-f4JrksrIklgahy5i p{margin:0;}#mermaid-svg-f4JrksrIklgahy5i .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-f4JrksrIklgahy5i .cluster-label text{fill:#333;}#mermaid-svg-f4JrksrIklgahy5i .cluster-label span{color:#333;}#mermaid-svg-f4JrksrIklgahy5i .cluster-label span p{background-color:transparent;}#mermaid-svg-f4JrksrIklgahy5i .label text,#mermaid-svg-f4JrksrIklgahy5i span{fill:#333;color:#333;}#mermaid-svg-f4JrksrIklgahy5i .node rect,#mermaid-svg-f4JrksrIklgahy5i .node circle,#mermaid-svg-f4JrksrIklgahy5i .node ellipse,#mermaid-svg-f4JrksrIklgahy5i .node polygon,#mermaid-svg-f4JrksrIklgahy5i .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-f4JrksrIklgahy5i .rough-node .label text,#mermaid-svg-f4JrksrIklgahy5i .node .label text,#mermaid-svg-f4JrksrIklgahy5i .image-shape .label,#mermaid-svg-f4JrksrIklgahy5i .icon-shape .label{text-anchor:middle;}#mermaid-svg-f4JrksrIklgahy5i .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-f4JrksrIklgahy5i .rough-node .label,#mermaid-svg-f4JrksrIklgahy5i .node .label,#mermaid-svg-f4JrksrIklgahy5i .image-shape .label,#mermaid-svg-f4JrksrIklgahy5i .icon-shape .label{text-align:center;}#mermaid-svg-f4JrksrIklgahy5i .node.clickable{cursor:pointer;}#mermaid-svg-f4JrksrIklgahy5i .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-f4JrksrIklgahy5i .arrowheadPath{fill:#333333;}#mermaid-svg-f4JrksrIklgahy5i .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-f4JrksrIklgahy5i .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-f4JrksrIklgahy5i .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-f4JrksrIklgahy5i .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-f4JrksrIklgahy5i .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-f4JrksrIklgahy5i .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-f4JrksrIklgahy5i .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-f4JrksrIklgahy5i .cluster text{fill:#333;}#mermaid-svg-f4JrksrIklgahy5i .cluster span{color:#333;}#mermaid-svg-f4JrksrIklgahy5i div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-f4JrksrIklgahy5i .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-f4JrksrIklgahy5i rect.text{fill:none;stroke-width:0;}#mermaid-svg-f4JrksrIklgahy5i .icon-shape,#mermaid-svg-f4JrksrIklgahy5i .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-f4JrksrIklgahy5i .icon-shape p,#mermaid-svg-f4JrksrIklgahy5i .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-f4JrksrIklgahy5i .icon-shape .label rect,#mermaid-svg-f4JrksrIklgahy5i .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-f4JrksrIklgahy5i .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-f4JrksrIklgahy5i .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-f4JrksrIklgahy5i :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} OpenClaw 工具执行流
pi-agent-core 触发工具调用
before_tool_call Hook
{ block: true } = 终止(低优先级 handler 停止)
Exec Approval 检查
危险 bash 命令需确认
执行工具
tool start/update/end 事件
实时流出
after_tool_call Hook
tool_result_persist Hook
落盘前最后变换
写入 JSONL 转录
(会话写锁保护)
七、工具循环护栏(Tool Guardrails)------ Hermes 独有
这是 Hermes Agent Loop 中一个重要的保护层,源码位于 agent/tool_guardrails.py(~500 行)。OpenClaw 没有等价物------工具的重复调用完全由 LLM 自觉,没有护栏层。
工具分类体系
python
# 只读工具(无副作用)
IDEMPOTENT_TOOL_NAMES = frozenset({
"read_file", "search_files", "web_search", "web_extract",
"session_search", "browser_snapshot", "browser_console",
"browser_get_images", "mcp_filesystem_read_file",
"mcp_filesystem_list_directory", ...
})
# 有副作用的工具
MUTATING_TOOL_NAMES = frozenset({
"terminal", "execute_code", "write_file", "patch",
"todo", "memory", "skill_manage",
"browser_click", "browser_type", "browser_navigate",
"send_message", "cronjob", "delegate_task", "process", ...
})
三种检测机制
| 检测类型 | 触发条件 | 默认警告阈值 | 默认阻断阈值 |
|---|---|---|---|
| exact_failure | 完全相同参数 + 相同错误结果 | 2 次 | 5 次 |
| same_tool_failure | 同工具不同参数均失败 | 3 次 | 8 次 |
| no_progress | 连续只使用只读工具无进展 | 2 次 | 5 次 |
护栏行为层级
ALLOW → 静默通过
WARN → 注入 synthetic system message 提示 agent 改变策略
HALT → 直接截断,强制 LLM 给出最终答案
Warnings 默认开启且不阻止工具执行;Hard Stops 需要显式在 config.yaml 中开启(hard_stop_enabled: true)。
针对不同工具的失败提示
护栏系统会根据失败的工具类型给出定制化的提示:
python
# terminal 工具失败的专项提示
if tool_name == "terminal":
return common + (
"For terminal failures, run a small diagnostic such as "
"`pwd && ls -la` in the same tool, then try an absolute path, "
"a simpler command, a different working directory, "
"or a different tool such as read_file/write_file/patch."
)
# 通用工具失败提示
return common + (
"Try different arguments, a narrower query/path, "
"an absolute path when relevant, or a different tool "
"that can make progress."
)
设计哲学
tool_guardrails.py 的 docstring 明确声明:
"The controller in this module is intentionally side-effect free: it tracks per-turn tool-call observations and returns decisions. Runtime code owns whether those decisions become warning guidance, synthetic tool results, or controlled turn halts."
护栏层是纯检测+决策,不主动干预执行------是否转为警告/阻断由 Runtime 决定。
八、迭代预算(Iteration Budget)------ Hermes 独有
Hermes 的 agent/iteration_budget.py(线程安全计数器,源码已验证)
python
class IterationBudget:
"""Thread-safe iteration counter for an agent."""
def __init__(self, max_total: int):
# 父 Agent 默认 90,子 Agent 从 delegation.max_iterations 取(默认 50)
self.max_total = max_total
self._used = 0
self._lock = threading.Lock()
def consume(self) -> bool: # 消耗 1 次,返回 True 表示在预算内
def refund(self) -> None: # 退还 1 次(仅 execute_code 成功后调用)
@property
def used(self) -> int: # 已使用次数
@property
def remaining(self) -> int: # 剩余次数
关键设计:
- 父子关系 (代码内有两处矛盾的注释):
agent_init.py注释说 "Shared --- consumed across parent + all subagents",而iteration_budget.pydocstring 说 "Each subagent gets an independent budget"。实际行为取决于delegate_task调用时是否传入父 Agent 的 budget 对象。子 Agent 默认上限为delegation.max_iterations(默认 50) - 软限制:用完时注入 system message 提示尽快结束,而非直接截断
- 精准退还 :只有
execute_code成功时才 refund,防止 agent 仅依赖 LLM 推理而不实际执行
OpenClaw 靠 timeoutMs 硬超时,没有「濒临上限时注入提示」的软机制。
九、并发模型的根本差异
Hermes:为单/少量 Agent 设计
用户请求 → AIAgent 实例(一般每用户一个进程)
→ ThreadPoolExecutor(仅用于工具并发,max 8 workers)
→ 工具 A / 工具 B / 工具 N
OpenClaw:为多用户/多渠道/多 Agent 并发设计
多渠道入站(WhatsApp / Telegram / Discord / ...)
→ Gateway RPC
→ 全局 Queue(可选,跨会话调度)
→ 会话 Channel A(本 session 所有 Run 串行)
→ 会话 Channel B
→ 会话 Channel N
→ Session Write Lock(跨进程 + 进程感知,文件级锁,等待超时 60s)
→ pi-embedded-runner A
→ pi-embedded-runner B
Session Write Lock 是跨进程的文件锁(不只是进程内互斥),能捕获来自其他进程的写入者。这是 OpenClaw 为多实例部署设计的保护机制。
十、System Prompt 组装策略
Hermes:砖块式 Prompt 建筑
agent/prompt_builder.py 定义了多个独立的「指导砖块」,按需组合:
python
# 基础身份
DEFAULT_AGENT_IDENTITY = "You are Hermes Agent, an intelligent AI assistant..."
# 如何使用 memory 工具
MEMORY_GUIDANCE = (
"You have persistent memory across sessions. Save durable facts using the memory "
"tool: user preferences, environment details, tool quirks, and stable conventions. "
"Memory is injected into every turn, so keep it compact..."
"Do NOT save task progress, session outcomes, completed-work logs..."
"Write memories as declarative facts, not instructions to yourself..."
)
# 何时创建 skill
SKILLS_GUIDANCE = (
"After completing a complex task (5+ tool calls), fixing a tricky error, "
"or discovering a non-trivial workflow, save the approach as a "
"skill with skill_manage so you can reuse it next time."
"When using a skill and finding it outdated, incomplete, or wrong, "
"patch it immediately with skill_manage(action='patch')..."
)
# 何时用 session_search
SESSION_SEARCH_GUIDANCE = (
"When the user references something from a past conversation... "
"use session_search to recall it before asking them to repeat themselves."
)
# 强制执行工具调用
TOOL_USE_ENFORCEMENT_GUIDANCE = (
"# Tool-use enforcement\n"
"You MUST use your tools to take action --- do not describe what you would do "
"or plan to do without actually doing it..."
)
# 必须跑出真实结果
TASK_COMPLETION_GUIDANCE = (
"# Finishing the job\n"
"When the user asks you to build, run, or verify something, the deliverable is "
"a working artifact backed by real tool output --- not a description of one."
"NEVER substitute plausible-looking fabricated output..."
)
按模型品牌定制行为指导
Hermes 针对不同模型家族的已知缺陷注入专项指导:
python
# 这些模型家族需要额外的「必须用工具,别只说不做」prompt
TOOL_USE_ENFORCEMENT_MODELS = (
"gpt", "codex", "gemini", "gemma", "grok", "glm", "qwen", "deepseek"
)
OpenAI GPT/Codex 和 xAI Grok 还有额外的 OPENAI_MODEL_EXECUTION_GUIDANCE,解决这些模型「声称完成但不实际执行」「跳过前置检查」「幻觉替代工具结果」等已知失败模式。
看板模式
当 Agent 运行在 Kanban(看板)模式时,会注入完整的任务协议:
python
KANBAN_GUIDANCE = (
"# Kanban task execution protocol\n"
"1. Orient → kanban_show()\n"
"2. Work inside the workspace\n"
"3. Heartbeat on long operations → kanban_heartbeat()\n"
"4. Block on genuine ambiguity → kanban_block()\n"
"5. Complete with structured handoff → kanban_complete()\n"
"6. If follow-up work appears, create it; don't do it → kanban_create()\n"
)
OpenClaw:分层注入
SOUL.md → AGENTS.md → Skills → TOOLS.md → runtime context
模板化,文件和 prompt 分开管理。没有按模型品牌定制的行为指导。
十一、上下文文件安全扫描 ------ Hermes 独有
agent/prompt_builder.py 中包含一个安全层------在加载 AGENTS.md / HERMES.md 等上下文文件前,扫描注入威胁:
python
def _scan_context_content(content: str, filename: str) -> str:
"""Scan context file content for injection. Returns sanitized content.
Uses the "context" scope from the shared threat-pattern library, which
covers classic injection + promptware/C2 patterns + role-play hijack.
Content matching is BLOCKED at this layer because the file would
otherwise enter the system prompt verbatim and the user has no chance
to intervene.
"""
findings = _scan_for_threats(content, scope="context")
if findings:
return f"[BLOCKED: {filename} contained potential prompt injection "
f"({', '.join(findings)}). Content not loaded.]"
return content
Hermes 还会在项目目录中搜索 .hermes.md 和 HERMES.md(从 cwd 向上遍历到 git root),在注入 system prompt 前剥离 YAML frontmatter。OpenClaw 没有这层安全扫描。
十二、模型元数据与上下文长度探测 ------ Hermes 更深
agent/model_metadata.py(~21KB)实现了复杂的上下文长度探测系统:
Provider 推断
Hermes 能从 base_url 自动推断 provider:
python
_URL_TO_PROVIDER = {
"api.openai.com": "openai",
"api.anthropic.com": "anthropic",
"api.deepseek.com": "deepseek",
"api.x.ai": "xai",
"dashscope.aliyuncs.com": "alibaba",
"integrate.api.nvidia.com": "nvidia",
# ... 30+ 条目
}
上下文长度探测阶梯
当模型未知时,从高到低逐级探测:
python
CONTEXT_PROBE_TIERS = [256_000, 128_000, 64_000, 32_000, 16_000, 8_000]
MINIMUM_CONTEXT_LENGTH = 64_000 # 低于此值的模型拒绝运行
本地端点识别
能识别 Tailscale CGNAT(100.64.0.0/10)、Docker 内部 DNS、RFC-1918 私有地址,自动调整超时策略。
OpenClaw 的模型元数据解析内嵌在 pi-ai 层,没有 Hermes 这么细粒度的探测和 provider 推断逻辑。
十三、OpenClaw 的 VISION.md 里有一条被忽略的关键声明
OpenClaw 的 VISION.md 明确写着不会合并的功能:
What We Will Not Merge (For Now):
- Agent-hierarchy frameworks (manager-of-managers / nested planner trees)
as a default architecture
- Heavy orchestration layers that duplicate existing agent and tool
infrastructure
这不是「OpenClaw 架构天然支持 Agent Tree」,而是主动拒绝它 。这与 Hermes 内置 delegate_task() 的 Agent Tree 路线形成了清晰的哲学对立。
Hermes 的 delegate_task:
- 直接在
run_agent.py内拦截,创建新的AIAgent实例 - 子 Agent 的迭代上限来自
delegation.max_iterations(默认 50),总额独立于父 Agent - ⚠️ 注意:
agent_init.py注释称 budget "shared across parent + subagents",但iteration_budget.pydocstring 称子 Agent 有 "independent budget"。实际行为取决于传入的iteration_budget参数
OpenClaw 的立场:明确不做这个。
十四、Provider 抽象与 Fallback
#mermaid-svg-gssHhV1mv4bmx7eK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gssHhV1mv4bmx7eK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gssHhV1mv4bmx7eK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gssHhV1mv4bmx7eK .error-icon{fill:#552222;}#mermaid-svg-gssHhV1mv4bmx7eK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gssHhV1mv4bmx7eK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gssHhV1mv4bmx7eK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gssHhV1mv4bmx7eK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gssHhV1mv4bmx7eK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gssHhV1mv4bmx7eK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gssHhV1mv4bmx7eK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gssHhV1mv4bmx7eK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gssHhV1mv4bmx7eK .marker.cross{stroke:#333333;}#mermaid-svg-gssHhV1mv4bmx7eK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gssHhV1mv4bmx7eK p{margin:0;}#mermaid-svg-gssHhV1mv4bmx7eK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gssHhV1mv4bmx7eK .cluster-label text{fill:#333;}#mermaid-svg-gssHhV1mv4bmx7eK .cluster-label span{color:#333;}#mermaid-svg-gssHhV1mv4bmx7eK .cluster-label span p{background-color:transparent;}#mermaid-svg-gssHhV1mv4bmx7eK .label text,#mermaid-svg-gssHhV1mv4bmx7eK span{fill:#333;color:#333;}#mermaid-svg-gssHhV1mv4bmx7eK .node rect,#mermaid-svg-gssHhV1mv4bmx7eK .node circle,#mermaid-svg-gssHhV1mv4bmx7eK .node ellipse,#mermaid-svg-gssHhV1mv4bmx7eK .node polygon,#mermaid-svg-gssHhV1mv4bmx7eK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gssHhV1mv4bmx7eK .rough-node .label text,#mermaid-svg-gssHhV1mv4bmx7eK .node .label text,#mermaid-svg-gssHhV1mv4bmx7eK .image-shape .label,#mermaid-svg-gssHhV1mv4bmx7eK .icon-shape .label{text-anchor:middle;}#mermaid-svg-gssHhV1mv4bmx7eK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gssHhV1mv4bmx7eK .rough-node .label,#mermaid-svg-gssHhV1mv4bmx7eK .node .label,#mermaid-svg-gssHhV1mv4bmx7eK .image-shape .label,#mermaid-svg-gssHhV1mv4bmx7eK .icon-shape .label{text-align:center;}#mermaid-svg-gssHhV1mv4bmx7eK .node.clickable{cursor:pointer;}#mermaid-svg-gssHhV1mv4bmx7eK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gssHhV1mv4bmx7eK .arrowheadPath{fill:#333333;}#mermaid-svg-gssHhV1mv4bmx7eK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gssHhV1mv4bmx7eK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gssHhV1mv4bmx7eK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gssHhV1mv4bmx7eK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gssHhV1mv4bmx7eK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gssHhV1mv4bmx7eK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gssHhV1mv4bmx7eK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gssHhV1mv4bmx7eK .cluster text{fill:#333;}#mermaid-svg-gssHhV1mv4bmx7eK .cluster span{color:#333;}#mermaid-svg-gssHhV1mv4bmx7eK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gssHhV1mv4bmx7eK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gssHhV1mv4bmx7eK rect.text{fill:none;stroke-width:0;}#mermaid-svg-gssHhV1mv4bmx7eK .icon-shape,#mermaid-svg-gssHhV1mv4bmx7eK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gssHhV1mv4bmx7eK .icon-shape p,#mermaid-svg-gssHhV1mv4bmx7eK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gssHhV1mv4bmx7eK .icon-shape .label rect,#mermaid-svg-gssHhV1mv4bmx7eK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gssHhV1mv4bmx7eK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gssHhV1mv4bmx7eK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gssHhV1mv4bmx7eK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} OpenClaw:pi-ai 多 Provider 抽象
getModel(provider, modelId)
api 字段路由
openai-completions
(兼容所有 OpenAI 格式端点)
anthropic
(原生 Anthropic SDK)
google / groq / bedrock...
统一 stream 事件
text_delta / thinking_delta / done
runWithModelFallback()
FailoverError 分类引擎
Hermes:深度 Provider 抽象
统一入口
API 模式判断
4级优先级
chat_completions
OpenAI / OpenRouter / 自定义
codex_responses
OpenAI Codex
anthropic_messages
原生 Anthropic SDK
统一 OpenAI 格式
Fallback 链
主 → 备1 → 备2
各辅助任务独立 Fallback 链
两边都有 Fallback,但实现路径不同:
- Hermes 的 Fallback 逻辑在
AIAgent内,是 Agent 自己的重试行为 - OpenClaw 的 Fallback 在
runWithModelFallback()层,是 Runtime 层面的 Provider 切换
十五、扩展机制:事后通知 vs 流水线拦截
| Hermes(Callback,事后通知型) | OpenClaw(Hook + Plugin,可拦截型) | |
|---|---|---|
| 工具回调 | tool_progress_callback |
before_tool_call 🔴 可终止 |
| 思考状态 | thinking_callback |
--- |
| 推理内容 | reasoning_callback |
--- |
| 用户澄清 | clarify_callback |
--- |
| 步骤追踪 | step_callback / stream_delta_callback |
--- |
| 模型解析 | --- | before_model_resolve |
| Prompt 构建 | --- | before_prompt_build(可注入内容) |
| Agent 回复 | --- | before_agent_reply 🔴 可接管整轮 |
| 消息发送 | --- | message_sending 🔴 可终止发送 |
| 工具结果 | --- | tool_result_persist(落盘前变换) |
| 压缩 | --- | before/after_compaction |
| 安装 | --- | before/after_install |
🔴 = 可终止流水线的节点
OpenClaw AGENTS.md 明确规定了 Hook 的决策规则:
before_tool_call: { block: true }→ 终态,停止低优先级 handlerbefore_tool_call: { block: false }→ 空操作,不清除已有阻止message_sending: { cancel: true }→ 终态
十六、上下文压缩
核心差异
| Hermes | OpenClaw | |
|---|---|---|
| 压缩层数 | 双压缩层(Agent 50% + Gateway 85%) | 单层触发型 |
| 摘要格式 | 结构化摘要(Goal / Constraints / Progress / Key Decisions / Relevant Files / Next Steps / Critical Context) | 通用摘要 |
| 迭代合并 | ✅ 第二次压缩时更新上次摘要("items move from In Progress to Done") | ❌ |
| 引擎可插拔 | ✅ ContextEngine ABC 允许替换 |
❌ |
| Hook 可见 | ❌ 内部行为 | ✅ before/after_compaction 事件 |
| 压缩策略 | 先 flush Memory 到磁盘 → 压缩中间轮次 → 保留末尾 protect_last_n(默认 20)条 → 创建子 session lineage |
触发 → 执行压缩 → 可能触发重试 → 重置内存 buffer |
Hermes 的双压缩层
#mermaid-svg-WChjokYwAnj3H9gb{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WChjokYwAnj3H9gb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WChjokYwAnj3H9gb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WChjokYwAnj3H9gb .error-icon{fill:#552222;}#mermaid-svg-WChjokYwAnj3H9gb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WChjokYwAnj3H9gb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WChjokYwAnj3H9gb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WChjokYwAnj3H9gb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WChjokYwAnj3H9gb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WChjokYwAnj3H9gb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WChjokYwAnj3H9gb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WChjokYwAnj3H9gb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WChjokYwAnj3H9gb .marker.cross{stroke:#333333;}#mermaid-svg-WChjokYwAnj3H9gb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WChjokYwAnj3H9gb p{margin:0;}#mermaid-svg-WChjokYwAnj3H9gb .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-WChjokYwAnj3H9gb .cluster-label text{fill:#333;}#mermaid-svg-WChjokYwAnj3H9gb .cluster-label span{color:#333;}#mermaid-svg-WChjokYwAnj3H9gb .cluster-label span p{background-color:transparent;}#mermaid-svg-WChjokYwAnj3H9gb .label text,#mermaid-svg-WChjokYwAnj3H9gb span{fill:#333;color:#333;}#mermaid-svg-WChjokYwAnj3H9gb .node rect,#mermaid-svg-WChjokYwAnj3H9gb .node circle,#mermaid-svg-WChjokYwAnj3H9gb .node ellipse,#mermaid-svg-WChjokYwAnj3H9gb .node polygon,#mermaid-svg-WChjokYwAnj3H9gb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WChjokYwAnj3H9gb .rough-node .label text,#mermaid-svg-WChjokYwAnj3H9gb .node .label text,#mermaid-svg-WChjokYwAnj3H9gb .image-shape .label,#mermaid-svg-WChjokYwAnj3H9gb .icon-shape .label{text-anchor:middle;}#mermaid-svg-WChjokYwAnj3H9gb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WChjokYwAnj3H9gb .rough-node .label,#mermaid-svg-WChjokYwAnj3H9gb .node .label,#mermaid-svg-WChjokYwAnj3H9gb .image-shape .label,#mermaid-svg-WChjokYwAnj3H9gb .icon-shape .label{text-align:center;}#mermaid-svg-WChjokYwAnj3H9gb .node.clickable{cursor:pointer;}#mermaid-svg-WChjokYwAnj3H9gb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WChjokYwAnj3H9gb .arrowheadPath{fill:#333333;}#mermaid-svg-WChjokYwAnj3H9gb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WChjokYwAnj3H9gb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WChjokYwAnj3H9gb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WChjokYwAnj3H9gb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WChjokYwAnj3H9gb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WChjokYwAnj3H9gb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WChjokYwAnj3H9gb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WChjokYwAnj3H9gb .cluster text{fill:#333;}#mermaid-svg-WChjokYwAnj3H9gb .cluster span{color:#333;}#mermaid-svg-WChjokYwAnj3H9gb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WChjokYwAnj3H9gb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WChjokYwAnj3H9gb rect.text{fill:none;stroke-width:0;}#mermaid-svg-WChjokYwAnj3H9gb .icon-shape,#mermaid-svg-WChjokYwAnj3H9gb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WChjokYwAnj3H9gb .icon-shape p,#mermaid-svg-WChjokYwAnj3H9gb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WChjokYwAnj3H9gb .icon-shape .label rect,#mermaid-svg-WChjokYwAnj3H9gb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WChjokYwAnj3H9gb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WChjokYwAnj3H9gb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WChjokYwAnj3H9gb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Hermes:压缩是 Agent 决策
context > 50% → 预检压缩
Agent 层
先 flush Memory 到磁盘
(MEMORY.md / USER.md)
context > 85% → Gateway 触发
Gateway 层
ContextCompressor.compress()
摘要中间轮次
保留末尾 protect_last_n 条(默认20)
工具调用对保持完整
生成新 session lineage ID
压缩 = 创建子 session
OpenClaw 的压缩生命周期
#mermaid-svg-8cpAAxE9SgcqzJin{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8cpAAxE9SgcqzJin .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8cpAAxE9SgcqzJin .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8cpAAxE9SgcqzJin .error-icon{fill:#552222;}#mermaid-svg-8cpAAxE9SgcqzJin .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8cpAAxE9SgcqzJin .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8cpAAxE9SgcqzJin .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8cpAAxE9SgcqzJin .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8cpAAxE9SgcqzJin .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8cpAAxE9SgcqzJin .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8cpAAxE9SgcqzJin .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8cpAAxE9SgcqzJin .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8cpAAxE9SgcqzJin .marker.cross{stroke:#333333;}#mermaid-svg-8cpAAxE9SgcqzJin svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8cpAAxE9SgcqzJin p{margin:0;}#mermaid-svg-8cpAAxE9SgcqzJin .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8cpAAxE9SgcqzJin .cluster-label text{fill:#333;}#mermaid-svg-8cpAAxE9SgcqzJin .cluster-label span{color:#333;}#mermaid-svg-8cpAAxE9SgcqzJin .cluster-label span p{background-color:transparent;}#mermaid-svg-8cpAAxE9SgcqzJin .label text,#mermaid-svg-8cpAAxE9SgcqzJin span{fill:#333;color:#333;}#mermaid-svg-8cpAAxE9SgcqzJin .node rect,#mermaid-svg-8cpAAxE9SgcqzJin .node circle,#mermaid-svg-8cpAAxE9SgcqzJin .node ellipse,#mermaid-svg-8cpAAxE9SgcqzJin .node polygon,#mermaid-svg-8cpAAxE9SgcqzJin .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8cpAAxE9SgcqzJin .rough-node .label text,#mermaid-svg-8cpAAxE9SgcqzJin .node .label text,#mermaid-svg-8cpAAxE9SgcqzJin .image-shape .label,#mermaid-svg-8cpAAxE9SgcqzJin .icon-shape .label{text-anchor:middle;}#mermaid-svg-8cpAAxE9SgcqzJin .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8cpAAxE9SgcqzJin .rough-node .label,#mermaid-svg-8cpAAxE9SgcqzJin .node .label,#mermaid-svg-8cpAAxE9SgcqzJin .image-shape .label,#mermaid-svg-8cpAAxE9SgcqzJin .icon-shape .label{text-align:center;}#mermaid-svg-8cpAAxE9SgcqzJin .node.clickable{cursor:pointer;}#mermaid-svg-8cpAAxE9SgcqzJin .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8cpAAxE9SgcqzJin .arrowheadPath{fill:#333333;}#mermaid-svg-8cpAAxE9SgcqzJin .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8cpAAxE9SgcqzJin .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8cpAAxE9SgcqzJin .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8cpAAxE9SgcqzJin .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8cpAAxE9SgcqzJin .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8cpAAxE9SgcqzJin .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8cpAAxE9SgcqzJin .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8cpAAxE9SgcqzJin .cluster text{fill:#333;}#mermaid-svg-8cpAAxE9SgcqzJin .cluster span{color:#333;}#mermaid-svg-8cpAAxE9SgcqzJin div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8cpAAxE9SgcqzJin .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8cpAAxE9SgcqzJin rect.text{fill:none;stroke-width:0;}#mermaid-svg-8cpAAxE9SgcqzJin .icon-shape,#mermaid-svg-8cpAAxE9SgcqzJin .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8cpAAxE9SgcqzJin .icon-shape p,#mermaid-svg-8cpAAxE9SgcqzJin .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8cpAAxE9SgcqzJin .icon-shape .label rect,#mermaid-svg-8cpAAxE9SgcqzJin .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8cpAAxE9SgcqzJin .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8cpAAxE9SgcqzJin .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8cpAAxE9SgcqzJin :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} OpenClaw:压缩是 Runtime 生命周期
compaction 事件
before_compaction Hook
外部可注入 / 观察
执行压缩算法
(pi-coding-agent 层)
after_compaction Hook
外部可感知
可能触发 Agent 重试
重置内存 buffer 避免重复
十七、自进化能力:Hermes 独有
这是 Hermes 最重要的差异化特性,OpenClaw 完全没有对应物:
#mermaid-svg-esnxyztPNApI5OfP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-esnxyztPNApI5OfP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-esnxyztPNApI5OfP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-esnxyztPNApI5OfP .error-icon{fill:#552222;}#mermaid-svg-esnxyztPNApI5OfP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-esnxyztPNApI5OfP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-esnxyztPNApI5OfP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-esnxyztPNApI5OfP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-esnxyztPNApI5OfP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-esnxyztPNApI5OfP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-esnxyztPNApI5OfP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-esnxyztPNApI5OfP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-esnxyztPNApI5OfP .marker.cross{stroke:#333333;}#mermaid-svg-esnxyztPNApI5OfP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-esnxyztPNApI5OfP p{margin:0;}#mermaid-svg-esnxyztPNApI5OfP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-esnxyztPNApI5OfP .cluster-label text{fill:#333;}#mermaid-svg-esnxyztPNApI5OfP .cluster-label span{color:#333;}#mermaid-svg-esnxyztPNApI5OfP .cluster-label span p{background-color:transparent;}#mermaid-svg-esnxyztPNApI5OfP .label text,#mermaid-svg-esnxyztPNApI5OfP span{fill:#333;color:#333;}#mermaid-svg-esnxyztPNApI5OfP .node rect,#mermaid-svg-esnxyztPNApI5OfP .node circle,#mermaid-svg-esnxyztPNApI5OfP .node ellipse,#mermaid-svg-esnxyztPNApI5OfP .node polygon,#mermaid-svg-esnxyztPNApI5OfP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-esnxyztPNApI5OfP .rough-node .label text,#mermaid-svg-esnxyztPNApI5OfP .node .label text,#mermaid-svg-esnxyztPNApI5OfP .image-shape .label,#mermaid-svg-esnxyztPNApI5OfP .icon-shape .label{text-anchor:middle;}#mermaid-svg-esnxyztPNApI5OfP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-esnxyztPNApI5OfP .rough-node .label,#mermaid-svg-esnxyztPNApI5OfP .node .label,#mermaid-svg-esnxyztPNApI5OfP .image-shape .label,#mermaid-svg-esnxyztPNApI5OfP .icon-shape .label{text-align:center;}#mermaid-svg-esnxyztPNApI5OfP .node.clickable{cursor:pointer;}#mermaid-svg-esnxyztPNApI5OfP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-esnxyztPNApI5OfP .arrowheadPath{fill:#333333;}#mermaid-svg-esnxyztPNApI5OfP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-esnxyztPNApI5OfP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-esnxyztPNApI5OfP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-esnxyztPNApI5OfP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-esnxyztPNApI5OfP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-esnxyztPNApI5OfP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-esnxyztPNApI5OfP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-esnxyztPNApI5OfP .cluster text{fill:#333;}#mermaid-svg-esnxyztPNApI5OfP .cluster span{color:#333;}#mermaid-svg-esnxyztPNApI5OfP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-esnxyztPNApI5OfP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-esnxyztPNApI5OfP rect.text{fill:none;stroke-width:0;}#mermaid-svg-esnxyztPNApI5OfP .icon-shape,#mermaid-svg-esnxyztPNApI5OfP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-esnxyztPNApI5OfP .icon-shape p,#mermaid-svg-esnxyztPNApI5OfP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-esnxyztPNApI5OfP .icon-shape .label rect,#mermaid-svg-esnxyztPNApI5OfP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-esnxyztPNApI5OfP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-esnxyztPNApI5OfP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-esnxyztPNApI5OfP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Hermes 闭环学习系统
完成任务
自主创建 SKILL.md
可复用的程序化记忆
技能在使用中自我改进
(类 DSPy GEPA 进化)
持久化 Memory
SQLite FTS5 搜索
USER.md 用户画像
Honcho dialectic 建模
下次对话
跨 session / 跨平台 / 跨设备 记忆
技能自动创建
agent/background_review.py(~31KB)实现了后台自我回顾:
python
# 伪代码还原自源码
class BackgroundReviewer:
def review_and_create_skill(self, tool_calls_count, task_result):
if tool_calls_count < 5:
return # 简单任务不触发
review_prompt = (
"Review this completed task and its tool calls. "
"If the workflow is reusable, create a concise SKILL.md..."
)
skill_md = self._call_auxiliary_llm(review_prompt)
self._dispatch_tool("skill_manage", action="create", name=..., content=skill_md)
Memory Nudge(记忆自驱)
每个 turn 结束后,后台线程自动运行:
python
# 伪代码还原自源码
def _background_memory_nudge(self):
nudge_prompt = (
"Review this conversation turn. What durable facts about the user, "
"their environment, preferences, or recurring patterns should be "
"remembered for future sessions?"
)
memories = self._call_auxiliary_llm(nudge_prompt)
for m in memories:
self._dispatch_tool("memory", action="add", content=m)
# 在独立线程中启动,不阻塞主响应
threading.Thread(target=background_memory_nudge).start()
技能自我改进
Agent 可以随时通过 skill_manage 工具修改已有技能:
python
# Agent 可直接调用的工具
skill_manage(action="create", name="deploy-k8s", content=full_skill_md)
skill_manage(action="patch", name="deploy-k8s", old_string="...", new_string="...")
skill_manage(action="edit", name="deploy-k8s", file_path="SKILL.md", ...)
skill_manage(action="delete", name="obsolete-skill")
衍生项目
Nous Research 还开了独立仓库 hermes-agent-self-evolution,用 DSPy + GEPA 做技能文件的进化优化:
- 阶段 1:SKILL.md 内容进化 ✅
- 阶段 2:工具描述进化(计划中)
- 阶段 3:系统提示进化(计划中)
- 阶段 4:工具实现代码进化(计划中)
这是 Hermes 与 OpenClaw 在 AI 能力维度上的本质差异。
十八、OpenClaw 独有的 Post-Turn 设计细节
OpenClaw 虽然没有 Hermes 的「回头看」自进化机制,但 Agent Loop 退出后有完整的收尾流程,体现在 runs.ts 的 run 生命周期管理中:
Run 生命周期管理
ACTIVE_EMBEDDED_RUNS → 当前活跃的 run handle
ACTIVE_EMBEDDED_RUN_SNAPSHOTS → run 状态快照
ABANDONED_EMBEDDED_RUNS → 被放弃的 run(session 断开后追踪)
EMBEDDED_RUN_WAITERS → 等待 run 结束的外部观察者
EMBEDDED_RUN_MODEL_SWITCH_REQUESTS → 运行中切换模型的请求队列
消息队列(Run 内 Steering)
typescript
// 运行中向 agent 注入消息的能力
queueEmbeddedAgentMessage(sessionId, text, options)
// 返回状态:
// - { queued: true, target: "embedded_run" } → 成功注入
// - { queued: true, target: "reply_run" } → 转入 reply 管道
// - { queued: false, reason: "no_active_run" } → 无活跃 run
// - { queued: false, reason: "not_streaming" } → run 已结束流
// - { queued: false, reason: "compacting" } → run 正在压缩
// - { queued: false, reason: "runtime_rejected" } → run 内部拒绝
Abort 机制
typescript
// 按 sessionId 终止单个 run
abortEmbeddedAgentRun(sessionId)
// 批量终止模式
abortEmbeddedAgentRun(undefined, { mode: "all" }) // 全部
abortEmbeddedAgentRun(undefined, { mode: "compacting" }) // 仅压缩中的
这套 Run 生命周期管理是 OpenClaw 作为「生产级 Gateway」的体现------hermes 的 post-turn 更多是「自我改进」,而 OpenClaw 的 post-turn 更多是「运行态管理」。
十九、多渠道支持:OpenClaw 独有
#mermaid-svg-R6u3O3u3YjTshGKL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-R6u3O3u3YjTshGKL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-R6u3O3u3YjTshGKL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-R6u3O3u3YjTshGKL .error-icon{fill:#552222;}#mermaid-svg-R6u3O3u3YjTshGKL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-R6u3O3u3YjTshGKL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-R6u3O3u3YjTshGKL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-R6u3O3u3YjTshGKL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-R6u3O3u3YjTshGKL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-R6u3O3u3YjTshGKL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-R6u3O3u3YjTshGKL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-R6u3O3u3YjTshGKL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-R6u3O3u3YjTshGKL .marker.cross{stroke:#333333;}#mermaid-svg-R6u3O3u3YjTshGKL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-R6u3O3u3YjTshGKL p{margin:0;}#mermaid-svg-R6u3O3u3YjTshGKL .edge{stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .section--1 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section--1 path,#mermaid-svg-R6u3O3u3YjTshGKL .section--1 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section--1 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section--1 text{fill:#ffffff;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth--1{stroke-width:17;}#mermaid-svg-R6u3O3u3YjTshGKL .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-0 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-0 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-0 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-0 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-0 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-0{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-0{stroke-width:14;}#mermaid-svg-R6u3O3u3YjTshGKL .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-1 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-1 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-1 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-1 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-1 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-1{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-1{stroke-width:11;}#mermaid-svg-R6u3O3u3YjTshGKL .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-2 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-2 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-2 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-2 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-2 text{fill:#ffffff;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-2{stroke-width:8;}#mermaid-svg-R6u3O3u3YjTshGKL .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-3 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-3 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-3 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-3 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-3 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-3{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-3{stroke-width:5;}#mermaid-svg-R6u3O3u3YjTshGKL .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-4 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-4 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-4 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-4 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-4 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-4{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-4{stroke-width:2;}#mermaid-svg-R6u3O3u3YjTshGKL .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-5 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-5 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-5 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-5 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-5 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-5{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-5{stroke-width:-1;}#mermaid-svg-R6u3O3u3YjTshGKL .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-6 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-6 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-6 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-6 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-6 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-6{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-6{stroke-width:-4;}#mermaid-svg-R6u3O3u3YjTshGKL .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-7 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-7 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-7 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-7 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-7 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-7{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-7{stroke-width:-7;}#mermaid-svg-R6u3O3u3YjTshGKL .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-8 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-8 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-8 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-8 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-8 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-8{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-8{stroke-width:-10;}#mermaid-svg-R6u3O3u3YjTshGKL .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-9 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-9 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-9 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-9 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-9 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-9{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-9{stroke-width:-13;}#mermaid-svg-R6u3O3u3YjTshGKL .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-10 rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-10 path,#mermaid-svg-R6u3O3u3YjTshGKL .section-10 circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-10 polygon,#mermaid-svg-R6u3O3u3YjTshGKL .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-10 text{fill:black;}#mermaid-svg-R6u3O3u3YjTshGKL .node-icon-10{font-size:40px;color:black;}#mermaid-svg-R6u3O3u3YjTshGKL .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .edge-depth-10{stroke-width:-16;}#mermaid-svg-R6u3O3u3YjTshGKL .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled,#mermaid-svg-R6u3O3u3YjTshGKL .disabled circle,#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:lightgray;}#mermaid-svg-R6u3O3u3YjTshGKL .disabled text{fill:#efefef;}#mermaid-svg-R6u3O3u3YjTshGKL .section-root rect,#mermaid-svg-R6u3O3u3YjTshGKL .section-root path,#mermaid-svg-R6u3O3u3YjTshGKL .section-root circle,#mermaid-svg-R6u3O3u3YjTshGKL .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-R6u3O3u3YjTshGKL .section-root text{fill:#ffffff;}#mermaid-svg-R6u3O3u3YjTshGKL .section-root span{color:#ffffff;}#mermaid-svg-R6u3O3u3YjTshGKL .section-2 span{color:#ffffff;}#mermaid-svg-R6u3O3u3YjTshGKL .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-R6u3O3u3YjTshGKL .edge{fill:none;}#mermaid-svg-R6u3O3u3YjTshGKL .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-R6u3O3u3YjTshGKL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} OpenClaw Gateway
消息平台
WhatsApp
Telegram
Discord
Slack
Signal
iMessage
Microsoft Teams
WeChat / QQ
Matrix / IRC
LINE / Feishu
还有 10 余个
伴侣应用
macOS 菜单栏
iOS Node
Android Node
Windows Hub
特殊能力
Voice Wake(macOS/iOS)
Talk Mode(Android,连续语音)
Live Canvas(A2UI)
Web Chat
Hermes 支持 Telegram、Discord、Slack、WhatsApp、Signal 等,但渠道广度和多平台伴侣应用是 OpenClaw 的核心护城河。
二十、架构定位重新校准
基于源码的真实结论:
#mermaid-svg-srnKY48xFfXQDfDI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-srnKY48xFfXQDfDI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-srnKY48xFfXQDfDI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-srnKY48xFfXQDfDI .error-icon{fill:#552222;}#mermaid-svg-srnKY48xFfXQDfDI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-srnKY48xFfXQDfDI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-srnKY48xFfXQDfDI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-srnKY48xFfXQDfDI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-srnKY48xFfXQDfDI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-srnKY48xFfXQDfDI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-srnKY48xFfXQDfDI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-srnKY48xFfXQDfDI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-srnKY48xFfXQDfDI .marker.cross{stroke:#333333;}#mermaid-svg-srnKY48xFfXQDfDI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-srnKY48xFfXQDfDI p{margin:0;}#mermaid-svg-srnKY48xFfXQDfDI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-srnKY48xFfXQDfDI .cluster-label text{fill:#333;}#mermaid-svg-srnKY48xFfXQDfDI .cluster-label span{color:#333;}#mermaid-svg-srnKY48xFfXQDfDI .cluster-label span p{background-color:transparent;}#mermaid-svg-srnKY48xFfXQDfDI .label text,#mermaid-svg-srnKY48xFfXQDfDI span{fill:#333;color:#333;}#mermaid-svg-srnKY48xFfXQDfDI .node rect,#mermaid-svg-srnKY48xFfXQDfDI .node circle,#mermaid-svg-srnKY48xFfXQDfDI .node ellipse,#mermaid-svg-srnKY48xFfXQDfDI .node polygon,#mermaid-svg-srnKY48xFfXQDfDI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-srnKY48xFfXQDfDI .rough-node .label text,#mermaid-svg-srnKY48xFfXQDfDI .node .label text,#mermaid-svg-srnKY48xFfXQDfDI .image-shape .label,#mermaid-svg-srnKY48xFfXQDfDI .icon-shape .label{text-anchor:middle;}#mermaid-svg-srnKY48xFfXQDfDI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-srnKY48xFfXQDfDI .rough-node .label,#mermaid-svg-srnKY48xFfXQDfDI .node .label,#mermaid-svg-srnKY48xFfXQDfDI .image-shape .label,#mermaid-svg-srnKY48xFfXQDfDI .icon-shape .label{text-align:center;}#mermaid-svg-srnKY48xFfXQDfDI .node.clickable{cursor:pointer;}#mermaid-svg-srnKY48xFfXQDfDI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-srnKY48xFfXQDfDI .arrowheadPath{fill:#333333;}#mermaid-svg-srnKY48xFfXQDfDI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-srnKY48xFfXQDfDI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-srnKY48xFfXQDfDI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-srnKY48xFfXQDfDI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-srnKY48xFfXQDfDI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-srnKY48xFfXQDfDI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-srnKY48xFfXQDfDI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-srnKY48xFfXQDfDI .cluster text{fill:#333;}#mermaid-svg-srnKY48xFfXQDfDI .cluster span{color:#333;}#mermaid-svg-srnKY48xFfXQDfDI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-srnKY48xFfXQDfDI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-srnKY48xFfXQDfDI rect.text{fill:none;stroke-width:0;}#mermaid-svg-srnKY48xFfXQDfDI .icon-shape,#mermaid-svg-srnKY48xFfXQDfDI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-srnKY48xFfXQDfDI .icon-shape p,#mermaid-svg-srnKY48xFfXQDfDI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-srnKY48xFfXQDfDI .icon-shape .label rect,#mermaid-svg-srnKY48xFfXQDfDI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-srnKY48xFfXQDfDI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-srnKY48xFfXQDfDI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-srnKY48xFfXQDfDI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 各自核心优势
OpenClaw 优势:
多渠道接入广度
Runtime 生产稳定性
Hook 可拦截扩展
社区规模
Hermes 优势:
跨 session 持久记忆
闭环技能自进化
多 Provider 统一抽象
Agent Tree 子任务
真实的关系(基于源码)
Hermes 填补 OpenClaw 的记忆短板
hermes claw migrate 内置迁移工具
OpenClaw
2025-11 起源
TypeScript / 消息平台优先
Gateway + 多渠道 + Runtime
开源社区驱动
Hermes
2026-02 发布
Python / 终端 + 记忆优先
闭环学习 + Agent 能力
Nous Research 主导
二十一、核心指标真实速查表
| 维度 | Hermes | OpenClaw |
|---|---|---|
| 起源时间 | 2026-02 | 2025-11(as Clawdbot) |
| 关系 | 在 OpenClaw 基础上发展,内置迁移工具 | 原版,更早 |
| 主语言 | Python 83% + TypeScript 13% | TypeScript(Node.js 22+) |
| 核心入口 | run_agent.py: AIAgent(6,933 行) |
pi-embedded-runner/run.ts: runEmbeddedPiAgent |
| Agent Loop | 同步 while + _interruptible_api_call |
异步事件流(pi-agent-core) |
| Loop 结构 | Agent 直连 LLM,while 循环内聚 | Gateway 代理 LLM,事件驱动 |
| Post-Turn | ✅ 技能自动生成 + Memory Nudge | ❌ 直接结束,无「回头看」 |
| 工具并发 | _should_parallelize_tool_batch() + ThreadPool(max 8) |
事件化,异步原生 |
| 工具护栏 | ✅ 3 种 loop guardrail(exact_failure / same_tool / no_progress) | ❌ 无 |
| 迭代预算 | ✅ 90 次软限制 + refund 机制 | ❌ 仅硬超时(600s 默认) |
| 上下文文件扫描 | ✅ 注入检测 + HERMES.md 发现 | ❌ 无 |
| 模型探测 | ✅ 阶梯式上下文探测 + 30+ Provider 自动推断 | pi-ai 层处理 |
| Prompt 组装 | 砖块式 + 按模型品牌定制指导 | 分层模板注入 |
| Agent Tree | ✅ 原生,delegate_task() 内置 |
主动拒绝(VISION.md) |
| Fallback | ✅ 内置 | ✅ runWithModelFallback() |
| 压缩层数 | 双压缩层(Agent 50% + Gateway 85%) | 单层触发型 |
| 压缩格式 | 8 字段结构化摘要 + 迭代合并 | 通用摘要 |
| 上下文压缩引擎 | 可插拔(ContextEngine ABC) |
内置 |
| 扩展机制 | Callback(通知型) | Hook + Plugin(可拦截型,可终止) |
| 记忆系统 | 🔥 核心优势,跨 session + 自进化 SKILL + 8 个外部 Provider | 需手动配置 |
| 跨会话搜索 | session_search(SQLite FTS5 全文检索,搜索原始消息) |
memory_search(语义搜索,搜索记忆摘要) |
| 多渠道 | Telegram/Discord/Slack 等主流 | 🔥 20+ 渠道 + 全平台伴侣应用 |
| Run 生命周期 | 阻塞式返回值 | Queue / Abort / Waiter / Model Switch |
| 定位 | 个人助手 + AI 研究工具(Nous Research) | 个人助手 + 消息平台中枢(社区项目) |
结语
OpenClaw 解决:怎么接入所有消息平台,怎么稳定运行。
Hermes 解决:怎么让 Agent 记住你,怎么让 Agent 变得更聪明。
两者不是同一赛道的竞争对手,而是从 OpenClaw 这个共同根基上长出的两个方向。Hermes 是在承认「OpenClaw 在渠道和 Runtime 上已经很好了」之后,专门去补它记忆能力不足的缺口。
理解这个关系,比任何架构框架都更接近事实。
附录:论断溯源索引
本文基于对以下源文件的直接读取:
Hermes: run_agent.py(6,933行)、agent/tool_guardrails.py(500行)、`agent/background_review.py`(31KB)、agent/prompt_builder.py(19KB)、`agent/context_compressor.py`(22KB)、agent/model_metadata.py(21KB)、`agent/display.py`(20KB)、agent/iteration_budget.py(3.4KB)、`agent/tool_dispatch_helpers.py`(17KB)、agent/agent_runtime_helpers.py(110KB)、`agent/agent_init.py`(88KB)
OpenClaw: src/agents/pi-embedded-runner/run.ts、src/auto-reply/reply/agent-runner.ts、VISION.md(已验证)、AGENTS.md(已验证)、src/agents/embedded-agent-runner/runs.ts
以下是本文关键论断的验证状态,顺便作做个记录感兴趣的筒子们可以自己对照着看一下:
| # | 论断 | 验证状态 | 源文件 |
|---|---|---|---|
| 1 | _NEVER_PARALLEL_TOOLS = frozenset({"clarify"}) |
✅ 已验证 | agent/tool_dispatch_helpers.py:59 |
| 2 | _PARALLEL_SAFE_TOOLS 含 ha_get_state, skills_list 等 11 个 |
✅ 已验证 | agent/tool_dispatch_helpers.py:61-72 |
| 3 | _PATH_SCOPED_TOOLS = frozenset({"read_file", "write_file", "patch"}) |
✅ 已验证 | agent/tool_dispatch_helpers.py:75 |
| 4 | _should_parallelize_tool_batch() 逻辑(路径重叠检测等) |
✅ 已验证 | agent/tool_dispatch_helpers.py:132-177 |
| 5 | _is_destructive_command() --- 终端命令破坏性检测 |
✅ 已验证 | agent/tool_dispatch_helpers.py:78-128 |
| 6 | IDEMPOTENT_TOOL_NAMES / MUTATING_TOOL_NAMES 完整名单 |
✅ 已验证 | agent/tool_guardrails.py:22-59 |
| 7 | ToolCallGuardrailConfig 默认阈值(2/5, 3/8, 2/5) |
✅ 已验证 | agent/tool_guardrails.py:63-97 |
| 8 | Guardrail 决策级别:ALLOW / WARN / BLOCK / HALT | ✅ 已验证 | agent/tool_guardrails.py:149-162 |
| 9 | Warnings 默认开启 + Hard Stops 需显式开启 | ✅ 已验证 | agent/tool_guardrails.py:80-82 |
| 10 | IterationBudget 类:consume(), refund(), 线程安全 |
✅ 已验证 | agent/iteration_budget.py:26-61 |
| 11 | max_iterations 默认 90(agent_init.py) |
✅ 已验证 | agent/agent_init.py:228 |
| 12 | 子 Agent 默认 50 次(来自 delegation.max_iterations) |
✅ 已验证 | agent/iteration_budget.py:17-19 |
| 13 | BackgroundReviewer 后台线程 + fork AIAgent |
✅ 已验证 | agent/background_review.py:1-26 |
| 14 | _MEMORY_REVIEW_PROMPT / _SKILL_REVIEW_PROMPT 完整内容 |
✅ 已验证 | agent/background_review.py:38-178 |
| 15 | _scan_context_content() --- 上下文文件注入检测 |
✅ 已验证 | agent/prompt_builder.py |
| 16 | _URL_TO_PROVIDER --- 30+ Provider 自动推断 |
✅ 已验证 | agent/model_metadata.py |
| 17 | CONTEXT_PROBE_TIERS 阶梯探测 + MINIMUM_CONTEXT_LENGTH = 64000 |
✅ 已验证 | agent/model_metadata.py |
| 18 | TOOL_USE_ENFORCEMENT_MODELS 名单 |
✅ 已验证 | agent/prompt_builder.py |
| 19 | VISION.md "What We Will Not Merge" --- Agent Tree 拒绝 | ✅ 已验证 | OpenClaw VISION.md |
| 20 | AGENTS.md Hook 决策规则({ block: true } 终态等) |
✅ 已验证 | OpenClaw AGENTS.md |
| 21 | execution_context 区分 foreground/background/trajectory |
✅ 已验证 | agent/background_review.py:185-201 |
| 22 | api_mode 4 级自动检测(chat/codex/anthropic/bedrock) | ✅ 已验证 | agent/agent_init.py |
| 23 | IterationBudget 父子共享 vs 独立(代码内矛盾) | ✅ 矛盾已确认 | agent_init.py:251:"Shared --- consumed across parent + all subagents";iteration_budget.py:15-20:"Each subagent gets an independent budget" |
| 24 | _interruptible_api_call() 函数 |
✅ 已验证 | run_agent.py:3968(thin forwarder)→ 实现在 agent/chat_completion_helpers.py:125,后台线程 + 请求级取消标志 + stale-call 检测 |
| 25 | _MAX_TOOL_WORKERS = 8 |
✅ 已验证 | run_agent.py 模块级常量(位于 _openrouter_prewarm_done 上方) |
| 26 | _SafeWriter 类 |
✅ 已验证 | agent/process_bootstrap.py:62-103,包装 stdout/stderr 静默捕获 broken pipe 的 OSError/ValueError |
读者复核指南:
- 全部 26 项关键论断均已完成源码交叉验证,标记 ✅ 的可直接引用对应文件行号
- 本文于 2026-06-10 完成验证;两个项目的仓库持续更新中,关心的童鞋请以最新源码为准
--
本文在发布前经过了系统性的源码交叉验证。如果你发现错误,请在评论区给我留言或者私信俺。