全文约 1766 字,读完大约 3 分钟。
Hermes 源码解读九:Skill 与 Memory,Agent 如何沉淀经验
很多 Agent 用起来像一次性工具。
这一轮帮你改代码。
下一轮帮你写文章。
再下一轮又像失忆一样,重新问你项目规则、写作偏好、常用命令、发布流程。
如果 Agent 不能沉淀经验,它就很难变成长期工作流。
Hermes 在这块有两条线:
Skill
→ 沉淀可复用工作流
Memory
→ 沉淀长期偏好和跨会话事实这篇看 agent/skill_utils.py、tools/skills_tool.py、agent/memory_manager.py、agent/memory_provider.py 和 prompt 组装里的 skills/memory 注入。
我的核心判断是:
Skill 解决“下次怎么做”,Memory 解决“下次还记得什么”。这两个东西不能混在一起。
Skill 不是普通文档,是可加载的操作包

Hermes 的 skill 通常围绕 SKILL.md。
它可以有 frontmatter、description、platform requirements、linked files、references、templates、scripts、assets。
模型默认不会一次性加载所有 skill 全文。
它先在 system prompt 里看到 skills index,需要时再通过 skill_view 加载具体内容。
这是一种渐进式披露。
原因很简单:skill 可能很多,全部塞进 system prompt 会撑爆上下文,也会干扰模型判断。
所以 Hermes 把 skill 分成两层:
| 层 | 模型看到什么 |
|---|---|
| Skills index | 名称、描述、何时使用 |
skill_view | 具体 SKILL.md 和 linked files |
这和工具系统里的 tool_search 思路很像。
能力太多时,不要全部暴露细节。
先让模型知道“有哪些能力”,再按任务加载。
Skill 扫描也有治理逻辑
agent/skill_utils.py 里有很多看似琐碎的逻辑。
比如:
- • 排除 support path;
- • 识别
references/、templates/、assets/、scripts/; - • 处理 platform/environment 兼容;
- • 读取 disabled skills;
- • 支持 external skills dirs;
- • 检查 skill name collision;
- • 解析 skill config vars;
- • 区分 plugin-provided skills 和本地 skills。
这些都说明 Hermes 没把 skill 当成“随便读一个 Markdown”。
Skill 一旦进入运行时,就会影响模型行为。
所以要回答:
这个 skill 是否应该显示?
是否适合当前平台?
是否被用户禁用?
是否和其他 skill 重名?
是否需要额外配置?
是否来自可信目录?
linked file 是否越权访问?这和后端服务加载配置、插件、策略文件是同一个问题。
可复用能力越强,加载边界越要清楚。
Skill 的价值在于工作流复用
对 Agent 工程来说,Skill 最有价值的地方不是“给模型更多知识”。
知识可以检索,文档可以阅读。
Skill 更像一个操作 SOP。
比如:
- • 做代码 review 时先看哪些文件;
- • 写公众号时要按什么质量门禁;
- • 发布前要跑哪些 dry-run;
- • 某个项目的部署步骤;
- • 某类图片生成要用什么脚本;
- • 某个业务排障要收集哪些日志。
这些内容如果每次都靠用户重新讲,Agent 就永远只是临时助手。
沉淀成 Skill 后,下一次同类任务可以直接复用。
我的理解是:
Skill 是把“人教过 Agent 的流程”变成可重复调用的资产。
Memory 负责长期事实,但要避免吃进 Skill 噪音

Memory 是另一回事。
Hermes 有 MemoryManager,也有 MemoryProvider 抽象,用来接 Honcho、OpenViking、Mem0、Holographic 等外部 memory backend。
MemoryProvider 的接口大概包含:
handle_tool_call()
on_session_end(messages)这说明 memory backend 不只是一个文件。
它可以暴露工具给模型,也可以在 session 结束时做信息提取和写入。
但这里有一个细节很值得看:MemoryManager 会 strip skill scaffolding。
也就是说,当用户通过 skill 或 bundle 执行任务时,Hermes 不希望把整个 skill body 当成用户长期记忆写进去。
它会尝试提取真正的 user instruction。
为什么?
因为 Skill 是工作流说明,Memory 是长期事实。
如果把 skill 内容全写进 memory,长期记忆会被操作手册污染。
以后模型检索 memory 时,可能以为这些大段流程都是用户个人偏好或事实。
这就是 Skill 和 Memory 必须分开的原因。
Prompt 里也区分 Skill 和 Memory
回到 Prompt 组装,Hermes 把 skills prompt 放在 stable tier,把 memory snapshot 放在 volatile tier。
这不是随便放的。
Skill 描述更像系统能力索引,相对稳定。
Memory 更像用户和会话状态快照,会变化。
它们都可能影响模型行为,但语义不同:
| 类型 | 问题 |
|---|---|
| Skill | 遇到这类任务时,我应该按什么流程做? |
| Memory | 关于用户、环境、偏好,我长期记住了什么? |
很多 Agent 项目会把这两类都叫“上下文”。
但上下文这个词太大。
一旦不区分,就会出现几个问题:
- • 把长期偏好写成操作流程;
- • 把操作流程当用户事实;
- • 把临时检索结果写进长期记忆;
- • 把项目规则塞进全局 memory;
- • memory 越写越脏,skill 越写越像百科。
Hermes 的源码至少在努力把边界拉开。
这对个人 AI 工作流有什么启发
如果你要做自己的 Agent 系统,我建议用一句话区分 Skill 和 Memory:
Skill:以后遇到这类任务怎么做
Memory:以后遇到这个用户/环境要记得什么举几个例子:
| 内容 | 更适合放哪里 |
|---|---|
| “公众号最终稿不能混入标题备选” | Skill / 项目规则 |
| “用户偏好中文输出” | Memory 或项目规则 |
| “这个项目发布公众号用 09_wechat_publish” | Skill / 项目规则 |
| “用户的账号叫 Jerry聊AI” | Memory / 项目定位 |
| “写 CSDN 要有代码、配置、日志证据” | Skill |
| “本机 Python 缺某个依赖” | Memory,且要谨慎保留 |
我的判断是:
Agent 的长期能力,不是记住越多越好,而是知道什么该沉淀成流程,什么该沉淀成事实。
Hermes 的 Skill 和 Memory 设计还可以继续演进,但这个分层非常值得借鉴。
尤其是个人 AI 工作流。
你不可能每次都重新教 Agent 怎么写文章、怎么跑发布、怎么检查项目、怎么做源码解读。
这些应该变成 Skill。
你也不希望 Agent 每次都忘记你的账号定位、语言偏好、常用项目路径、稳定工具链。
这些应该进入 Memory 或项目级策略。
但两者不要乱放。
当 Skill 和 Memory 都有了以后,定时任务就不该只是“到点执行脚本”,而可以变成“到点启动一个带技能、带 provider、带 delivery 的 Agent 任务”。
这也是 Hermes 很有意思的一层。
如果你正在搭自己的 AI 工作流系统,建议认真区分这两类资产。否则长期记忆很快会变成垃圾堆,技能库也会变成资料仓库。

夜雨聆风