SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-30

如何撰寫自己的 agent skill

從一次真實失敗建立 agent skill,了解 SKILL.md 結構、決定觸發時機的 description 撰寫方式,以及如何用相同任務測試技能是否生效。

從一次真實失敗撰寫自己的 agent skill

撰寫自己的 agent skill,最有效的方法是從一次真實失敗中提煉。找出 coding agent 做錯兩次的任務,記下你兩次輸入的修正內容,並將該修正儲存為 agent 可自行載入的 SKILL.md 檔案。之後的工作都只是機械性的:檔案配置,以及決定 skill 是否會觸發的那一行設定。

順序很重要。憑空撰寫的 skill 是在記錄你從未遇過的問題,而且每次工作階段都會佔用 context。從你親眼觀察到的失敗中提煉 skill,會自帶測試:再次提出相同要求,確認 agent 這次是否能正確完成。如果你不熟悉這種格式,請先閱讀agent skill 是什麼,以及 agent 如何載入它,再回來撰寫。

從代理程式連續兩次做錯的工作開始

一次可能只是偶然。兩次就形成模式,而模式值得記錄成檔案。

以下是實際伺服器上會反覆發生的失敗情況。你要求代理程式在 nginx 中加入反向代理區塊。它修改了 /etc/nginx/conf.d/app.conf,接著執行 sudo systemctl restart nginx。修改內容有錯字,因此 nginx 拒絕啟動,網站在你修正前都會中斷:

nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12
Job for nginx.service failed because the control process exited with error code.

你在對話中修正問題。先使用 sudo nginx -t 測試設定,再使用 reload 套用變更,不要使用 restart。一週後,在另一項工作中又發生相同錯誤。第二次就是訊號。

趁失敗仍在眼前時,記下兩件事:你輸入的要求,以及你提供的修正,保留原本使用的措辭。這兩行會成為技能。要求決定觸發條件必須比對的內容。修正則是技能的完整內容。

Anthropic 自己的撰寫指南也把這項做法放在第一位。先在沒有技能的情況下,讓代理程式執行具代表性的工作,記錄它失敗的地方,再撰寫能修正這些失敗的最少指示。失敗就是規格,因此無法追溯至某次失敗的技能,通常是沒有人真正需要的技能。

如要查看相同提煉過程的完整範例,可以先從頭讀到尾:Ponytail 將代理程式過度改寫內容這項重複失敗,轉換成一項技能,再撰寫自己的技能。

技能的結構

技能是一個目錄,其中包含一個必要檔案。

.claude/skills/nginx-config-changes/
├── SKILL.md
├── reference/
│   └── proxy-headers.md
└── scripts/
    └── check-and-reload.sh

SKILL.md 開頭是 frontmatter 區塊,其中包含幾項以 YAML 撰寫的設定(Docker Compose 檔案使用相同的設定格式),並以 --- 標記包住,後面則是 markdown 格式的指示。以下是上述失敗案例的完整技能。

---
name: nginx-config-changes
description: Tests and reloads nginx safely after a config edit. Use when editing files under /etc/nginx, adding a server block or a reverse proxy, or changing a TLS certificate path.
---

## Rules

Run `sudo nginx -t` after every edit under `/etc/nginx`. Do not touch the service until it prints `test is successful`.

Apply the change with `sudo systemctl reload nginx`. Never use `restart`. A reload keeps the running workers serving traffic until the new config parses, so a broken config leaves the site up. A restart stops nginx first, so a broken config takes the site down.

If `nginx -t` fails, fix the file and test again. Never reload a config that failed the test.

For the proxy header defaults this project expects, see [reference/proxy-headers.md](reference/proxy-headers.md).

該檔案不到 20 行,但已經是完整的技能。各部分如下:

  • name:最多 64 個字元,只能使用小寫字母、數字和連字號,且不能包含 claudeanthropic。在個人技能或專案技能中,這只是顯示標籤。輸入的命令取自目錄名稱,因此此技能可用 /nginx-config-changes 呼叫。
  • description:說明技能的功能與使用時機,最多 1,024 個字元。這一行負責實際觸發技能,下一節只會說明這部分。
  • 主體:僅在技能實際觸發時載入的指示。
  • reference/:代理程式按需讀取的額外檔案。從 SKILL.md 連結這些檔案,並讓連結維持一層深度,因為從另一個參照檔案連結的檔案,常常只會被讀取一部分。
  • scripts/:代理程式會執行而不是讀取的檔案。只有輸出內容會占用 context,因此 300 行的 script 也不會造成太大負擔。

當技能要修正的行為非常頑固,必須使用完整結構時,技能就會擴充為完整配置。unlazy 技能將這些空間用於 Depth Tree、gate 檔案集合和 PLAN.md 契約,防止代理程式宣告工作已完成,卻仍有整個分支未處理。

目錄的位置會決定誰能使用這項技能。

  • .claude/skills/<name>/SKILL.md:位於 repository 中,僅適用於此專案,且會隨 repository 提供給所有 clone 它的人。
  • ~/.claude/skills/<name>/SKILL.md:適用於你電腦上的所有專案,其他人的電腦則不適用。
  • <plugin>/skills/<name>/SKILL.md:隨 plugin 一起提供,在啟用該 plugin 的任何位置都可使用。

使用 mkdir -p .claude/skills/nginx-config-changes 建立技能,然後寫入檔案。Claude Code 會監看這些目錄,因此編輯現有技能後,變更會在執行中的 session 內生效。若建立 session 開始時不存在的頂層 skills 目錄,則需要重新啟動,因為 session 開始時沒有可監看的目錄。

description 欄位是檔案中影響最大的一行

啟動時,agent 會將每個可用 skill 的 namedescription 載入其 context。它不會載入本文。當你的 request 到達時,這一行就是判斷該 skill 是否相關的唯一依據。因此,即使本文內容完整,只要 description 含糊不清,就不會被讀取。

請以第三人稱撰寫 description。「安全地測試並重新載入 nginx」可以。「我可以協助你處理 nginx」則不行,因為這段文字會注入 system prompt,而第一人稱會讓人以為是 model 在描述自己。

description 中應包含兩項資訊:skill 的功能,以及適用的條件。先寫重要的使用情境,因為 Claude Code 會在 1,536 個字元處截斷 listing 項目。另有選用的 when_to_use 欄位,可放置額外的觸發詞組與範例 request;這些內容會附加在 description 後方,並受相同的字元上限限制。

接著使用你實際會輸入的詞彙。description: Helps with nginx 不會匹配任何內容,因為沒有人會輸入「協助處理」。上一個版本列出了 /etc/nginxserver blockreverse proxyTLS (transport layer security) certificate path,這大致就是任何應觸發該 skill 的 request 所使用的詞彙。

以下是測試 description 的方法:將這一行文字,以及你準備輸入的 request,一起提供給從未看過本文的人,詢問他們該 skill 是否適用。如果他們無法判斷,model 也無法判斷。

讓主體保持精簡,因為內容會持續保留在上下文中

呼叫 skill 時,其呈現的內容會以一則訊息加入對話,並在整個工作階段中持續保留。Claude Code 不會在後續回合重新讀取該檔案。你寫入的每一行,都是整個工作階段都要負擔的成本,而不是只影響一個回答。

Anthropic 建議將 SKILL.md 控制在 500 行以內,並將詳細內容移至個別檔案。壓縮機制說明了這個數字並非任意設定。對話經摘要以釋放上下文空間時,Claude Code 會重新附加每個 skill 最近一次呼叫的內容,每個 skill 只保留前 5,000 個 token,並從最近呼叫的 skill 開始,填入總計 25,000 個 token 的預算。過長的 skill 會在中途被截斷。多個過長的 skill 也可能將彼此完全排除。

因此,只寫入模型原本不知道的內容。模型知道 nginx 是什麼,也知道反向代理的用途。模型不知道你對 reload 超過 restart 的內部規則,而該規則正是這個檔案存在的唯一原因。

如果 skill 要求代理程式執行隨附的指令碼,請使用 ${CLAUDE_SKILL_DIR} 指定路徑,讓路徑能解析至 skill 的安裝位置,並預先核准相同的指令,避免執行時因權限提示而停止。

---
name: nginx-config-changes
description: Tests and reloads nginx safely after a config edit. Use when editing files under /etc/nginx, adding a server block or a reverse proxy, or changing a TLS certificate path.
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/check-and-reload.sh *)
---

授權涵蓋呼叫 skill 的該回合,並會在你傳送下一則訊息時清除,因此不會無聲地變成永久權限。

如何證明 skill 會觸發

查看 skill 載入只能證明 agent 找到了它,不能證明回答已經改變。兩者都要檢查,而且要在新的工作階段中檢查,因為撰寫 skill 的工作階段已經保留了你在撰寫過程中提供的所有內容。這些殘留的上下文會掩蓋檔案中的缺口。

  1. 在專案中使用 claude 開始新的工作階段。
  2. 以平常工作日會使用的方式,用自己的話輸入請求,不要提及 skill。
  3. 觀察是否觸發。如果 skill 沒有觸發,請修正描述。此時問題還不在內容。
  4. 使用 /nginx-config-changes 手動觸發,作為對照。手動觸發時行為正確,但透過請求觸發時行為錯誤,表示問題在觸發條件,而不是指示內容。
  5. 關閉 skill 後執行相同的請求,並比較兩個回答。在 /skills 選單中選取 skill,按 Space 將狀態切換為 off,再按 Enter 儲存。這會在 .claude/settings.local.json 中寫入 skillOverrides 項目。完成後,再按一次 Space,即可將狀態切換回 on
  6. 撰寫幾個不應觸發 skill 的請求,確認它在這些請求中保持靜默。

若要自動化這個流程,請從官方 marketplace 安裝 skill-creator plugin。

/plugin marketplace add anthropics/claude-plugins-official
/plugin install skill-creator@claude-plugins-official

如果安裝輸出顯示 Run /reload-plugins to activate.,請執行該命令。接著要求 Claude 依 skill 名稱評估 skill。plugin 會在 skill 目錄中的 evals/evals.json 儲存測試案例,並在各自的 subagent 中執行每個案例,因此每次執行都會從乾淨的上下文開始。接著它會產生啟用 skill 與未啟用 skill 的比較;這才是可信的數字:以 skill 所耗用的 token 與時間為基準,計算通過率的提升幅度。

skill 也可以攜帶自己的驗證方式,不必交由獨立的 eval 執行。Old Coder skill 會要求 agent 交回可由你自行重新執行的證據報告,便是這種做法

失效模式:技能完全不會觸發

您輸入請求後,代理程式仍執行原本錯誤的操作,而且沒有出現技能行。請依序檢查以下項目。

  • 描述只說明技能的功能,卻沒有說明何時使用,因此您的請求沒有任何內容符合它。
  • 描述未使用您輸入的詞彙。如果您說「nginx」,描述中也必須寫出 nginx。
  • 前置資料中設定了 disable-model-invocation: true。這會讓描述完全不出現在模型的上下文中,技能只能由您使用 /name 呼叫。
  • 前置資料中的 paths glob 會限制啟用範圍,只套用至符合條件的檔案,而您目前處理的檔案不符合。
  • 技能位於起始目錄下的巢狀 .claude/skills/ 目錄中。代理程式只有在讀取或編輯該子目錄內的檔案後,才會載入這些技能;在此之前,技能完全無法使用。

失效模式:技能持續觸發

另一個問題是描述範圍過大,導致技能在無關工作上觸發。「處理伺服器時使用」幾乎符合伺服器儲存庫中的任何請求。這會讓主體內容載入到不適用的工作中,並在工作階段剩餘時間持續保留於上下文中。

請將描述縮小至真正重要的條件,並列出涵蓋的檔案或命令。若技能只適用於特定檔案,請加入 paths glob。對於 deploy 或 commit 等具有副作用的操作,請設定 disable-model-invocation: true,並使用 /name 自行叫用,這樣代理程式就不會自行判斷現在是否適合執行 deploy。

失敗模式:這項技能應放在規則檔案中

規則檔案,例如 CLAUDE.mdAGENTS.md,會在每次工作階段開始時載入,並套用至所有工作。技能本文只有在技能觸發時才會載入。判斷依據是套用頻率。凡是適用於儲存庫中每項工作的資訊,例如所使用的套件管理器,都應放在規則檔案中。凡是只適用於少數工作的程序,例如上述的 nginx 規則,則應放在技能中;不需要編輯 nginx 時,不會產生額外成本。

真正的問題是把同一項內容放在兩處。兩份內容會逐漸產生差異;代理程式執行錯誤時,您無法判斷它遵循的是哪一份。每項指示都應指定唯一的存放位置。規則若已經只放在其中一處,卻仍被略過,這是另一個問題。在將它移入技能並期待移動能解決問題前,值得先檢查 遭忽略指示背後的運作機制技能、MCP 伺服器與規則檔案之間的界線會說明更複雜的情況,包括正確答案可能是 MCP (model context protocol) 伺服器:它提供代理程式新的工具,而不是新的指示。

在實際工作中證明有用後再分享

經過一週實際工作仍然可靠的技能,才值得提交。.claude/skills/ 中的專案技能會像程式碼一樣接受審查,並隨儲存庫一同提供。因此,隊友複製儲存庫後,無須額外設定就能取得你的修正。如何在儲存庫之間搬移技能而不使用複製貼上,則是另一個問題,請參閱如何在儲存庫之間分享代理程式技能

另有一項可攜性注意事項。Claude Code 接受許多 frontmatter 欄位,但 Agent Skills 標準只允許 6 個:namedescriptionlicensecompatibilitymetadataallowed-tools。如果將含有其他 frontmatter 欄位的技能上傳至 claude.ai,或將其封裝供 Skills API 使用,操作會直接失敗,而不是忽略該欄位:

Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name

只使用這 6 個欄位,同一個檔案就能在 Claude Code 及其他讀取此標準的工具中載入。不過,檔案載入的位置仍會決定它能執行的工作,因為Cowork 在 Anthropic sandbox 中執行,而 Claude Code 則在你自己的機器或 VPS 上執行。因此,上述 nginx 技能適合帶到隊友的 checkout,卻無法在連不到伺服器的 sandbox 中發揮作用。如何撰寫能適應不同模型的指示,是另一項工作;請參閱撰寫適用於任何模型的技能

FAQ

SKILL.md 檔案應該多長?

請控制在 500 行以內,而且多數實用的 skill 都會遠少於這個長度。本文內容會在 skill 叫用時加入對話,並持續保留到本次工作階段結束,因此每一行都是反覆產生的成本,而不是一次性成本。請將較長的參考資料移至 skill 目錄中的個別檔案,並從 SKILL.md 連結這些檔案,深度維持一層,讓代理程式只在需要時讀取。系統會直接執行隨附的指令碼,而不是讀取其內容,因此成本只有指令碼的輸出。

為什麼我的 skill 從未觸發?

通常原因是描述,因為模型做出判斷時,只有描述會存在於上下文中。請確認描述說明何時應使用此 skill,而不只是說明它能做什麼,並且包含您實際在請求中輸入的詞語。如果描述看起來正確,請檢查 frontmatter 是否包含 disable-model-invocation: true;此設定會讓模型完全看不到 skill。也請檢查 paths glob 是否將適用範圍限制在您未處理的檔案。若 skill 位於起始目錄下的巢狀 .claude/skills/ 目錄中,也可能造成此問題:代理程式只有在讀取或編輯該子目錄中的檔案後,才會載入它。

這應該是 skill,還是寫在規則檔案中的一行?

請先確認它適用於多少工作。規則檔案會在每個工作階段載入,因此應放入每項工作都成立的資訊,例如套件管理器或分支命名慣例。skill 只會在觸發時載入,因此適合存放只適用於少數工作的程序。請勿在兩處寫入相同指示,否則兩份內容會逐漸偏離,您也無法判斷代理程式遵循了哪一份。

如何確認 skill 確實有所幫助?

請將它與基準結果比較。收集幾個真實請求,在 skill 可用的情況下,於全新工作階段中分別執行每個請求;接著從 /skills 選單關閉 skill,再次執行這些請求,並將兩組回答並排檢視。使用全新工作階段很重要,因為撰寫 skill 的對話仍包含您的說明,會讓不完整的檔案看起來像是完整的。skill-creator plugin 會代您執行這項比較,並在 token 成本旁報告通過率。

我可以在不同的代理程式中使用相同的 SKILL.md 嗎?

可以,只要使用 Agent Skills 標準定義的欄位:namedescriptionlicensecompatibilitymetadataallowed-tools。Claude Code 接受更多欄位,也支援其他工具不會執行的本文功能,例如 shell command injection。若上傳的 skill 包含標準以外的欄位,系統會傳回明確錯誤,並列出允許的屬性。因此,請及早決定 skill 是只供 Claude Code 使用,還是需要在不同工具間移植。