免費

從 Slash Commands 到 Skills:什麼時候遷、怎麼遷

custom commands 已併入 Skills:什麼時候該遷到 `.claude/skills/`,遷了之後能多做什麼


前三篇講了 slash command 的完整用法:從 Markdown 檔案,到 !命令 注入,再到 subagent 跟 MCP 編排。這些內容都沒過時——但官方在背後做了一次合併:custom commands 已經併入 Skills

你的 .claude/commands/review.md 還是能跑,/review 還是能用,什麼都不用改。但如果打算讓命令長出更多能力(多檔案、fork 執行、按路徑自動啟用),新路徑是 .claude/skills/review/SKILL.md。這篇講清楚兩件事:怎麼遷,以及值不值得遷。


最小遷移:改一個路徑,其他不動

官方的相容性承諾很明確:.claude/commands/deploy.md.claude/skills/deploy/SKILL.md 都會註冊成 /deploy,行為完全一樣。同名衝突時 skills 優先。

最小遷移步驟:

cd .claude/commands
mkdir -p ../skills/review
mv review.md ../skills/review/SKILL.md

檔案內容一行都不用改。YAML frontmatter、!`命令`@file$ARGUMENTS——全都相容。

但光做這一步,讀者會問:那遷它幹嘛?答案是 skill 目錄可以放多個檔案,而 command 只能一個。


為什麼要遷:SKILL.md 多出來的四樣東西

1. 支援檔案:把長文件拆出去

SKILL.md 是入口,同目錄可以放任意附屬檔案。想像一下這樣的目錄:

.claude/skills/review/
├── SKILL.md            # 入口,簡短的指令 + 引用
├── checklist.md        # 長長的程式碼審查清單
├── examples/
│   └── good-diff.md    # 正面範例
└── scripts/
    └── lint.sh         # SKILL.md 可以呼叫的 script

在 SKILL.md 裡用相對路徑引用:

審查當前 diff,遵循 [checklist.md](checklist.md) 裡的標準。
參考 [examples/good-diff.md](examples/good-diff.md) 理解期望的輸出格式。

這些附屬檔案不會自動進 context——Claude 按需讀取。官方建議 SKILL.md 控制在 500 行以內,其他都丟到附屬檔案裡。

2. disable-model-invocation:哪些 skill 只能你手動觸發

預設情況下,Claude 看到合適時機就會自主呼叫任何 skill。這對 /deploy/commit/send-email 這種有副作用的命令很危險——你不會希望它「看程式碼順眼就去部署」。

---
name: deploy
description: 部署到 production
disable-model-invocation: true
allowed-tools: Bash(kamal deploy:*), Bash(git push:*)
---

加這一行之後,/deploy 只能你手動輸入觸發,Claude 在對話裡不會自作主張叫它。

反過來 user-invocable: false 則是「只允許 Claude 自己呼叫,但不出現在 / 選單裡」——適合背景知識型的 skill(比如 legacy-system-context,相關情境下 Claude 自動載入,但你手動觸發沒有意義)。

3. context: fork:讓 skill 在子代理裡跑

這是最大的升級。上一篇講到 command 可以用 allowed-tools: Task 讓模型去起子代理——但你得在 prompt 裡手動描述「起個 Explore 子代理做……」。

SKILL 直接一行 frontmatter 搞定:

---
name: deep-research
description: 深入調研某個符號
context: fork
agent: Explore
---

調研 $ARGUMENTS 的所有用法:
- 所有呼叫點
- 業務場景
- 替代實作

回傳 ≤300 字總結。

觸發 /deep-research SomeClass 時:整個 SKILL.md 變成一個獨立子代理的 prompt,用 Explore agent type 執行,跑完只回傳結論。主對話的 context 完全乾淨。

這等於把「起子代理」這件事從 prompt 裡的描述文字變成了 skill 的宣告屬性。

4. paths:按檔案類型自動啟用

---
name: rails-conventions
description: Rails 專案的編碼規範
paths: ["app/**/*.rb", "config/**/*.rb"]
---

遵循本專案的 Rails 規範:
- 使用 service object,不要 fat controller
- ActiveRecord scope 必須命名化
...

當你正在編輯 app/models/user.rb 時,這個 skill 會自動加進 context;編輯 package.json 時不會。比 CLAUDE.md 的全域背景更精準——等於是「按路徑分層的 CLAUDE.md」。


實戰:把 /plan 升級成 skill

上一篇最後那個 /plan 範例,原本是單檔 command:

.claude/commands/plan.md

升級成 skill:

.claude/skills/plan/
├── SKILL.md
├── research-prompt.md     # 子代理 1 的指令
└── risk-prompt.md         # 子代理 2 的指令

SKILL.md:

---
name: plan
description: 基於 Linear ticket 產出實作方案
disable-model-invocation: true
allowed-tools: mcp__linear__*, Task, Read, Grep, Bash(git log:*)
---

## 上下文

@.claude/context/architecture.md

## 狀態

!`git log --oneline -10`

## 任務

拉取 Linear ticket $ARGUMENTS 的描述和留言。

用 Task 起兩個子代理並行調研:
1. 程式碼調研:prompt 見 [research-prompt.md](research-prompt.md)
2. 風險評估:prompt 見 [risk-prompt.md](risk-prompt.md)

彙總兩個結果後輸出實作步驟 + 風險清單 + commit 粒度建議。

兩個子代理的 prompt 放在獨立檔案,維護時改一處不用動到 SKILL.md。Skill 本身 30 行內清爽,附屬檔案可以各自幾百行詳細。

如果不想自己調度子代理,可以更激進——把整個 skill 丟進 fork,讓 Explore agent 一口氣執行:

---
name: plan
context: fork
agent: Explore
allowed-tools: mcp__linear__*
---

觸發 /plan ENG-4213 → 獨立 context 裡的 Explore agent 接過全部 SKILL.md 內容當任務執行 → 只回傳最終方案。主對話完全不髒。


什麼時候不用遷

不是所有 command 都值得升級。留在 .claude/commands/ 更合適的情況:

  • 單一 Markdown 就夠:沒有需要拆出去的 checklist、examples、scripts
  • 不需要 fork 執行:任務跟主對話深度耦合,需要看到完整歷史
  • 不需要按路徑自動啟用:就是使用者手動觸發
  • 不需要存取控制:讓 Claude 自動呼叫也不會出事

簡單的 /commit/pr-desc 這類就是一個 frontmatter + 幾行 prompt——放 .claude/commands/ 反而更直觀。官方明講兩種形式並存、都不會被淘汰


並存現況

現在 .claude/ 裡最乾淨的組織方式:

.claude/
├── commands/           # 輕量:單檔 + 簡單 prompt
│   ├── commit.md
│   └── pr-desc.md
├── skills/             # 重型:多檔 / fork / 權限控制
│   ├── plan/
│   │   ├── SKILL.md
│   │   ├── research-prompt.md
│   │   └── risk-prompt.md
│   ├── deploy/
│   │   └── SKILL.md    # disable-model-invocation
│   └── rails-conventions/
│       └── SKILL.md    # paths glob 自動啟用
└── context/
    └── coding-standards.md

不要一股腦全遷。遷移的觸發條件是「這個 command 已經開始膨脹」——正文超過 200 行、需要拆文件、想讓子代理執行。到那一步再改路徑,幾分鐘的事。


小結

想要的能力 commands/ skills/
單檔提示詞快捷鍵
!`命令` / @file / $ARGUMENTS
allowed-tools 權限控制
附屬檔案(reference、scripts)
disable-model-invocation 防誤觸發
context: fork + agent: 隔離執行
paths: glob 按路徑自動啟用

前三項 commands 跟 skills 完全等價;後四項是 skills 獨有。需要哪個就用哪個,不需要就別折騰。

官方路線正往 skills 傾斜,但 commands/ 的相容性承諾很明確——這不是「立刻全遷不然被淘汰」的變更,而是「新能力給你但不強迫」的擴展。搞清楚差異,按需要遷,別為了形式上的整齊硬遷。