深入源码:Hermes Agent 如何实现 Self-Improving
深入源码:Hermes Agent 如何实现 "Self-Improving"
来源: 阿里云开发者 - 白家杰 原文: https://mp.weixin.qq.com/s/Qi68ptxQRyiA932JU49SYQ 仓库: github.com/NousResearch/hermes-agent
核心观点
Hermes Agent 与 OpenClaw 的根本区别不是功能多少,而是设计哲学的分野:OpenClaw 的 Skill 靠人喂(手写 Markdown),Hermes 的 Skill 自己长(Agent 自动创建+自动修补)。三个子系统(Memory + Skill + Nudge Engine)构成自学习闭环,用得越久能力越强。
第一章:Memory — 越用越懂你
两个文件,全部认知
Memory 设计极其克制——两个纯文本文件,用 § 分隔条目:
硬上限设计:MEMORY 限 2200 chars,USER 限 1375 chars。容量有限迫使 Agent 挑重要的记,过时的自然被挤掉。对比 OpenClaw 的 MEMORY.md 是纯追加模式,用几个月就膨胀成几万行的怪兽文件。
核心实现:
超限处理:强迫自我反思
超限后 add 直接失败,返回当前所有条目让模型自己决定删/合并:
错误信息中 "Replace or remove existing entries first" 引导模型走向 replace 和 remove 操作。模型不是被动执行淘汰规则,而是主动做信息整理——这本身就是一次自我反思。
冻结快照机制
每次会话启动时冻结一份快照,之后系统提示词用的都是这份快照:
为什么冻结而非实时更新? 系统提示词会话内不变就能共享前缀缓存(KV Cache),省掉重复计费。新写入只改磁盘,下一个会话才刷新。
提示词引导:声明式事实 vs 命令式指令
Memory 要求写成声明式事实("User prefers concise responses"),而非命令式指令("Always respond concisely")。前者是偏好,可被当前上下文覆盖;后者是死命令,限制灵活性。
Tool Schema 还规定 "If you've discovered a new way to do something, save it as a skill." —— Memory 不存操作步骤,操作步骤归 Skill 管。
第二章:Skill — 把做过的事变成会做的事
Skill 结构
每个 Skill 是一个目录,核心是 SKILL.md:
典型 SKILL.md 包含:When to use(触发条件)、Steps(执行步骤)、Pitfalls(踩坑记录)。Pitfalls 不是预先写好的,而是 Agent 踩坑后追加的。
自动创建触发
Agent 不需要用户说"帮我创建 Skill"。驱动力来自 tool schema:
创建门槛:工具调用超过 5 次(简单任务不记)、踩过坑再修复的经验才有价值、用户纠正过的做法要铭记。
自我修补(patch)
执行 Skill 时发现新坑,完成后回头做精确局部修补:
用 fuzzy_find_and_replace 容忍格式差异,每次修改后跑 _security_scan_skill(),不通过自动回滚。
渐进式加载
Skill 多了不能全塞进系统提示词。Hermes 默认只放轻量索引(名字+一句话描述),Agent 判断相关时才通过 skill_view 加载完整内容。先看目录再翻全文,按需加载。
对比 OpenClaw 的"重型背包"模式:每次会话把 SOUL.md、IDENTITY.md 和各种设定一股脑塞进上下文,设定越多背包越沉,Token 浪费严重,模型注意力被稀释。
第三章:Nudge Engine — 谁来提醒 Agent "该学习了"
Memory 和 Skill 都是存储系统,写入需要有人触发。Nudge Engine 就是这个触发器——运行时维护两个计数器,定时提醒 Agent 该停下来想想。
两个计数器,两种粒度:Memory 的信息来自用户输入,按回合计;Skill 的经验来自工具使用过程,按迭代计。计数器到阈值就触发审查,Agent 主动调用了 memory 或 skill_manage 则重置。
后台 fork Agent:静默审查
Nudge 触发后不在主对话中插话——在后台 fork 一个独立 Agent 实例,拿着主对话的快照做审查:
- 输出重定向到
/dev/null,用户完全无感知 - 最多 8 次工具调用,不会无限消耗 API
- Review Agent 自身的 nudge 被禁用,避免无限递归
- 和主 Agent 共享同一份 Memory,写入直接生效
"干活"和"反思"拆成两个实例,互不干扰。 审查在响应发送给用户之后才触发。
Review Agent 靠两套审查提示词:Memory Review 关注用户偏好和个人信息,Skill Review 关注非平凡的解题过程。每个 prompt 都以 "If nothing is worth saving, just say 'Nothing to save.' and stop." 收尾——防止 Review Agent 每次都往里塞东西"交差"。
第四章:完整案例 — 三次会话从"不会"到"精通"
K8s 部署场景的三次会话演进:
| 维度 | 会话 1(冷启动) | 会话 2(Skill 复用) | 会话 3(全协同) |
|---|---|---|---|
| 工具调用 | 12 次 | 9 次 | 6 次 |
| 错误数 | 2 | 1 | 0 |
| Memory | 无 | 触发写入 | 系统提示词注入 |
| Skill | 触发创建 | 复用 + 自我修补 | 复用已修补版本 |
- 会话 1:冷启动,靠基座知识摸索,12 次调用踩两个坑。Review Agent 自动创建 Skill
- 会话 2:加载 Skill 后照步骤做,已知坑被绕过,遇到 Django 新坑。Review Agent 写入用户画像 + 记住 registry 地址 + patch Skill
- 会话 3:Agent 已知用户身份、环境信息、所有坑点,6 次调用零错误
第五章:安全机制
Agent 能往自己"脑子"里写东西,攻击面随之增大。两层防护:
第一层:Memory 内容扫描 — 因为 Memory 最终注入系统提示词,如果被诱导记住 "ignore all previous instructions",下次会话就被劫持
第二层:Skill 安全扫描 — 自创和 Hub 安装的 Skill 走同一套扫描,不通过就回滚
第六章:设计取舍一览
| 设计决策 | 表面效果 | 背后考量 |
|---|---|---|
| Memory 限 2200 chars | 迫使 Agent 挑重要的记 | 低质量 Memory 注入系统提示词 = 每次 API 调用都带噪声 |
| 声明式事实 vs 操作步骤分离 | Memory 存事实,Skill 存步骤 | 两者更新频率、触发条件、安全风险完全不同 |
| 冻结快照模式 | 系统提示词会话内不变 | 保护前缀缓存,避免每轮 API 调用重新计费 |
| 后台 fork 审查 | 用户感知不到 review 过程 | 自省不应占用用户任务的 attention budget |
| Nudge 计数器可配置 | 默认 10 | 太频繁浪费 API 成本,太稀疏错过学习机会 |
| patch 优先于全量重写 | 局部修复 Skill | 保留已验证的稳定部分,只改需要改的 |
| 安全扫描 + 自动回滚 | 拒绝恶意写入 | Memory/Skill 最终进入系统提示词,是一等安全边界 |
第七章:RDSHermes — 从开发者工具到团队产品
开源 Hermes 仍是偏开发者的工具。RDSHermes 补齐四件事:
- 数据库安全纳管:多引擎一键接入,可设只读模式
- 身份认证托管:AK/SK 加密托管,网关代理鉴权,密钥不落盘
- 内置数据库专业技能:Skill Hub 预装智能巡检/慢 SQL 诊断/索引优化,解决冷启动
- 全链路监控审计:写操作需确认,会话可追溯,Token 消耗可监控
团队场景下 Skill 存储从本地磁盘搬到云端——一个 DBA 踩过的坑,团队里所有人的 Agent 都能绕过。自我进化从单点变为组织级。
关键引用
"OpenClaw 的 Skill 是手写的配置文件,用了一年还是那份手写的配置文件;Hermes 的 Skill 是越用越厚的经验资产——每一次踩坑都在加固护城河。"
"真正的护城河是 Agent 在工作中积累的领域知识。"
"Skills that aren't maintained become liabilities."
关联页面
- Hermes Agent — 核心实体
- Harness Engineering — Hermes 是 Harness Engineering 的自进化实现
- Claude Code vs Hermes Harness — 与 Claude Code Harness 的对比
- Skill — Hermes 的 Skill 自动创建+修补是核心差异
- Agent — Agent 自学习闭环
- Multi-Agent — Nudge Engine 的后台 fork 是一种多 Agent 模式
- OpenClaw — 对比参照
- KV Cache — 冻结快照保护前缀缓存的技术基础