跳至主要內容
未分類

Claude Code 技能怎麼做:最小 SKILL.md 與觸發、驗證一次看懂

發佈於 12 分鐘閱讀 MixRoute

Claude Code 技能怎麼做:最小 SKILL.md 與觸發、驗證一次看懂
Claude Code 技能怎麼做:最小 SKILL.md 與觸發、驗證一次看懂

Claude Code 技能就是一個資料夾,裡面至少有一個 SKILL.md:開頭是 frontmatter,下面寫指示。它不是寫得比較長的提示,也不用先裝外掛。Claude 會依相關性決定什麼時候把它載進上下文,您也可以在訊息開頭打 /技能名直接叫用。

做出最小可用版本只要三步:建立資料夾、寫好 SKILL.md、用 /技能名測一次。過程不用寫程式,也不用碰外掛或 MCP。指示寫順了,再決定要不要補支援檔案,或打包給同事。

Claude Code 技能是什麼,跟提示、外掛與 MCP 工具差在哪?

差別在誰決定內容什麼時候進到上下文。技能放在資料夾裡,由 Claude 依相關性決定何時載入。提示是您在對話裡直接輸入的內容,每次都得自己講清楚。CLAUDE.md 偏向每次開始就載入的背景說明,內容會一直待在上下文裡。三者常常同時存在,在同一場工作階段裡各補各的位。

Claude Code 技能是什麼,跟提示、外掛與 MCP 工具差在哪?
項目 它是什麼 什麼時候進到上下文
Claude Code 技能 一個資料夾,內含 SKILL.md,可再放 reference.md、examples.md 與 scripts/ 預設只有描述一直在上下文,叫用時才載入完整內容
提示 您在對話裡直接輸入的內容 您送出的那一刻
CLAUDE.md 專案或使用者層級的指導內容 每次開始就載入,不會等您問
外掛 技能資料夾加上 .claude-plugin/plugin.json 之後的打包單位 依外掛啟用範圍載入,可一起帶上代理、hooks 與 MCP 伺服器
MCP 工具 由 MCP 伺服器提供的工具,跟技能的指示與資源是不同層的東西 由伺服器連線決定

在技能資料夾裡加上 .claude-plugin/plugin.json,整包就會以 <name>@skills-dir 的名義載入成外掛,技能、代理、hooks 與 MCP 伺服器可以綁在一起交付。在專案的 .claude/skills/ 裡這樣做,第一次要先接受工作區信任對話。

舊的 .claude/commands/ 命令檔仍然有效,frontmatter 也大致相同,只是沒有 name 與 paths 這兩個欄位。新的工作直接寫成技能比較合適,因為技能支援支援檔案。

技能什麼時候會被載入、什麼時候會自己觸發?

預設情況下,技能的名稱與描述一直在上下文裡,Claude 可以自己判斷要不要叫用,叫用時才載入完整的 SKILL.md。所以描述要讓人一眼看出這個技能該在什麼情境上場,不然它只是躺在清單裡。

Skill 三層載入表:中繼資料常駐、觸發時載入指示、按需載入資源
Agent Skills 概覽(How Skills work)官方頁面 截圖,2026-10-24
技能什麼時候會被載入、什麼時候會自己觸發?
Frontmatter 設定 您可以叫用 Claude 可以叫用 描述是否在上下文中
(預設,不加欄位) 是 是 是
disable-model-invocation: true 是 無法自行叫用 否
user-invocable: false 否 是 是

這兩個開關各有適合的場景。disable-model-invocation: true 用在有實際副作用、或想自己決定何時發生的工作流程,例如 /commit、/deploy。這時描述不會進上下文,Claude 根本不知道有這個技能。user-invocable: false 相反,只有 Claude 能叫用,適合不能當指令操作的背景知識,例如解釋舊系統怎麼運作的 legacy-system-context。

直接叫用的寫法是把名稱放在訊息開頭,例如 /deploy staging,Claude Code 會直接執行。名稱出現在一般文字中間就不會直接跑任何東西,那個名稱只算您對這則訊息授予的權限,Claude 會依您的措辭判斷要不要用。如果只是不想讓某個技能一直出現在 Claude 的清單裡,可以用設定裡的 skillOverrides 個別調整,調成 off 之後連 / 選單都不會顯示。

技能也能吃參數。$ARGUMENTS 是叫用時傳進來的全部參數,$ARGUMENTS[0] 或簡寫 $0 取第一個,也可以用 arguments: [issue, branch] 宣告命名參數,讓 $issue、$branch 依序展開。像 /fix-issue 這種吃編號的技能,用參數比在內文裡寫「請使用者輸入」可靠。

frontmatter 裡有幾個欄位要先分清楚。compatibility 是 Agent Skills 規範定義的環境前提,接受最多 500 個字元的字串;Claude Code 接受這個欄位,但不會照著做任何事,別把它當成版本檢查。license 與 metadata 同樣只提供資訊,不改變叫用行為。

在某些上傳或 Skills API 工具裡,欄位拼錯會回報一則錯誤訊息,並列出可接受的屬性。那份清單只適用於該工具,Claude Code 的可用欄位要看它自己的文件。

最小可用的技能目錄長什麼樣,SKILL.md 要寫什麼?

最小可用的技能目錄長什麼樣,SKILL.md 要寫什麼?

建立資料夾與 SKILL.md

最小結構是一個資料夾加一個 SKILL.md。以 personal 位置為例,先建目錄:

Code
mkdir -p ~/.claude/skills/summarize-changes

接著在裡面寫 SKILL.md。frontmatter 的欄位都是選填,至少寫 description,內文放指示。官方文件的第一個範例做的是「整理未提交的變更」:

Code
---
description: Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff.
---
## Current changes
!`git diff HEAD`

## Instructions
Summarize the changes above in two or three bullet points, then list any risks you notice such as missing error handling, hardcoded values, or tests that need updating. If the diff is empty, say there are no uncommitted changes.

存檔之後,在對話裡問一句 What did I change?,或在訊息開頭打 /技能名,就會跑一次。第一次測試兩種都試:自動觸發看的是描述寫得準不準,手動叫用看的是指示有沒有被遵守。

支援檔案按需要載入

SKILL.md 不用塞下所有東西。細節拆成支援檔案,Claude 需要時才讀;腳本是直接執行,不會進到上下文:

Code
my-skill/
├── SKILL.md        (必要,總覽與導覽)
├── reference.md    (需要時載入,例如完整 API 細節)
├── examples.md     (需要時載入,例如使用範例)
└── scripts/
    └── helper.py   (執行,不載入上下文)

SKILL.md 裡用相對連結指向這兩個檔案就好,寫成 [reference.md](reference.md) 的形式。指示裡要引用跟技能一起打包的腳本,用 ${CLAUDE_SKILL_DIR} 組出絕對路徑;要指向專案裡的檔案,用 ${CLAUDE_PROJECT_DIR}。這樣做的原因是注入命令跑在工作階段的當前工作目錄,Claude 中途 cd 過的話,路徑就會跟著移動。

想讓每次叫用的結果留在同一個地方,可以用 ${CLAUDE_SESSION_ID} 組出檔名,例如把內容附加到 logs/${CLAUDE_SESSION_ID}.log,同一場工作階段的紀錄就會集中在一起。要依當下的努力程度調整指示,用 ${CLAUDE_EFFORT},它會展開成 low、medium、high、xhigh 或 max,實際能用到哪一級取決於模型。這兩個變數展開的是該場工作階段的實際值,同一份技能在不同工作階段能留下不同、但對得起來的紀錄。

description 是寫給模型看的,關鍵用例放最前面

description 是寫給模型看的,不是給人讀的摘要。Claude Code 在工作階段開始時會建立一份可用技能與描述的清單,再用它判斷眼前的請求對應哪個技能。所以這個欄位要寫成「什麼情況該觸發我」,把希望觸發的詞直接寫進去。

另一個容易吃虧的地方是長度。為了節省上下文,description 與 when_to_use 的合併文字在技能清單中會被截斷為 1,536 個字元,最關鍵的用例要放最前面。這個上限只作用在清單裡的那段文字,SKILL.md 全文沒有這個限制。

省略 description 的話,Claude Code 會改用 Markdown 內容的第一個非空行。第一行如果只是標題,模型看到的觸發說明就不是您以為的那句。

用注入命令帶進環境資訊

SKILL.md 裡以驚嘆號開頭的注入命令,會在叫用時先跑指令,再把輸出放進技能內容,適合放 git diff、node --version 這類每次都要重算的資訊;寫成獨立的區塊也可以。每個注入命令都在 Bash 工具的預設 2 分鐘逾時下執行。

逾時之後怎麼走,要看命令類型。Bash 工具把逾時的命令移到背景時,技能還是會呈現,注入的文字會報出背景任務與收集輸出的檔案。如果那條命令屬於 Bash 工具從不自動背景化的類型,Claude Code 會在逾時時把它殺掉,這個失敗會中止整次叫用。

另一種失敗跟環境有關:frontmatter 寫 shell: bash 但環境裡沒有 Git Bash,叫用會在執行任何命令之前就失敗,訊息是 Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found。逾時要看時間,這個錯誤要看環境,檢查的方向完全不同。輸出量超過 Bash 工具的內聯上限時,注入的會是檔案路徑加一段短預覽,不是被切斷的文字。

技能裡的腳本要呼叫模型時

技能裡的腳本要呼叫模型,不必自己多寫一層轉接。MixRoute 提供 Anthropic 相容的 Messages 端點 POST https://api.mixroute.ai/v1/messages,原生 Anthropic 的請求與回應格式都能直接送。用 Anthropic SDK 的話,只換 key 與 base_url(https://api.mixroute.ai,結尾不含 /v1),同一個 client 與 client.messages.create 照用。

這是 Anthropic 相容的那一條路。腳本如果改走 OpenAI 相容的 Chat Completions,base URL 是 https://api.mixroute.ai/v1,模型名稱不用改。用哪一條,看原本的 SDK 是哪一套;混用兩邊的位址,會變成很難查的錯。比較 MixRoute 的 API 方案與計費方式

怎麼確認技能真的被觸發、真的照做?

有回應不等於技能被叫用,Claude 可能只是用自己的方式回答了。依這個順序看就能分清楚:

  1. 在 / 選單確認技能名稱與描述都在,代表它確實被載入。
  2. 在訊息開頭打 /技能名,確認它會直接執行,沒有被當成一般文字。
  3. 檢查輸出有沒有照 SKILL.md 的指示走,例如指定的段落數、欄位或檢查項目。
  4. 用描述裡提到的情境自然問一次,看 Claude 會不會自己叫用。
  5. 覺得哪裡怪,用 /doctor 看擴充項目、安裝健康狀態與是否有更新版本。

內建的 /run 與 /verify 是同一種東西,可以拿來對照行為。/run 啟動並驅動您的應用,看變更是否生效;/verify 建置並跑起來,確認程式碼行為符合預期;/run-skill-generator 則教這兩個技能怎麼建置與啟動您的專案。

用 skill-creator 把「感覺變好」換成可比較的數字

要更嚴謹,可以裝 skill-creator 外掛跑評估:/plugin install skill-creator@claude-plugins-official。測試案例放在技能目錄的 evals/evals.json,裡面存提示、輸入檔與預期行為。每次執行會為每個案例開一個子代理,從乾淨的上下文開始,並記錄 token 數與時間。

評分結果寫進 grading.json,有技能與無技能的通過率、時間與 token 會彙整成 benchmark.json,用來比較品質提升多少、代價是多少。

同一個外掛也能對技能的兩個版本跑盲測 A/B,在提交編輯前確認這次改動是改進。描述調校則會產生「應該觸發」與「不應該觸發」的提示,量出命中率,並在技能在錯誤的請求上啟動時提出描述修改建議。每一步都有落地的檔案可以前後比對,不用只憑一次對話的感覺決定。

如果某個技能很少用到,而您在意它佔掉的上下文,個人與專案技能可以在 skillOverrides 裡設成 off 停用。要評估外掛提供的技能,依外掛文件執行 claude plugin eval,那是另一個評估入口。

技能沒生效時,先檢查哪幾件事?

有些失效是完全安靜的,沒有錯誤訊息,技能就是不會出現。剛把技能放進專案、打了名字卻沒反應的話,照下面的順序看最快:

  • 資料夾名稱:不要把自製技能命名為 synced,不分大小寫。叫 synced 的技能資料夾保留給從 claude.ai 下載的技能,enterprise、personal、project 位置裡用這個名字的自製技能會被略過。
  • 保留前綴:外掛之外,名為 anthropic-skills 或以 anthropic-skills: 開頭的技能資料夾或命令檔不會載入;外掛裡叫 anthropic-skills 的不受此限。
  • 上傳或 Skills API 工具的 frontmatter 欄位:在這些路徑中,拼錯或不被接受的欄位會回報 Unexpected key(s) in SKILL.md frontmatter,並列出該工具接受的屬性;Claude Code 的可用欄位要看它自己的文件。
  • shell 設定:寫了 shell: bash 而環境沒有 Git Bash,叫用會在命令執行前失敗;啟用 PowerShell 工具並設定 shell: powershell 時,命令則走 PowerShell 執行。
  • 逾時:先看 Bash 工具的 2 分鐘預設,以及該命令能不能被移到背景。
  • 顯示設定:調成 name-only 時,Claude 只看得到名稱、看不到描述,自動觸發就變得靠運氣;調成 user-invocable-only 時,Claude 完全看不到這個技能,只剩您手動叫用。
  • 同名衝突:Enterprise 優先於 personal,personal 優先於 project。自訂技能會取代同名的內建指令,但不會取代它的別名,例如專案裡的 code-review 技能取代 /code-review,內建的別名 /review 仍然執行原本的指令。本機技能也勝過同名的命令檔。

寫完第一個技能之後,怎麼放進日常開發流程?

自己用的技能放 personal 位置,本機所有專案都吃得到,但 Cowork 與雲端工作階段不算在內。要讓同事共用,把技能放進專案的 .claude/skills/ 並提交版控,同一份儲存庫的人就有同一個技能。專案是多層目錄的話,也可以放在子目錄的 .claude/skills/,在該目錄或其下啟動的工作階段會載入它。企業要一次部署到所有機器,走的是託管設定目錄。

需要腳本、hooks 或代理一起交付時,多加一層外掛設定,整包就以同一個名字變成外掛。從個人測試走到團隊共用,通常是這個順序:先在自己機器上把指示寫順,再進版控,最後才包成外掛,因為外掛處理的是安裝與更新,不是指示本身。

包成外掛之後,叫用的名字也跟著變。外掛裡的技能會掛上外掛名,例如 my-plugin/skills/review/SKILL.md 對應 /my-plugin:review,frontmatter 裡寫了 name: fancy 就變成 /my-plugin:fancy。外掛根目錄那個 SKILL.md 以 frontmatter 的 name 為準,沒有寫才回退到外掛目錄名稱。

從 claude.ai 帳號同步下來的技能一律掛 anthropic-skills: 前綴,帳號裡叫 deploy 的技能就是 /anthropic-skills:deploy,只有在沒有其他命令佔用這個名稱時,才會簡化成 /deploy。

團隊成員說「我這邊打了沒反應」,先問他打的是哪一個完整名稱,通常比翻文件快。技能把「怎麼做」固定下來之後,下一步是把整段開發流程交給 Claude 走完。想接著看從需求到實作的完整走法,可以看 vibe coding 的完整開發流程。

FAQ

Claude Code 技能跟提示、CLAUDE.md 有什麼不同?

差在載入方式。技能的名稱和描述平常掛在清單上,您打 /技能名,或 Claude 判斷眼前的請求相關時,才把完整內容載進來。提示只有這次講的內容,講漏了就沒有。CLAUDE.md 幾乎每次開始都在上下文裡,屬於不分任務都要知道的背景。實務上常見的搭配是 CLAUDE.md 放專案規範,技能放有明確觸發條件、可以重複使用的做法。

寫技能一定要會寫程式嗎?

不一定。最小技能只需要一個 SKILL.md,用 Markdown 寫指示就能被叫用,description 也只是普通文字。要放腳本時才需要程式能力,而 scripts/ 裡的腳本是執行用的,不會佔用上下文。純指示的技能可以先上線,之後再補支援檔案。不是工程師但熟悉某個流程的話,把步驟寫成指示、把觸發條件寫進 description,同樣能做出可用的技能。

技能建好了,為什麼沒有被觸發?

先看它有沒有出現在 / 選單,這一步能分開「沒載入」和「載入了但沒被叫用」。沒出現的話,檢查位置對不對:personal 的技能只有本機能用,專案的技能要放在該儲存庫的 .claude/skills/ 裡,而且要在該儲存庫的工作階段才看得到。有出現但問了一般問句沒反應,就回頭看 description 有沒有把實際會講的詞寫進去,關鍵用例放最前面,被截斷就等於沒寫。以上都對,再核對保留名稱那一項,某些名字的技能不會被載入。

我打了 /技能名卻沒有直接執行,為什麼?

看名稱放在哪裡。名稱在訊息開頭,Claude Code 會直接執行;夾在一般文字中間,例如 go ahead and /deploy to staging,就不會直接跑,那個名字只代表您在這次訊息裡開放了這個技能,要不要用仍由 Claude 依措辭判斷。另外,關掉模型自行叫用的權限之後,那個技能反過來只有您能叫用,Claude 不會自己啟動。連 / 選單都找不到它的話,是載入階段的問題,跟叫用方式無關。

技能要放哪裡,同事才用得到?

放進專案、提交版控,同事就用得到。專案的 .claude/skills/ 對這個儲存庫的工作階段生效,同事拉下程式碼就有同一個技能。多層目錄的專案也可以放在子目錄的 .claude/skills/,在該目錄或其下啟動的工作階段會直接載入,從上層啟動的工作階段則要等 Claude 處理到那裡的檔案才載入。personal 位置只在自己這台機器上,Cowork 與雲端工作階段也吃不到。要一次部署到全公司,走企業層級的託管設定;需要連腳本、hooks 或代理一起交付,就包成外掛,安裝與更新交給外掛處理。

技能可以自己執行指令嗎?

可以。在 SKILL.md 裡寫注入命令,叫用時會先跑指令再把輸出放進內容,git diff、node --version 這類結果會變動的資訊很適合這樣放。每個注入命令都在 Bash 工具的預設 2 分鐘逾時下執行;逾時時,命令被移到背景的話技能照常呈現,屬於不自動背景化的類型就會被殺掉,整次叫用中止。命令在執行前就失敗的話,訊息會指出缺了什麼,照著看比翻文件快。

技能跟外掛、MCP 工具有什麼不同?

技能是 Claude 依相關性載入的指示與資源。外掛是打包單位,多一層外掛設定之後,就能把技能、代理、hooks 與 MCP 伺服器綁在一起交付與安裝。MCP 工具由 MCP 伺服器提供,跟指示與資源是不同層的東西,兩者可以同時存在於同一場工作階段。要挑的話,先問要交付的是做法還是連線:做法寫成技能,對外系統的連線交給 MCP 伺服器。

掃描以分享
掃描以分享