每位开发者最终都会形成一套自己反复使用的开发工作流程:他们有固定的提交信息编写方式,会在提交拉取请求之前执行特定的检查清单,也会在代码审查时遵循一定的结构。这些流程都是他们手动制定的,在每次与助手交流时都会向助手解释这些要求,然而却会发现每次助手对这些要求的理解都有所不同。

助手的功能可以解决这个问题。所谓“技能”,其实就是一种Markdown格式的文件,当你需要使用时,它会自动被Claude Code系统加载并应用到相应的场景中。你只需一次性编写好这套工作流程,之后助手就会每次都按照这个流程来执行操作。而且由于这些技能遵循的是开放标准,因此同一个文件可以在Claude Code、GitHub Copilot、Cursor以及Gemini CLI等工具中正常使用。

本教程将教你如何从零开始创建这样的技能。你将会制作一个名为“提交信息编写助手”的技能——这个技能能够读取你准备提交的代码变更内容,并根据“常规提交规范”生成结构清晰的提交信息。完成学习后,你将拥有一个可以立即使用的功能完备的技能,同时也会掌握构建任何所需技能的基本方法。

目录

  1. 什么是助手技能

  2. 如何决定要创建什么技能

  3. 如何构建技能的结构

  4. 如何编写技能的描述

  5. 如何编写使用说明

  6. 如何创建“提交信息编写助手”技能

  7. 如何安装并测试你的技能

  8. 如何逐步提升你的技能水平

  9. 下一步该做什么

什么是助手技能

一个技能实际上就是一个包含`SKILL.md`文件的文件夹。这个文件由两部分组成:顶部的YAML格式的前置内容,以及下方的Markdown格式的主体内容。

my-skill/
└── SKILL.md

前置内容会告诉助手这个技能的名称以及何时应该使用它;而主体内容则会告诉助手在加载该技能后应该执行哪些操作。以下是最低限度的结构要求:

---
name: my-skill
description: 这个技能的功能及其使用场景。
---
 
# 我的技能
 
助手的使用说明放在这里。

当你调用某个技能时——无论是通过`/skill-name`这样的路径明确指定,还是描述你想要完成的任务——助手就会读取`SKILL.md`文件中的主体内容,并按照其中的指示来执行操作。而前置内容则永远不会被传递给助手,它只是技能系统用来决定是否加载该技能的元数据而已。

助手是如何决定是否加载某个技能的

在编写第一个技能之前,有最重要的一点需要理解:代理是否加载你的技能,完全取决于描述字段的内容。

在Claude Code中,技能以名称和描述的列表形式呈现。当你发起请求时,代理会扫描这个列表,并加载那些描述与你的需求相匹配的技能。如果描述不够明确,那么在需要该技能时它就不会被加载;而如果描述过于具体,那么对于同一请求的不同变体,该技能也不会被加载。

只有当技能被成功加载之后,文件中的指令才会发挥作用。因此,确保描述准确无误,才是决定技能是否能够被加载的关键因素。

哪些不属于技能

技能实际上就是指令文件。它们本身无法运行代码,但可以指示代理使用现有的工具来执行相应的操作。它们既不是插件,也不是扩展程序或包,更没有运行时环境。这些技能文件其实就是Markdown格式的文本文件,代理会像厨师按照食谱一样阅读这些文件。

如何选择要开发的技能

优秀的技能应该具备以下三个特点:

  1. 它们能够定义可重复的工作流程。

    如果每次执行操作的方式都不同,那么这样的技能就没什么作用;只有当你每次都能按照相同的步骤来操作时,这个技能才具有实用性。

  2. 它们必须有明确的触发条件。

    你应该能够用一句话完整地表达“当我想要……的时候,就需要这个技能”。如果无法用一个完整的句子来描述这个需求,那么这样的工作流程就不适合被定义为技能。

  3. 它们产生的输出格式必须统一。

    那些能生成结构化输出的技能(比如提交信息、代码评审报告或功能规格说明)要比那些产生自由文本的技能更容易开发和测试。

适合开发成技能的例子包括:提交信息、拉取请求描述、代码评审内容、变更日志记录等。而不适合的例子则有“帮我思考这个问题”或“把这个做得更好”——这类要求过于开放,无法被有效地编码成技能。

对于本教程来说,生成提交信息正是合适的开发对象。它的触发条件很明确(就是当你想要提交代码时),工作流程也有固定的规范(比如阅读分阶段的修改内容、遵循常规的提交格式),而且输出结果也是结构化的(即具有固定格式的提交信息)。

如何构建技能文件

每个技能文件最初都只是一个包含一个文件的文件夹:

commit-message-writer/
└── SKILL.md

随着技能内容的增加,还可以添加其他文件,这些文件会在需要时被代理加载:

commit-message-writer/
├── SKILL.md          ← 每次技能被触发时都会被加载
└── references/
    └── examples.md   ← 只有在代理需要示例内容时才会被加载

SKILL.md文件的正文部分应该控制在500行以内。如果说明内容超过了这个长度,可以将辅助细节放到references/子文件夹中,并告诉代理在什么情况下需要读取这些文件。这样就能确保技能文件保持简洁,代理只会加载真正需要的内容。

对于本教程来说,一个单独的 SKILL.md 文件就足够了。

如何编写描述

描述字段实际上起到了触发条件的作用——它决定了你的技能何时会被执行,何时不会被执行。大多数情况下,技能无法正常运行并不是因为指令有误,而是因为描述内容与人们实际请求帮助的方式不匹配。

以下是一个效果较差的描述示例:

description: 生成提交信息。

这样的描述会导致技能被错误地触发。“生成提交信息”这个指令会使得该技能被执行,而“为我的修改编写提交信息”或“总结我暂存区的更改”这类指令则可能不会触发该技能。尽管这三种请求实际上都是要求生成提交信息,但描述不够具体,因此会导致技能无法正确响应。

下面是一个效果更好的描述示例:

description: 会根据 Conventional Commits 标准生成结构化的提交信息。当你需要为修改内容编写格式规范的提交信息时,可以使用该技能。该技能会在接收到“编写提交信息”、“提交我的修改”、“总结我暂存区的更改”或任何与代码变更描述相关的请求时被触发。

正确的描述格式应该是:技能的功能 + 使用场景 + 具体的触发语句。这样的描述能够覆盖开发者可能用到的各种表达方式。

编写描述时需要遵循两条规则:

明确输出结果的具体内容。“生成提交信息”这种描述太模糊了,而“根据 Conventional Commits 标准生成结构化的提交信息”则能清楚地告诉技能执行者以及使用者最终会得到什么结果。

描述应具有一定的引导性。智能助手通常会有倾向于不触发技能执行的倾向,而是自己处理请求。因此,在描述中明确列出触发语句非常重要。这样做并不会造成重复,反而有助于让智能助手更好地理解用户的意图。

如何编写使用说明

SKILL.md 文件的正文部分用于定义技能被执行时应该完成的具体操作。优秀的使用说明需要遵循以下两个原则:

先生成结果,再进行必要的澄清。智能助手应该立即产生输出结果,而不是先提出问题来要求用户进行补充说明。如果必须做出某些假设,也应该明确标注出来,而不是通过提问来获取信息。在生成结果之前先提问会增加操作流程的复杂性,从而削弱技能的实际作用。

明确指定输出结果的格式。不要只是说“编写一份好的提交信息”,而应该具体说明输出内容的结构、所需填写的字段以及字符长度限制等要求。输出格式越明确,结果就越一致。

以下是一个描述效果较差的使用说明示例:

# 提交信息生成器

请查看暂存区的更改内容,并编写一份能准确描述这些更改的提交信息。

这样的描述会导致每次执行技能时产生不同的结果:格式不同、长度不一、格式规范也不一致。这样的“技能”其实根本无法发挥应有的作用,它只是一种提示工具而已。

以下是格式规范的提交信息编写指南:

# 提交信息编写工具

使用 `git diff --staged` 命令查看已暂存的修改内容。请按照“常规提交”标准来生成提交信息。

输出格式:
- **类型**:72个字符以内的简短描述
- **正文**(如果修改内容较为复杂):说明具体发生了哪些变化以及原因,而非修改的具体步骤;每个逻辑上的变更应使用单独的项来表述。
- **脚注**(如适用):添加“重大变更提示”或“已解决GitHub问题编号”。

该工具能够准确生成所需的输出内容。无论在何种会话中、针对哪个项目,只要使用支持该标准的工具,生成的输出结果都是一致的。

如何构建提交信息编写工具

现在开始构建这个工具吧。首先创建相应的目录:

mkdir -p ~/.claude/skills/commit-message-writer

在Windows PowerShell中执行如下命令:

注意:PowerShell使用反引号(`)来表示行续接,而不是反斜杠。

New-Item -ItemType Directory -Force -Path "$HOME\.claude\skills\commit-message-writer"

在该目录下创建SKILL.md文件,其内容如下:

---
name: 提交信息编写工具
description: 该工具能根据“常规提交”标准生成结构化的提交信息。当你需要提交修改内容且希望提交信息格式规范时,可以使用这个工具。适用于执行“编写提交信息”、“提交我的修改内容”、“总结已暂存的修改内容”等操作,或者任何与版本控制相关的、需要描述或记录暂存变更的任务。

---
 
# 提交信息编写工具

该工具用于根据已暂存的Git修改内容生成结构化的提交信息。

## 使用方法

运行 `git diff --staged` 命令查看已暂存的修改内容。如果没有任何内容被暂存,应告知用户先执行 `git add` 操作。

在生成提交信息之前,不要询问任何需要进一步确认的问题。如果必须对修改内容的范围或类型进行假设,请在生成信息后注明这些假设。

## 输出格式

~~~
type(范围): 简短描述

[正文 — 可选,如果修改内容较为复杂,请包含这部分]
 
[脚注 — 可选]
~~~

**类型**:请选择其中一个选项:
- `feat`:新增功能
- `fix`:修复漏洞
- `docs`:仅涉及文档修改
- `refactor`:既不修复漏洞也不添加新功能的代码优化
- `test`:添加或更新测试用例
- `chore`:与构建流程、工具或依赖项相关的更新

**范围**:指出受影响的模块、文件或具体区域。可以使用目录名或组件名称来表示;如果修改内容涉及整个代码库,则省略这一字段。

**简短描述**:使用祈使句式书写,长度不超过72个字符,结尾不要加句号。例如:“添加用户认证功能”,而不是“Added user authentication”或“Adds user authentication”。

**正文**:说明具体发生了哪些变化以及原因,而非修改的具体步骤。每个逻辑上的变更应使用单独的项来表述。如果简短描述已经能够清楚地说明问题,就可以省略正文部分。

**脚注**:如果此次提交会破坏之前的兼容性,请添加“重大变更提示”;如果此次提交解决了某个GitHub问题,请添加“已解决#N号问题”。

## 质量要求

- 简短描述中绝对不要使用“更新了”、“修改了”之类的表述,应具体说明修改的内容。
- 不要写“各种改进”或“杂项修复”,而应该明确指出哪些方面得到了改善。
- 如果有超过三个文件因为不相关的理由而被修改,请特别注明:“这些修改内容最好分成多个单独的提交来处理:[列出相关问题]”。
- 简短描述的长度必须控制在72个字符以内,在输出之前请先确认长度是否符合要求。

## 示例输出

输入:为某个API接口添加了速率限制功能

~~~
feat(api): 为/query接口添加速率限制功能

- 使用Cloudflare的速率限制机制,将每分钟每个IP地址的请求次数限制在100次以内。
- 当请求次数超过限制时,会返回429状态码,并附带“Retry-After”头部信息。
- 将速率限制配置添加到wrangler.toml文件中。

已解决#47号问题
~~~

保存该文件,这样这个功能就搭建完成了。

如何安装并测试你的功能

确认文件是否存在

cat ~/.claude/skills/commit-message-writer/SKILL.md

你应该能看到SKILL.md文件的全部内容。如果出现错误,请检查目录路径是否正确。

测试该功能

在任何包含已暂存更改的git仓库中打开Claude Code,然后输入以下命令:

/commit-message-writer

该功能会读取你暂存的更改内容,并按照你定义的格式生成提交信息。

你也可以用自然语言来触发这个功能:

为我的暂存更改编写一条提交信息
为git生成一份摘要信息

以上三种方式都应该能够使该功能正常运行并生成格式规范的提交信息。如果使用自然语言请求时该功能无法响应,说明描述中的触发语句还不够准确——请参考下面的改进方法。

测试边缘情况

在正式环境中使用该功能之前,请先测试以下这些特殊情况:

# 不暂存任何内容,然后请求生成提交信息
git add -p  # 不暂存任何内容
# 在Claude Code中输入:「编写一条提交信息」
# 预期结果:该功能会提示你没有暂存任何内容,并建议你使用git add命令
# 将不同文件中的更改一起暂存
git add src/api.ts src/styles.css README.md
# 在Claude Code中输入:「编写一条提交信息」
# 预期结果:该功能会提示你这些更改应该分开提交

如何逐步改进你的功能

任何功能的初始版本都只是草稿。你可以通过观察它何时会产生不一致或错误的输出,然后据此更新使用说明来不断改进它。

当该功能无法正确响应请求时

如果你输入“为git生成一份摘要信息”,而该功能没有响应,请将这个短语添加到描述中的触发语句列表中:

description: ... 当输入“编写一条提交信息”、“提交我的更改”、“为git生成摘要信息”等指令时,该功能应能正常响应

描述内容是解决功能触发问题时的关键依据。

当输出格式发生变化时

如果该功能生成的提交信息与你的预期格式不符——类型错误、范围缺失或文本格式不正确——就需要对使用说明进行进一步细化。请添加具体的示例,说明错误情况以及正确的输出结果:

## 需要避免的常见错误

错误示例:「更新了认证流程」
正确示例:「重构(auth)模块:简化令牌验证逻辑」

错误示例:「修复了漏洞」
正确示例:「修复(api)模块:处理上游服务返回的空响应」

具体的反例比抽象的规则更有效。

当范围扩大时

如果你发现自己需要掌握某些技能来处理相关任务——比如审阅提交信息、生成变更日志或编写拉取请求描述——请不要试图将所有这些功能都整合到同一个技能中。应该分别为这些任务创建独立的技能。每个技能都应该专注于完成某一项特定的任务。Agent Skills标准正是为这种组合使用而设计的,而不是为了制定单一的、全面的指令。

Comments are closed.