以前你想在 Claude Code 裡自訂一個 /指令,做法很單純:在 .claude/commands/ 底下丟一個 markdown 檔,寫好你要它做的事,存檔,下次打 /那個檔名 就會跑。很多人——包括我——的 .claude/commands/ 裡都躺著一疊這種小抄:/commit/review/standup,各自包一段你懶得每次重打的 prompt。

現在你打開官方文件想找 commands 那一頁,會發現它不見了。不是被砍掉,是被併進了另一個東西——Skill。官方很明確地講了這句話:commands 跟 skills 現在是同一個東西了。你舊有的那些自訂指令,沒有消失,它們全都「變成」skill 了。

這個合併乍看只是改名換湯,但搞懂它為什麼要合併,比記住新語法有用得多。

先用一個比方說清楚差在哪

把 Claude 的工作空間想成你的辦公桌。

舊的 command,像是你貼在螢幕邊框上的便利貼。它有個好處:隨時看得到,伸手就用。但壞處是——不管你今天用不用得到,它都一直黏在那裡佔著視線。十張便利貼貼上去,螢幕邊框就被塞滿了,每一張都在分掉你(其實是分掉 Claude)的注意力。

新的 skill,像是你抽屜裡分類好的食譜卡。平常它安安靜靜躺在抽屜裡,完全不佔桌面。等你真的要做某道菜,才把對應那張卡抽出來攤開。做完收回去,桌面又乾淨了。

這個差別的學名叫 context efficiency(上下文效率)。一個 skill 只在你真的用得到的時候才被載入進對話,其餘時間你的 context window 是乾淨的。對照之下,舊的做法比較像「先把所有指令的說明都塞進腦袋,再開始工作」——指令越多,開工前腦袋就越擠。當你的自訂指令從三個長到三十個,這個差別就不再是細節,而是「Claude 還沒開始做事就已經被一堆用不到的說明塞滿」的實際問題了。

一個 skill 到底長什麼樣

說穿了沒什麼玄機。一個 skill 就是 .claude/skills/<名字>/ 這個資料夾底下的一個 SKILL.md 檔,前面掛一段 YAML frontmatter,後面寫指令內容。

1
2
3
4
5
6
7
---
name: commit
description: 把目前的變更整理成一個 conventional commit
---

讀取 git diff,依變更內容分類,產生一句 conventional commit 訊息,
用繁體中文寫,type 從 feat/fix/refactor/docs/chore 裡挑。

存好之後,兩種方式會觸發它。第一種是你親手打 /commit——跟以前的 command 一模一樣。第二種是 Claude 自己判斷現在這個情境用得上這個 skill,自動把它叫出來。那段 description 就是給 Claude 看的:它靠這句話判斷「現在該不該抽這張卡出來」。所以 description 寫得清不清楚,直接決定 skill 會不會在對的時機被自動喚起。

這也回答了「我舊的 commands 怎麼辦」這個問題——基本上你什麼都不用改,原本能打 /那個名字 的行為都還在,差別只在它現在多了「能被自動觸發」這個能力,而且不再常駐佔位子。

你需要的三段控制

光是「能自動觸發」聽起來有點失控——萬一我不想要它自作主張呢?這就帶到 frontmatter 裡幾個關鍵的開關。

想完全手動、不准它自己跑,加一行 disable-model-invocation: true。這樣這個 skill 就只認你親手打的 /名字,Claude 不會自作主張喚它。適合那種「跑下去會有副作用、我要自己決定時機」的指令,例如部署、發版這類。

想讓它在一個乾淨的隔離空間跑,用 context: fork。加了這個,skill 不在你當前對話裡執行,而是丟到一個 subagent 裡跑——這就接到下一個常被搞混的問題了。

skill 還是 subagent?看一件事就好:要不要隔離

很多人卡在這裡:明明都能「打包一段工作交給 AI」,到底什麼時候用 skill、什麼時候用 subagent?

判斷標準其實只有一個——這件事的過程,你想不想看見

skill 在你當前的對話裡跑。它做的每一步、產生的每一段中間結果,都攤在你眼前,你可以隨時插話、隨時喊停、隨時調整方向。適合那種你想「邊看邊指揮」的流程。

subagent 則是丟到一個自己的 context window 裡跑,跟你的主對話隔開。它在裡面翻檔案、讀 log、跑一長串推理,這些雜訊全部留在那個隔離空間,最後只把一份摘要回報給你。適合那種「我不想看你怎麼查的,給我結論就好」的側邊任務——深度搜尋、log 分析、依賴稽核這類,做完只回一句話的那種。

倒過來想,什麼情況用錯了會難受?如果你把一個需要你全程盯著、隨時要修正方向的任務丟給 subagent,你會看不到它跑歪了;反過來,如果你把一個會吐出一大堆中間雜訊、你又根本不想看的任務寫成 skill,那堆雜訊就會把你的主對話 context 塞爆。選錯邊,不是不能跑,是會把你想避開的麻煩原封不動請回來。

多了就打包,順便解決撞名

當你手上的 skill、hook、subagent 累積到一定數量,每個團隊成員都要手動裝一遍很煩。這時候就把它們打包成一個 plugin——skills、hooks、subagents、工具,全部包進去,別人一鍵安裝。

打包還順手解了一個你遲早會遇到的問題:撞名。plugin 裡的 skill 會自動加上命名空間,變成像 /security:scan 這樣,前面那個 security: 就是 plugin 名。這樣就算你本地專案也有個叫 scan 的 skill,兩個也不會打架。簡潔的設計往往就是這樣——不是多加一層管理,而是讓衝突在命名規則裡自己消失。

順帶一提,這個「用一個檔案描述 AI 該怎麼做事」的方向,不只 Claude 在走。隔壁的 Cursor 有 rules、Codex 跟 Copilot 認 AGENTS.md,大家都在把「對 AI 的指令」從散落各處收斂成可版控、可分享的檔案。Claude 這套 skill 模型比較特別的地方,在於那個「按需載入」——別家多半是把規則整包塞進去,Claude 則是讓它平常躺著、要用才抽出來。對 context 是固定資源這件事,它顯然想得比較透。

原文來源:Steering Claude Code: skills, hooks, subagents and more
官方文件:code.claude.com/docs

真正變的不是語法,是擴充的思路

如果你只把這次合併當成「command 改叫 skill 了」,那你會錯過重點。

真正換掉的,是「怎麼擴充 Claude」這件事背後的思路。舊的模型是加法——你想多一個能力,就多貼一張便利貼,全部常駐,直到桌面被貼滿。新的模型是按需供給——你建的是一座分類好的工具庫,平常一張卡都不佔位子,Claude 在對的時機自己去抽對的那一張。

這個轉變,跟你寫程式時學會「不要把所有東西塞進全域變數,而是需要時才 import」是同一回事。地基都一樣:注意力跟 context 都是有限的資源,誰能把「平常不佔,要用才取」這件事做好,誰就跑得久、跑得穩。下次你又想加一個自訂指令時,別只問「它要做什麼」,多問一句——「它平常該不該一直待在桌上?」想清楚這題,你就真的吃懂這次合併了。