← Back to all skills

Writing Skills

writing-skills

Create, edit and validate skills before deploying them.

$ npx superpowers-zh
View source on GitHub ↗
📖 This skill's content is written in Chinese — superpowers-zh is a Chinese-localized toolkit.

编写技能

概述

编写技能就是将测试驱动开发应用于流程文档。

个人技能存放在智能体特定的目录中(Claude Code 用 ~/.claude/skills,Codex 用 ~/.agents/skills/

你编写测试用例(带子智能体的压力场景),观察它们失败(基线行为),编写技能(文档),观察测试通过(智能体遵守规则),然后重构(堵住漏洞)。

核心原则: 如果你没有观察到智能体在没有该技能时失败,你就不知道这个技能是否教了正确的东西。

必需背景: 在使用此技能前,你必须理解 superpowers:test-driven-development。该技能定义了基本的红-绿-重构循环。本技能将 TDD 适配到文档编写中。

官方指南: Anthropic 官方的技能编写最佳实践请参见 anthropic-best-practices.md。该文档提供了补充本技能 TDD 导向方法的额外模式和指南。

什么是技能?

技能是经过验证的技术、模式或工具的参考指南。技能帮助未来的 Claude 实例找到并应用有效的方法。

技能是: 可复用的技术、模式、工具、参考指南

技能不是: 关于你某次如何解决问题的叙事

TDD 映射到技能

TDD 概念技能创建
测试用例带子智能体的压力场景
生产代码技能文档(SKILL.md)
测试失败(红)智能体在没有技能时违反规则(基线)
测试通过(绿)智能体在有技能时遵守规则
重构在保持合规的同时堵住漏洞
先写测试在编写技能之前先运行基线场景
观察失败记录智能体使用的确切合理化借口
最小代码编写针对那些具体违规行为的技能
观察通过验证智能体现在遵守规则
重构循环发现新的合理化借口 → 堵住 → 重新验证

整个技能创建过程遵循红-绿-重构。

何时创建技能

创建条件:

不要创建:

技能类型

技术类

有具体步骤的方法(condition-based-waiting、root-cause-tracing)

模式类

思考问题的方式(flatten-with-flags、test-invariants)

参考类

API 文档、语法指南、工具文档(office docs)

目录结构

skills/
  skill-name/
    SKILL.md              # 主参考文档(必需)
    supporting-file.*     # 仅在需要时

扁平命名空间 - 所有技能在一个可搜索的命名空间中

分离文件的情况:

  1. 大量参考内容(100+ 行)- API 文档、全面的语法说明
  2. 可复用工具 - 脚本、实用程序、模板

保持内联:

SKILL.md 结构

Frontmatter(YAML):

---
name: Skill-Name-With-Hyphens
description: Use when [具体的触发条件和症状]
---

# 技能名称

## 概述
这是什么?用 1-2 句话说明核心原则。

## 何时使用
[如果决策不明显,使用小型内联流程图]

症状和用例的要点列表
不适用的场景

## 核心模式(技术/模式类)
前后代码对比

## 快速参考
用于快速浏览常见操作的表格或要点

## 实现
简单模式内联代码
大量参考或可复用工具链接到文件

## 常见错误
常见问题 + 修复方法

## 实际效果(可选)
具体结果

Claude 搜索优化(CSO)

发现至关重要: 未来的 Claude 需要找到你的技能

1. 丰富的描述字段

目的: Claude 读取描述来决定为当前任务加载哪些技能。让它能回答:"我现在应该读这个技能吗?"

格式: 以"Use when..."开头,聚焦于触发条件

关键:描述 = 何时使用,不是技能做什么

描述应该只描述触发条件。不要在描述中总结技能的流程或工作流。

为什么这很重要: 测试表明,当描述总结了技能的工作流时,Claude 可能会跟随描述而非阅读完整的技能内容。一个写着"任务间进行代码审查"的描述导致 Claude 只做了一次审查,尽管技能的流程图清楚地展示了两次审查(先规格合规再代码质量)。

当描述改为仅"在当前会话中执行包含独立任务的实现计划时使用"(无工作流摘要)时,Claude 正确地阅读了流程图并遵循了两阶段审查流程。

陷阱: 总结工作流的描述创建了 Claude 会走的捷径。技能正文变成了 Claude 跳过的文档。

# 错误:总结了工作流 - Claude 可能会跟随描述而非阅读技能
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

内容:

# 错误:太抽象、模糊,未包含何时使用
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. 关键词覆盖

使用 Claude 会搜索的词语:

3. 描述性命名

使用主动语态,动词优先:

4. Token 效率(关键)

问题: getting-started 和频繁引用的技能会加载到每个对话中。每个 token 都很重要。

目标字数:

技巧:

将细节移到工具帮助中:

# 错误:在 SKILL.md 中列出所有参数
search-conversations supports --text, --both, --after DATE, --before DATE, --limit N

# 正确:引用 --help
search-conversations 支持多种模式和过滤器。运行 --help 查看详情。

使用交叉引用:

# 错误:重复工作流细节
搜索时,用模板分派子智能体……
[20 行重复的说明]

# 正确:引用其他技能
始终使用子智能体(节省 50-100 倍上下文)。必需:使用 [other-skill-name] 工作流。

压缩示例:

# 错误:冗长的示例(42 词)
你的搭档:"我们之前是怎么处理 React Router 中的认证错误的?"
你:我来搜索过去对话中的 React Router 认证模式。
[用搜索查询分派子智能体:"React Router authentication error handling 401"]

# 正确:精简的示例(20 词)
搭档:"我们之前是怎么处理 React Router 中的认证错误的?"
你:正在搜索……
[分派子智能体 → 整合]

消除冗余:

验证:

wc -w skills/path/SKILL.md
# getting-started 工作流:目标 <150 每个
# 其他频繁加载的:目标总计 <200

用你做的事或核心洞察来命名:

动名词(-ing)适合描述流程:

4. 交叉引用其他技能

编写引用其他技能的文档时:

仅使用技能名称,带有明确的必需标记:

为什么不用 @ 链接: @ 语法会立即强制加载文件,在你需要之前就消耗 200k+ 的上下文。

流程图使用

digraph when_flowchart {
    "需要展示信息?" [shape=diamond];
    "我可能在决策中犯错?" [shape=diamond];
    "使用 markdown" [shape=box];
    "小型内联流程图" [shape=box];

    "需要展示信息?" -> "我可能在决策中犯错?" [label="是"];
    "我可能在决策中犯错?" -> "小型内联流程图" [label="是"];
    "我可能在决策中犯错?" -> "使用 markdown" [label="否"];
}

仅在以下情况使用流程图:

绝不使用流程图用于:

参见 @graphviz-conventions.dot 了解 graphviz 样式规则。

为你的搭档可视化: 使用此目录中的 render-graphs.js 将技能的流程图渲染为 SVG:

./render-graphs.js ../some-skill           # 每个图表分别渲染
./render-graphs.js ../some-skill --combine # 所有图表合并为一个 SVG

代码示例

一个优秀的示例胜过多个平庸的

选择最相关的语言:

好的示例:

不要:

你擅长语言移植——一个优秀的示例就够了。

文件组织

自包含技能

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、完成前验证、编码前设计

测试方式:

成功标准: 智能体在最大压力下遵循规则

技术类技能(操作指南)

例如: condition-based-waiting、root-cause-tracing、defensive-programming

测试方式:

成功标准: 智能体成功将技术应用于新场景

模式类技能(心智模型)

例如: reducing-complexity、information-hiding 概念

测试方式:

成功标准: 智能体正确识别何时/如何应用模式

参考类技能(文档/API)

例如: API 文档、命令参考、库指南

测试方式:

成功标准: 智能体找到并正确应用参考信息

跳过测试的常见合理化借口

借口现实
"技能显然很清晰"对你清晰 ≠ 对其他智能体清晰。测试它。
"这只是参考资料"参考资料可能有遗漏、不清楚的地方。测试检索。
"测试太过了"未测试的技能总有问题。15 分钟测试省下数小时。
"有问题再测试"问题 = 智能体无法使用技能。在部署前测试。
"测试太繁琐"测试比在生产中调试坏技能少繁琐得多。
"我有信心它很好"过度自信保证出问题。无论如何都要测试。
"学术审查就够了"阅读 ≠ 使用。测试应用场景。
"没时间测试"部署未测试的技能比后面修复浪费更多时间。

以上所有都意味着:部署前测试。无例外。

让技能经受住合理化的考验

执行纪律的技能(如 TDD)需要抵抗合理化。智能体很聪明,在压力下会找到漏洞。

心理学说明: 理解说服技巧为什么有效有助于你系统性地应用它们。参见 persuasion-principles.md 了解研究基础(Cialdini, 2021; Meincke et al., 2025),涵盖权威、承诺、稀缺、社会认同和归属原则。

明确堵住每个漏洞

不要只是陈述规则——禁止具体的变通方法:

先写代码再写测试?删掉它。
先写代码再写测试?删掉它。重新开始。

**无例外:**
- 不要保留作为"参考"
- 不要在写测试时"调整"它
- 不要看它
- 删除就是删除

应对"精神 vs 字面"的辩论

在前面加入基础原则:

**违反规则的字面意思就是违反规则的精神。**

这切断了整类"我遵循的是精神"的合理化借口。

构建合理化借口表

从基线测试中捕获合理化借口(参见下方测试章节)。智能体使用的每个借口都进入表中:

| 借口 | 现实 |
|------|------|
| "太简单不值得测试" | 简单的代码也会出错。测试只需 30 秒。 |
| "我后面再测试" | 测试立即通过什么也证明不了。 |
| "后写测试效果一样" | 后写测试 = "这做了什么?" 先写测试 = "这应该做什么?" |

创建红线列表

让智能体容易自查是否在合理化:

## 红线 - 停下来重新开始

- 先写代码再写测试
- "我已经手动测试过了"
- "后写测试效果一样"
- "重要的是精神不是仪式"
- "这个情况不同,因为……"

**以上所有都意味着:删除代码。用 TDD 重新开始。**

更新 CSO 以包含违规症状

在描述中添加:你即将违反规则时的症状:

description: use when implementing any feature or bugfix, before writing implementation code

技能的红-绿-重构

遵循 TDD 循环:

红:编写失败的测试(基线)

在没有技能的情况下运行压力场景。逐字记录行为:

这就是"观察测试失败"——在编写技能之前你必须看到智能体自然会怎么做。

绿:编写最小技能

编写针对那些具体合理化借口的技能。不要为假设情况添加额外内容。

用技能运行相同的场景。智能体应该现在遵守。

重构:堵住漏洞

智能体找到了新的合理化借口?添加明确的反驳。重新测试直到无懈可击。

测试方法论: 参见 @testing-skills-with-subagents.md 了解完整的测试方法:

反模式

叙事式示例

"在 2025-10-03 的会话中,我们发现空的 projectDir 导致了……" 为什么不好: 太具体,不可复用

多语言稀释

example-js.js、example-py.py、example-go.go 为什么不好: 质量平庸,维护负担重

流程图中的代码

step1 [label="import fs"];
step2 [label="read file"];

为什么不好: 无法复制粘贴,难以阅读

通用标签

helper1、helper2、step3、pattern4 为什么不好: 标签应有语义意义

停下:进入下一个技能之前

编写任何技能后,你必须停下来完成部署流程。

不要:

下面的部署清单对每个技能都是强制性的。

部署未测试的技能 = 部署未测试的代码。这是对质量标准的违反。

技能创建清单(TDD 适配版)

重要:使用 TodoWrite 为下面的每个清单项创建待办。

红色阶段 - 编写失败的测试:

绿色阶段 - 编写最小技能:

重构阶段 - 堵住漏洞:

质量检查:

部署:

发现工作流

未来的 Claude 如何找到你的技能:

  1. 遇到问题("测试不稳定")
  2. 找到技能(描述匹配)
  3. 浏览概述(这相关吗?)
  4. 阅读模式(快速参考表)
  5. 加载示例(仅在实现时)

为此流程优化 - 把可搜索的术语放在前面和各处。

总结

创建技能就是流程文档的 TDD。

同样的铁律:没有失败的测试就不写技能。 同样的循环:红(基线)→ 绿(写技能)→ 重构(堵漏洞)。 同样的好处:更高的质量、更少的意外、无懈可击的结果。

如果你对代码遵循 TDD,对技能也应如此。这是同样的纪律应用于文档。

← Back to all skills