我为较弱的模型做了这些 Skills,后来为什么删掉了大部分

less than 1 minute read

Published:

这周,我给自己的 Claude Code 配置做了一次健康检查,发现里面有 174 个自定义 Skill,其中 124 个我一次都没有调用过。它们并不是失败品。大部分只是我为当时需要额外支撑的模型搭起的脚手架,而模型早已不再需要它们,我却一直把它们留到了现在。

作者:Koutian WuGitHub: ktwu01

在 Claude Code 里,一个 Skill 就是一个文件夹,里面有一份 Markdown 文件,告诉 Agent 如何完成某项具体任务。每次会话开始时,所有已安装 Skill 的名称和描述都会进入模型的 Context,让 Agent 知道自己可以调用什么。只有在 Skill 被调用时,它的正文才会载入。这种设计很好,因为一百个 Skill 占用的是一百条描述,而不是一百套完整流程。

问题在于,描述也不是免费的。在我动手清理前,这份 Skill 列表已经增长到大约 13,800 个 Token。Claude Code 为 Skill 列表预留的空间约占 Context Window 的百分之一,超过以后就会截断内容,路由效果也会下降。我的列表已经达到预算的约七倍。那些我真正使用的 Skill,反而因为大量不用的 Skill 而变得更难被 Agent 找到。

这些 Skills 当初在补偿什么

回头阅读那些从未调用过的 Skill,我看到了一个规律。它们可以分成几组,而且几乎每一组都在绕过某种具体的能力短板。

最大的一组是流程拆解。paper-planresearch-pipelineexperiment-plandse-loop 之类的 Skill,负责把一个多步骤流程固定下来。先写大纲,再写方法,然后写结果,最后对照论点检查图表。我编写这些 Skill,是因为早期模型常常开局很好,到了第四步就丢了主线。Skill 相当于一份外部记忆,替模型保存它自身无法持续掌握的流程。

第二组用来约束输出形态,包括 formal-docs-affirmative-prosesci-writing-prose-rulesfigure-never-annotation-caption。它们编码了那些我已经厌倦反复强调的规则:不要含糊其词,不要把 Caption 放进图里,不要在方法部分使用营销语言。每一个 Skill 的存在,都是因为如果没有东西把模型约束住,它就会漂回一种通用的表达方式。

第三组是验证脚手架,包括 result-to-claimsci-validation-checklistsci-geoscience-metric-claims。它们迫使 Agent 把论文里的一个数字一路追溯到生成该数字的代码。我曾被那些看似可信、其中数字却经不起核查的图表坑过,于是构建了这些 Skill。

第四组与能力完全无关。dbs-*nature-*ios-* 来自外部 Skill Pack。我安装了它们,试过其中一两个,之后就把其余部分留在那里。它们从来没有补偿过任何能力,只是杂物,因此也最容易被删除。

那些不再值得占据位置的 Skills

第一组和第二组体现了最有意思的变化。现在的模型无需一份逐步清单,也能规划多步骤工作;只要告诉它采用什么表达风格,它也能保持这种风格。当我今天调用 paper-plan 时,大多数情况下只是让模型按照我十八个月前选定的顺序,去做它原本就会做的事。

这正是人们容易忽略的成本。一个过时的 Skill 并非中性。它是一条固定指令,会和模型自身的判断竞争,而且它会胜出,因为我把它写成了指令。如果 Skill 里编码的流程还不如模型在没有指令时会采用的方案,那么它一边显得更加严谨,一边主动让输出变差。

result-to-claim 不是在补偿推理能力不足,而是在应对一个事实:Agent 无法独立核实某个数字。它必须查看代码。这是结构性缺口,不是能力缺口。模型能力的提升无法弥合这个缺口,因为再深入的推理也无法验证涉及我数据的结论。因此,这些 Skill 会留下。

基于同样的理由,我还保留了另外几个 Skill。gemini-review 会把一份产物交给另一个模型评审,它的价值恰恰来自评审者不是产生产物的同一个模型。wkt 会在实施工作开始前创建 Git Worktree,这是我对仓库的策略选择,不是推理辅助。atomic-commit 编码了我希望 Git 历史呈现的样子。这些都不是脚手架,而是偏好和结构性事实。模型变得更强,并不会让它们过时。

我最后采用的判断方法

我最终用来区分它们的问题是:一个 Skill 补偿的,是模型无法做到的事情,还是它过去暂时做不到的事情?

编码了外部访问能力的 Skill 应该保留,例如读取文件、调用另一个模型、对照来源核查数字,以及遵循我的仓库特有的约定。模型变得更聪明,也无法自行推导出这些东西。

如果一个 Skill 编码的是模型现在可以自行推断的流程,它就应该被移除。检验这一点的诚实办法,是删掉这个 Skill,再在没有它的情况下完成一次任务。如果输出相同,这个 Skill 只是仪式。如果输出变差,说明它确实承担了工作,应该放回来。

有两件事让这个过程比听上去容易。首先,禁用是可逆的,所以判断错一次只需要改回一项设置。其次,使用次数让第一轮筛选变得机械。一千多次会话以后,调用次数仍然为零的 Skill,不需要再做主观判断。

实际发生了什么变化

我禁用了 124 个从未使用的 Skill。列表从大约 13,800 个 Token 降到约 5,700 个。剩下的大部分是内置 Skill,以及一个我仍然启用、但并不适用于当前仓库的 Plugin。

我还把一大段项目特有的评审标准,从一个始终会加载的指令文件移进了只在调用时才加载的 Skill。这是同一条原则的另一个方向:这部分内容值得保留,但没有必要常驻在每一次会话中。

真正值得推广的不是 Token 数量,而是我已经积累了一整年的变通方案,却从未重新检查当初需要绕过的问题是否仍然存在。围绕模型局限构建的工具,应该在局限发生变化时重新审视。记录实际调用情况的计数器一直都在配置文件里。