编写技能
如何编写、测试并迭代一个 SKILL.md — 选择模式、调优描述、让它可靠触发的完整流程
概述 介绍了什么是 Agent Skills。5 种技能设计模式 罗列了技能可能呈现的结构形态。本页讨论生产过程 —如何真正写出一个技能、验证它是否工作、并在不过拟合测试用例的前提下持续改进它。
作者循环 (Authoring Loop)
要写出能经受真实用户检验的技能,必须依赖迭代。起草一版 → 用真实 prompt 测试 → 看输出 → 改进。大部分收益藏在循环里,而不是第一稿。
五个活动围绕同一个产物展开:
- 意图捕获 (Capture Intent) — 每个技能仅一次。技能要让 Agent 做什么?何时触发?期望输出是什么?
- 起草 (Draft) — 从 设计模式 中选一种作为起点,填充 SKILL.md。
- 测试 (Test) — 用 2–3 个真实 prompt 启用技能运行,同时跑一组不启用技能的基线对比。
- 评审 (Review) — 定性阅读输出,定量追踪可客观断言的指标。
- 改进 (Improve) — 从反馈中泛化,不要把具体用例”打补丁”进去,然后回到第 3 步。
保持每轮循环廉价。一轮只需几分钟,你才敢尝试大胆改动并果断丢弃;一轮要几小时,你会被迫过早承诺一个可能走不远的设计。
1. 意图捕获
动笔之前先回答四个问题:
- 这个技能要让 Agent 能做什么? 描述能力,而非实现。
- 何时触发? 用户会说什么短语、处于什么上下文、涉及哪些文件类型?这将直接成为 description 的内容。
- 期望输出是什么? 文件格式、章节结构、字段布局。
- 输出适合自动化测试吗? 客观输出(文件转换、数据抽取、代码生成、固定流程步骤)适合。主观输出(写作语气、创意工作)通常不适合 — 定性评审更合适。
如果用户是在某次对话中途说”把这个变成一个技能”,先从对话历史里提取答案 —使用过的工具、步骤顺序、用户做过的修正。只在信息有缺口时提问。动手前确认一遍。
2. 起草 SKILL.md
Frontmatter
---
name: skill-name
description: 用一两句话说清这个技能做什么 AND 何时使用它。
---
仅 name 和 description 是必填的。其他字段(兼容性、许可证)可选,多数情况下用不上。
形态选择。 从 5 种设计模式 里选一种作为起点。大部分技能都从 Tool
Wrapper 开始(指令 + references/),只有在迭代信号明确要求时才升级到更重的模式 —见下方
模式演进。
正文长度
正文控制在 500 行以内。接近上限时,把细节拆到
references/,在 SKILL.md 中留一个短索引指向下一步读哪个文件。较大的 reference 文件(>300 行)应包含目录,让 Agent 能跳到相关章节而非整体加载。
多变体技能
当技能服务于多个变体(AWS / GCP / Azure;Python / TypeScript / Rust)时,按变体分组,让 SKILL.md 充当路由器:
cloud-deploy/
├── SKILL.md # 工作流 + 变体选择规则
└── references/
├── aws.md
├── gcp.md
└── azure.md
Agent 只读它当前需要的变体。每增加一个变体只多一个小文件,而不是在单体 SKILL.md 里多一条分支。
3. 写作风格
四条看似简单却影响深远的规则。
优先使用祈使语气。 从栈跟踪中提取错误码 比 你应该提取错误码
读起来更干净。把 Agent 当作刚加入项目的胜任同事对待,不要把它当作被指挥的用户。
解释”为什么”。 LLM 具备良好的 theory of mind。告诉它 “我们把 session token 存在 sessionStore
里,因为中间件 X在建立请求上下文时会读这个值” 比 “ALWAYS 写 session token 到 sessionStore”
更鲁棒。当 Agent 遇到技能没预见的边界情况时,理解理由使它能泛化;裸露的规则只会崩坏。
慎用全大写的 MUST。 如果你正在写 ALWAYS 或 NEVER
这类全大写词,或者在用一层僵硬的脚手架强制行为,这就是个黄灯信号。用推理重构一遍,通常能以更可靠的方式得到同样的结果。
泛化而非过拟合。 你是在为未来的百万次调用写,不是为眼前三个测试 prompt 写。某次测试失败时,忍住再加一条 MUST 条款去专门针对它的冲动。退一步想 — 这背后代表的是哪一类问题?
4. 描述调优
description 字段是 SKILL.md 里最重要的一行。它是 Agent 在 L1 metadata 加载阶段看到的内容 — 约 100 token 的钩子,决定了这个技能在当前轮次会不会被列入候选。
Agent 默认会触发不足 (undertrigger)
实际观察表明,Agent 常常不使用本该有帮助的技能。模型看到描述后会判断”我用基础工具就能处理”,然后跳过技能。对抗这个偏差的方式是把描述写得比自然感觉稍微”主动”一点:
差:
How to build a dashboard to display internal data.
好:
How to build a fast dashboard to display internal data. Use this skill whenever the user
mentions dashboards, data visualization, internal metrics, or wants to display company data —
even if they don't explicitly ask for a "dashboard."
第二版列出了触发短语,并明确推动 Agent 激活。这不是欺骗,而是在补偿 Agent 跳过技能的默认倾向。
一份好描述的要素
- 具体触发短语 — 用户真实会打出的词,而非抽象概念
- 范围信号 — 什么属于范围、什么不属于,避免在相邻任务上误触发
- 上下文标记 — 文件类型、领域、用户会提及的工具
评估触发准确度
若要严格调优描述,生成 20 个真实查询 — 10 个应该触发、10 个不应该触发。难写的是不应触发的那组:它们必须是 near-miss(相近但不触发)查询 —与技能共享关键词但实际需要别的东西。用 “写一个斐波那契函数” 作为 PDF 技能的负例太容易了 — 它什么都测不出来。
量化触发率(每个查询多跑几次,模型不是确定性的),反复修改描述直到两端都达标:正例上高触发、负例上低触发。
一个提醒:简单的一步查询如 “read this PDF” 即便描述完美也可能不触发技能 — Agent 能直接处理。你的评估查询要足够有分量,让”咨询技能”真的有价值。
5. 测试与迭代
什么时候值得写断言
测试用例的投入在技能有可客观验证的输出时获得回报:
| 输出类型 | 断言方式 |
|---|---|
| 文件转换(docx、xlsx、csv) | 结构、内容、数量检查 |
| 数据抽取 | 字段级相等比较 |
| 代码生成 | 编译 + 单元测试 |
| 固定流程步骤 | 步骤的存在性与顺序检查 |
对于主观输出 — 写作语气、设计质量、解释清晰度 — 跳过自动断言,依赖定性评审。强行给主观内容加断言会产生两种糟糕的结果:要么是永远通过、与技能质量无关的”水断言”;要么是对美学变化过于敏感的脆弱断言。
如何运行一轮迭代
每一轮:
- 用测试 prompt 运行技能,同时跑一组”不启用技能”的基线,以便看到技能到底增值了什么
- 评审输出 — 哪里不对、哪里意外、哪里缺失
- 做 1–2 个有针对性的改进,而非一次改十处
- 重跑,判断修复是泛化了还是只补丁了单个失败用例
迭代启发式
读 transcript,不要只读最终输出。 如果 Agent 用了 8 轮但 2 轮就能完成,说明技能在让它绕路。寻找无效循环 — 最简洁的优化往往藏在那里。
把重复工作沉淀到 scripts/。 如果三次独立测试都写出了相似的辅助脚本,那这个脚本应该被技能自带。写一次、放进
scripts/、让技能显式调用。以后每次调用都省掉重新推导的成本。
保持指令精简。 砍掉没有为准确性做贡献的指令。字数多 ≠ 可靠性高 — 往往只是出错方式变多。
反馈很简短时,要多看几眼。 用户一句”这不对”是信号而不是结论。走进他的视角,搞清楚到底哪里失败了,修复底层模式,而不是表面的抱怨。
6. 模式演进 (Pattern Evolution)
迭代不仅改善技能的内容,有时还会改变它的形态。一个 Tool Wrapper 若反复重新推导同一个模板,它在呼唤变成 Generator;一个 Generator 若步骤顺序漂移不定,它在呼唤变成 Pipeline。
两个典型信号:
- 输出中反复出现的结构 → 把结构提升为
assets/template.*。技能从 Tool Wrapper 迁移到 Generator。 - 步骤顺序或验证没有被强制 → 加入带门控的
scripts/和分步式 SKILL.md 正文。技能迁移到 Pipeline。
反向也成立。如果你一次性加了 scripts/
却从未用过,就删掉。无法证明自己维护成本合理的结构应当收缩。迭代的目的不是往阶梯上爬,而是停在那个真正承重的台阶。
反模式
- 写完技能就宣告胜利。 没测试过的技能只是一个假设。出手前至少跑 2–3 个真实 prompt。
- 对测试 prompt 过拟合。
如果用户问 Q4,则…这种规则是把失败用例打了补丁但破坏了泛化。 - 全大写 MUST 块。 用大写祈使恐吓模型通常不如解释理由有效。
- 模糊的描述。 抽象描述让技能触发不可靠,正文再好也白搭。
- 单体巨型 SKILL.md。
500 行以上没有分层的 SKILL.md 会让 Agent 每次都把它整体加载,token 成本压过收益。把细节拆到
references/。
相关阅读
- 概述 — 什么是 Agent Skills、Progressive Disclosure 的工作原理
- 5 种技能设计模式 — 上文引用的结构模板
- agentskills.io 规范 — SKILL.md 的开放格式
- Anthropic 的 skill-creator — 本文方法论的主要来源