拆开 Hermes 的"自我进化":不是黑魔法,是个会反思的夜班值班员
源码版本:hermes-agent v0.10.0 读源码日期:2026-04-19
最近在玩 Nous Research 开源的 Hermes Agent。它的卖点是「自我进化」——用得越多越聪明,会自己创建技能、自己修改技能、不用你手写配置。
听着挺玄。我把源码翻了一遍,发现这事既比我想象的简单,又比我想象的有意思。
先消除一个误解
很多人(包括我)一开始以为「自我进化」是某种神秘的 ML 训练循环——agent 偷偷在后台 fine-tune 模型权重,越用越准。
完全不是。
Hermes 的自我进化和模型权重无关。它进化的是一组 markdown 文件——存在 ~/.hermes/skills/ 目录下,每个 .md 都是 agent 给自己写的"小抄",告诉自己"以后遇到 X 类任务,按这几步做"。
模型本身没变。变的是模型每次干活时被塞进 prompt 的那本"小抄册"。
这个思路本身不新——Mitchell Hashimoto 一年前就写过:他用 Claude Code 时,每次 AI 犯错就在 CLAUDE.md 里加一条规则,几周下来 CLAUDE.md 变成了一份非常详细的项目规范。Hermes 做的事情本质一样,只是把"加规则"这件事自动化了。
你能想到的问题
如果让你来设计一个"自动加规则"的系统,你大概会想:
- 谁来决定加哪条规则? 让 LLM 自己想?
- 什么时候触发? 每次对话结束都跑一遍?太贵了
- 怎么防止它瞎加? 如果它写的规则是错的,越用越糟咋办
我读 Hermes 源码时,发现它对这三个问题都给了挺工程化的答案。
答案是什么
Hermes 的自我进化由三层机制叠加组成。我用一个类比解释完整张图:
想象你雇了一个超能干的助理。除了完成你日常交代的活,他下班后还兼职做一件事——复盘。每天等你下线了,他坐下来翻当天的工作记录,决定要不要把某个解法整理成 SOP 加进自己的工作手册。
这个比喻里:
- 白天的助理 = 主 LLM
- 下班后复盘的助理 = 后台 fork 出来的第二个 LLM
- 工作手册 =
~/.hermes/skills/下的 markdown 文件 - "下班"信号 = 累积满 10 次工具调用
下面把三层拆开讲。
第 1 层:常驻提醒("白天助理记着这件事")
每次 Hermes 处理你的请求时,它的 system prompt 里都被注入了这么一段(在 agent/prompt_builder.py 里写死):
完成复杂任务后(用了 5+ 工具),或修复了一个棘手 bug,或发现了一个非平凡的工作流——用 skill_manage 把它存成 skill,方便下次复用。
用某个 skill 时发现它过时、不全、或写错了——立刻用 skill_manage(action='patch') 修它,不要等用户来要求。没人维护的 skill 会变成包袱。
简单粗暴:告诉 LLM "你应该这么做"。
LLM 在处理任务时,理论上看到这段话,干完活就会自己想起来"啊我该建个 skill",然后调用 skill_manage 工具。
这一层的问题:LLM 经常忙忘了。它在专注处理你的任务,5 步、10 步、20 步下来,注意力都在解决问题上,根本想不起来要反思。这就是为什么需要第 2 层。
第 2 层:周期性 nudge("工时打卡")
源码里有个计数器:
self._skill_nudge_interval = 10 # 每 10 次工具调用触发一次
self._iters_since_skill = 0 # 自上次建/改 skill 以来用了几次工具
每次 LLM 调用任何工具(搜索、读文件、跑命令…),计数器 +1。一旦它主动调了 skill_manage,计数器清零。
到 10 次还没主动调?强制触发一次"该不该建 skill 的审视"。
这个设计有两个细节我觉得很妙:
1. 触发单位不是时间,是工具调用次数。
如果用 cron 定时(比如"每 30 分钟反思一次"),那你聊天闲扯也会触发反思——浪费 token、浪费钱。
用工具调用次数计算意味着:只有 agent 实际在干活时才积累触发条件。和你聊家常不算工作,也就不需要反思。
2. 主动调用会重置计数器。
如果 LLM 自己已经在第 1 层的提醒下主动建了 skill,计数器归零,第 2 层就不用再多嘴。只在 LLM 自己忘了时才介入。这是一种很优雅的"兜底"——能自驱就自驱,自驱失败才强制。
第 3 层:后台 review agent("夜班值班员")
这是最有意思的一层。
当第 2 层的 nudge 触发时,Hermes 做的不是"在主对话里插一句话提醒 LLM"——它做的是重新创建一个 LLM agent 实例,专门跑反思。
源码长这样(简化版):
def _spawn_background_review():
# fork 一个新 agent,同模型同配置
review_agent = AIAgent(
model=self.model,
max_iterations=8, # 给 8 步预算就够
quiet_mode=True, # 不打扰用户
)
# 关键:禁用嵌套 nudge,防止套娃
review_agent._skill_nudge_interval = 0
# 喂它专门的 review prompt + 完整对话历史
review_agent.run_conversation(
user_message=_SKILL_REVIEW_PROMPT,
conversation_history=messages_snapshot,
)
翻译成人话:
主对话 LLM 给你回完话之后,Hermes 默默 fork 一个第二个 LLM agent。这个 agent 唯一的工作是:
"看看这段对话,决定要不要建/改 skill。"
它读完整对话历史 + 一段固定的 review prompt,调用 skill_manage 工具创建或修改 skill,然后退出。8 步预算用完就停。
整个过程:
- 完全静默:stdout/stderr 都重定向到 /dev/null,你看不到它在跑
- 零延迟:在你已经看到主 agent 的回复之后才启动,你感知不到
- 独立上下文:它有自己的对话窗口,不污染主 agent
- 递归安全:它自己的 nudge 计数器关掉了,不会"反思 review 自己要不要建 skill"
这种设计在 LLM 圈有个名字叫 agent-as-judge——用一个 agent 当另一个 agent 的评估者/反思者。Anthropic 最近的研究里也越来越多看到这个模式。
为什么不让主 agent 自己反思?
这个问题我一开始想了半天。让主 agent 在回复用户后多说一句"我决定建一个 skill"不是更简单吗?
读完源码我意识到答案:注意力的问题。
LLM 处理一个长对话时,注意力是分布的。它在帮你 debug 一个 bug,前面 8 步都在读代码、改代码、跑测试,它的注意力锚定在问题本身。这时候让它"再多想一步去反思要不要建 skill"——质量会很差,因为它的整个 reasoning 链都在 bug 上。
而 fork 出来的 review agent 没有这个负担。它打开就看到一段已完成的对话,唯一的任务是反思。它的注意力是集中的、目标是单一的、reasoning 链是新的。
这有点像写完代码立刻自己 review vs 隔一天回头看自己的 PR——后者总能发现前者发现不了的问题。
安全网:skills_guard
有人会担心:万一 agent 自己写的 skill 是错的、有害的、甚至包含恶意指令呢?
Hermes 在 tools/skills_guard.py 里塞了一个安全扫描器:
Agent-created skills get the same scrutiny as community hub installs.
翻译:agent 自己写的 skill 和你从社区装的 skill 走完全一样的安全扫描。检查可疑命令、提示注入、敏感文件操作。扫描不通过就拒绝落地。
这是个挺重要的工程细节——它说明 Hermes 团队没有信任自己的 LLM。LLM 可能写出有问题的 skill,所以加了一道独立的检查。
完整时序图
把三层串起来:
[你说话]
↓
prefetch 历史记忆 → 拼进 prompt
↓
主 LLM 处理(多轮工具调用,每次 _iters_since_skill +1)
↓
[主 LLM 回复你] ← 你立即看到结果,零延迟
↓
sync 这一轮到 SQLite
↓
检查 _iters_since_skill >= 10?
├─ 否 → 结束本轮
└─ 是 → spawn 后台 review agent
↓
review agent 读完整对话
↓
它判断: 这次的解法值得固化吗?
之前用过的某个 skill 该 patch 吗?
↓
它 tool-call skill_manage.create/patch
↓
skills_guard 扫描 → 通过才写入 ~/.hermes/skills/
↓
返回一句汇总 ("Created: X" / "Updated: Y")
↓
主 agent 转告你
这个设计的代价
讲了这么多优点,必须也说局限。
1. 强依赖 LLM 质量。 Review agent 的判断质量直接决定 skill 库的质量。用 GPT-4o / Claude Sonnet 4 / Hermes 3 70B 跑,效果好;用 GPT-3.5 或者小模型跑,可能反思得很糟,建的 skill 全是噪声。
2. 钱。 每 10 次工具调用就跑一次 review agent,每次 8 步预算——意味着实际 token 消耗是不开自我进化时的 1.2-1.5 倍。重度使用一个月可能多花几十刀 API 费。
3. 没有遗忘机制。 Skill 只增不减。三个月前 review agent 总结的"经验"可能已经过时(比如某个 API 改版了),但没人告诉它"这条该删了"。需要你定期手动检查 ~/.hermes/skills/ 清理。
4. 反思质量取决于反馈清晰度。 如果你只是觉得"agent 这次回得不对"但没说哪里不对——review agent 复盘时只能猜,可能猜偏。你的反馈越具体,自我进化越准。
所以"自我进化"到底是什么
回到题目。读完源码我对"自我进化"有了更准确的理解:
它不是模型变聪明,是 prompt 上下文越来越精准。
每次 Hermes 处理任务,它的 system prompt 里塞着一份动态生长的 skill 索引——告诉自己"针对你这种用户,过去验证过这些方法管用"。这份索引由 review agent 每 10 次工具调用就检查一次该不该更新。
某种意义上,这是用工程手段模拟"经验"——人类的经验本质就是"过去做过的事在脑子里留下的程序性记忆"。Hermes 把这种"记忆"做成了可读的 markdown 文件 + 一个会自动更新这些文件的后台 agent。
没有黑魔法。全是可读的 markdown + 一个会反思的夜班值班员。
我喜欢这个设计的什么
最后说点感性的。
我喜欢 Hermes 的一点是:它没有把"自我进化"做成一个不可看的黑盒。所有 skill 都是 markdown 文件,存在你能直接 cat/edit 的目录下。Review agent 改了什么,diff 看得清清楚楚。你不喜欢某条规则?打开 markdown 删掉就行。
这种**"自动化但透明"**的态度,比那种"自动化且神秘"的产品更让我放心。
我也喜欢它对**"自驱失败才介入"**的设计哲学。第 1 层鼓励 LLM 自己想起来反思,第 2 层只在 LLM 忘了时才强制触发——这是对模型能力的尊重,而不是把所有事情都强制管控。
当然,Hermes 还是个 v0.10 阶段的项目,很多边界情况没处理好(最明显的就是没遗忘机制)。但**「让 agent 用第二个 agent 反思自己」这个核心思路**,我觉得会被越来越多 AI 工具借鉴。
毕竟,人都是在反思中成长的。AI 也一样。
本文基于 hermes-agent v0.10.0 源码(
agent/prompt_builder.py、run_agent.py、tools/skill_manager_tool.py、tools/skills_guard.py)。 项目地址:https://github.com/NousResearch/hermes-agent