乐于分享
好东西不私藏

Hermes 源码解读九:Skill 与 Memory,Agent 如何沉淀经验

Hermes 源码解读九:Skill 与 Memory,Agent 如何沉淀经验

全文约 1766 字,读完大约 3 分钟。

Hermes 源码解读九:Skill 与 Memory,Agent 如何沉淀经验

很多 Agent 用起来像一次性工具。

这一轮帮你改代码。

下一轮帮你写文章。

再下一轮又像失忆一样,重新问你项目规则、写作偏好、常用命令、发布流程。

如果 Agent 不能沉淀经验,它就很难变成长期工作流。

Hermes 在这块有两条线:

Skill
  → 沉淀可复用工作流

Memory
  → 沉淀长期偏好和跨会话事实

这篇看 agent/skill_utils.pytools/skills_tool.pyagent/memory_manager.pyagent/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 工作流系统,建议认真区分这两类资产。否则长期记忆很快会变成垃圾堆,技能库也会变成资料仓库。