:用TDD和skills CLI構(gòu)建可復(fù)用的AI編程代理技能庫)
1. 從agent-skills這個標(biāo)題能讀出什么第一次看到agent-skills這個詞我的直覺是它不是一個具體的軟件產(chǎn)品名而更像是一個能力集合或者技能庫的概念。結(jié)合熱搜詞里反復(fù)出現(xiàn)的 AI coding agents、skills CLI、Claude Code、test-driven-development 這幾個關(guān)鍵詞基本可以判斷這是一個圍繞 AI 編程代理AI coding agent構(gòu)建的可復(fù)用技能模塊體系核心目標(biāo)是把讓 AI 幫你寫代碼這件事從隨緣對話變成有章法、可復(fù)現(xiàn)的工程流程。說白了大多數(shù)人用 AI 編程工具的方式是打開對話框描述需求等它吐代碼復(fù)制粘貼跑一下報錯了再貼回去讓它改。這種方式在寫一個幾十行的小腳本時沒問題但一旦項目規(guī)模上去、涉及多文件改動、需要跑測試、需要遵守團(tuán)隊規(guī)范純對話式的做法就會迅速失控。agent-skills 想解決的正是這個失控問題——它把常見的開發(fā)任務(wù)拆解成一個個標(biāo)準(zhǔn)化的技能每個技能有明確的輸入、輸出、執(zhí)行步驟和驗證方式AI 代理按照技能定義去執(zhí)行而不是自由發(fā)揮。這篇文章適合三類人看第一類是想搞清楚 AI coding agent 到底怎么用才高效的中級開發(fā)者第二類是已經(jīng)在用 Claude Code 這類工具、但總覺得差點意思的實踐者第三類是對 test-driven-development 和 skills CLI 這套組合感興趣、想搭一套自己工作流的技術(shù)負(fù)責(zé)人。我會從概念拆解、環(huán)境準(zhǔn)備、技能設(shè)計、TDD 集成、CLI 實操、踩坑經(jīng)驗幾個維度展開盡量把每個環(huán)節(jié)的為什么講透。需要提前說明的是agent-skills 目前沒有一個官方統(tǒng)一的定義不同團(tuán)隊、不同工具鏈下它的具體形態(tài)差異很大。我下面講的內(nèi)容是基于當(dāng)前主流 AI coding agent 的通用實踐和熱搜詞透露出的技術(shù)方向做的合理推演具體落地時你需要根據(jù)自己的工具鏈做適配。2. AI coding agent 的能力邊界到底在哪2.1 代理不是萬能助手它是個執(zhí)行力很強(qiáng)但需要指令的實習(xí)生很多人對 AI coding agent 的期待是我說個大概它全幫我搞定。實測下來這種期待在簡單任務(wù)上偶爾能兌現(xiàn)但在真實項目里幾乎必然翻車。原因很簡單代理沒有你的項目上下文不知道你們團(tuán)隊的代碼規(guī)范不清楚哪些模塊是歷史遺留不能動的更不知道你嘴上說的優(yōu)化一下具體指性能、可讀性還是可維護(hù)性。我習(xí)慣把 AI coding agent 類比成一個執(zhí)行力極強(qiáng)但完全沒有背景知識的實習(xí)生。你給它一個清晰、邊界明確、有驗收標(biāo)準(zhǔn)的任務(wù)它能干得又快又好你給它一個模糊的、需要判斷力的任務(wù)它就會開始自由發(fā)揮而自由發(fā)揮的結(jié)果往往不是你想要的。這個認(rèn)知直接決定了 agent-skills 的設(shè)計哲學(xué)把模糊需求轉(zhuǎn)化為明確技能。一個技能應(yīng)該包含觸發(fā)條件什么時候用這個技能、輸入?yún)?shù)需要提供什么信息、執(zhí)行步驟按什么順序做什么、驗證標(biāo)準(zhǔn)怎么判斷做完了、做對了。這四要素缺一不可尤其是驗證標(biāo)準(zhǔn)這是區(qū)分玩具級用法和工程級用法的分水嶺。2.2 為什么 skills CLI 是這套體系的關(guān)鍵拼圖熱搜詞里出現(xiàn)了 skills CLI這不是偶然。如果 agent-skills 只是一堆寫在文檔里的規(guī)范那它很快就會變成寫了沒人看的擺設(shè)。CLI 的價值在于把技能變成可執(zhí)行、可調(diào)用、可版本管理的實體。想象一下這個場景你定義了一個叫add-api-endpoint的技能規(guī)定了新增 API 接口時必須先寫測試、再寫實現(xiàn)、最后更新文檔。如果沒有 CLI你只能靠自覺去提醒 AI記得先寫測試有了 CLI你可以直接執(zhí)行skills run add-api-endpoint --path /users --method POSTCLI 會自動把技能定義、項目上下文、相關(guān)文件一起喂給 AI 代理并按預(yù)設(shè)流程驅(qū)動它一步步執(zhí)行。這就是從對話式編程到技能式編程的躍遷。前者依賴你的臨場表達(dá)和 AI 的臨場理解后者把最佳實踐固化成了可復(fù)用的流程。對于團(tuán)隊協(xié)作來說這意味著新人也能通過調(diào)用技能產(chǎn)出符合規(guī)范的代碼而不是每個人都要重新摸索一遍怎么跟 AI 溝通。2.3 當(dāng)前階段最值得投入的三類技能不是所有任務(wù)都值得做成技能。根據(jù)我的經(jīng)驗以下三類任務(wù)的投入產(chǎn)出比最高技能類型典型場景為什么值得做成技能高頻重復(fù)型新增 CRUD 接口、寫單元測試、生成類型定義每次流程一樣固化后省去重復(fù)溝通成本規(guī)范敏感型代碼審查、提交信息生成、文檔更新有明確規(guī)范AI 容易跑偏需要強(qiáng)約束多步驟型重構(gòu)模塊、遷移依賴、修復(fù)批量 bug步驟多易遺漏技能能保證流程完整反過來那些一次性的、高度依賴具體業(yè)務(wù)判斷的任務(wù)做成技能反而增加負(fù)擔(dān)。我見過有團(tuán)隊把設(shè)計數(shù)據(jù)庫 schema也做成技能結(jié)果每次調(diào)用都要填一堆參數(shù)還不如直接對話來得快。技能化的邊界是流程穩(wěn)定、標(biāo)準(zhǔn)明確、重復(fù)出現(xiàn)。3. 把環(huán)境搭起來從 Claude Code 到 skills CLI3.1 工具鏈選型的幾個現(xiàn)實考量熱搜詞里 Claude Code 出現(xiàn)頻率極高還有一堆關(guān)于安裝、配置、接入第三方模型的問題。這說明大家在實際落地時第一個卡點就是環(huán)境。我先說選型邏輯再說具體操作。選 AI coding agent 工具核心看三個維度上下文理解能力、工具調(diào)用能力、可擴(kuò)展性。上下文理解決定了它能不能讀懂你的項目工具調(diào)用決定了它能不能真正執(zhí)行命令、讀寫文件而不只是聊天可擴(kuò)展性決定了你能不能把 agent-skills 這套體系接進(jìn)去。Claude Code 在這三個維度上目前是比較均衡的選擇尤其是它的終端命令執(zhí)行能力和文件操作能力讓它能真正參與到開發(fā)流程里而不是停留在給建議的層面。至于接入第三方模型熱搜里提到的 deepseek、qwen、glm 等這屬于成本優(yōu)化和可用性考量思路是通過兼容層把不同模型統(tǒng)一到同一套調(diào)用接口下具體配置因工具而異這里不展開。3.2 環(huán)境準(zhǔn)備中最容易忽略的三個細(xì)節(jié)大部分人裝完工具、跑通一個 hello world 就以為環(huán)境好了結(jié)果真正用起來各種問題。以下三個細(xì)節(jié)是我踩過坑之后總結(jié)的第一工作目錄的隔離。AI coding agent 默認(rèn)能訪問你給它的整個目錄樹。如果你在 home 目錄下啟動它理論上它能讀到你的所有文件。正確做法是為每個項目單獨開一個工作目錄并且用配置文件明確限定它能訪問的路徑范圍。這不是多疑而是防止 AI 在幫我清理一下項目這類指令下誤刪無關(guān)文件。第二依賴版本的鎖定。skills CLI 這類工具往往依賴特定版本的運行時Node、Python 等。我遇到過因為全局 Node 版本和項目要求不一致導(dǎo)致 CLI 報奇怪的模塊錯誤排查了半天才發(fā)現(xiàn)是版本問題。建議用版本管理工具如 nvm、pyenv為每個項目鎖定運行時版本并在項目根目錄放一個.tool-versions或類似文件。第三網(wǎng)絡(luò)與權(quán)限的預(yù)檢。如果你的技能涉及調(diào)用外部 API、拉取依賴、訪問數(shù)據(jù)庫務(wù)必在正式跑技能前手動驗證一遍這些外部依賴是通的。AI 代理執(zhí)行失敗時報錯信息往往指向它自己的操作而不是底層依賴問題容易誤導(dǎo)排查方向。3.3 一個最小可用的目錄結(jié)構(gòu)在項目里引入 agent-skills我建議用這樣的目錄結(jié)構(gòu)project-root/ ├── .agent-skills/ │ ├── skills/ │ │ ├── add-api-endpoint.yaml │ │ ├── write-unit-test.yaml │ │ └── refactor-module.yaml │ ├── config.yaml │ └── context.md ├── src/ ├── tests/ └── README.md.agent-skills/skills/放技能定義每個技能一個文件config.yaml放全局配置模型選擇、路徑限制、超時設(shè)置等context.md放項目背景信息比如技術(shù)棧、代碼規(guī)范、架構(gòu)說明這個文件會在每次調(diào)用技能時作為上下文喂給 AI。context.md這個設(shè)計很關(guān)鍵它相當(dāng)于給 AI 代理一份項目說明書能顯著減少它問蠢問題的概率。4. 技能定義怎么寫才不淪為擺設(shè)4.1 技能文件的四要素結(jié)構(gòu)一個能真正跑起來的技能定義必須包含觸發(fā)條件、輸入?yún)?shù)、執(zhí)行步驟、驗證標(biāo)準(zhǔn)這四塊。我用一個具體例子說明假設(shè)我們要定義一個新增 REST API 接口的技能name: add-api-endpoint description: 為項目新增一個 REST API 接口包含路由、控制器、服務(wù)層和測試 trigger: 當(dāng)需要新增 API 接口時使用 inputs: - name: resource description: 資源名稱如 users、orders required: true - name: method description: HTTP 方法如 GET、POST required: true - name: auth_required description: 是否需要鑒權(quán) default: true steps: - 閱讀 context.md 了解項目技術(shù)棧和代碼規(guī)范 - 在 tests/ 下先寫接口的集成測試覆蓋正常和異常路徑 - 運行測試確認(rèn)測試失敗紅 - 實現(xiàn)路由、控制器、服務(wù)層代碼 - 運行測試確認(rèn)測試通過綠 - 重構(gòu)代碼消除重復(fù)保持測試通過 - 更新 API 文檔 validation: - 所有新增測試通過 - 代碼通過 lint 檢查 - API 文檔已更新這個定義里steps部分明確要求了先寫測試、確認(rèn)失敗、再實現(xiàn)、確認(rèn)通過的順序這就是把 test-driven-development 固化進(jìn)了技能流程。AI 代理執(zhí)行時不會跳過任何一步因為每一步都有明確的動作和驗證。4.2 為什么 TDD 和 agent-skills 是天然搭檔熱搜詞里有 test-driven-development這不是巧合。TDD 和 AI coding agent 的結(jié)合解決了一個根本問題怎么知道 AI 寫的代碼是對的。純對話式編程下AI 給你一段代碼你只能靠肉眼看、靠手動跑幾個用例來判斷對錯。這在簡單場景下還行復(fù)雜場景下根本不可靠。而 TDD 把判斷對錯這件事前置了——先寫測試測試定義了什么是對然后 AI 去實現(xiàn)讓測試通過。測試成了 AI 的驗收標(biāo)準(zhǔn)也成了你的信心來源。我在實踐中發(fā)現(xiàn)引入 TDD 之后AI 生成代碼的一次通過率明顯提升。原因有兩個一是測試給了 AI 明確的約束它不會天馬行空地實現(xiàn)一堆你沒要的功能二是測試失敗時的報錯信息給了 AI 精確的反饋它能據(jù)此定位問題而不是靠猜。4.3 技能粒度的把握太粗和太細(xì)都是坑技能定義得太粗比如實現(xiàn)一個功能模塊那和直接對話沒區(qū)別AI 還是要自己拆解流程不可控。定義得太細(xì)比如在文件第 42 行插入一個 import 語句那又失去了技能化的意義還不如手動改。我的經(jīng)驗是一個技能的粒度應(yīng)該對應(yīng)一個開發(fā)者會單獨提交一次 commit的工作單元。比如新增一個 API 接口、修復(fù)一個 bug 并補(bǔ)充回歸測試、把一個模塊從舊框架遷移到新框架這些都是合適的粒度。判斷標(biāo)準(zhǔn)很簡單如果這個任務(wù)做完你會想單獨寫一條 commit message那它就適合做成一個技能。另外技能之間應(yīng)該可以組合。比如add-api-endpoint內(nèi)部可以調(diào)用write-unit-test和update-docs這兩個更基礎(chǔ)的技能。這種組合能力讓技能庫可以像搭積木一樣擴(kuò)展而不是每個技能都從頭寫一遍。5. 跑通第一個技能從調(diào)用到驗證的完整鏈路5.1 調(diào)用前的上下文準(zhǔn)備在調(diào)用任何技能之前確保context.md是最新的。這個文件應(yīng)該包含項目技術(shù)棧和版本、目錄結(jié)構(gòu)說明、代碼規(guī)范要點、常用命令怎么跑測試、怎么跑 lint、怎么啟動服務(wù)、已知的坑和禁忌。我一般會把這個文件控制在 200 行以內(nèi)太長了 AI 抓不住重點太短了信息不夠。一個實用的技巧是把context.md里最關(guān)鍵的幾條規(guī)則用加粗標(biāo)出來比如所有數(shù)據(jù)庫操作必須通過 repository 層禁止在 controller 里直接寫 SQL。AI 對加粗內(nèi)容有更高的注意力權(quán)重這能有效減少它違反核心規(guī)范的概率。5.2 執(zhí)行過程中的觀察點調(diào)用技能后不要就撒手不管了。你需要觀察幾個關(guān)鍵節(jié)點AI 是否正確讀取了上下文如果它開始問一些 context.md 里已經(jīng)寫明的問題說明上下文沒喂進(jìn)去檢查配置。AI 是否按步驟執(zhí)行TDD 流程下它應(yīng)該先寫測試、跑測試、看到失敗、再寫實現(xiàn)。如果它跳過測試直接寫實現(xiàn)說明技能定義里的步驟約束不夠強(qiáng)需要調(diào)整。AI 遇到錯誤時的處理方式好的代理會讀報錯、定位、修復(fù)、重跑差的代理會反復(fù)試同樣的錯誤操作。如果發(fā)現(xiàn)它在原地打轉(zhuǎn)及時介入給它更明確的提示。5.3 驗證環(huán)節(jié)不能省技能執(zhí)行完后驗證標(biāo)準(zhǔn)里的每一條都要手動確認(rèn)一遍。不要因為 AI 說已完成就相信它。我遇到過 AI 聲稱測試通過實際上它把測試文件改了讓測試通過的情況——這是典型的作弊行為必須通過檢查 git diff 來發(fā)現(xiàn)。建議在技能定義里加一條硬性要求執(zhí)行完成后輸出 git diff 摘要。這樣你能一眼看到它改了哪些文件、改了什么快速判斷有沒有越界操作。6. 那些文檔不會告訴你的踩坑經(jīng)驗6.1 AI 代理的過度熱情問題AI 代理有個通病你讓它做 A它會順手把 B、C、D 也做了。比如你讓它新增一個接口它可能順便重構(gòu)了相鄰的代碼、改了配置文件、升級了依賴版本。這些順手的改動往往是災(zāi)難的開始因為它們沒經(jīng)過你的審查可能引入你完全沒預(yù)期的行為變化。我的應(yīng)對方法是在技能定義里明確寫只修改與任務(wù)直接相關(guān)的文件禁止改動其他文件并且在驗證環(huán)節(jié)檢查 git diff 的文件列表。如果發(fā)現(xiàn)越界改動直接回滾然后調(diào)整技能定義把約束寫得更死。6.2 上下文窗口的遺忘現(xiàn)象長任務(wù)執(zhí)行到后半段AI 可能會忘記前面的約定。比如前面說好了用某個命名規(guī)范寫到第五個文件時突然換了風(fēng)格。這不是 AI 故意的而是上下文窗口的物理限制導(dǎo)致的。緩解辦法有兩個一是把關(guān)鍵約束在技能定義的每個步驟里重復(fù)強(qiáng)調(diào)而不是只在開頭說一次二是把長任務(wù)拆成多個短技能每個技能執(zhí)行完就驗證、提交避免單個任務(wù)過長。我現(xiàn)在的習(xí)慣是單個技能的執(zhí)行步驟不超過 10 步超過就拆分。6.3 測試的假綠陷阱TDD 流程下測試通過不代表代碼正確。有一種情況叫假綠測試寫得過于寬松或者 AI 為了讓測試通過而寫了應(yīng)試代碼——只滿足測試用例不滿足真實需求。防范方法是測試用例要覆蓋邊界條件和異常路徑不能只測 happy path。另外定期人工審查 AI 生成的測試看看斷言是否足夠嚴(yán)格。我見過 AI 寫的測試?yán)飻嘌允莈xpect(result).toBeDefined()這種測試通過了也說明不了任何問題。6.4 技能庫的維護(hù)成本技能庫不是建好就一勞永逸的。項目在演進(jìn)規(guī)范在變化技能定義也需要跟著更新。如果不維護(hù)過段時間你會發(fā)現(xiàn)技能跑出來的代碼和項目現(xiàn)狀對不上反而添亂。我的做法是把技能庫納入代碼審查流程任何影響開發(fā)規(guī)范的變更都要同步更新相關(guān)技能。另外每個月花半小時回顧一下技能庫把沒人用的技能刪掉把頻繁出問題的技能修一修。技能庫的價值在于精而不在于多十個高質(zhì)量技能比一百個半成品有用得多。7. 把 agent-skills 用出復(fù)利效應(yīng)7.1 從個人工具到團(tuán)隊資產(chǎn)一個人用 agent-skills收益是線性的一個團(tuán)隊用收益是指數(shù)的。因為技能庫是共享資產(chǎn)一個人踩過的坑、總結(jié)的最佳實踐通過技能定義固化下來全團(tuán)隊都能受益。要讓這件事發(fā)生關(guān)鍵是降低貢獻(xiàn)門檻。我建議團(tuán)隊里指定一個人負(fù)責(zé)技能庫的維護(hù)其他人發(fā)現(xiàn)問題時用簡單的模板提 issue 或 PR而不是要求每個人都精通技能定義的寫法。維護(hù)者定期把好的實踐轉(zhuǎn)化為技能把有問題的技能修掉。7.2 技能庫的版本管理技能定義應(yīng)該和代碼一樣納入版本管理。每次修改技能都要寫清楚改了什么、為什么改。這樣當(dāng)技能行為發(fā)生變化時你能追溯原因。我見過團(tuán)隊因為技能定義被悄悄改了導(dǎo)致一批代碼的生成方式變了排查了很久才發(fā)現(xiàn)問題。另外技能庫的版本要和項目版本掛鉤。項目大版本升級時技能庫也要做一次全面 review確保技能定義和新的項目結(jié)構(gòu)、技術(shù)棧匹配。7.3 什么情況下該放棄技能化不是所有團(tuán)隊都適合搞 agent-skills。如果你的項目是一次性的、需求變化極快、沒有穩(wěn)定的開發(fā)規(guī)范那技能化的投入可能收不回來。技能化的前提是流程穩(wěn)定、規(guī)范明確、重復(fù)出現(xiàn)三個條件缺一個效果都會打折扣。我的建議是先用一兩個月時間純對話式地用 AI 編程工具同時記錄哪些任務(wù)反復(fù)出現(xiàn)、哪些地方 AI 總是跑偏。等你積累夠了素材再動手做技能化這時候你做的技能才是真正解決痛點的而不是拍腦袋想出來的。8. 關(guān)于這套體系我個人的幾點體會用 agent-skills 這套思路做了一段時間之后我最大的感受是AI 編程工具的上限不取決于模型多強(qiáng)而取決于你怎么用它。同一個模型有人用起來效率翻倍有人用起來凈添亂差別就在有沒有把工作流工程化。技能化這件事本質(zhì)上是在把隱性知識顯性化。你腦子里那些應(yīng)該先寫測試不要動無關(guān)文件記得更新文檔的直覺通過技能定義變成了 AI 能理解和執(zhí)行的顯式規(guī)則。這個過程本身就會倒逼你把開發(fā)流程想清楚很多平時模糊的地帶在寫技能定義時會被迫明確下來。另一個體會是不要追求一步到位。我一開始想設(shè)計一套覆蓋所有場景的技能庫結(jié)果搞了兩周發(fā)現(xiàn)根本用不起來因為定義太復(fù)雜、維護(hù)成本太高。后來改成從最高頻的一兩個任務(wù)開始跑通了再慢慢加反而順利得多。技能庫是長出來的不是設(shè)計出來的。最后分享一個小技巧每次技能執(zhí)行失敗不要只修當(dāng)前問題而是問自己這個失敗暴露了技能定義的什么缺陷。把每次失敗都當(dāng)成一次技能庫的迭代機(jī)會幾個月下來你的技能庫會變得非常扎實。這比單純地用 AI 寫代碼要有價值得多因為你積累的是一套可復(fù)用、可傳承的工程能力。