每位開發(fā)者最終都會形成一套自己反復(fù)使用的開發(fā)工作流程:他們有固定的提交信息編寫方式,會在提交拉取請求之前執(zhí)行特定的檢查清單,也會在代碼審查時遵循一定的結(jié)構(gòu)。這些流程都是他們手動制定的,在每次與助手交流時都會向助手解釋這些要求,然而卻會發(fā)現(xiàn)每次助手對這些要求的理解都有所不同。

助手的功能可以解決這個問題。所謂“技能”,其實就是一種Markdown格式的文件,當(dāng)你需要使用時,它會自動被Claude Code系統(tǒng)加載并應(yīng)用到相應(yīng)的場景中。你只需一次性編寫好這套工作流程,之后助手就會每次都按照這個流程來執(zhí)行操作。而且由于這些技能遵循的是開放標(biāo)準(zhǔn),因此同一個文件可以在Claude Code、GitHub Copilot、Cursor以及Gemini CLI等工具中正常使用。

本教程將教你如何從零開始創(chuàng)建這樣的技能。你將會制作一個名為“提交信息編寫助手”的技能——這個技能能夠讀取你準(zhǔn)備提交的代碼變更內(nèi)容,并根據(jù)“常規(guī)提交規(guī)范”生成結(jié)構(gòu)清晰的提交信息。完成學(xué)習(xí)后,你將擁有一個可以立即使用的功能完備的技能,同時也會掌握構(gòu)建任何所需技能的基本方法。

目錄

  1. 什么是助手技能

  2. 如何決定要創(chuàng)建什么技能

  3. 如何構(gòu)建技能的結(jié)構(gòu)

  4. 如何編寫技能的描述

  5. 如何編寫使用說明

  6. 如何創(chuàng)建“提交信息編寫助手”技能

  7. 如何安裝并測試你的技能

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

  9. 下一步該做什么

什么是助手技能

一個技能實際上就是一個包含`SKILL.md`文件的文件夾。這個文件由兩部分組成:頂部的YAML格式的前置內(nèi)容,以及下方的Markdown格式的主體內(nèi)容。

my-skill/
└── SKILL.md

前置內(nèi)容會告訴助手這個技能的名稱以及何時應(yīng)該使用它;而主體內(nèi)容則會告訴助手在加載該技能后應(yīng)該執(zhí)行哪些操作。以下是最低限度的結(jié)構(gòu)要求:

---
name: my-skill
description: 這個技能的功能及其使用場景。
---
 
# 我的技能
 
助手的使用說明放在這里。

當(dāng)你調(diào)用某個技能時——無論是通過`/skill-name`這樣的路徑明確指定,還是描述你想要完成的任務(wù)——助手就會讀取`SKILL.md`文件中的主體內(nèi)容,并按照其中的指示來執(zhí)行操作。而前置內(nèi)容則永遠(yuǎn)不會被傳遞給助手,它只是技能系統(tǒng)用來決定是否加載該技能的元數(shù)據(jù)而已。

助手是如何決定是否加載某個技能的

在編寫第一個技能之前,有最重要的一點需要理解:代理是否加載你的技能,完全取決于描述字段的內(nèi)容。

在Claude Code中,技能以名稱和描述的列表形式呈現(xiàn)。當(dāng)你發(fā)起請求時,代理會掃描這個列表,并加載那些描述與你的需求相匹配的技能。如果描述不夠明確,那么在需要該技能時它就不會被加載;而如果描述過于具體,那么對于同一請求的不同變體,該技能也不會被加載。

只有當(dāng)技能被成功加載之后,文件中的指令才會發(fā)揮作用。因此,確保描述準(zhǔn)確無誤,才是決定技能是否能夠被加載的關(guān)鍵因素。

哪些不屬于技能

技能實際上就是指令文件。它們本身無法運行代碼,但可以指示代理使用現(xiàn)有的工具來執(zhí)行相應(yīng)的操作。它們既不是插件,也不是擴(kuò)展程序或包,更沒有運行時環(huán)境。這些技能文件其實就是Markdown格式的文本文件,代理會像廚師按照食譜一樣閱讀這些文件。

如何選擇要開發(fā)的技能

優(yōu)秀的技能應(yīng)該具備以下三個特點:

  1. 它們能夠定義可重復(fù)的工作流程。

    如果每次執(zhí)行操作的方式都不同,那么這樣的技能就沒什么作用;只有當(dāng)你每次都能按照相同的步驟來操作時,這個技能才具有實用性。

  2. 它們必須有明確的觸發(fā)條件。

    你應(yīng)該能夠用一句話完整地表達(dá)“當(dāng)我想要……的時候,就需要這個技能”。如果無法用一個完整的句子來描述這個需求,那么這樣的工作流程就不適合被定義為技能。

  3. 它們產(chǎn)生的輸出格式必須統(tǒng)一。

    那些能生成結(jié)構(gòu)化輸出的技能(比如提交信息、代碼評審報告或功能規(guī)格說明)要比那些產(chǎn)生自由文本的技能更容易開發(fā)和測試。

適合開發(fā)成技能的例子包括:提交信息、拉取請求描述、代碼評審內(nèi)容、變更日志記錄等。而不適合的例子則有“幫我思考這個問題”或“把這個做得更好”——這類要求過于開放,無法被有效地編碼成技能。

對于本教程來說,生成提交信息正是合適的開發(fā)對象。它的觸發(fā)條件很明確(就是當(dāng)你想要提交代碼時),工作流程也有固定的規(guī)范(比如閱讀分階段的修改內(nèi)容、遵循常規(guī)的提交格式),而且輸出結(jié)果也是結(jié)構(gòu)化的(即具有固定格式的提交信息)。

如何構(gòu)建技能文件

每個技能文件最初都只是一個包含一個文件的文件夾:

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

隨著技能內(nèi)容的增加,還可以添加其他文件,這些文件會在需要時被代理加載:

commit-message-writer/
├── SKILL.md          ← 每次技能被觸發(fā)時都會被加載
└── references/
    └── examples.md   ← 只有在代理需要示例內(nèi)容時才會被加載

SKILL.md文件的正文部分應(yīng)該控制在500行以內(nèi)。如果說明內(nèi)容超過了這個長度,可以將輔助細(xì)節(jié)放到references/子文件夾中,并告訴代理在什么情況下需要讀取這些文件。這樣就能確保技能文件保持簡潔,代理只會加載真正需要的內(nèi)容。

對于本教程來說,一個單獨的 SKILL.md 文件就足夠了。

如何編寫描述

描述字段實際上起到了觸發(fā)條件的作用——它決定了你的技能何時會被執(zhí)行,何時不會被執(zhí)行。大多數(shù)情況下,技能無法正常運行并不是因為指令有誤,而是因為描述內(nèi)容與人們實際請求幫助的方式不匹配。

以下是一個效果較差的描述示例:

description: 生成提交信息。

這樣的描述會導(dǎo)致技能被錯誤地觸發(fā)。“生成提交信息”這個指令會使得該技能被執(zhí)行,而“為我的修改編寫提交信息”或“總結(jié)我暫存區(qū)的更改”這類指令則可能不會觸發(fā)該技能。盡管這三種請求實際上都是要求生成提交信息,但描述不夠具體,因此會導(dǎo)致技能無法正確響應(yīng)。

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

description: 會根據(jù) Conventional Commits 標(biāo)準(zhǔn)生成結(jié)構(gòu)化的提交信息。當(dāng)你需要為修改內(nèi)容編寫格式規(guī)范的提交信息時,可以使用該技能。該技能會在接收到“編寫提交信息”、“提交我的修改”、“總結(jié)我暫存區(qū)的更改”或任何與代碼變更描述相關(guān)的請求時被觸發(fā)。

正確的描述格式應(yīng)該是:技能的功能 + 使用場景 + 具體的觸發(fā)語句。這樣的描述能夠覆蓋開發(fā)者可能用到的各種表達(dá)方式。

編寫描述時需要遵循兩條規(guī)則:

明確輸出結(jié)果的具體內(nèi)容。“生成提交信息”這種描述太模糊了,而“根據(jù) Conventional Commits 標(biāo)準(zhǔn)生成結(jié)構(gòu)化的提交信息”則能清楚地告訴技能執(zhí)行者以及使用者最終會得到什么結(jié)果。

描述應(yīng)具有一定的引導(dǎo)性。智能助手通常會有傾向于不觸發(fā)技能執(zhí)行的傾向,而是自己處理請求。因此,在描述中明確列出觸發(fā)語句非常重要。這樣做并不會造成重復(fù),反而有助于讓智能助手更好地理解用戶的意圖。

如何編寫使用說明

SKILL.md 文件的正文部分用于定義技能被執(zhí)行時應(yīng)該完成的具體操作。優(yōu)秀的使用說明需要遵循以下兩個原則:

先生成結(jié)果,再進(jìn)行必要的澄清。智能助手應(yīng)該立即產(chǎn)生輸出結(jié)果,而不是先提出問題來要求用戶進(jìn)行補(bǔ)充說明。如果必須做出某些假設(shè),也應(yīng)該明確標(biāo)注出來,而不是通過提問來獲取信息。在生成結(jié)果之前先提問會增加操作流程的復(fù)雜性,從而削弱技能的實際作用。

明確指定輸出結(jié)果的格式。不要只是說“編寫一份好的提交信息”,而應(yīng)該具體說明輸出內(nèi)容的結(jié)構(gòu)、所需填寫的字段以及字符長度限制等要求。輸出格式越明確,結(jié)果就越一致。

以下是一個描述效果較差的使用說明示例:

# 提交信息生成器

請查看暫存區(qū)的更改內(nèi)容,并編寫一份能準(zhǔn)確描述這些更改的提交信息。

這樣的描述會導(dǎo)致每次執(zhí)行技能時產(chǎn)生不同的結(jié)果:格式不同、長度不一、格式規(guī)范也不一致。這樣的“技能”其實根本無法發(fā)揮應(yīng)有的作用,它只是一種提示工具而已。

以下是格式規(guī)范的提交信息編寫指南:

# 提交信息編寫工具

使用 `git diff --staged` 命令查看已暫存的修改內(nèi)容。請按照“常規(guī)提交”標(biāo)準(zhǔn)來生成提交信息。

輸出格式:
- **類型**:72個字符以內(nèi)的簡短描述
- **正文**(如果修改內(nèi)容較為復(fù)雜):說明具體發(fā)生了哪些變化以及原因,而非修改的具體步驟;每個邏輯上的變更應(yīng)使用單獨的項來表述。
- **腳注**(如適用):添加“重大變更提示”或“已解決GitHub問題編號”。

該工具能夠準(zhǔn)確生成所需的輸出內(nèi)容。無論在何種會話中、針對哪個項目,只要使用支持該標(biāo)準(zhǔn)的工具,生成的輸出結(jié)果都是一致的。

如何構(gòu)建提交信息編寫工具

現(xiàn)在開始構(gòu)建這個工具吧。首先創(chuàng)建相應(yīng)的目錄:

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

在Windows PowerShell中執(zhí)行如下命令:

注意:PowerShell使用反引號(`)來表示行續(xù)接,而不是反斜杠。

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

在該目錄下創(chuàng)建SKILL.md文件,其內(nèi)容如下:

---
name: 提交信息編寫工具
description: 該工具能根據(jù)“常規(guī)提交”標(biāo)準(zhǔn)生成結(jié)構(gòu)化的提交信息。當(dāng)你需要提交修改內(nèi)容且希望提交信息格式規(guī)范時,可以使用這個工具。適用于執(zhí)行“編寫提交信息”、“提交我的修改內(nèi)容”、“總結(jié)已暫存的修改內(nèi)容”等操作,或者任何與版本控制相關(guān)的、需要描述或記錄暫存變更的任務(wù)。

---
 
# 提交信息編寫工具

該工具用于根據(jù)已暫存的Git修改內(nèi)容生成結(jié)構(gòu)化的提交信息。

## 使用方法

運行 `git diff --staged` 命令查看已暫存的修改內(nèi)容。如果沒有任何內(nèi)容被暫存,應(yīng)告知用戶先執(zhí)行 `git add` 操作。

在生成提交信息之前,不要詢問任何需要進(jìn)一步確認(rèn)的問題。如果必須對修改內(nèi)容的范圍或類型進(jìn)行假設(shè),請在生成信息后注明這些假設(shè)。

## 輸出格式

~~~
type(范圍): 簡短描述

[正文 — 可選,如果修改內(nèi)容較為復(fù)雜,請包含這部分]
 
[腳注 — 可選]
~~~

**類型**:請選擇其中一個選項:
- `feat`:新增功能
- `fix`:修復(fù)漏洞
- `docs`:僅涉及文檔修改
- `refactor`:既不修復(fù)漏洞也不添加新功能的代碼優(yōu)化
- `test`:添加或更新測試用例
- `chore`:與構(gòu)建流程、工具或依賴項相關(guān)的更新

**范圍**:指出受影響的模塊、文件或具體區(qū)域。可以使用目錄名或組件名稱來表示;如果修改內(nèi)容涉及整個代碼庫,則省略這一字段。

**簡短描述**:使用祈使句式書寫,長度不超過72個字符,結(jié)尾不要加句號。例如:“添加用戶認(rèn)證功能”,而不是“Added user authentication”或“Adds user authentication”。

**正文**:說明具體發(fā)生了哪些變化以及原因,而非修改的具體步驟。每個邏輯上的變更應(yīng)使用單獨的項來表述。如果簡短描述已經(jīng)能夠清楚地說明問題,就可以省略正文部分。

**腳注**:如果此次提交會破壞之前的兼容性,請?zhí)砑印爸卮笞兏崾尽保蝗绻舜翁峤唤鉀Q了某個GitHub問題,請?zhí)砑印耙呀鉀Q#N號問題”。

## 質(zhì)量要求

- 簡短描述中絕對不要使用“更新了”、“修改了”之類的表述,應(yīng)具體說明修改的內(nèi)容。
- 不要寫“各種改進(jìn)”或“雜項修復(fù)”,而應(yīng)該明確指出哪些方面得到了改善。
- 如果有超過三個文件因為不相關(guān)的理由而被修改,請?zhí)貏e注明:“這些修改內(nèi)容最好分成多個單獨的提交來處理:[列出相關(guān)問題]”。
- 簡短描述的長度必須控制在72個字符以內(nèi),在輸出之前請先確認(rèn)長度是否符合要求。

## 示例輸出

輸入:為某個API接口添加了速率限制功能

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

- 使用Cloudflare的速率限制機(jī)制,將每分鐘每個IP地址的請求次數(shù)限制在100次以內(nèi)。
- 當(dāng)請求次數(shù)超過限制時,會返回429狀態(tài)碼,并附帶“Retry-After”頭部信息。
- 將速率限制配置添加到wrangler.toml文件中。

已解決#47號問題
~~~

保存該文件,這樣這個功能就搭建完成了。

如何安裝并測試你的功能

確認(rèn)文件是否存在

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

你應(yīng)該能看到SKILL.md文件的全部內(nèi)容。如果出現(xiàn)錯誤,請檢查目錄路徑是否正確。

測試該功能

在任何包含已暫存更改的git倉庫中打開Claude Code,然后輸入以下命令:

/commit-message-writer

該功能會讀取你暫存的更改內(nèi)容,并按照你定義的格式生成提交信息。

你也可以用自然語言來觸發(fā)這個功能:

為我的暫存更改編寫一條提交信息
為git生成一份摘要信息

以上三種方式都應(yīng)該能夠使該功能正常運行并生成格式規(guī)范的提交信息。如果使用自然語言請求時該功能無法響應(yīng),說明描述中的觸發(fā)語句還不夠準(zhǔn)確——請參考下面的改進(jìn)方法。

測試邊緣情況

在正式環(huán)境中使用該功能之前,請先測試以下這些特殊情況:

# 不暫存任何內(nèi)容,然后請求生成提交信息
git add -p  # 不暫存任何內(nèi)容
# 在Claude Code中輸入:「編寫一條提交信息」
# 預(yù)期結(jié)果:該功能會提示你沒有暫存任何內(nèi)容,并建議你使用git add命令
# 將不同文件中的更改一起暫存
git add src/api.ts src/styles.css README.md
# 在Claude Code中輸入:「編寫一條提交信息」
# 預(yù)期結(jié)果:該功能會提示你這些更改應(yīng)該分開提交

如何逐步改進(jìn)你的功能

任何功能的初始版本都只是草稿。你可以通過觀察它何時會產(chǎn)生不一致或錯誤的輸出,然后據(jù)此更新使用說明來不斷改進(jìn)它。

當(dāng)該功能無法正確響應(yīng)請求時

如果你輸入“為git生成一份摘要信息”,而該功能沒有響應(yīng),請將這個短語添加到描述中的觸發(fā)語句列表中:

description: ... 當(dāng)輸入“編寫一條提交信息”、“提交我的更改”、“為git生成摘要信息”等指令時,該功能應(yīng)能正常響應(yīng)

描述內(nèi)容是解決功能觸發(fā)問題時的關(guān)鍵依據(jù)。

當(dāng)輸出格式發(fā)生變化時

如果該功能生成的提交信息與你的預(yù)期格式不符——類型錯誤、范圍缺失或文本格式不正確——就需要對使用說明進(jìn)行進(jìn)一步細(xì)化。請?zhí)砑泳唧w的示例,說明錯誤情況以及正確的輸出結(jié)果:

## 需要避免的常見錯誤

錯誤示例:「更新了認(rèn)證流程」
正確示例:「重構(gòu)(auth)模塊:簡化令牌驗證邏輯」

錯誤示例:「修復(fù)了漏洞」
正確示例:「修復(fù)(api)模塊:處理上游服務(wù)返回的空響應(yīng)」

具體的反例比抽象的規(guī)則更有效。

當(dāng)范圍擴(kuò)大時

如果你發(fā)現(xiàn)自己需要掌握某些技能來處理相關(guān)任務(wù)——比如審閱提交信息、生成變更日志或編寫拉取請求描述——請不要試圖將所有這些功能都整合到同一個技能中。應(yīng)該分別為這些任務(wù)創(chuàng)建獨立的技能。每個技能都應(yīng)該專注于完成某一項特定的任務(wù)。Agent Skills標(biāo)準(zhǔn)正是為這種組合使用而設(shè)計的,而不是為了制定單一的、全面的指令。

Comments are closed.