戰(zhàn):從 SKILL.md 到可復(fù)用 AI 能力模塊)
1. 從“skills”這個(gè)熱詞說(shuō)起它到底是什么為什么突然火了最近幾個(gè)月不管是在技術(shù)社區(qū)還是各種開(kāi)發(fā)者群聊里“skills”這個(gè)詞出現(xiàn)的頻率高得離譜。如果你只是偶爾刷到可能會(huì)以為它說(shuō)的是“技能”這個(gè)泛泛的概念但只要你稍微往深里看一眼就會(huì)發(fā)現(xiàn)大家討論的其實(shí)是Agent Skills——一種讓 AI 編程助手比如 Claude Code、Codex 這類工具具備可復(fù)用、可組合、可版本管理的“能力模塊”的機(jī)制。說(shuō)白了以前我們用 AI 寫(xiě)代碼每次都得把上下文、規(guī)范、項(xiàng)目結(jié)構(gòu)重新喂一遍效率低不說(shuō)結(jié)果還不穩(wěn)定。而 Skills 的出現(xiàn)本質(zhì)上是把“怎么做一個(gè)特定任務(wù)”這件事從一次性的對(duì)話里抽出來(lái)變成一個(gè)獨(dú)立的、有結(jié)構(gòu)的文件包。這個(gè)文件包里最核心的就是SKILL.md它用自然語(yǔ)言加少量元數(shù)據(jù)的方式告訴 AI 在什么場(chǎng)景下該調(diào)用什么能力、按什么步驟執(zhí)行、注意哪些邊界條件。我最早接觸這個(gè)概念是在一個(gè)前端項(xiàng)目里當(dāng)時(shí)團(tuán)隊(duì)想讓 AI 幫忙統(tǒng)一處理組件的命名規(guī)范和目錄結(jié)構(gòu)。一開(kāi)始大家都是把規(guī)則寫(xiě)在 prompt 里但每次新開(kāi)一個(gè)會(huì)話就得重新貼一遍而且不同人寫(xiě)的 prompt 風(fēng)格不一樣AI 的輸出也飄忽不定。后來(lái)有人提議把這套規(guī)則做成一個(gè) skill放在項(xiàng)目根目錄的.skills文件夾下結(jié)果整個(gè)流程一下子就穩(wěn)了——不管誰(shuí)用、什么時(shí)候用只要觸發(fā)條件匹配AI 就會(huì)自動(dòng)加載這個(gè) skill按同樣的邏輯干活。所以如果你問(wèn)我 skills 解決了什么問(wèn)題我的回答很直接它解決的是 AI 輔助開(kāi)發(fā)中“重復(fù)勞動(dòng)”和“一致性缺失”這兩個(gè)老大難問(wèn)題。適合誰(shuí)來(lái)學(xué)我覺(jué)得只要你在日常工作中會(huì)用到 AI 編程工具不管是前端、后端、數(shù)據(jù)科學(xué)還是數(shù)學(xué)建模都值得花點(diǎn)時(shí)間了解一下。哪怕你暫時(shí)不打算自己寫(xiě) skill至少要知道怎么安裝、怎么用別人分享的 skill這已經(jīng)能幫你省下大量重復(fù)溝通的成本。2. Skills 的核心機(jī)制拆解為什么是 SKILL.md而不是別的2.1 SKILL.md 的設(shè)計(jì)哲學(xué)讓 AI 自己決定什么時(shí)候用很多人第一次看到SKILL.md的時(shí)候會(huì)有點(diǎn)懵——這不就是一個(gè) Markdown 文件嗎憑什么它能讓 AI 變聰明這里面的關(guān)鍵不在于文件格式本身而在于它的內(nèi)容結(jié)構(gòu)和加載時(shí)機(jī)。一個(gè)典型的SKILL.md通常包含幾個(gè)部分頂部的元信息比如 name、description、trigger 條件中間的步驟說(shuō)明以及底部的示例和邊界情況。AI 在運(yùn)行時(shí)會(huì)先掃描所有可用的 skill然后根據(jù)當(dāng)前對(duì)話的上下文判斷哪個(gè) skill 的 trigger 條件被滿足了再把對(duì)應(yīng)的內(nèi)容加載進(jìn)上下文。這個(gè)過(guò)程是按需加載的不需要你手動(dòng)切換也不需要你把所有規(guī)則都塞進(jìn)系統(tǒng)提示里。我打個(gè)比方以前的 prompt 就像你每次做飯都得把菜譜從頭念一遍給廚師聽(tīng)而 skill 就像你把菜譜寫(xiě)好了放在架子上廚師看到你今天點(diǎn)了紅燒肉自己就去把對(duì)應(yīng)的菜譜抽出來(lái)照著做。這個(gè)“自己抽”的動(dòng)作就是 skill 機(jī)制最值錢的地方。2.2 和傳統(tǒng) prompt 工程的區(qū)別從“一次性”到“可積累”傳統(tǒng) prompt 工程最大的問(wèn)題是不可積累。你今天調(diào)好了一個(gè)很滿意的 prompt明天換個(gè)會(huì)話、換個(gè)模型版本可能就失效了。而且 prompt 通常是寫(xiě)在對(duì)話里的沒(méi)法版本管理沒(méi)法 code review更沒(méi)法分享給團(tuán)隊(duì)其他人復(fù)用。Skills 把這件事變成了工程化的。SKILL.md可以放在 Git 倉(cāng)庫(kù)里可以寫(xiě) changelog可以打 tag可以像代碼一樣做 review。你改了一版 skill團(tuán)隊(duì)里所有人拉下來(lái)就能用效果是一致的。更重要的是skill 可以被組合——一個(gè) skill 可以依賴另一個(gè) skill就像函數(shù)調(diào)用一樣。這種可組合性讓復(fù)雜任務(wù)的拆解變得非常自然。2.3 觸發(fā)機(jī)制與上下文管理AI 是怎么“想起”某個(gè) skill 的這里涉及一個(gè)很多人忽略的細(xì)節(jié)skill 不是越多越好。如果你在項(xiàng)目里塞了幾十個(gè) skillAI 在判斷該用哪個(gè)的時(shí)候反而容易出錯(cuò)因?yàn)?trigger 條件之間可能會(huì)打架。我實(shí)測(cè)下來(lái)一個(gè)項(xiàng)目里同時(shí)激活的 skill 最好控制在 5 到 8 個(gè)以內(nèi)超過(guò)這個(gè)數(shù)量AI 的調(diào)用準(zhǔn)確率會(huì)明顯下降。觸發(fā)機(jī)制一般有兩種一種是關(guān)鍵詞觸發(fā)比如 skill 的 description 里寫(xiě)了“當(dāng)用戶提到組件命名規(guī)范時(shí)使用”那 AI 看到相關(guān)關(guān)鍵詞就會(huì)加載另一種是顯式調(diào)用比如你在對(duì)話里直接說(shuō)“用 xxx skill 來(lái)處理這個(gè)任務(wù)”。前者更自然后者更可控。我的建議是兩者結(jié)合——日常用關(guān)鍵詞觸發(fā)關(guān)鍵任務(wù)用顯式調(diào)用兜底。3. 從零開(kāi)始寫(xiě)一個(gè)自己的 Skill完整實(shí)操流程3.1 環(huán)境準(zhǔn)備你需要什么工具和目錄結(jié)構(gòu)先說(shuō)清楚寫(xiě) skill 本身不需要什么特殊環(huán)境一個(gè)文本編輯器加一個(gè) Git 倉(cāng)庫(kù)就夠了。但如果你想讓 skill 真正跑起來(lái)得確保你用的 AI 編程工具支持這個(gè)機(jī)制。目前 Claude Code 對(duì) skills 的支持比較成熟Codex 這邊也在跟進(jìn)具體版本要求建議看官方文檔的最新說(shuō)明。目錄結(jié)構(gòu)方面我習(xí)慣在項(xiàng)目根目錄下建一個(gè).skills文件夾里面每個(gè) skill 一個(gè)子目錄子目錄名就是 skill 的標(biāo)識(shí)符。比如.skills/ component-naming/ SKILL.md examples/ good-example.tsx bad-example.tsx api-error-handling/ SKILL.md每個(gè) skill 目錄里至少有一個(gè)SKILL.md如果有示例文件或者輔助腳本可以放在同級(jí)目錄下在SKILL.md里用相對(duì)路徑引用。3.2 寫(xiě)好 SKILL.md 的五個(gè)關(guān)鍵部分我寫(xiě)過(guò)的 skill 不算多但踩過(guò)的坑不少??偨Y(jié)下來(lái)一個(gè)能穩(wěn)定工作的SKILL.md應(yīng)該包含以下五個(gè)部分第一部分是元信息頭。通常用 YAML front matter 的格式寫(xiě)在文件最上面包括 name、description、version、trigger 這幾個(gè)字段。description 要寫(xiě)得具體但不啰嗦trigger 要覆蓋你希望 AI 自動(dòng)加載這個(gè) skill 的典型場(chǎng)景。第二部分是目標(biāo)說(shuō)明。用一兩句話講清楚這個(gè) skill 是干什么的解決什么問(wèn)題。這部分是給 AI 看的也是給以后維護(hù)這個(gè) skill 的人看的。第三部分是執(zhí)行步驟。這是核心內(nèi)容要按順序列出 AI 應(yīng)該怎么做。每一步都要具體到可執(zhí)行的程度不要寫(xiě)“優(yōu)化代碼結(jié)構(gòu)”這種模糊的話而要寫(xiě)“檢查每個(gè)組件的文件名是否以 PascalCase 命名如果不是重命名為 PascalCase”。第四部分是示例。給一兩個(gè)正例和反例讓 AI 知道什么算做對(duì)了什么算做錯(cuò)了。示例不用多但要有代表性。第五部分是邊界和禁忌。明確告訴 AI 在什么情況下不要用這個(gè) skill或者執(zhí)行過(guò)程中有哪些絕對(duì)不能做的事。這部分很多人會(huì)忽略但實(shí)際用起來(lái)能避免大量誤操作。3.3 一個(gè)真實(shí)案例前端組件命名規(guī)范 skill下面是我實(shí)際在用的一個(gè) skill 的簡(jiǎn)化版你可以直接參考這個(gè)結(jié)構(gòu)來(lái)寫(xiě)自己的--- name: component-naming description: 統(tǒng)一 React 組件的文件命名和導(dǎo)出規(guī)范 version: 1.2.0 trigger: - 用戶提到組件命名 - 用戶要求整理組件目錄 - 新建組件文件時(shí) --- ## 目標(biāo) 確保項(xiàng)目中所有 React 組件的文件名、導(dǎo)出名和目錄結(jié)構(gòu)保持一致。 ## 執(zhí)行步驟 1. 掃描 src/components 下所有 .tsx 文件 2. 檢查文件名是否為 PascalCase如果不是重命名 3. 檢查默認(rèn)導(dǎo)出名是否與文件名一致如果不一致修正 4. 檢查每個(gè)組件是否放在以組件名命名的子目錄中 5. 如果組件有配套的樣式文件或測(cè)試文件確保它們?cè)谕荒夸浵?## 示例 正例src/components/UserProfile/UserProfile.tsx 反例src/components/user-profile/index.tsx ## 邊界 - 不要修改 node_modules 下的任何文件 - 不要重命名已經(jīng)被其他文件引用的組件除非同時(shí)更新所有引用 - 如果組件名和文件名沖突無(wú)法自動(dòng)解決停下來(lái)詢問(wèn)用戶這個(gè) skill 寫(xiě)完之后我們團(tuán)隊(duì)里不管誰(shuí)用 AI 整理組件輸出都是一致的。以前每次都要在對(duì)話里重復(fù)一遍規(guī)則現(xiàn)在完全不用了。3.4 調(diào)試和迭代怎么知道 skill 寫(xiě)得好不好寫(xiě)完一個(gè) skill 只是開(kāi)始真正花時(shí)間的是調(diào)試。我的做法是先在小范圍試比如拿一個(gè)具體的任務(wù)讓 AI 跑一遍看它有沒(méi)有正確加載 skill、有沒(méi)有按步驟執(zhí)行、有沒(méi)有在邊界情況下停下來(lái)。如果發(fā)現(xiàn) AI 沒(méi)加載 skill通常是 trigger 寫(xiě)得不夠具體或者 description 和實(shí)際對(duì)話的匹配度不高。如果加載了但執(zhí)行不對(duì)多半是步驟寫(xiě)得太模糊或者示例不夠有代表性。如果 AI 在邊界情況下亂來(lái)那就是禁忌部分沒(méi)寫(xiě)清楚。我一般會(huì)迭代三到五版才覺(jué)得一個(gè) skill 比較穩(wěn)。每次改完都記一下改了什么、為什么改這樣后面維護(hù)的時(shí)候不至于忘了當(dāng)時(shí)的思路。4. 安裝和使用別人分享的 Skills少走彎路的實(shí)操建議4.1 從哪里找現(xiàn)成的 skill現(xiàn)在網(wǎng)上分享 skill 的地方越來(lái)越多GitHub 上搜SKILL.md或者agent-skills能出來(lái)一大堆。比較活躍的倉(cāng)庫(kù)通常會(huì)有分類目錄比如前端開(kāi)發(fā)、數(shù)據(jù)處理、數(shù)學(xué)建模、文檔寫(xiě)作等等。我建議優(yōu)先找star 數(shù)高、最近有更新、有實(shí)際使用案例的倉(cāng)庫(kù)不要隨便下一個(gè)來(lái)路不明的 skill 就往項(xiàng)目里塞。另外有些 skill 是跟特定工具綁定的比如專門給 Claude Code 用的或者專門給 Codex 用的。下載之前看清楚兼容性說(shuō)明不然裝上去可能根本不生效。4.2 手動(dòng)安裝 skill 的完整步驟假設(shè)你在 GitHub 上找到了一個(gè)想要的 skill手動(dòng)安裝的流程大概是這樣的把倉(cāng)庫(kù) clone 到本地或者直接下載 zip 包解壓找到里面包含SKILL.md的目錄通常一個(gè) skill 一個(gè)目錄把整個(gè) skill 目錄復(fù)制到你項(xiàng)目的.skills文件夾下檢查SKILL.md里的 trigger 條件是否和你的項(xiàng)目場(chǎng)景匹配不匹配就改一下重啟你的 AI 編程工具讓它重新掃描 skill 目錄在對(duì)話里測(cè)試一下看 AI 能不能正確加載注意有些 skill 會(huì)依賴外部腳本或者特定的環(huán)境變量裝之前一定要看 README 里的依賴說(shuō)明不然跑起來(lái)會(huì)報(bào)錯(cuò)。4.3 常見(jiàn)安裝問(wèn)題排查我遇到過(guò)幾次裝完不生效的情況排查下來(lái)基本是這幾個(gè)原因問(wèn)題現(xiàn)象可能原因解決方法AI 完全不加載 skill目錄結(jié)構(gòu)不對(duì)SKILL.md 不在正確位置確認(rèn) skill 目錄直接放在 .skills 下不要多套一層加載了但執(zhí)行報(bào)錯(cuò)缺少依賴或環(huán)境變量看 SKILL.md 里的依賴說(shuō)明補(bǔ)齊缺失項(xiàng)多個(gè) skill 沖突trigger 條件重疊精簡(jiǎn) trigger或者改成顯式調(diào)用改了 skill 不生效工具緩存了舊版本重啟工具或者手動(dòng)清除緩存目錄4.4 使用別人 skill 的注意事項(xiàng)別人的 skill 再好也是為別人的項(xiàng)目場(chǎng)景寫(xiě)的。直接拿來(lái)用之前我建議至少做三件事讀一遍 SKILL.md 的每一步確認(rèn)沒(méi)有你不希望 AI 執(zhí)行的操作檢查示例是否符合你的項(xiàng)目規(guī)范不符合就改掉在測(cè)試分支上先跑一遍確認(rèn)沒(méi)問(wèn)題再合到主分支。還有一點(diǎn)很重要不要同時(shí)裝太多功能重疊的 skill。比如你裝了兩個(gè)都是處理代碼格式化的 skillAI 在觸發(fā)的時(shí)候就會(huì)猶豫甚至可能兩個(gè)都加載導(dǎo)致指令沖突。我的做法是同類功能只保留一個(gè)其他的要么刪掉要么改成手動(dòng)調(diào)用。5. 進(jìn)階玩法把 Skills 組合起來(lái)解決復(fù)雜任務(wù)5.1 Skill 之間的依賴和調(diào)用單個(gè) skill 能解決的問(wèn)題是有限的真正有意思的是把多個(gè) skill 組合起來(lái)。比如你可以有一個(gè) skill 負(fù)責(zé)代碼規(guī)范檢查另一個(gè) skill 負(fù)責(zé)生成測(cè)試用例第三個(gè) skill 負(fù)責(zé)更新文檔。當(dāng)你說(shuō)“幫我重構(gòu)這個(gè)模塊”的時(shí)候AI 可以依次加載這三個(gè) skill按順序執(zhí)行。實(shí)現(xiàn)這種方式的關(guān)鍵是在 skill 的步驟里顯式引用其他 skill。比如在重構(gòu) skill 的最后一步寫(xiě)“調(diào)用 test-generation skill 為修改后的代碼生成測(cè)試”。這樣 AI 就知道該去加載哪個(gè) skill 了。5.2 用 skill 做數(shù)學(xué)建模和數(shù)據(jù)分析我看到不少人在討論數(shù)學(xué)建模比賽里怎么用 skills。說(shuō)實(shí)話這個(gè)場(chǎng)景特別適合。數(shù)學(xué)建模的流程通常是固定的理解問(wèn)題、選擇模型、寫(xiě)代碼求解、分析結(jié)果、寫(xiě)論文。你可以把每個(gè)階段做成一個(gè) skill比如“模型選擇 skill”里寫(xiě)清楚什么類型的問(wèn)題該用什么模型“論文寫(xiě)作 skill”里規(guī)定好摘要、假設(shè)、符號(hào)說(shuō)明的格式。這樣不管題目怎么變AI 都能按同樣的流程幫你推進(jìn)不會(huì)因?yàn)閾Q了個(gè)題目就完全不知道從哪下手。我試過(guò)用這種方式輔助寫(xiě)代碼效率提升很明顯尤其是那些重復(fù)性的數(shù)據(jù)預(yù)處理和可視化部分。5.3 團(tuán)隊(duì)協(xié)作中的 skill 管理如果是團(tuán)隊(duì)一起用 skill我強(qiáng)烈建議把.skills目錄納入 Git 管理并且制定一個(gè)簡(jiǎn)單的 review 流程。誰(shuí)想加新 skill提個(gè) PR其他人看一下 trigger 條件有沒(méi)有沖突、步驟有沒(méi)有歧義、禁忌有沒(méi)有遺漏。合并之后所有人拉下來(lái)就能用同一套能力。另外skill 也要寫(xiě) changelog。每次改了什么都記一下這樣當(dāng) AI 的行為發(fā)生變化時(shí)你能快速定位是哪個(gè) skill 的哪次改動(dòng)導(dǎo)致的。6. 我踩過(guò)的坑和總結(jié)出來(lái)的經(jīng)驗(yàn)6.1 不要試圖用一個(gè) skill 解決所有問(wèn)題我一開(kāi)始寫(xiě) skill 的時(shí)候總想寫(xiě)一個(gè)“萬(wàn)能 skill”把所有規(guī)范都塞進(jìn)去。結(jié)果就是 trigger 條件寫(xiě)得特別寬泛AI 動(dòng)不動(dòng)就加載它加載之后又因?yàn)椴襟E太多太雜執(zhí)行到一半就亂了。后來(lái)我學(xué)乖了一個(gè) skill 只做一件事做精做透。需要多個(gè)能力的時(shí)候用組合的方式解決而不是堆在一個(gè)文件里。6.2 trigger 要具體但不要過(guò)于狹窄trigger 寫(xiě)得太寬skill 會(huì)被頻繁誤加載寫(xiě)得太窄又可能該加載的時(shí)候不加載。我的經(jīng)驗(yàn)是用具體的動(dòng)作詞加對(duì)象詞比如“當(dāng)用戶要求重命名組件文件時(shí)”就比“當(dāng)用戶提到組件時(shí)”好得多。同時(shí)可以留一兩個(gè)稍微寬泛的 trigger 作為兜底但不要超過(guò)三個(gè)。6.3 示例比描述更有用AI 對(duì)示例的敏感度遠(yuǎn)高于對(duì)抽象描述的理解。與其寫(xiě)“代碼要整潔”不如直接給一段整潔的代碼和一段不整潔的代碼讓 AI 自己去對(duì)比。我后來(lái)寫(xiě) skill 的時(shí)候示例部分花的時(shí)間比步驟部分還多但效果確實(shí)好很多。6.4 定期清理不再使用的 skill項(xiàng)目在變skill 也要跟著變。有些 skill 可能半年前很有用但現(xiàn)在項(xiàng)目結(jié)構(gòu)改了它已經(jīng)過(guò)時(shí)了。如果不清理這些過(guò)時(shí)的 skill 會(huì)干擾 AI 的判斷。我一般每個(gè)月花十分鐘過(guò)一遍.skills目錄把不再用的刪掉把需要更新的更新一下。6.5 不要忽略安全邊界最后說(shuō)一個(gè)容易被忽略的點(diǎn)skill 里一定要寫(xiě)清楚AI 不能做什么。比如不能自動(dòng)提交代碼、不能修改生產(chǎn)環(huán)境配置、不能刪除文件而不詢問(wèn)。這些邊界看起來(lái)是常識(shí)但 AI 在執(zhí)行復(fù)雜任務(wù)的時(shí)候如果沒(méi)有明確限制真的可能會(huì)做出你意想不到的操作。我在禁忌部分通常會(huì)寫(xiě)三到五條硬性規(guī)則實(shí)測(cè)下來(lái)能避免絕大多數(shù)誤操作。關(guān)于 skills 這個(gè)話題能聊的還有很多比如怎么給 skill 做版本管理、怎么在 CI 里自動(dòng)校驗(yàn) skill 的格式、怎么把 skill 和現(xiàn)有的 lint 工具結(jié)合起來(lái)。但上面這些是我覺(jué)得最核心、最實(shí)用的部分。如果你剛開(kāi)始接觸建議先從寫(xiě)一個(gè)最簡(jiǎn)單的 skill 開(kāi)始跑通了再慢慢加復(fù)雜度。別一上來(lái)就搞大而全的東西那樣很容易受挫。