很多人第一次写 Skill,会下意识把它写成一个更长的 Prompt。

把背景、规则、注意事项、示例、参考资料,全都塞进一个 SKILL.md。看起来很完整,但实际并不一定好用。

Skill 的价值不在于"让模型一次读更多东西",而在于:

当用户提出某类需求时,Agent 能自动识别场景,加载对应流程,使用合适工具,并按固定方法完成任务。

Prompt 是一次性的指令。

Skill 是可复用、可触发、可维护的工作流。

它真正解决的问题不是"这次怎么提示模型",而是"以后每次遇到类似任务,Agent 应该怎么稳定地做"。

1. 遵守 Skill 的原则:按需加载

Skill 和 CLAUDE.md / 系统提示词不一样。

CLAUDE.md 更像常驻上下文。只要你在这个项目里工作,它就会一直存在,持续影响模型行为。

Slash command 更像手动命令。用户必须明确输入某个命令,Agent 才知道要执行对应流程。

Skill 介于两者之间。

它的特点是 on-demand loading:按需加载。

平时它不会把整个 SKILL.md 都塞进上下文。只有当用户输入和 Skill 的 description 匹配时,它才会被加载。

这有两个好处:

  1. 节省 context。
  2. 减少无关规则对当前任务的干扰。

但有一个细节很重要:

Skill 的完整内容不是常驻的,但 Skill 的 description 会长期参与匹配。

所以 description 写得好不好,直接决定 Skill 会不会被正确触发。

比如一个"生成封面图"的 Skill,如果 description 只写:

1
Create an image.

可能不够。

因为用户真实会说的是:

  • 帮我做一张封面图
  • 给这篇文章配个图
  • 做一张小红书封面
  • 生成一张适合 X 长文的配图
  • 按这个标题做一张科技感海报

再比如一个"生成 X 长文"的 Skill,用户不一定会说"调用 longform skill"。

他更可能说:

  • 把这个想法展开成一篇长推
  • 帮我写一篇 X 长文
  • 这个观点能不能写成一条长内容
  • 按我的语气扩写一下
  • 给我一个开头更抓人的版本

这些真实表达最好写进 description 或触发示例里。

否则 Skill 明明存在,却可能不会被调用。

还有一种情况:如果你有很多 Skill,或者某个 Skill 本身很长,可以在 Skill 里设置 disable,关闭自动加载。

disable 的核心意义不只是防止误触发,更重要的是节省 context。

因为自动触发类 Skill 至少要让 description 长期参与匹配。Skill 越多、description 越多,常驻的匹配成本就越高。

有些 Skill 很专业、很长、使用频率又不高,就没必要一直占用资源。

比如:

  • 年终总结 Skill:一年可能只用几次。
  • 简历重写 Skill:找工作阶段才用。
  • 封面图生成 Skill:只有做内容发布时才用。
  • 课程讲义整理 Skill:只有学习某门课时才用。

这类 Skill 可以先 disable 掉。

需要时再手动调用。

这相当于把它从"自动出现的工作流"变成"手动调用的工具":

  • 优点:更省 context,更少误调用。
  • 缺点:用户必须记得主动叫它。

所以 Skill 的第一件事,不是写很多规则,而是想清楚:

它应该自动触发,还是只适合手动触发?

2. 给 Skill 合适的工具边界

Skill 可以限制允许使用哪些工具。

这不是必须的,但很有用。

因为不同 Skill 需要的权限不同。

比如在 Claude Code 里,可以写类似:

1
2
3
4
allowed-tools:
  - Bash
  - Read
  - Grep

如果只是整理学习资料,可能只需要:

1
2
3
4
allowed-tools:
  - Read
  - Grep
  - Write

如果是文档整理,可能只需要:

1
2
3
4
allowed-tools:
  - Read
  - Write
  - Grep

如果是封面图生成,可能需要读参考资料、写出 prompt,再调用图片工具:

1
2
3
4
allowed-tools:
  - Read
  - Write
  - ImageGenerate

如果是批量整理资料,才需要开放更多权限,比如:

1
2
3
4
5
allowed-tools:
  - Read
  - Write
  - Edit
  - Bash

核心原则很简单:

只给完成任务所需的最小权限。

不要让只负责生成建议的 Skill 默认能修改文件。

不要让只读分析 Skill 默认能执行任意命令。

工具越多不一定越强,有时只是风险更大。

3. 不同 Skill 可以设置不同模型

Skill 也可以指定模型。

这点经常被忽略,但很实用。

因为不同任务对模型的要求不一样。

写文档、做图、数据分析、信息爬取、整理学习笔记、生成长文,其实不应该默认使用同一个模型。

举几个例子:

  • 写文档:需要表达清楚、结构稳定,可以用擅长写作和总结的模型。
  • 做图 / 设计:需要视觉理解、布局审美,适合多模态或设计能力更强的模型。
  • 数据分析:需要稳定处理表格、解释结果,可以用推理不错但成本较低的模型。
  • 信息爬取:很多时候是批处理和抽取,不一定需要最强模型,便宜快的模型更合适。
  • 整理学习笔记:需要分类、提炼重点、保留原意,可以用稳定便宜的模型。
  • 生成 X 长文:需要结构、语气、节奏和观点判断,可以用写作能力更强的模型。
  • 修改简历:需要理解岗位要求和表达取舍,可以用更谨慎的模型。

模型选择不是炫技,而是成本和可靠性的平衡。

有些模型更强,但更贵。

有些模型便宜,但足够完成简单任务。

一个成熟的 Skill 系统,不应该所有任务都默认用同一个模型。

它应该根据任务类型选择合适的执行模型。

4. 渐进式披露,限制 Skill.md 的大小

SKILL.md 不应该承载所有内容。

它更像入口文件。

里面应该放:

  • 什么时候触发。
  • 做事原则。
  • 执行步骤。
  • 需要哪些工具。
  • 其他资料在哪里。
  • 最后怎么验证。

但不要把所有参考资料、长案例、脚本、模板都塞进去。

更好的方式是分层:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
生成封面图/
  SKILL.md
  references/
    封面图风格参考.md
    常见平台尺寸.md
    好坏案例对比.md
  scripts/
    检查图片尺寸.py
    导出多平台版本.py
  assets/
    封面图模板.md
    字体与配色示例.json

不同目录放不同东西。

references/ 放长文档、风格参考、平台尺寸、详细案例。

scripts/ 放可执行代码。比如检查图片尺寸、批量重命名文件、导出多平台版本、整理表格。这些确定性操作用脚本比让模型每次现场生成更稳定。

assets/ 放模板、schema、图片、示例文件、输出样式。

这样做的好处是:

Agent 不需要每次加载所有内容。

它先读 SKILL.md,知道整体流程。真的需要细节时,再去读 reference,或者执行 script。

这就是 Progressive Disclosure:渐进式披露。

按需读,按需执行。

不要一次性把所有东西都塞进上下文。

这也解释了为什么 SKILL.md 最好少于 500 行。

不是因为 500 行有什么魔法,而是因为超过这个长度,通常说明你把太多东西混在一起了。

如果 Skill 太长,优先考虑三件事:

  1. 长说明移到 references/
  2. 稳定操作写成 scripts/
  3. 模板和样例放到 assets/

如果拆完还是很长,可能说明这不是一个 Skill,而是几个 Skill。

5. 写完 Skill 之后还需要验证、打分、迭代

Skill 写完,不代表它真的能用。

这点很重要。

如果你希望一个 Skill 更稳定,建议至少做三类验证:

  1. 能不能跑。
  2. 能不能正确触发。
  3. 跑出来的结果,是否真的比不用 Skill 更好。

第三点最容易被忽略。

很多 Skill 只是"看起来写完了"。但它到底有没有提升质量?有没有减少错误?有没有让输出更符合用户预期?如果没有 eval,其实没人知道。

Claude Code 的 Skill Creator 给了一个很好的思路:Skill 不应该只靠感觉发布,而应该配 test data、跑 eval、看结果、再迭代。

它的核心流程大概是:

  1. 明确 Skill 要解决什么任务。
  2. 写出 Skill 初稿。
  3. 准备 test data / test prompts。
  4. 用这些测试运行 Skill。
  5. 对每个测试结果做 evaluation。
  6. 给每个结果打分。
  7. 根据失败点修改 Skill。
  8. 再跑一轮。
  9. 直到主要测试都达到最低可接受分数。

你可以把它理解成给 Skill 写测试。

不是单元测试那么死,但思路类似:不要只相信 Skill 文件本身,要看它在样本任务里的表现。

第一层:验证它能不能跑

先测试最基础的执行能力。

比如:

  • 文件路径对不对?
  • 工具权限够不够?
  • 脚本能不能执行?
  • reference 能不能被读到?
  • assets 模板能不能被正确使用?
  • 输出格式是否符合预期?
  • 有没有漏掉必要步骤?

如果一个 Skill 连真实任务都跑不通,后面谈触发和质量都没意义。

第二层:验证它能不能正确触发

自动加载类 Skill 还要测试触发。

不能只测一句:

1
请运行 X 长文 skill。

因为真实用户不会这么说。

应该准备一组用户真实可能会说的话:

1
2
3
4
5
把这个想法展开成一篇长推
帮我写一篇 X 长文
这个观点能不能写成一条长内容
按我的语气扩写一下
给我一个开头更抓人的版本

如果是封面图 Skill,也可以测试:

1
2
3
4
帮我做一张封面图
给这篇文章配个图
按这个标题做一张科技感海报
做一张适合小红书的封面

这些就是 trigger eval。

每条测试都应该标记:

1
2
3
4
[
  {"query": "把这个想法展开成一篇长推", "should_trigger": true},
  {"query": "帮我查一下今天的天气", "should_trigger": false}
]

如果该触发的不触发,description 要补关键词。

如果不该触发的触发了,description 要收窄边界。

这一步优化的是 Skill 的入口。

入口不准,正文写得再好也没用。

第三层:准备 test data / eval cases

更关键的是结果质量验证。

你需要准备 test data。

但这不等于用户要亲自准备一堆测试材料。

更合理的做法是:让 Agent 根据 Skill 的用途,自动生成第一批 test data 和 eval cases,用户只需要检查这些测试是否贴近真实场景。

比如:

  • 封面图生成 Skill:准备 5 个标题、5 种内容类型、几张参考图。
  • X 长文 Skill:准备 5 条原始想法、目标读者、理想成稿风格。
  • 学习笔记整理 Skill:准备几份课堂笔记、摘抄、截图 OCR 文本。
  • 简历重写 Skill:准备不同岗位 JD、原始简历、理想修改方向。
  • 周报总结 Skill:准备一周零散记录、会议纪要、完成事项。

每个 test case 最好包含:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "id": 1,
  "prompt": "用户会怎么提这个任务",
  "files": ["测试输入文件"],
  "expected_output": "什么样的结果算好",
  "assertions": [
    "必须保留用户原始观点",
    "必须生成抓人的开头",
    "不能编造用户没有说过的经历"
  ]
}

这里的重点不是格式,而是思路:

你要提前定义"什么算好"。

否则 eval 就会变成事后凭感觉。

第四层:打分,不要只说好不好

跑完 test data 后,不要只写"结果不错"。

应该给每个 case 打分,比如 0 到 10 分。

可以用这个简单标准:

  • 0-2 分:完全没完成任务,或方向错了。
  • 3-4 分:勉强相关,但漏掉关键要求。
  • 5-6 分:基本可用,但还有明显问题。
  • 7-8 分:质量稳定,少量细节可改。
  • 9-10 分:非常符合预期,可以作为示范输出。

最低标准可以设成:主要 test data 至少 5 分以上。

如果某个重要 case 低于 5 分,就说明这个 Skill 还不够稳。

尤其是高频 Skill,这通常意味着它在某个常见场景下还不可用。

第五层:和 baseline 对比

如果想更专业,可以做 baseline 对比。

也就是同一个测试,跑两次:

  1. 不使用 Skill。
  2. 使用 Skill。

然后比较结果。

Claude Code Skill Creator 的 eval 思路里,就有类似 A/B benchmark:skill-enabled vs baseline。

这很有价值。

因为一个 Skill 不只是要"能跑",还应该证明自己有用。

如果不用 Skill 的结果已经 7 分,用了 Skill 还是 7 分,那这个 Skill 可能没有提供明显增益。

如果不用 Skill 是 4 分,用了 Skill 是 8 分,这才说明它真的把经验固化进去了。

第六层:根据失败点修改 Skill

评分不是为了好看。

评分是为了定位该改哪里。

常见修法有几种:

  • 触发失败:改 description,加真实 trigger phrases。
  • 误触发:收窄 description,加入 negative cases。
  • 步骤漏掉:改 SKILL.md 的 workflow。
  • 输出格式不稳定:加 output template 到 assets/
  • 确定性检查不稳定:写 script。
  • 参考信息太长:拆到 references/
  • 工具权限不够:补 allowed tools。
  • 工具权限太大:收紧 allowed tools。
  • 模型能力不够:换更适合的 model。

然后再跑一轮 eval。

这就是 Skill 的优化闭环:

1
2
3
4
5
6
7
8
写 Skill
→ 准备 test data
→ 运行 eval
→ 逐项打分
→ 找失败原因
→ 修改 Skill
→ 再跑 eval
→ 达到最低分数线,或者至少知道它的边界

如果是高频、复杂、要交给别人使用的 Skill,最好跑过这个闭环。

否则它可能只是一个未经验证的 Prompt 文件。

一个好 Skill 应该是什么样的?

一个好 Skill 不需要很玄。

它只需要做到几件事:

  1. 能被正确触发。
  2. 不该触发时保持安静。
  3. 工具权限足够但不过度。
  4. 模型选择符合任务成本和难度。
  5. SKILL.md 足够短,资料按需展开。
  6. 重要 Skill 最好有 test data、有 eval、有失败案例、有迭代。

所以写 Skill 时,不要只问:

“我要告诉模型什么?”

更应该问:

  • 用户说出哪些话时,这个 Skill 应该出现?
  • 它出现后,应该按什么流程做?
  • 它允许用哪些工具,不允许做什么?
  • 它需要什么模型?
  • 哪些内容应该留在主文件,哪些应该拆出去?
  • 我要怎么证明它真的有效?

这才是 Skill 和 Prompt 最大的区别。

Prompt 解决的是这一次对话。

Skill 解决的是之后一百次类似任务。

它不是把提示词写长。

它是把经验固化成一个可触发、可执行、可测试、可维护的工作流。