Agent 的 Skill 自进化机制:它是如何自己长记性的

How LLM Agents Self-Improve Through Procedural Memory Evolution

昨天我用 Agent 处理一个棘手的部署任务。它第一次跑的时候踩了个坑——少了一步 docker login,推送镜像时报错了。Agent 发现问题,自己补上登录步骤,重试后跑通了。

但最让我惊讶的不是它跑通了,而是它默默更新了自己的操作手册

下一次我再让它做同样的任务时,它直接带上了 docker login,一步到位。

它自己"长记性"了。

这不是魔法,是 Hermes Agent 的 Skill 自进化机制。它把一次性的试错经验,固化成了可复用的程序化记忆。

记忆 vs 技能:两种不同的知识

在 Agent 系统中,记忆(Memory)和技能(Skills)是两种截然不同的存在。

Memory(声明式记忆) 是"我知道什么":

  • “我的博客在 ~/Projects/blog2
  • “用户喜欢中文写作”
  • “Qwen 有 1M 上下文窗口”

Skill(程序化记忆) 是"我会做什么":

  • “写博客的 5 步流程”
  • “遇到 permission denied 时先检查权限再重试”
  • “Rust 项目用 cargo build,不要用 make

Memory 是静态的,而 Skill 是活的。它会随着 Agent 的使用而生长、修补、进化。

技能是如何诞生的?(自动生成)

Skill 的创建不是预先写好所有可能用到的技能,而是按需生成

System Prompt 中有一段 SKILLS_GUIDANCE 明确指导 Agent 何时创建技能:

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.

触发条件总结为三点

  1. 复杂任务成功(5+ 次工具调用)——说明这是一个值得沉淀的流程。
  2. 克服了一个棘手错误——这个排错过程极其宝贵。
  3. 发现了非平凡的工作流——即使没有错误,如果发现了一条更优路径,也值得记录。

例如,Agent 成功写了一篇复杂的博客文章后,可能会调用:

skill_manage(
    action='create',
    name='hugo-blog-post',
    content='...',
    category='writing'
)
# generated by hugo AI

这样,下次它再写博客时,直接加载这个 skill,按标准流程执行,不需要从头摸索。

技能是如何进化的?(热修补)

这是整个机制最精彩的部分——发现即修补(Patch on Discovery)

很多 Agent 系统有 skill,但它们是静态的。如果 skill 过时了,agent 还是会傻傻地照着做,或者默默忍受错误。

Hermes 的设计哲学是:“Skills that aren’t maintained become liabilities”(不维护的技能比没有更糟)。

当 Agent 使用一个 skill 时,如果发现:

  • 步骤报错了
  • 缺少了关键信息
  • 有更好的实现方式

它会 立即 调用 patch 修正,不等待用户反馈,不等待定期检查:

skill_manage(
    action='patch',
    name='deploy-api',
    old_string='docker push $IMAGE',
    new_string='docker login  # 必须先登录\n'
               'docker push $IMAGE',
    file_path=None  # 直接修补 SKILL.md
)
# generated by hugo AI

模糊匹配:修补成功率的关键

LLM 不擅长精确字符串匹配。如果旧文本里有几个空格的变化,传统的 str.replace 就会失败。

_patch_skill 内部使用了模糊匹配引擎(Fuzzy Matching),能容忍:

  • 空白字符差异(空格 vs 制表符)
  • 缩进层级变化
  • 转义字符差异

这意味着 Agent 不需要精确复制粘贴旧文本,只要提供"大致内容",系统就能找到并替换。这大大提高了自我修正的成功率。

技能是如何巩固的?(后台审查)

除了 Agent 在对话中的主动保存,系统还有一个无感的后台审查机制

每次对话结束时,系统会检查距离上次 skill 操作是否已经过了 10 次对话(_skill_nudge_interval)。如果是,它会在后台启动一个审查 Agent

用户对话结束
_iters_since_skill >= 10?
    ▼ (是)
启动后台线程 (不影响用户)
注入审查 Prompt:
"Review the conversation... 
was a non-trivial approach used... 
If a relevant skill already exists, update it..."
审查 Agent 扫描历史
    ├── 发现有价值的流程 → 创建新 skill
    ├── 发现现有 skill 的不足 → 更新 skill
    └── 没有值得保存的 → 结束

为什么用后台线程? 因为审查过程需要额外的 LLM 调用(最多 8 次迭代),如果在主线程执行会阻塞用户响应。后台执行让用户感知不到延迟,但 Agent 却在悄悄进化。

审查成功后,主会话会打印一行小字: 💾 Skill 'deploy-api' updated

安全防线:如何防止 Agent 乱改技能?

Agent 自己改自己的指令库,听起来有点危险。系统设计了多层防护:

1. 安全扫描(Security Scan)

每次 skill 写入后,运行 skills_guard 扫描器,检查是否包含:

  • Prompt 注入攻击(如 ignore previous instructions
  • 恶意命令(如 rm -rf /
  • 越权访问指令

如果扫描不通过,自动回滚到修改前的状态。

2. 原子写入(Atomic Writes)

使用 tempfile + os.replace() 确保写入是原子的。即使在写入过程中系统崩溃,也不会留下半损坏的文件。

3. Frontmatter 校验

修改后的 SKILL.md 必须仍然包含有效的 YAML 头(name, description 等)。如果 patch 破坏了结构,拒绝保存。

4. 大小限制

Skill 内容限制在 100K 字符以内,防止技能无限膨胀。如果太大,提示 Agent 拆分技能。

框架总结:Agent 技能自进化模型

┌──────────────────────────────────────────────────┐
│              技能自进化模型                       │
├──────────────────────────────────────────────────┤
│                                                  │
│  1. 触发 (Trigger)                               │
│     - 复杂任务完成                               │
│     - 错误修复                                   │
│     - 用户纠正                                   │
│     - 后台审查 (每 10 次对话)                    │
│                                                  │
│  2. 决策 (Decision)                              │
│     - 创建新技能 (Create)                        │
│     - 修补旧技能 (Patch)                         │
│     - 废弃无用技能 (Delete)                      │
│                                                  │
│  3. 执行 (Execution)                             │
│     - skill_manage 工具调用                      │
│     - 模糊匹配定位旧内容                         │
│     - 原子写入新内容                             │
│                                                  │
│  4. 防御 (Defense)                               │
│     - 安全扫描                                   │
│     - 自动回滚                                   │
│     - 结构校验                                   │
│                                                  │
└──────────────────────────────────────────────────┘

升维思考:从静态 Prompt 到动态 Skill

传统的 LLM 应用开发中,Prompt 是硬编码的。开发者写好 Prompt,部署,然后祈祷它能覆盖所有边缘情况。如果遇到问题,开发者手动修改 Prompt,重新部署。

Agent 的 Skill 机制把这个过程内化了。Agent 不再是一个静态的执行器,而是一个自我优化的系统

  • 它从经验中学习,而不是从代码中学习。
  • 它自己修补错误,而不是等待开发者发版。
  • 它按需进化,而不是预先设计所有路径。

这才是 Agent 真正区别于 Chatbot 的地方:它不是在执行你的指令,它在根据你的使用习惯,进化出更适合你的工作方式。

你在构建 Agent 系统时,有考虑过这种"自我进化"的机制吗?还是更倾向于手动维护 Prompt?欢迎留言讨论。


See also