寫 Claude Code 的 skill 寫到現在,每次要用進階欄位都得重查文件。這篇一次整理完 SKILL.md frontmatter 的完整欄位,之後填參數直接翻這頁。
先講一個掃出來的事實:我掃了本機 ~/.claude/skills/ 底下 52 個 skill 的 frontmatter,49 個只用了 name 和 description(頂多再加 license、version、metadata 這種不影響行為的欄位),真正用到行為控制欄位的只有 3 個。也就是說:大多數 skill 根本不需要進階欄位,description 寫好比什麼都重要。但剩下那些欄位各有明確用途——控制觸發方式、傳參數、免權限詢問、指定 model、丟給 subagent 跑——需要的時候不知道它存在,就只能土法繞路。
欄位表整理自官方文件(code.claude.com/docs 的 skills 與 sub-agents 兩頁),查於 2026-08。Claude Code 迭代很快,遇到行為對不上時以官方 reference 為準。
一、SKILL.md 是什麼、放在哪
一個 skill 就是一個資料夾加一份 SKILL.md:frontmatter 描述「它是什麼、怎麼觸發、怎麼執行」,內文是觸發後載入的指示。存放位置有五層,同名時上層蓋下層:
| 優先序 | 層級 | 路徑 |
|---|---|---|
| 1(最高) | Enterprise | 由組織 managed settings 派發 |
| 2 | Personal | ~/.claude/skills/<name>/SKILL.md |
| 3 | Project | .claude/skills/<name>/SKILL.md |
| 4 | Plugin | <plugin>/skills/<name>/SKILL.md |
| 5(最低) | 內建 | 隨 Claude Code 提供 |
注意 personal 蓋 project——個人層的同名 skill 會蓋掉專案層的,跟直覺相反(多數設定是專案優先)。plugin skill 用 plugin-name:skill-name 的 namespace,不會跟其他層衝突。舊的 .claude/commands/ 指令若與 skill 同名,skill 優先。
二、欄位總表
| 欄位 | 預設 | 作用 |
|---|---|---|
name |
目錄名 | 顯示名稱;平常可省略 |
description |
內文首段 | 決定會不會被自動觸發的唯一依據(見第三節) |
when_to_use |
— | 補充觸發條件,附加在 description 後 |
argument-hint |
— | 打 /name 時自動補全顯示的參數提示,如 [issue-number] |
arguments |
— | 宣告具名參數,內文用 $名稱 取值 |
disable-model-invocation |
false |
true = 只有使用者能用 /name 呼叫,模型不會自動觸發 |
user-invocable |
true |
false = 不出現在 / 選單,只有模型能觸發 |
paths |
— | glob 樣式;只有工作檔案符合時才觸發 |
allowed-tools |
— | 該輪免詢問的工具清單(不是白名單,見第五節) |
disallowed-tools |
— | 該輪移除的工具 |
model |
inherit |
執行這個 skill 用的 model(見第六節) |
effort |
繼承 session | 該 skill 的 reasoning effort(low 到 max) |
context |
— | fork = 丟到 subagent 執行(見第七節) |
agent |
general-purpose |
搭配 context: fork,指定 subagent 型別 |
background |
true |
搭配 context: fork;false = 前景等結果 |
shell |
bash |
內文動態注入指令用的 shell,可改 powershell |
hooks |
— | 該 skill 生命週期的 hook(PreToolUse 等) |
license / compatibility |
— | Agent Skills 開放規格的欄位,Claude Code 收下但不動作 |
metadata |
— | 自訂 key-value,給外部工具讀 |
一個容易踩的坑:欄位名打錯不會報錯。我掃到本機有個 skill 寫了 trigger:——官方欄位清單裡沒有這個欄位,skill 照樣載入、照樣能用,只是那行沒有任何效果,也沒有任何警告。這正是需要一份欄位表的原因:寫錯的欄位是靜默失效,不是報錯。
三、觸發機制:description 是唯一的門面
Claude Code 平常只把每個 skill 的 name 和 description 載進 context,不是全文。模型靠這一兩句話決定要不要觸發,所以:
- 第一句就放核心用途與關鍵詞(清單有字元預算,超出會被裁)
- 把觸發語寫進去(「比對兩個 DLL」「幫我看這兩個 trace 差在哪」這種使用者真的會說的話)
description+when_to_use合計上限 1,536 字元;所有 skill 的描述清單總預算約佔 context 的 1%,爆掉時先砍最少用的 skill
觸發方式由兩個布林欄位組成四種組合:
| 模型可自動觸發 | 模型不可觸發 | |
|---|---|---|
使用者可 /name |
預設 | disable-model-invocation: true |
| 使用者不可 | user-invocable: false |
(無意義的組合) |
disable-model-invocation: true 適合有副作用、只想手動跑的指令型 skill(部署、發文);user-invocable: false 適合純背景知識型 skill(讓模型自己判斷要不要看,不佔 / 選單)。另外 paths 可以再加一層條件——只有正在處理的檔案符合 glob 時才觸發。
四、參數傳遞:$ARGUMENTS 家族
使用者打 /skill-name foo bar 之後,參數這樣進到 skill 內文:
| 語法 | 意思 | /migrate SearchBar React Vue 的結果 |
|---|---|---|
$ARGUMENTS |
完整參數字串 | SearchBar React Vue |
$0、$1、$2 |
位置參數(0 起算) | $0=SearchBar,$1=React |
$名稱 |
arguments: 宣告的具名參數 |
arguments: [component, from, to] 後用 $from |
${CLAUDE_SKILL_DIR} |
skill 目錄的絕對路徑 | 引用附屬腳本用 |
${CLAUDE_PROJECT_DIR} |
專案根目錄 | |
${CLAUDE_SESSION_ID} |
當前 session ID | 寫 log 用 |
幾個行為細節:內文完全沒用 $ARGUMENTS 時,Claude Code 會自動把 ARGUMENTS: <值> 附加到內容尾端,所以不寫佔位符參數也不會丟失;多詞參數用引號括(/skill "hello world");要輸出字面的 $1.00 用 \$1.00 逃逸;索引超出實際參數數量時佔位符保留原樣。
五、allowed-tools:是「免詢問」,不是「白名單」
這個欄位的名字容易誤導。它不是限制 skill 只能用這些工具——所有工具照常可用——而是「這一輪裡,清單上的工具不跳權限詢問」。下一輪 grant 自動消失。真正要拿掉工具用的是 disallowed-tools。
支援的寫法:
1 | allowed-tools: Read, Grep # 逗號或空格分隔 |
兩個要點:settings 的 permissions.deny 規則優先於 allowed-tools,skill 預核不了被 deny 的東西;skill 內文的動態注入指令(!`command`)從不彈詢問,權限檢查不過就直接中止整個 skill——所以注入指令用到的工具要記得預核。
六、讓 skill 用指定 model 跑
model 欄位接受 alias(haiku、sonnet、opus、fable)、完整 model ID,或 inherit(預設,跟主對話)。生效範圍是該 skill 執行的那一輪:那一輪用指定的 model 跑,下一輪自動回到 session 原本的 model,不會改掉整個對話。effort 欄位同理,控制該輪的 reasoning effort。
實際的用法是成本分工:
1 | # 機械性的整理工作,便宜模型就夠 |
1 | # 審查、除錯類,需要深思 |
翻譯、重排版、跑固定腳本這類 skill 掛 haiku,額度省很多;審查類 skill 拉高 effort。這是「各 skill 指定 model」最直接的形式——不用動 session 設定,每個 skill 自帶合適的腦。
七、丟給 agent 跑:context: fork
context: fork 把 skill 的執行整個丟到 subagent:skill 內文變成 subagent 的 prompt,在獨立的 context window 裡跑,看不到主對話的歷史,跑完把結果回報回來。主對話的 context 不會被 skill 過程中的工具輸出灌爆——這是它最大的價值。
1 | context: fork |
agent 可以填內建型別(Explore、Plan、general-purpose),或自訂的 .claude/agents/<name>.md。幾個行為細節:
background預設true:skill 在背景跑,你繼續工作,完成後收到通知。要同步等結果就設false。非互動模式(-p)與排程觸發時會強制前景。- 內建
Explore和Plan不載入 CLAUDE.md 與 git status——刻意保持輕量。其他 agent 會載入主對話的 CLAUDE.md。 - 背景 subagent 的工具集受限(沒有 Artifact 等)。
model 由誰決定?優先序四層,由高到低:
CLAUDE_CODE_SUBAGENT_MODEL環境變數- 呼叫當下傳的 model 參數(模型透過 Agent tool 呼叫時)
- frontmatter 的
model欄位——skill 有context: fork時,skill 的model蓋過 agent 定義檔的model - 主對話的 model
整個執行位置的決策長這樣:
flowchart TD
S([skill 被觸發]) --> F{"有 context: fork?"}
F -- 否 --> M["在主對話執行
model / effort 只影響這一輪"]
F -- 是 --> A["丟給 agent 欄位指定的 subagent
獨立 context,看不到對話歷史"]
A --> B{"background?"}
B -- "true(預設)" --> BG[背景跑,完成後回報]
B -- false --> FG[前景等結果]
八、常用組合
最小可用——絕大多數 skill 該長的樣子:
1 |
|
手動指令型——有副作用,不讓模型自作主張:
1 |
|
固定工具免詢問——跑固定腳本不想一直按允許:
1 |
|
便宜模型跑雜活——丟給 subagent、用 haiku、不污染主對話 context:
1 |
|
九、其他實務提醒
- SKILL.md 保持在 500 行以下(官方建議)。細節拆到同目錄的附屬
.md,在 SKILL.md 用相對連結引用,模型按需載入;scripts/裡的腳本是直接執行、不進 context。 - 內文可以用
!`command`動態注入指令輸出(skill 載入前先執行、把結果嵌進內容)。Windows 使用者注意:預設 shell 是bash,要跑 PowerShell 指令記得加shell: powershell。 - 回到開頭的統計:52 個 skill 裡 49 個只需要
name+description。先把 description 寫到會被正確觸發,再考慮進階欄位——順序反了就是過度設計。
參考連結
- Agent Skills 官方文件(frontmatter reference 的原始出處)
- Subagents 官方文件(model 優先序與內建 agent 型別)
- Skill 撰寫 best practices
- Agent Skills 開放規格(
license、compatibility欄位的來源)
同分類的其他文章:
留言