你在 Claude Code 裡寫了一個 skill,把團隊的 PR 規範、commit 慣例、release notes 格式全包進去。用得很順。隔天你開 Cursor 想做同一件事,發現它不在了——skill 躺在 .claude/skills/,Cursor 根本不看那個目錄。

於是你手動複製一份到 Cursor 的目錄。過兩天 Codex 也想用,再複製一份。然後 skill 改了一版,你得回頭把三個地方各更新一次,還很容易漏掉其中一個。再然後新同事加進來,問你「這個 skill 要怎麼裝」,你開始懷疑自己是不是該寫一份安裝說明。

這整條路我走過,每一步都不難,但加起來就是一堆瑣碎到讓人不想做的搬運工。問題的形狀其實很清楚:skill 本身是可攜的,可攜的東西卻沒有一個負責搬運的工具。

試過的兩條死路

第一條是手動複製。能動,但你等於把自己變成人肉同步器。三個 agent、五個專案、十個 skill,排列組合一拉開,維護成本就爆了。而且 symlink、相對路徑、版本號這些細節,手動做遲早出錯。

第二條是「那我把 skill 寫進每個工具各自的設定」。聽起來乾淨,實際上更糟——你把同一份知識切成了好幾份,從此它們開始各自漂移。哪天規範變了,你根本不知道有幾份副本要改。

兩條路的共同問題是:它們都在解「把檔案放對位置」這件事,但用的是人工。而「把檔案放對位置」這種有明確規則、可重複的事,本來就該交給工具。

skills 怎麼切進來

Vercel Labs 做的 skills 就是那個工具。一句話講,它是 agent skills 界的 npm

1
2
3
4
5
# GitHub 簡寫:owner/repo
npx skills add vercel-labs/agent-skills

# 也吃完整 URL、直指某個 skill、GitLab、本機路徑
npx skills add ./my-local-skills

跑下去,它會去 repo 把 skill 抓下來,然後依照一張內建的對照表,把它放進你電腦上各種 agent 對應的目錄。Claude Code 認 .claude/skills/,Cursor、Codex、Copilot 這些則共用 .agents/skills/,Windsurf 走 .windsurf/skills/——這些它都記得。寫一次,72 種以上的 agent 都能用。

這裡有個分工值得先記住,因為很多人會搞混:

格式是 Anthropic 定的,工具是 Vercel 做的。 Anthropic 定義「skill 長什麼樣」這個規範(後來開源成 agentskills.io 標準),Vercel Labs 的 skills 負責「跨平台把它裝對位置」。類比一下:Anthropic 出規格,Vercel 做 npm。

而所謂 skill,說穿了就是一個資料夾,裡面至少有一個 SKILL.md。最小的長這樣,短到不可思議:

1
2
3
4
---
name: skill-name
description: A description of what this skill does and when to use it.
---

namedescription 是僅有的兩個必填欄位。name 規則很硬:最長 64 字元、只能小寫英數和連字號、而且必須跟父目錄同名。最常見的「No skills found」幾乎都是栽在這——不是 name 漏了,就是 YAML 寫壞了。

真正被解掉的那一步

裝好之後最有感的是更新。預設用 symlink,各 agent 目錄都連到同一份副本,所以你 skills update 一次,所有工具同時到位。不支援 symlink 的環境就加 --copy 退回複製模式。

scope 也只有兩種選擇,對應兩種真實需求:

1
2
3
4
5
# 裝到專案(預設),跟著 repo commit,全隊共享
npx skills add owner/repo

# 裝到 global(-g),自己所有專案都能用
npx skills add owner/repo -g

回頭看開頭那條搬運鏈:跨 agent 不用複製了(它認得每個目錄)、團隊同步交給 git(project scope commit 進 repo)、版本一致交給 symlink + update、新同事一行 npx skills add 就上手。那條讓人不想做的瑣事鏈,被它從中間剪斷了。

常用指令大概這幾個,記起來跟 npm 幾乎一一對應:

指令 功能
skills add <source> 從 repo 安裝
skills list / ls 列出已裝的(像 npm ls
skills find [query] 搜尋,後端接官方目錄站 skills.sh
skills update 更新到最新版
skills remove / rm 移除
skills init [name] 生一份 SKILL.md 範本

還有一個 use 比較特別,它不安裝,只把 skill 轉成 prompt 印出來,可以直接 pipe 給 agent:

1
npx skills use vercel-labs/agent-skills@web-design-guidelines | claude

為什麼它不會把 context 撐爆

如果你擔心「裝一堆 skill,agent 一啟動不就把它們全讀進來、context 馬上滿?」——這正是整套機制最聰明的地方,叫 progressive disclosure,分三階段按需載入。

啟動時它只讀每個 skill 的 namedescription,大概 100 tokens,僅夠 agent 判斷「這個現在用得到嗎」。等你的任務真的對上某個 skill 的 description,才把整個 SKILL.md 讀進去。至於 scripts/references/ 裡的細節,要等真正執行到那一步才載入。

換個生活化的講法:這像你書架上的書。平常你只記得書背上的標題(discovery),需要時才抽出來翻目錄(activation),真要查某個細節才翻到那一頁(execution)。沒人會把整個書架的內容同時塞進腦袋。這也是為什麼規範建議 SKILL.md 控制在 500 行內、指令部分少於 5000 tokens——太肥的話 activation 那一下就會一次吞掉一大包,該拆的細節請丟到 references/ 用相對路徑引用。

官方範例 skill 裡,web-design-guidelines 把這招玩到極致:SKILL.md 本身很精簡,真正那 100 多條 a11y 與效能規則,是在執行階段才用 WebFetch 從 GitHub 抓最新版。規則更新了,你不用重裝 skill。順帶一提,範例 skill 不在 vercel-labs/skills(那是 CLI 本體),而在另一個 repo vercel-labs/agent-skills,別找錯。

還沒解掉的部分

它不是萬靈丹,有幾個邊界要先知道。

CLI 只負責「把檔案放對位置」,真正的觸發、載入、執行是各 agent 自己照規範處理。所以進階功能是 agent-specific 的,不是每家都吃:context: fork(讓 skill 在獨立 context 跑)目前只有 Claude Code 支援;Hooks 只有 Claude Code、Cline、Kiro 吃;allowed-tools 還是實驗性的。跨 agent 共用前,先確認目標 agent 撐不撐你用到的進階 feature,不然會裝了卻沒反應。

另外它要 Node.js 才能跑 npx、抓遠端 source 要有 git、要驗 skill 格式得另外裝官方的 skills-ref。它預設會收匿名 telemetry,介意的話用 DISABLE_TELEMETRYDO_NOT_TRACK 關掉(CI 環境會自動關)。最後,它屬於 Vercel Labs 的實驗專案,迭代很快、社群採用度也高,授權是 MIT,但「實驗專案」這四個字還是放心上。

回到開頭那個你——裝了 skill、隔天換工具發現不見的那個。現在的處理方式變成:skill 寫好放進 repo,npx skills add 一行裝進所有 agent,commit,收工。中間那些複製貼上、版本對不齊、教新人安裝的工,全部不見了。

說到底,這工具沒有發明任何新東西。skill 早就是可攜的格式,它只是補上了那個一直缺席的搬運工。而軟體工程裡最值錢的進步,往往就是這種——不是讓你能做新的事,是把一件你本來就在做、卻做得很煩的事,降到一行指令的成本。當搬運的摩擦低到可以忽略,你才會真的開始把知識打包、共享、累積。npm 當年對 JavaScript 生態做的,就是這件事。

專案連結:github.com/vercel-labs/skills(CLI 本體)、github.com/vercel-labs/agent-skills(官方範例 skill 集)
規範與目錄:agentskills.ioskills.sh