编写技能

如何编写、测试并迭代一个 SKILL.md — 选择模式、调优描述、让它可靠触发的完整流程

概述 介绍了什么是 Agent Skills。5 种技能设计模式 罗列了技能可能呈现的结构形态。本页讨论生产过程 —如何真正写出一个技能、验证它是否工作、并在不过拟合测试用例的前提下持续改进它。


作者循环 (Authoring Loop)

要写出能经受真实用户检验的技能,必须依赖迭代。起草一版 → 用真实 prompt 测试 → 看输出 → 改进。大部分收益藏在循环里,而不是第一稿。

SKILL 作者循环 (Authoring Loop) 起草 → 测试 → 评审 → 改进 → 循环迭代 ① 意图捕获 每个技能一次 ② 起草 选择模式 ③ 测试 启用技能运行 ④ 评审 定性 + 指标 ⑤ 改进 泛化避免过拟合 SKILL.md 迭代塑造的产物 运行 评分 反馈 修订

五个活动围绕同一个产物展开:

  1. 意图捕获 (Capture Intent) — 每个技能仅一次。技能要让 Agent 做什么?何时触发?期望输出是什么?
  2. 起草 (Draft) — 从 设计模式 中选一种作为起点,填充 SKILL.md。
  3. 测试 (Test) — 用 2–3 个真实 prompt 启用技能运行,同时跑一组不启用技能的基线对比。
  4. 评审 (Review) — 定性阅读输出,定量追踪可客观断言的指标。
  5. 改进 (Improve) — 从反馈中泛化,不要把具体用例”打补丁”进去,然后回到第 3 步。

保持每轮循环廉价。一轮只需几分钟,你才敢尝试大胆改动并果断丢弃;一轮要几小时,你会被迫过早承诺一个可能走不远的设计。


1. 意图捕获

动笔之前先回答四个问题:

  1. 这个技能要让 Agent 能做什么? 描述能力,而非实现。
  2. 何时触发? 用户会说什么短语、处于什么上下文、涉及哪些文件类型?这将直接成为 description 的内容。
  3. 期望输出是什么? 文件格式、章节结构、字段布局。
  4. 输出适合自动化测试吗? 客观输出(文件转换、数据抽取、代码生成、固定流程步骤)适合。主观输出(写作语气、创意工作)通常不适合 — 定性评审更合适。

如果用户是在某次对话中途说”把这个变成一个技能”,先从对话历史里提取答案 —使用过的工具、步骤顺序、用户做过的修正。只在信息有缺口时提问。动手前确认一遍。


2. 起草 SKILL.md

Frontmatter

---
name: skill-name
description: 用一两句话说清这个技能做什么 AND 何时使用它。
---

namedescription 是必填的。其他字段(兼容性、许可证)可选,多数情况下用不上。

形态选择。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。 如果你正在写 ALWAYSNEVER 这类全大写词,或者在用一层僵硬的脚手架强制行为,这就是个黄灯信号。用推理重构一遍,通常能以更可靠的方式得到同样的结果。

泛化而非过拟合。 你是在为未来的百万次调用写,不是为眼前三个测试 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)结构、内容、数量检查
数据抽取字段级相等比较
代码生成编译 + 单元测试
固定流程步骤步骤的存在性与顺序检查

对于主观输出 — 写作语气、设计质量、解释清晰度 — 跳过自动断言,依赖定性评审。强行给主观内容加断言会产生两种糟糕的结果:要么是永远通过、与技能质量无关的”水断言”;要么是对美学变化过于敏感的脆弱断言。

如何运行一轮迭代

每一轮:

  1. 用测试 prompt 运行技能,同时跑一组”不启用技能”的基线,以便看到技能到底增值了什么
  2. 评审输出 — 哪里不对、哪里意外、哪里缺失
  3. 做 1–2 个有针对性的改进,而非一次改十处
  4. 重跑,判断修复是泛化了还是只补丁了单个失败用例

迭代启发式

读 transcript,不要只读最终输出。 如果 Agent 用了 8 轮但 2 轮就能完成,说明技能在让它绕路。寻找无效循环 — 最简洁的优化往往藏在那里。

把重复工作沉淀到 scripts/ 如果三次独立测试都写出了相似的辅助脚本,那这个脚本应该被技能自带。写一次、放进 scripts/、让技能显式调用。以后每次调用都省掉重新推导的成本。

保持指令精简。 砍掉没有为准确性做贡献的指令。字数多 ≠ 可靠性高 — 往往只是出错方式变多。

反馈很简短时,要多看几眼。 用户一句”这不对”是信号而不是结论。走进他的视角,搞清楚到底哪里失败了,修复底层模式,而不是表面的抱怨。


6. 模式演进 (Pattern Evolution)

迭代不仅改善技能的内容,有时还会改变它的形态。一个 Tool Wrapper 若反复重新推导同一个模板,它在呼唤变成 Generator;一个 Generator 若步骤顺序漂移不定,它在呼唤变成 Pipeline。

迭代驱动的模式演进 (Pattern Evolution) 让测试结果告诉你何时升级结构 Tool Wrapper SKILL.md + references/ 起点 3/3 测试产出相似模板 → 提取到 assets/ Generator + assets/ 模板 加入结构约束 步骤需要强制顺序与验证 → 加入 scripts/ 与门控 Pipeline + scripts/ + 顺序门控 完整编排 模式也能收缩 — 当结构无法证明其成本时,应当简化

两个典型信号:

  • 输出中反复出现的结构 → 把结构提升为 assets/template.*。技能从 Tool Wrapper 迁移到 Generator
  • 步骤顺序或验证没有被强制 → 加入带门控的 scripts/ 和分步式 SKILL.md 正文。技能迁移到 Pipeline

反向也成立。如果你一次性加了 scripts/ 却从未用过,就删掉。无法证明自己维护成本合理的结构应当收缩。迭代的目的不是往阶梯上爬,而是停在那个真正承重的台阶


反模式

  • 写完技能就宣告胜利。 没测试过的技能只是一个假设。出手前至少跑 2–3 个真实 prompt。
  • 对测试 prompt 过拟合。 如果用户问 Q4,则… 这种规则是把失败用例打了补丁但破坏了泛化。
  • 全大写 MUST 块。 用大写祈使恐吓模型通常不如解释理由有效。
  • 模糊的描述。 抽象描述让技能触发不可靠,正文再好也白搭。
  • 单体巨型 SKILL.md。 500 行以上没有分层的 SKILL.md 会让 Agent 每次都把它整体加载,token 成本压过收益。把细节拆到 references/

相关阅读

这页有帮助吗?