摘要:作者在 Hugging Face 和 Google DeepMind 长期使用 Skills,从写好描述、控制自由度、覆盖反例到何时退役,提炼了 8 条让 Skill 真正好用的实战经验。
Skills 已经成为 agent 里最常用的扩展点之一。它们灵活、容易做、容易分发。
但灵活也带来一个麻烦:怎么判断什么是好的、什么真正能用?什么样的 skill 值得做?写出一个好 skill 的关键是什么?什么时候该把它分享出去?
我自己重度使用 skills,手头长期跑着不少。下面是这一路总结出来的一些经验。
1. 先搞清楚 Skill 是什么
一个 skill 就是一个文件夹,里面有一个 SKILL.md 文件,可选地配上一些辅助文件:
my-skill/
├── SKILL.md ← 唯一必需的文件
├── scripts/ ← agent 可调用的可复用代码
├── references/ ← agent 按需读取的文档
└── assets/ ← 模板、图片或输出用到的文件
一个 skill 由三层组成:
- Frontmatter(
name+description):每次 prompt 都会带上,告诉 agent 什么时候 用这个 skill。 SKILL.md正文:frontmatter 下方的 Markdown 指令,告诉 agent 怎么 完成任务。- Assets(可选):
scripts/、references/、assets/三个文件夹。
skill 永远落在两类里之一:
- Capability skills(能力型):补足基础模型做不稳定的事情(比如填 PDF 表单)。模型变强后这类可能就不再必要——靠 eval 来判断什么时候该撤。
- Preference skills(偏好型):把你的具体工作流编码下来(比如团队的 code review 流程)。这类生命周期长,但需要跟你实际流程保持同步。
2. 描述(description)写到位
SKILL.md 里的 description 是触发开关。写得太模糊,agent 不知道何时触发;写得太宽,每次请求都触发。一定要明确说清 skill 做什么 + 什么时候用,两个都要写进去。skill 正文只有在触发之后才会加载。
| ✗ 太模糊 | ✓ 具体且可执行 |
|---|---|
| 「辅助处理文档」 | 「创建、编辑、分析 .docx 文件,处理修订追踪、批注、格式或文本提取」 |
| 「API 助手」 | 「调用 Gemini API 写文本生成、多轮对话、图像生成或流式响应代码时使用」 |
我见过仅仅靠改写 description 就拿到 50% 提升的案例。
3. 写指令,别写论文
agent 很聪明。你的工作是告诉它它本来不知道的东西。研究表明,更长、塞更多 context 的指令实际上会损害性能。
- 用祈使句:「始终使用
interactions.create()」 是指令;「Interactions API 是推荐做法」 只是 trivia,agent 不会拿来行动。 - 示例先行:5 行代码片段胜过 5 段解释。
- 解释 why:当一条规则重要时,说明为什么。「用模型 X,模型 Y 已弃用且会报错」 能让 agent 跨用例泛化,而不是死记你那几个测试 prompt。
- 别过拟合:避免那种只为通过你三个测试 prompt 的「修修补补」。你要写的是能跑过几百万次调用的 skill。
4. 保持精简
别把所有东西都塞进一个文件里。agent 是分层加载信息的:
- 每次都加载:
SKILL.md的 frontmatter(name+description) - 触发后加载:
SKILL.md正文(控制在 500 行以内) - 按需加载:reference 文件、scripts、assets
如果你的 skill 覆盖多个主题(比如 AWS 和 GCP 部署),拆成独立的 reference 文件。agent 只读它真正需要的那一份,给真任务腾出 context。
Tip:单个 reference 文件超过 500 行时,在顶部加一个带「行号提示」的目录,agent 可以快速定位。
5. 把握合适的自由度
写 skill 常见的一个错误,是把它写成 step-by-step 的工作流:「第一步:读文件。第二步:解析 JSON。第三步:取出字段……」 当你规定每一步的时候,你也剥夺了 agent 自适应、纠错、找更好路径的能力。描述你想要什么,而不是怎么做到。
告诉 agent 要达成什么:
- ✗ 「第一步:读 config 文件。第二步:找到数据库 URL。第三步:改端口。第四步:写回文件。」
- ✓ 「按用户指定的值更新 config 文件里的数据库端口。」
给约束,而不是流程:
- ✗ 「第一步:建分支。第二步:改代码。第三步:跑测试。第四步:开 PR。」
- ✓ 「开 PR 之前必须跑测试。永远不要直接 push 到 main。」
如果步骤的精确顺序真的关键,那就写脚本。 如果一个任务脆弱到第三步在第二步前面就崩,那不是 skill 问题,是 scripting 问题。
6. 别跳过反例
想清楚 skill 在什么时候不应该触发。一句 「任何编码任务都用」 这种描述,会劫持每一次请求。
「处理 PDF 文件时使用。不要用于通用文档编辑、电子表格或纯文本文件。」
「应该触发」和「不应该触发」两类用例都要测。少了后者,你只会朝一个方向优化 skill。
7. Ship 之前先 evaluate
不评估就别上线。每次跑结果可能都不一样,单跑一次根本不够。
- 手动跑几遍,用不同 prompt。看它在哪里崩。是不是假设了某个依赖存在?是不是跳了步骤?
- 写下「成功」长什么样,要可衡量。输出能编译吗?用对了 API 吗?步骤都走完了吗?看结果,别看路径。
- 试 10–20 个 prompt。混入应该处理的、应该忽略的、刁钻的边界。每个 prompt 都该有自己的成功判据。
- 跑多轮。agent 输出非确定。每个 prompt 跑 3–5 轮,看分布而不是一次成败。
- 每轮隔离。每次测试用干净环境。轮次之间的 context 串扰会掩盖真实问题。
- 先修描述。多数问题出在触发器,不在指令。
8. 知道何时退役一个 skill
把 skill 关掉再跑 eval。如果照样能过,说明模型已经把这个 skill 的价值吸收了,skill 就没必要存在了——退役掉。这一点对 capability skills 尤其成立:模型变强,差距收窄。
想要一个具体的、step-by-step 的 eval 工作流,看 Practical Guide to Evaluating and Testing Agent Skills 。
