当需要创建新技能、编辑现有技能或在部署前验证技能是否正常工作时使用
编写技能
概述
编写技能就是将测试驱动开发应用于流程文档。
个人技能存放在运行时的技能目录中——路径请参见 claude-code-tools.md、codex-tools.md、copilot-tools.md 或 gemini-tools.md。Codex、Copilot CLI 和 Gemini CLI 也都将 ~/.agents/skills/ 识别为跨运行时别名。
你编写测试用例(包含子代理的压力场景),观察它们失败(基线行为),编写技能(文档),观察测试通过(代理遵守),然后重构(堵住漏洞)。
核心原则: 如果你没有观察过代理在没有技能的情况下失败,你就不知道技能是否教会了正确的东西。
必需背景: 在使用此技能之前,你必须理解 superpowers:test-driven-development。该技能定义了基本的 RED-GREEN-REFACTOR 循环。本技能将 TDD 适配到文档编写。
官方指南: 有关 Anthropic 官方的技能编写最佳实践,请参见 anthropic-best-practices.md。本文档提供了额外的模式和指南,补充了本技能中 TDD 聚焦的方法。
什么是技能?
技能是经过验证的技术、模式或工具的参考指南。技能帮助未来的代理找到并应用有效的方法。
技能是: 可复用的技术、模式、工具、参考指南
技能不是: 关于你如何解决某个问题的叙述
技能的 TDD 映射
| TDD 概念 | 技能创建 |
|---|---|
| 测试用例 | 包含子代理的压力场景 |
| 生产代码 | 技能文档 (SKILL.md) |
| 测试失败 (RED) | 代理在没有技能时违反规则(基线) |
| 测试通过 (GREEN) | 代理在有技能时遵守规则 |
| 重构 | 在保持合规的同时堵住漏洞 |
| 先写测试 | 在编写技能之前运行基线场景 |
| 观察失败 | 记录代理使用的确切理由 |
| 最小代码 | 编写针对这些特定违规行为的技能 |
| 观察通过 | 验证代理现在遵守规则 |
| 重构循环 | 发现新的理由 → 堵住 → 重新验证 |
整个技能创建过程遵循 RED-GREEN-REFACTOR。
何时创建技能
创建时机:
- 该技术对你来说并非直观明显
- 你会在多个项目中再次参考它
- 模式适用范围广(非项目特定)
- 其他人会受益
不要为以下情况创建:
- 一次性解决方案
- 其他地方已有良好文档的标准实践
- 项目特定的约定(放在你的指令文件中)
- 机械约束(如果可以用正则表达式/验证强制执行,就自动化——将文档留给需要判断的情况)
技能类型
技术
具有可遵循步骤的具体方法(condition-based-waiting、root-cause-tracing)
模式
思考问题的方式(flatten-with-flags、test-invariants)
参考
API 文档、语法指南、工具文档(office docs)
目录结构
skills/
skill-name/
SKILL.md # 主要参考(必需)
supporting-file.* # 仅在需要时
扁平命名空间 - 所有技能都在一个可搜索的命名空间中
单独文件用于:
- 大量参考(100 行以上)- API 文档、全面语法
- 可复用工具 - 脚本、实用程序、模板
保持内联:
- 原则和概念
- 代码模式(少于 50 行)
- 其他所有内容
SKILL.md 结构
前置元数据 (YAML):
- 两个必需字段:
name和description(所有支持的字段请参见 agentskills.io/specification) - 总字符数最多 1024
name:仅使用字母、数字和连字符(无括号、特殊字符)description:第三人称,仅描述何时使用(而非做什么)- 以“Use when...”开头,聚焦触发条件
- 包含具体症状、情境和上下文
- 切勿总结技能的过程或工作流(原因见 SDO 部分)
- 如果可能,保持在 500 字符以内
---
name: Skill-Name-With-Hyphens
description: Use when [具体的触发条件和症状]
---
# Skill Name
## Overview
这是什么?用 1-2 句话说明核心原则。
## When to Use
[如果决策不直观,使用小型内联流程图]
包含症状和用例的列表
何时不使用
## Core Pattern(针对技术/模式)
前后代码对比
## Quick Reference
用于快速浏览常见操作的表格或列表
## Implementation
简单模式使用内联代码
大量参考或可复用工具链接到文件
## Common Mistakes
出错的地方 + 修复方法
## Real-World Impact(可选)
具体结果
技能发现优化 (SDO)
对发现至关重要: 未来的代理需要找到你的技能
1. 丰富的描述字段
目的: 你的代理读取描述以决定为给定任务加载哪些技能。让它回答:“我现在应该阅读这个技能吗?”
格式: 以“Use when...”开头,聚焦触发条件
关键:描述 = 何时使用,而非技能做什么
描述应仅描述触发条件。不要在描述中总结技能的过程或工作流。
为什么这很重要: 测试表明,当描述总结了技能的工作流时,代理可能会遵循描述而不是阅读完整的技能内容。一个描述为“在任务之间进行代码审查”的技能导致代理只进行了一次审查,尽管技能的流程图清楚地显示了两次审查(先规范合规,再代码质量)。
当描述改为“Use when executing implementation plans with independent tasks”(没有工作流总结)时,代理正确地阅读了流程图并遵循了两阶段审查过程。
陷阱: 总结工作流的描述会创建代理会走的捷径。技能正文成为代理跳过的文档。
# ❌ 错误:总结了工作流——代理可能会遵循此描述而不是阅读技能
description: Use when executing plans - dispatches subagent per task with code review between tasks
# ❌ 错误:过程细节太多
description: Use for TDD - write test first, watch it fail, write minimal code, refactor
# ✅ 正确:仅触发条件,无工作流总结
description: Use when executing implementation plans with independent tasks in the current session
# ✅ 正确:仅触发条件
description: Use when implementing any feature or bugfix, before writing implementation code
内容:
- 使用具体的触发器、症状和情境来表明该技能适用
- 描述问题(竞态条件、不一致行为)而非语言特定的症状(setTimeout、sleep)
- 保持触发器与技术无关,除非技能本身是技术特定的
- 如果技能是技术特定的,在触发器中明确说明
- 使用第三人称(注入到系统提示中)
- 切勿总结技能的过程或工作流
# ❌ 错误:过于抽象、模糊,未包含何时使用
description: For async testing
# ❌ 错误:第一人称
description: I can help you with async tests when they're flaky
# ❌ 错误:提到了技术但技能并非特定于该技术
description: Use when tests use setTimeout/sleep and are flaky
# ✅ 正确:以“Use when”开头,描述问题,无工作流
description: Use when tests have race conditions, timing dependencies, or pass/fail inconsistently
# ✅ 正确:技术特定技能,带有明确触发器
description: Use when using React Router and handling authentication redirects
2. 关键词覆盖
使用代理可能搜索的词:
- 错误消息:“Hook timed out”、“ENOTEMPTY”、“race condition”
- 症状:“flaky”、“hanging”、“zombie”、“pollution”
- 同义词:“timeout/hang/freeze”、“cleanup/teardown/afterEach”
- 工具:实际命令、库名、文件类型
3. 描述性命名
使用主动语态,动词优先:
- ✅
creating-skills而非skill-creation - ✅
condition-based-waiting而非async-test-helpers
4. Token 效率(关键)
问题: 入门指南和频繁引用的技能会加载到每次对话中。每个 token 都很重要。
目标字数:
- 入门工作流:每个 <150 词
- 频繁加载的技能:总计 <200 词
- 其他技能:<500 词(仍需简洁)
技巧:
将细节移至工具帮助:
# ❌ 错误:在 SKILL.md 中记录所有标志
search-conversations supports --text, --both, --after DATE, --before DATE, --limit N
# ✅ 正确:引用 --help
search-conversations supports multiple modes and filters. Run --help for details.
使用交叉引用:
# ❌ 错误:重复工作流细节
When searching, dispatch subagent with template...
[20 lines of repeated instructions]
# ✅ 正确:引用其他技能
Always use subagents (50-100x context savings). REQUIRED: Use [other-skill-name] for workflow.
压缩示例:
# ❌ 错误:冗长示例(42 词)
your human partner: "How did we handle authentication errors in React Router before?"
You: I'll search past conversations for React Router authentication patterns.
[Dispatch subagent with search query: "React Router authentication error handling 401"]
# ✅ 正确:最小示例(20 词)
Partner: "How did we handle auth errors in React Router?"
You: Searching...
[Dispatch subagent → synthesis]
消除冗余:
- 不要重复交叉引用技能中的内容
- 不要解释命令中显而易见的内容
- 不要包含同一模式的多个示例
验证:
wc -w skills/path/SKILL.md
# 入门工作流:目标每个 <150
# 其他频繁加载:目标总计 <200
根据你做什么或核心见解命名:
- ✅
condition-based-waiting>async-test-helpers - ✅
using-skills而非skill-usage - ✅
flatten-with-flags>data-structure-refactoring - ✅
root-cause-tracing>debugging-techniques
动名词 (-ing) 适用于过程:
creating-skills、testing-skills、debugging-with-logs- 主动,描述你正在采取的行动
5. 交叉引用其他技能
在编写引用其他技能的文档时:
仅使用技能名称,并带有明确的必需标记:
- ✅ 正确:
**REQUIRED SUB-SKILL:** Use superpowers:test-driven-development - ✅ 正确:
**REQUIRED BACKGROUND:** You MUST understand superpowers:systematic-debugging - ❌ 错误:
See skills/testing/test-driven-development(不清楚是否必需) - ❌ 错误:
@skills/testing/test-driven-development/SKILL.md(强制加载,消耗上下文)
为什么不用 @ 链接: @ 语法会立即强制加载文件,在需要之前就消耗 200k+ 上下文。
流程图使用
digraph when_flowchart {
"Need to show information?" [shape=diamond];
"Decision where I might go wrong?" [shape=diamond];
"Use markdown" [shape=box];
"Small inline flowchart" [shape=box];
"Need to show information?" -> "Decision where I might go wrong?" [label="yes"];
"Decision where I might go wrong?" -> "Small inline flowchart" [label="yes"];
"Decision where I might go wrong?" -> "Use markdown" [label="no"];
}
仅在以下情况使用流程图:
- 非显而易见的决策点
- 可能过早停止的过程循环
- “何时使用 A 与 B”的决策
切勿将流程图用于:
- 参考资料 → 表格、列表
- 代码示例 → Markdown 代码块
- 线性指令 → 编号列表
- 没有语义含义的标签(step1、helper2)
有关 graphviz 样式规则,请参见此目录中的 graphviz-conventions.dot。
为人类伙伴可视化: 使用此目录中的 render-graphs.js 将技能的流程图渲染为 SVG:
./render-graphs.js ../some-skill # 每个图表单独
./render-graphs.js ../some-skill --combine # 所有图表在一个 SVG 中
代码示例
一个优秀的示例胜过多个平庸的示例
选择最相关的语言:
- 测试技术 → TypeScript/JavaScript
- 系统调试 → Shell/Python
- 数据处理 → Python
好的示例:
- 完整且可运行
- 注释充分,解释为什么
- 来自真实场景
- 清晰展示模式
- 可直接改编(非通用模板)
不要:
- 用 5 种以上语言实现
- 创建填空模板
- 编写牵强的示例
你擅长移植——一个优秀的示例就足够了。
文件组织
自包含技能
defense-in-depth/
SKILL.md # 所有内容内联
适用场景:所有内容都适合,无需大量参考
带有可复用工具的技能
condition-based-waiting/
SKILL.md # 概述 + 模式
example.ts # 可改编的工作辅助工具
适用场景:工具是可复用的代码,而不仅仅是叙述
带有大量参考的技能
pptx/
SKILL.md # 概述 + 工作流
pptxgenjs.md # 600 行 API 参考
ooxml.md # 500 行 XML 结构
scripts/ # 可执行工具
适用场景:参考资料太大,无法内联
铁律(与 TDD 相同)
没有失败的测试,就没有技能
这适用于新技能和现有技能的编辑。
先写技能再测试?删除它。重新开始。
编辑技能而不测试?同样的违规。
没有例外:
- 不适用于“简单添加”
- 不适用于“只是添加一个部分”
- 不适用于“文档更新”
- 不要将未经测试的更改保留为“参考”
- 不要在运行测试时“改编”
- 删除意味着删除
必需背景: superpowers:test-driven-development 技能解释了为什么这很重要。同样的原则适用于文档。
测试所有技能类型
不同类型的技能需要不同的测试方法:
纪律执行技能(规则/要求)
示例: TDD、verification-before-completion、designing-before-coding
测试方法:
- 学术问题:他们理解规则吗?
- 压力场景:他们在压力下遵守吗?
- 多种压力组合:时间 + 沉没成本 + 疲惫
- 识别理由并添加明确的对抗措施
成功标准: 代理在最大压力下遵循规则
技术技能(操作指南)
示例: condition-based-waiting、root-cause-tracing、defensive-programming
测试方法:
- 应用场景:他们能正确应用技术吗?
- 变体场景:他们能处理边缘情况吗?
- 信息缺失测试:指令是否有空白?
成功标准: 代理成功将技术应用于新场景
模式技能(心智模型)
示例: reducing-complexity、information-hiding concepts
测试方法:
- 识别场景:他们能识别模式何时适用吗?
- 应用场景:他们能使用心智模型吗?
- 反例:他们知道何时不适用吗?
成功标准: 代理正确识别何时/如何应用模式
参考技能(文档/API)
示例: API 文档、命令参考、库指南
测试方法:
- 检索场景:他们能找到正确的信息吗?
- 应用场景:他们能正确使用找到的信息吗?
- 空白测试:常见用例是否覆盖?
成功标准: 代理找到并正确应用参考信息
跳过测试的常见理由
| 借口 | 现实 |
|---|---|
| “技能显然很清楚” | 对你清楚 ≠ 对其他代理清楚。测试它。 |
| “这只是个参考” | 参考可能有空白、不清晰的部分。测试检索。 |
| “测试是过度杀伤” | 未经测试的技能总有问题。15 分钟测试节省数小时。 |
| “如果出现问题我会测试” | 问题 = 代理无法使用技能。在部署前测试。 |
| “测试太繁琐” | 测试比在生产中调试糟糕的技能更不繁琐。 |
| “我确信它很好” | 过度自信保证有问题。无论如何都要测试。 |
| “学术审查就够了” | 阅读 ≠ 使用。测试应用场景。 |
| “没时间测试” | 部署未经测试的技能以后修复会浪费更多时间。 |
所有这些都意味着:在部署前测试。没有例外。
使形式匹配失败类型
在编写指导之前,先分类基线失败。一种形式能防住一种失败类型,却可能明显适得其反于另一种。
| 基线失败 | 正确形式 | 错误形式 |
|---|---|---|
| 在压力下跳过/违反规则(知道更好,但还是做了) | 禁止 + 理由表 + 红旗(见下面的防弹) | 软指导(“prefer...”、“consider...”) |
| 遵守规则,但输出形状错误(提示臃肿、结论埋藏、重复规范) | 正面配方或契约:说明输出是什么——其部分和顺序 | 禁止列表(“don't restate”、“never narrate”) |
| 遗漏了已生成内容中的必需元素 | 结构性:他们填写的模板中的 REQUIRED 字段或槽位 | 模板附近的散文提醒 |
| 行为应取决于条件 | 条件性,键控于可观察谓词(“if the brief exists, reference it”) | 无条件规则 + 豁免条款 |
为什么禁止在塑造问题上适得其反: 在竞争性激励(“使提示自包含”)下,代理与“不要 X”讨价还价。在调度提示指导的正面措辞测试中,禁止臂产生的非期望内容明显多于配方臂(完全分离的分布),并且趋势甚至比无指导控制更差——请微测试你自己的案例而不是假设,但永远不要默认使用禁止。配方没有讨价还价的余地:输出要么匹配所述形状,要么不匹配。
无论你选择哪种形式,规则如下:
- 没有细微差别条款。 “除非重要否则不要 X”重新开启谈判——在获胜配方上附加一个细微差别条款使其从一致变为嘈杂,同样的措辞测试中也是如此。将真正的例外表达为基于可观察谓词的独立条件。
- 豁免条款不会限定范围。 “此限制不适用于代码块”仍然抑制代码块。如果输出的部分必须豁免,重新构建结构使规则无法触及它。
使技能防弹,防止理由化
执行纪律的技能(如 TDD)需要抵抗理由化。代理很聪明,会在压力下找到漏洞。
范围: 此工具包适用于纪律失败——代理知道规则但在压力下跳过它。对于形状错误的输出或遗漏元素,基于禁止的防弹会适得其反;请使用“使形式匹配失败类型”中的形式。
心理学说明: 理解为什么说服技巧有效有助于你系统性地应用它们。关于权威、承诺、稀缺、社会认同和统一原则的研究基础,请参见 persuasion-principles.md(Cialdini, 2021; Meincke et al., 2025)。
明确堵住每一个漏洞
不要只陈述规则——禁止特定的变通方法:
<错误>
Write code before test? Delete it.
</错误>
<正确>
Write code before test? Delete it. Start over.
**No exceptions:**
- Don't keep it as "reference"
- Don't "adapt" it while writing tests
- Don't look at it
- Delete means delete
</正确>
处理“精神与文字”的争论
尽早添加基本原则:
**Violating the letter of the rules is violating the spirit of the rules.**
这切断了整类“我在遵循精神”的理由。
构建理由表
从基线测试中捕获理由(见下面的测试部分)。代理使用的每一个借口都放入表中:
| Excuse | Reality |
|--------|---------|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll test after" | Tests passing immediately prove nothing. |
| "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
创建红旗列表
使代理在理由化时易于自我检查:
## Red Flags - STOP and Start Over
- Code before test
- "I already manually tested it"
- "Tests after achieve the same purpose"
- "It's about spirit not ritual"
- "This is different because..."
**All of these mean: Delete code. Start over with TDD.**
更新 SDO 以包含违规症状
在描述中添加:你即将违反规则时的症状:
description: use when implementing any feature or bugfix, before writing implementation code
技能的 RED-GREEN-REFACTOR
遵循 TDD 循环:
RED:编写失败的测试(基线)
在没有技能的情况下,使用子代理运行压力场景。记录确切行为:
- 他们做了什么选择?
- 他们使用了什么理由(逐字)?
- 哪些压力触发了违规?
这是“观察测试失败”——你必须在编写技能之前看到代理自然的行为。
GREEN:编写最小技能
编写针对这些特定理由的技能。不要为假设情况添加额外内容。
使用技能运行相同场景。代理现在应遵守。
REFACTOR:堵住漏洞
代理发现了新的理由?添加明确的对抗措施。重新测试直到防弹。
在完整场景之前微测试措辞
完整的压力场景运行是最终关卡,但每次迭代缓慢且昂贵。首先用微测试验证措辞本身:
- 每次调用一个全新上下文的样本——原始 API 调用,或者如果你没有 API 访问权限,则使用单次子代理。系统提示 = 指导将存在的现实上下文(完整的技能或提示模板,而非孤立的指导);用户消息 = 一个诱使失败的任务。
- 始终包含无指导控制。 如果控制没有表现出失败,就没有什么需要修复的——停止,不要编写指导。
- 每个变体 5 次以上重复。 单个样本会撒谎。
- 手动阅读每个标记的匹配。 如果你愿意,可以编程评分,但模板回显和引用的反例会伪装成命中;仅自动计数会高估失败和成功。
- 方差是一个指标。 当指导落地时,重复会收敛到相同的形状。五次重复中五种不同的解释意味着措辞没有约束力——在添加词语之前收紧形式。
微测试验证措辞;它们不能替代纪律技能的压力场景。
测试方法: 完整的测试方法请参见 testing-skills-with-subagents.md:
- 如何编写压力场景
- 压力类型(时间、沉没成本、权威、疲惫)
- 系统性地堵住漏洞
- 元测试技术
反模式
❌ 叙述性示例
"In session 2025-10-03, we found empty projectDir caused..."
为什么不好: 过于具体,不可复用
❌ 多语言稀释
example-js.js, example-py.py, example-go.go
为什么不好: 质量平庸,维护负担
❌ 流程图中的代码
step1 [label="import fs"];
step2 [label="read file"];
为什么不好: 无法复制粘贴,难以阅读
❌ 通用标签
helper1, helper2, step3, pattern4
为什么不好: 标签应有语义含义
停止:在进入下一个技能之前
在编写任何技能之后,你必须停止并完成部署过程。
不要:
- 批量创建多个技能而不测试每个
- 在当前技能验证之前进入下一个技能
- 因为“批处理更高效”而跳过测试
下面的部署检查清单对每个技能都是强制性的。
部署未经测试的技能 = 部署未经测试的代码。这是对质量标准的违反。
技能创建检查清单(TDD 改编)
重要:为下面的每个检查清单项创建一个待办事项。
RED 阶段 - 编写失败的测试:
- [ ] 创建压力场景(纪律技能需要 3 种以上组合压力)
- [ ] 在没有技能的情况下运行场景 - 逐字记录基线行为
- [ ] 识别理由/失败的模式
GREEN 阶段 - 编写最小技能:
- [ ] 名称仅使用字母、数字、连字符(无括号/特殊字符)
- [ ] YAML 前置元数据包含必需的
name和description字段(最多 1024 字符;参见 spec) - [ ] 描述以“Use when...”开头,包含具体触发器/症状
- [ ] 描述使用第三人称
- [ ] 全文包含关键词以便搜索(错误、症状、工具)
- [ ] 清晰的概述,包含核心原则
- [ ] 针对 RED 中识别的特定基线失败
- [ ] 指导形式匹配失败类型(见“使形式匹配失败类型”)
- [ ] 对于行为塑造指导:措辞已针对无指导控制进行微测试(5 次以上重复,每个标记的匹配手动阅读)——纯参考技能不适用
- [ ] 代码内联或链接到单独文件
- [ ] 一个优秀的示例(非多语言)
- [ ] 使用技能运行场景 - 验证代理现在遵守
REFACTOR 阶段 - 堵住漏洞:
- [ ] 从测试中识别新的理由
- [ ] 添加明确的对抗措施(如果是纪律技能)
- [ ] 从所有测试迭代中构建理由表
- [ ] 创建红旗列表
- [ ] 重新测试直到防弹
质量检查:
- [ ] 仅当决策不直观时使用小型流程图
- [ ] 快速参考表
- [ ] 常见错误部分
- [ ] 没有叙述性故事
- [ ] 仅当工具或大量参考时使用支持文件
部署:
- [ ] 将技能提交到 git 并推送到你的分支(如果已配置)
- [ ] 考虑通过 PR 贡献回来(如果广泛有用)
发现工作流
未来的代理如何找到你的技能:
- 遇到问题(“tests are flaky”)
- 搜索技能(grep 描述,浏览类别)
- 找到技能(描述匹配)
- 扫描概述(这相关吗?)
- 阅读模式(快速参考表)
- 加载示例(仅在实现时)
针对此流程优化 - 尽早并经常放置可搜索的术语。
底线
创建技能就是流程文档的 TDD。
同样的铁律:没有失败的测试就没有技能。
同样的循环:RED(基线)→ GREEN(编写技能)→ REFACTOR(堵住漏洞)。
同样的好处:更好的质量,更少的意外,防弹的结果。
如果你对代码遵循 TDD,那么对技能也要遵循。这是应用于文档的同一纪律。






