最近在做 Coding Agent,踩了不少坑,也想明白了一些事。这篇文章是对整个 Skill 自学习机制设计过程的完整复盘,包括灵感来源、三轮迭代的细节,以及途中遇到的关键判断。
从 Hermes Agent 获得的启发
设计 Skill 机制时,核心参考来自 Hermes Agent。
Hermes 是 Nous Research 开发的一个开源自改进 Agent,它内置了一个完整的学习闭环:从经验中自动创建 Skill,在使用过程中持续改进,并在会话之间保持记忆。在 Nous Research 自己的基准测试中,拥有 20 个以上自创 Skill 的 Agent,完成研究任务的速度比零 Skill 的全新实例快了 40%。
从 Hermes 里借鉴的最重要的东西,是AI Agent 从经验中自主学习的完整闭环——经验提取、知识储存、智能检索、执行验证,再到自动改进。这个闭环有四个环节,每一个在不同的时间点触发,共同构成一个持续运转的反馈周期,Memory、Skill 和会话搜索都是这个过程的输出。
另一个关键的借鉴是Skill 和 Memory 的明确分工:
- Memory是持久化的事实和偏好,记录那些跨会话依然有效的稳定信息,比如用户的环境配置、习惯偏好——这是陈述性知识,适合存"是什么"。
- Skill则是程序性知识——执行任务的 workflow、步骤、以及踩过的坑。在 Hermes 里,Skill 是一段结构化的 Markdown 文档,记录任务的解决路径、边界情况,以及在过程中发现的领域知识——适合存"怎么做"。
这个分工决定了你把什么东西往哪里沉淀,设计之初就要想清楚。
此外,Hermes 的 Skill 遵循 agentskills.io 开放标准,也就是说 Skill 是可移植的、可共享的。这一点直接影响了我的设计判断——Skill 不只是当前 Agent 的私有知识,它是一套可以分发、可以给别人在自己 Agent 上直接复用的知识资产。
Skill 机制的三轮迭代
第一轮:粗糙的落地
一开始只是想把自学习机制作为实验性功能先跑起来,实现得非常粗糙。具体做法是:在 AI coding 过程中,让它识别"需要学习"的情况,然后写出一个 Skill,仅此而已。
很快就发现了问题——大模型对意图的理解出现了偏差。它的实现逻辑是:识别工具调用次数,一旦某个工具被反复调用超过几次,就把它记录成一个 Skill。
这种做法非常机械。有时候确实需要反复调用同一种工具,比如连续用几次read、grep、glob,但这并不意味着需要把它沉淀成 Skill。识别这一环有问题,解析这一环也一样粗糙——它直接解析工具调用序列然后复用,但 Agent 需要学到的是经验,而不是工具调用序列本身。
这一轮说实话只能算是想法的落地,甚至算不上真正的实验性功能。
第二轮:引入 LLM 判断
把其他功能做得差不多后,专门回头调试 Skill 机制。这一轮把机械的计数逻辑改成了:累积 20 轮对话之后,看这些对话里用了几次工具,如果超过两次、并且没有命中任何已有 Skill,就让大模型读这段对话,判断是否有 Skill 需要生成。
判断的输出方式是:如果认为有必要,就直接输出一段结构化的 Markdown 文档作为 Skill;如果认为没必要,就返回一个 JSON,包含true/false、置信度confidence,以及简短的判断理由reasoning。
第三轮:统一决策 + 维护机制
在仔细阅读了介绍 Claude Code Agent 自学习机制的博客之后,意识到第二轮还有几个明显不足。
第一,什么样的对话值得被学习成 Skill?标准应该是:复杂任务、比较棘手的错误、特殊的 workflow 信号,而不是简单地看工具调用次数。
第二,光生成新 Skill 是不够的,还要维护已有的 Skill。如果只是不断新增,会造成 Skill 膨胀。这些膨胀的 Skill 你可能用不到,但每次加载时都会占用 token——每个 Skill 的元数据大概消耗几十到一百多个 token,积累下来是很明显的开销。所以发现某个 Skill 过时、有错误、或者有可以补充的地方时,都需要及时更新。
基于这两点,做了最终的优化:
- 优化提示词,让 LLM 更准确地判断是否值得学习
- 把输出从"学了就输出 Markdown,不学就输出 JSON"改成统一的三态决策:
skip(跳过)、create(创建新 Skill)、patch(修改已有 Skill) - 无论
create还是patch,都先生成草稿,经过人工审批之后,再正式写入 Skill 列表,下次对话加载时就可以被注册调用
一个关键的方向性决策:Skill vs. 生成工具
整个过程中走过一个很典型的误区:自学习机制学到的东西,究竟应该沉淀成 Skill,还是直接生成一个新工具?
在和 AI 讨论了一段时间之后,彻底意识到这是个严重的方向性错误。
原因有几点。首先,Agent 应该学到的是经验,而不是工具。如果生成了很多工具,它们之间的功能可能会重叠,Agent 不知道该调用哪个。
但这还不是最关键的。最关键的是成本和收益完全不对称。
如果生成一个工具,后续需要去调试它,这已经是软件层面的问题,会真实影响整个系统的稳定性。但如果生成的是 Skill,即使质量不高,最多也就是加载时多消耗了几十个 token,代价极低。
另外,Skill 是可迁移的。Skill 的本质是一段结构化的 Markdown 文档,是封装好的提示词,和底层用的是什么 Agent 框架无关。不管是 Claude Code 还是其他框架,都可以直接复用,也可以分享给别人。它是一套可沉淀、可复制、成本低、效用高的资产。
AI Coding 的方法论反思
做这个项目对 AI coding 有了一些新的感悟,尤其是在 Agent 这种相对新的领域。
意图对齐的问题在 Agent 开发里会被放大。传统的 Web 开发,大模型对很多 common sense 是有感知的,你可以适当省略一些细节,它也能按预期实现。但 Agent 开发这个领域的训练数据相对少得多,所以你稍微模糊一点,意图对齐就会出问题。这次 Skill 机制做成那么机械的样子,本质上就是因为只说了"加入自学习机制",没有给出清晰的定义和实现步骤。
"你不知道模型不知道",这是个盲区。在结果呈现出来之前,你根本不知道它在某个地方的理解是偏的。所以建议在开始开发之前,先让模型讲讲它对方案的理解,方案里哪里写得不够详细就让它展开讲,不能带着一个模糊的大方案直接开始写代码。
自上而下的设计在 AI coding 里非常重要。AI 写代码的速度非常快,但正因为如此,一旦设计上有遗漏,后期再去重构或修改会很麻烦。基础一定要在早期打好。当然,Agent 本来就是在实践中不断演化的,不可能一开始就设计完备——这里说的不是要做到完美,而是要有足够清晰的方向和足够细化的初始设计。
测试与评测设计
做完一个新模块,怎么判断它真的有效?这需要数据来说话。
数据集设计覆盖了 Skill 的整个生命周期,从生成到调用,分三类场景:
- 生成测试:给它一些对话,看能不能正确识别哪些值得学习、提取出什么内容
- 维护测试:对话里包含的信息和已有 Skill 有部分重叠,看能不能判断出需要修整已有 Skill,而不是新建一个
- 跳过测试:对话本身没什么价值,看能不能正确判断并跳过
在调用侧,会编排一些明确指向某个 Skill 的对话,看能不能触发对应的 Skill,以及触发之后相比没有 Skill 的情况,完成效率和步数是否有提升。
这种方法本身也有局限性:它是特定设置的场景,不是真实的使用环境。所以如果条件允许,还会补充一个更真实的统计维度——在用户实际使用 Agent 的过程中,统计自动生成的 Skill 被调用的频率,来衡量它们是否真正有价值。
以上是整个 Skill 自学习机制的设计历程。核心结论其实很简单:Skill 的价值在于低成本、可迁移、能持续演化。生成工具是软件问题,生成 Skill 是知识问题,两者的代价和可控性天壤之别。理清这一点,很多设计决策自然就清晰了。