Skill 持续升级指南:让 AI 从记住方法走向自动驾驶

别让 Skill 写完就停止进化 真实任务会不断暴露新问题 用 8 项检查持续诊断和优化 让它真正成为长期生产力

上一篇文章讲了怎么从一次真实任务出发,做出自己的第一个 Skill。

但 Skill 写出来,只是开发的开始。

真正麻烦的事情通常发生在后面:第一次运行漏了一个步骤,于是补一条规则;第二次格式不对,再补一个示例;第三次模型误解了要求,就在文件末尾加一句“绝对不要……”。

几个月以后,原本几十行的 Skill 已经长到几百行。里面既有重复规则,也有过时参数,还有只为某一次失败留下的补丁。它仍然能跑,却越来越不稳定,也越来越难解释到底是哪条指令在控制结果。

上一篇最后已经谈到 Skill 的验证和维护,但只给出了原则:不要不断追加补丁,要保留单一事实来源,并用真实任务回归。这篇继续往下拆,讨论一份 Skill 开始失控时,具体会出现哪些可以辨认的症状:

怎样判断一份 Skill 写得好不好,以及如何在它开始腐烂以前,把问题找出来。

Matt Pocock 在后来更名为 writing-for-agents 的 Skill 中,总结了六种失效模式:过早完成、重复、沉积、蔓延、空操作和否定式引导。

他的完整方法还提醒作者不要过度拟合单次任务,只是没有把它列入原始六种失效模式。本文把“样本过拟合”提升为第七项;另外,把多功能 Skill 中常见的规则作用域混乱称为“分支串线”,作为第八项检查。

八项检查共同指向同一个目标:Skill 不需要让 Agent 每次输出完全相同的结果,但应该让它每次遵循相对稳定、可以检查的过程。

结果可以变,过程不能乱。

还没做完,就开始准备收工

过早完成,是指任务尚未真正结束,Agent 的注意力已经滑向“总结并交付”。完成标准越松,越容易发生。

最典型的写法是:

抽查几条,确认没有问题后进入下一步。

“几条”是多少?“没有问题”包含什么?这句话实际上无法验收。

改成:

检查开头三条、结尾三条字幕;逐条确认时间戳与音频对齐、文本不为空、相邻字幕没有重叠。任意一项失败,都不得进入下一步。

区别不在于后者更严厉,而在于它可以检查。每个关键步骤都应回答:

  1. 输入是什么?
  2. 要产生什么可观察的输出?
  3. 什么条件满足后,才算真正完成?

能机械验证且必须确定的验收,优先做成脚本。但先收紧完成标准;只有机械、重复、必须一致的部分,才值得程序化。

同一句规则,在文件里写了六遍

很多作者认为重要规则多提醒几次更保险,于是同一要求出现在开头、正文、避坑指南和验收清单里。这既浪费上下文、增加维护成本,也会过度提高它在上下文中的显著性。以后漏改一处,Skill 就开始互相冲突。

正确做法是建立“单一事实来源”:一条规则只在一个权威位置完整定义。其他地方需要它,就引用,不要换个说法再讲一遍。 比如,不在验收清单里重写尺寸规则,只写“尺寸要求见 references/platform-formats.md”。

写完后做一次同义扫描:不只搜相同句子,也找措辞不同但含义相同的段落。

新方案已经上线,旧规则还埋在文件里

这叫沉积。Skill 用久之后,最危险的通常不是缺少内容,而是留下太多历史。

早期用方案 A,后来改成方案 B。主流程更新了,旧参数、旧文件名和旧示例却没有清理。于是同一文件里,前面要求 4K 超采样,后面又说只是普通放大。

Agent 没有义务猜哪一句更新。两组冲突规则会显著增加执行的不确定性:它可能选择其中一组,也可能尝试折中,导致不同轮次结果不一致。

每次替换方案,都应该把它当成一次迁移,而不是简单追加:

  • 全局搜索旧术语;
  • 搜索旧参数和旧比例;
  • 搜索旧文件名、路径和命令;
  • 检查示例、验收项和参考文件是否仍在描述旧方案。

每一行都有用,整个 Skill 却越来越难执行

这叫蔓延,也可以理解为失控膨胀。一份 Skill 即使没有废话、重复和过时内容,也可能因为太长而变得难以稳定执行。

当 SKILL.md 塞满分支、边界条件和参考知识时,每一条可能都有用,但单次运行只会用到一小部分。主流程很容易被淹没。

上一篇已经讲过用渐进披露拆分主流程和参考资料。这里更值得解决的是:怎样判断蔓延已经发生。

不要只数行数。选出三种最常见的任务,分别标记每次执行真正使用了哪些段落。如果大量内容只服务某一个分支,却在所有任务中都会被加载;或者 Agent 经常跳过主流程、误用无关约束,每次修改还必须把所有功能重新测试一遍,说明 Skill 已经开始蔓延。

修复时也不要机械拆文件。先区分所有分支都需要的主流程、单个分支才需要的资料,以及已经没有任务会读取的内容。前两类重新归位,最后一类直接删除。移出去的资料必须留下明确的读取条件,否则只是把上下文负担变成导航负担。

说了很多正确的话,却没有一句改变行为

这叫空操作。Skill 里常见这样的句子:

这一步非常重要,不要省略。

请认真检查,确保高质量输出。

这些话不能说错,但几乎没有用。模型默认就知道任务应该认真完成,你只是把默认行为描述了一遍。

最有效的判断方法,是逐句做删除测试:

删除这句话以后,Agent 的可观察行为会变化吗?

如果不会,删掉整句,不要把它改短。“确保准确”可改成“关键事实优先核对一手来源;必要时用独立来源交叉验证,并保留链接”。“不要遗漏”可改成“逐项覆盖清单中的 12 个字段,并列出未取得的数据”。

反复强调“不要做”,反而让错误选项更加显眼

这叫否定式引导。它不必然导致错误,但会提高错误选项的显著性。

假设你真正想要的是 3:4 竖图,却写成:

竖图固定使用 3:4,不要做成 9:16,绝对不能再漂回 9:16。

3:4 只出现一次,9:16 却被反复点名。你想压制错误选项,却可能让它更显眼。

更干净的写法是:

竖图画布固定为 3:4。

直接描述目标行为,让不想要的选项从上下文里消失。

否定句并非绝对禁用。安全边界、破坏性操作或合规要求可能需要明确禁止,但要同时给出替代动作。

例如,与其只写“禁止覆盖原文件”,不如再补上“结果保存为新文件,文件名末尾添加 -edited”。

在一个任务上表现完美,换个输入就失灵

本文把这个问题单独称为样本过拟合。

很多 Skill 都是从一次成功协作中提炼出来的。这是很好的起点,却也容易把偶然细节误写成通用规则。

例如,一次内容整理任务使用了 notes/weekly/ 目录、三个固定文件名和某种特定标题格式。Agent 把整次执行过程原样整理进 Skill,结果它只能处理这一套目录;换个项目、换个日期结构,流程就断了。

一次成功执行只能证明“这条路走通过”,不能证明沿途所有细节都属于方法本身。

把真实任务写回 Skill 时,应该逐项区分:

  • 哪些是这类任务永远需要的约束;
  • 哪些是当前项目的专有知识,应该放进 reference 或配置;
  • 哪些只是这一次运行碰巧出现的文件名、路径和数据;
  • 哪些信息应该在执行时向用户确认,而不是永久写死。

检验方法也很简单:找一个结构相似但输入不同的任务再跑一次。如果只换一个目录、一个平台或一种文件命名,Skill 就无法工作,它保存的不是方法,而是一次运行录像。

每个分支单独看都对,放在一起却开始串线

本文把这种规则作用域混乱称为分支串线。

一个 Skill 经常不止一种用法。图片处理 Skill 可能同时支持压缩、裁切和格式转换;文章 Skill 可能同时支持改写、校对和事实核查。每个分支都有合理规则,但如果它们全部平铺在同一条主流程里,Agent 很容易把这个分支的要求带到另一个分支。

例如,压缩图片要求“不改变尺寸”,裁切图片却必须改变画布。两条规则都正确,但如果 Skill 没先判断用户走哪个分支,它们就会变成冲突指令。

蔓延解决的是“当前任务读了太多无关内容”,分支串线解决的是“把正确规则用在了错误场景”。二者可能同时发生,但不是同一个问题。

解决办法不是再加一句“根据情况灵活处理”,而是把分支选择写清楚:

  1. 先根据用户目标判断当前分支;
  2. 只加载该分支需要的规则和参考资料;
  3. 共享约束留在主流程,分支约束各自归位;
  4. 无法确定分支时先确认,不要同时执行多个互斥流程。

检查分支串线时,不要只测每个功能的标准请求。还要测试同时出现两个意图、说法模糊、执行中途改变目标等边界情况。

不要凭感觉追加规则,先给失败命名

Skill 某次运行出错后,不要立刻在文件末尾追加一条新规则。先判断它属于哪一种问题:

  • 步骤没有做完,检查完成标准;
  • 同一要求出现多次,检查重复;
  • 新旧规则互相冲突,检查沉积;
  • 主流程被大量分支淹没,检查蔓延;
  • 指令看起来正确却不改变行为,检查空操作;
  • 错误选项被反复点名,检查否定式引导;
  • 换一个同类样本就失灵,检查样本过拟合;
  • 单个功能正常,组合使用时混乱,检查分支串线。

先给故障命名,再修改对应位置。否则每次失败都会变成一条孤立补丁,最后制造出更多重复、沉积和冲突。

修改完成以后,再用原来的失败案例和一组正常案例做回归。检查的不只是这次错误有没有消失,还要看修复是否破坏了其他分支。

一份可以直接使用的 Skill 体检清单

  1. 每个关键步骤是否有可以检查的完成标准?
  2. 同一个意思是否以不同说法散落在多个位置?
  3. 旧术语、旧参数、旧路径和旧示例是否已经清理?
  4. 单次任务是否读取了大量与当前分支无关的内容?
  5. 是否存在“认真一点”“确保质量”这类不改变行为的话?
  6. 是否反复描述错误选项,却没有直接写出目标行为?
  7. 换一个同类输入后,Skill 是否仍然能够工作?
  8. 不同功能的规则是否会在组合使用时互相串线?
  9. description 是否仍然覆盖真实触发场景,并排除已经发现的误触发?
  10. 修复问题后,是否用旧案例和其他分支做过回归测试?

如果一份 Skill 在维护后变得更短,不一定是损失了能力,更可能是清掉了解释、重复、沉积和无效提醒。写好 Skill,不是把知道的一切都塞给 Agent,而是让它在正确的时间,稳定地执行正确的过程。

把八项检查变成一次可以执行的 Skill 体检

知道这些概念还不够。真正有用的做法,是拿一份正在使用的 Skill,把八项检查逐条跑一遍。

下面的提示词不绑定 Claude Code 或 Codex。使用时把 换成 Skill 的实际路径。

为了减少 Agent 凭空推断,最好同时准备六类输入:

  • Skill 路径;
  • 一至三条真实任务;
  • 一条已知失败案例;
  • 当时的实际错误输出;
  • 你希望出现的行为;
  • 已知的现行规则或权威业务约束。

没有这些材料也可以先做静态审计,但结果只能说明“哪里存在风险”,不能证明某条规则一定错误。

有一条操作原则很重要:先诊断,再修改。 不要一上来让 Agent “优化整个 Skill”。这种要求太宽,它通常会大规模改写,而你很难判断哪些变化真正解决了问题。

下面所有提示词都应遵守同一条证据边界:严格区分文件中的直接证据、真实运行证据和 Agent 的推断。无法确定规则意图、现行版本或预期行为时,标记为“待确认”,列出需要作者补充的信息,不得自行猜测。

一次性完成八项体检

如果只想收藏一条提示词,用下面这条:

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
请对 {{SKILL_PATH}} 做一次 Skill 失效模式审计。

先完整读取 SKILL.md,以及它直接引用的 references、scripts、配置文件,以及直接影响触发和执行的配置。
这一步只诊断,不修改任何文件。

严格区分三类依据:文件中的直接证据、用户提供的真实运行证据、你的推断。
无法确定规则意图、现行版本或预期行为时,标记为“待确认”,列出需要用户补充的信息,不得自行猜测。

逐项检查:
1. 过早完成:关键步骤是否缺少可检查的完成标准?
2. 重复:同一含义是否出现在多个位置?
3. 沉积:是否存在已经被新方案替代的旧术语、旧参数、旧路径、旧示例或旧脚本?
4. 蔓延:一次具体任务是否需要加载大量与当前分支无关的内容?
5. 空操作:哪些句子删除后不会改变 Agent 的可观察行为?
6. 否定式引导:是否反复描述错误选项,却没有直接定义目标行为?
7. 样本过拟合:哪些规则只适用于创建该 Skill 时的原始项目或样本?
8. 分支串线:不同功能的规则是否可能被同时加载或错误复用?

输出一张审计表,字段包括:
- 问题类型
- 严重程度:高 / 中 / 低
- 文件与原文证据
- 可能造成的具体行为
- 最小修复建议
- 建议如何验证修复

然后给出:
A. 最值得优先解决的三个问题;
B. 可以直接删除的内容;
C. 需要保留但应移动或改写的内容;
D. 一组修复前后都应该运行的回归测试。

不要因为追求更短而删除有效约束;每一项修改建议都必须对应可观察的行为变化。

这条提示词解决的是“我知道 Skill 不太对,但不知道问题在哪里”。它不会直接重写文件,而是先给你一张问题地图。

八类问题的专项检测提示词

一次性审计适合全身检查。已经知道症状时,使用下面的专项提示词更快。

所有专项提示词共用的证据前缀

复制任意一条专项提示词时,先把下面这段放在最前面:

text

1
2
3
4
只依据文件中的直接证据和用户提供的真实运行证据判断。
严格区分事实与推断;证据不足时标记为“待确认”,列出需要补充的信息。
不得自行发明规则、阈值、数量、现行版本或预期行为。
这一步只诊断,不修改任何文件。

检查步骤是否过早收工

text

1
2
3
4
5
6
7
8
9
10
11
读取 {{SKILL_PATH}},只检查过早完成问题,不修改文件。

找出所有包含“检查、确认、验证、整理、完成、确保、抽查、复核”等动作的步骤。
这些关键词只用于初筛,不能作为唯一判断依据;同时检查没有出现关键词、但实际承担验收责任的步骤。
对每一步回答:
1. Agent 能否明确区分“已完成”和“未完成”?
2. 检查范围是否有数量、边界或覆盖标准?
3. 失败后是否说明继续做什么?
4. 后续步骤是否可能诱使 Agent 提前结束当前步骤?

把模糊完成标准改写成可勾选条件,但先只输出原句、风险和建议改写,不直接修改文件。

适合检测“Agent 明明做了一部分,却总说已经完成”的 Skill。

找出换了说法的重复规则

text

1
2
3
4
5
6
7
8
9
10
11
12
读取 {{SKILL_PATH}} 及其直接引用的文件,做语义重复审计。

不要只找完全相同的句子,也要找措辞不同但行为含义相同的规则。
把重复内容按主题分组,并为每组指出:
- 所有出现位置;
- 哪个位置最适合作为唯一事实来源;
- 其他位置应该删除,还是改成引用;
- 各版本之间是否存在细微冲突。

区分无效重复与必要的摘要、索引、引用和平台差异。不要为了形式上的唯一而删除确实承担导航或兼容作用的内容。

只输出审计结果和最小合并方案,不修改文件。

适合检测文件越来越长、改一条规则却要同时改很多地方的问题。

清理新旧方案混在一起的沉积

text

1
2
3
4
5
6
7
8
9
10
11
12
对 {{SKILL_PATH}} 做历史沉积检查,不修改文件。

搜索可能属于旧方案的:术语、参数、比例、文件名、路径、命令、脚本、示例和验收项。
重点寻找这些信号:
- 同一个概念存在两种名称;
- 同一种输出存在两套数值或格式;
- 正文与示例描述不同流程;
- 当前脚本已经替换,但旧命令仍在说明中;
- 某条规则被“更正”“改为”“现在使用”等文字覆盖,却没有删除旧版本。

输出“当前规则 / 疑似旧规则 / 冲突位置 / 核验方法 / 建议处理”表格。
无法确认哪套是现行方案时明确标记,不要自行猜测。

适合版本迭代很多次、经常出现同一任务不同轮次走不同流程的 Skill。

判断主文件是否已经蔓延

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
读取 {{SKILL_PATH}},分析主文件的上下文蔓延问题,不修改文件。

先根据用户提供的真实任务或历史运行记录识别主要执行分支。
如果没有这些材料,再从 description 和示例中选择候选分支,并明确标记为假设;无法识别三个分支时,不得为了满足数量强行编造。
再把 SKILL.md 的每一节标记为:
- 所有分支都需要;
- 仅某个分支需要;
- 只用于解释或举例;
- 当前没有明确分支会使用。

分别分析最多三个具有证据支持的常见任务,列出每个任务真正需要读取的章节。
找出总是加载但在多数任务中无关的内容。

给出重新归位建议:保留在主流程、移动到指定 reference、合并到其他位置或删除。
每个移动建议必须同时给出主文件中的读取条件,避免产生没人会打开的 reference。

适合检测“每一行似乎都有用,但 Agent 经常漏掉主流程”的问题。

删除不会改变行为的空操作

text

1
2
3
4
5
6
7
8
9
10
11
12
13
读取 {{SKILL_PATH}},逐句执行 no-op test,不修改文件。

对每个说明句提问:
删除它以后,Agent 的可观察行为是否会发生变化?

重点检查“认真、仔细、确保质量、不要偷懒、非常重要、用户很在意、尽量完整”等泛泛要求。

把结果分成三组:
1. 可以直接删除;
2. 有意图但缺少可执行标准,需要改写;
3. 确实控制行为,应该保留。

第二组先指出缺少什么标准。只有现有文件、真实失败案例或用户要求能够提供依据时,才给出具体改写;没有依据时列为“待确认”,不得自行发明阈值、数量、范围或验收规则。

适合压缩那些看起来正确、实际没有约束力的内容。

把否定式命令改成目标行为

text

1
2
3
4
5
6
7
8
9
读取 {{SKILL_PATH}},找出所有以“不要、禁止、不得、避免、绝不能、不能再”表达的规则,不修改文件。

逐条判断:
- 能否直接改成目标行为;
- 是否属于必须保留的安全或破坏性操作护栏;
- 保留禁令时,是否同时提供了替代动作。

输出:原句 / 被反复点名的错误选项 / 建议的正向写法 / 是否需要保留禁令。
不要删除必要的安全边界。

适合检测“越提醒不要做,结果里越容易出现”的错误。

检查是否只适用于一个样本

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
读取 {{SKILL_PATH}},做泛化与样本过拟合检查,不修改文件。

列出所有写死的项目名、仓库名、目录、文件名、日期结构、平台、输出尺寸、人物和示例数据。
对每一项判断它属于:
- 任务本身不可缺少的通用约束;
- 当前项目的专有配置;
- 执行时应该确认的变量;
- 只来自原始样本的偶然细节。
- 现有证据不足,需要作者确认。

设计至少三个扰动案例:更换目录结构、更换输入类型、更换平台或命名方式。
预测当前 Skill 在每个案例中可能在哪里失效,并给出最小抽象候选方案。
如果环境允许,实际运行扰动案例;没有实际运行时,必须把结论标记为“静态预测”。
证据不足时不能直接删除或参数化硬编码规则,只能列出待确认问题和候选方案。

适合检测“原来的案例跑得很好,一换项目就坏”的 Skill。

检查不同功能是否互相串线

text

1
2
3
4
5
6
7
8
9
10
11
12
读取 {{SKILL_PATH}},做分支隔离审计,不修改文件。

列出这份 Skill 支持的所有功能分支,并建立矩阵:
- 分支触发条件;
- 共享规则;
- 该分支专用规则;
- 与其他分支互斥的规则;
- 需要按需加载的 reference 或 script;
- 分支无法判断时的处理方式。

然后设计四类测试:单一意图、两个意图同时出现、意图表达模糊、执行中途改变目标。
指出哪些规则可能被加载到错误分支,并给出路由或隔离建议。

适合多功能 Skill:每个功能单独运行正常,组合使用时却互相污染。

让 Agent 只做最小修复

审计完成后,不要接一句“那你全部优化一下”。使用下面的修复提示词:

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
根据刚才的审计结果,为 {{SKILL_PATH}} 设计最小修复方案。

修复目标只包括:
{{粘贴准备解决的问题}}

要求:
1. 不顺手重写无关章节;
2. 不改变没有证据表明需要改变的行为;
3. 同一规则只保留一个权威位置;
4. 移动内容时补上明确的读取条件;
5. 删除内容前说明删除后为什么不影响行为;
6. 新增规则必须对应已经观察到的失败;
7. 先输出修改清单和 diff,不直接修改文件;
8. 同时给出修复后必须运行的回归测试。

最后分别列出:
- 行为发生了什么变化;
- 哪些行为保持不变;
- 仍然无法从现有证据确定的问题。

这条提示词的作用,是防止一次局部修复演变成整份 Skill 的无依据重写。

生成一套可重复运行的回归测试

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
基于 {{SKILL_PATH}} 的目标、触发范围和执行分支,生成一套 Skill 回归测试。

预期行为优先来自用户明确要求、真实成功案例和权威业务规则。
现有 Skill 是待验证对象,不能单独作为正确答案来源;规则冲突或预期不明时标记为“待确认”,不得自行补全。

测试至少覆盖:
- 应该触发的典型请求;
- 不应该触发的相邻请求;
- 没有标准关键词但应该触发的口语请求;
- 每个功能分支的标准任务;
- 两个意图同时出现;
- 缺少必要输入;
- 输入结构发生变化;
- 已知历史失败案例;
- 修复可能影响的其他分支。

每个测试用例包含:
1. 用户请求;
2. 前置文件或环境;
3. 预期是否触发;
4. 必须执行的关键动作;
5. 禁止发生的越界行为;
6. 可检查的通过条件。

最终输出 Markdown 测试表,并标记最适合自动化的测试。

不要要求输出文字一模一样。回归测试应该检查过程、事实、边界和完成标准是否稳定。

一套实际可执行的维护流程

如果要把本文真正用起来,可以按下面的顺序操作:

  1. 选一份正在使用、但最近出现过问题的 Skill。
  2. 保存一条真实失败请求、实际输出和期望结果。
  3. 先运行“一次性完成八项体检”,不要允许 Agent 直接修改。
  4. 从审计结果中只选择一个高严重度问题。
  5. 使用“最小修复”提示词生成 diff。
  6. 人工确认修改确实对应原始失败,再应用变更。
  7. 使用回归测试提示词,重跑失败案例和其他分支。
  8. 记录这次修改解决了什么,不要只记录“优化 Skill”。

维护记录可以直接使用这个模板:

md

1
2
3
4
5
6
7
8
9
10
11
## Skill 修改记录

- 日期:
- 真实失败请求:
- 实际错误行为:
- 归属的失效模式:
- 根因:
- 最小修改:
- 修复后验证:
- 回归测试结果:
- 暂未解决的问题:

这样做的价值,是让 Skill 的每一条规则都有来历。几个月以后再读文件,你仍然知道某条约束为什么存在,也知道什么时候可以安全删除。