戰(zhàn):為 AI 編程助手注入技能包與四階段工作流)
做開發(fā)這么多年我越來越相信一件事工具本身不產(chǎn)生價(jià)值用工具的習(xí)慣才產(chǎn)生價(jià)值。superpowers 這個名字聽起來像游戲外掛實(shí)際上是一套圍繞 AI 編程助手設(shè)計(jì)的技能增強(qiáng)方案。它不是要替代 Codex 這類智能體而是給它們裝上角色意識、任務(wù)拆解能力和自檢機(jī)制讓一問一答變成說清楚需求、看著它規(guī)劃、一步步實(shí)現(xiàn)、最后自己檢查結(jié)果的完整閉環(huán)。這篇文章我把自己的實(shí)踐過程完整寫出來怎么裝、怎么配、跑 Java 重構(gòu)時(shí)踩過哪些坑以及排查思路給想折騰又不想走彎路的朋友一條可復(fù)現(xiàn)的路徑。全程沒有晦澀的理論只有我實(shí)測過的命令和配置。1. 項(xiàng)目定位與整體設(shè)計(jì)思路1.1 原生 AI 編程助手到底缺什么先說痛點(diǎn)。我過去直接用 Codex 干活遇到最簡單的需求還不錯比如給這個類加一個方法它能答得八九不離十。但一旦需求稍微復(fù)雜比如重構(gòu)這個模塊保持接口不變把 I/O 和業(yè)務(wù)邏輯拆開補(bǔ)上單元測試問題立刻出現(xiàn)。第一是沒有全局觀。默認(rèn)會話里助手只知道你貼給它的那幾段代碼和對話歷史對項(xiàng)目結(jié)構(gòu)、現(xiàn)有約定、構(gòu)建方式一概不知。于是它可能往一個明顯不該改的地方加邏輯甚至把 package 結(jié)構(gòu)搞亂。第二是沒有步驟感。復(fù)雜的改動不是一個動作能完成的它卻往往試圖一次性產(chǎn)出所有代碼。一次交互里改十幾個文件中間任何一個環(huán)節(jié)出錯后面全部白搭而且很難定位。第三是沒有自查意識。模型生成代碼后不會自動跑測試、不會對照 lint 規(guī)則檢查更不會主動說這里我改了私有方法調(diào)用方需要同步調(diào)整。導(dǎo)致的結(jié)果就是輸出完之后錯誤還是要靠人肉去查。這四個字叫上下文缺失加缺乏元認(rèn)知本質(zhì)上就一句話默認(rèn)助手是個很聰明的實(shí)習(xí)生但沒有工作方法。superpowers 想解決的問題恰恰是這個。1.2 設(shè)計(jì)理念給 AI 裝一套工作方法論我當(dāng)時(shí)看到這個方案的時(shí)候最認(rèn)同的并不是它有多少炫酷功能而是它的三個設(shè)計(jì)原則技能化、可編排、可追蹤。技能化是指所有高階能力都被拆成獨(dú)立的技能包Skill每個技能包就是一段結(jié)構(gòu)化的提示詞加執(zhí)行腳本。比如寫單元測試是一個技能做代碼審查是一個技能技能之間互相獨(dú)立按需加載。這樣既不會在無關(guān)場景下浪費(fèi) token也讓行為邊界可控??删幣攀侵?superpowers 定義了一套標(biāo)準(zhǔn)工作流狀態(tài)機(jī)——Plan、Implement、Test、Review。它不會讓 AI 自己亂發(fā)揮而是強(qiáng)制按階段推進(jìn)先讀懂需求和約束再產(chǎn)出方案確認(rèn)后動手寫代碼寫完跑測試最后自查改動范圍。每個階段有明確的產(chǎn)出物也有明確的終止條件??勺粉櫴侵杆嘘P(guān)鍵決策都落成文件或日志。方案寫到臨時(shí)文檔里改動列表記錄到會話摘要里測試結(jié)果與審查清單一并留存。出了任何問題可以回看是哪個階段、哪一步出了偏差而不是面對一團(tuán)黑盒輸出。這套設(shè)計(jì)解決的不只是代碼寫得對不對更深一層是工作方式穩(wěn)不穩(wěn)。對個人開發(fā)者來說它讓 AI 結(jié)對變成真正可依賴的流程對團(tuán)隊(duì)來說它讓 AI 生成的代碼風(fēng)格和提交記錄可控也方便人來做 review。2. 安裝與快速起步2.1 準(zhǔn)備這些前置環(huán)境我實(shí)測下來的推薦環(huán)境是這樣這也是項(xiàng)目文檔里要求的基線操作系統(tǒng)macOS 14 或 Ubuntu 22.04Windows 建議用 WSL2否則后面有些腳本會有路徑問題Node.js18 以上最好用 20 LTS。它底層很多工具鏈要跑 esbuildNode 16 會有兼容坑包管理器npm 或者 pnpm 都行Git2.30 以上一個已經(jīng)能用的 AI 編程助手 CLI我這邊用 Codex CLI原理上只要是支持讀取本地文件的命令行助手都適用先更新一下 Node。比如在 mac 上brew install node20 node -v在 Ubuntu 上curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs這里有一個容易踩的坑如果你之前裝過舊版 Node環(huán)境變量可能還是指向舊的二進(jìn)制。裝完務(wù)必新開一個終端執(zhí)行which node確認(rèn)路徑確實(shí)切過來了不然后面npm install成功后一運(yùn)行就報(bào)語法錯誤。2.2 三步完成安裝第一步拉代碼。superpowers 本身是一個用 Node 寫的命令行工具安裝方式不復(fù)雜git clone 你的倉庫地址或者官方倉庫地址 cd superpowers npm install第二步裝全局命令npm link superpowers --version如果能看到版本號說明安裝成功。第三步進(jìn)入項(xiàng)目目錄做初始化cd /path/to/your-proj superpowers init這個 init 命令會做幾件事在當(dāng)前項(xiàng)目里建一個.superpowers/目錄、一個AGENTS.md約定文件、一個skills/空目錄并向你詢問項(xiàng)目的構(gòu)建命令和測試命令。它生成的內(nèi)容大概長這樣superpowers init ? 項(xiàng)目類型: java-maven ? 構(gòu)建命令: mvn -q package -DskipTests ? 測試命令: mvn -q test ? 代碼規(guī)范文件: checkstyle.xml我不建議一路回車跳過這一步因?yàn)楹竺嫠泄ぷ髁鞫家蕾囘@些元數(shù)據(jù)。我自己的習(xí)慣是先手動把構(gòu)建和測試命令敲準(zhǔn)尤其是跳過測試的構(gòu)建和完整測試要分開寫因?yàn)?Plan 階段和 Test 階段用的命令并不一樣。2.3 首次連通性驗(yàn)證裝完之后先別急著做真實(shí)任務(wù)跑一個冒煙測試確認(rèn)助手能被正確喚起superpowers run 給 AGENTS.md 里的構(gòu)建命令加一行注釋這個指令會觸發(fā)一次最小工作流讀取項(xiàng)目元數(shù)據(jù)、加載技能、調(diào)用后端模型、執(zhí)行修改。如果順利你會看到類似下面的輸出[plan] 解析需求 [plan] 讀取 AGENTS.md [plan] 定位文件 [implement] 修改 src/AGENTS.md [test] 無測試需要執(zhí)行 [review] 變更內(nèi)容確認(rèn)這里我特別提醒一句第一次跑的時(shí)候如果輸出卡在連接模型那一步絕大多數(shù)情況是 API Key 沒有設(shè)置。superpowers 本身不負(fù)責(zé)管理密鑰它讀取的是你原 AI 助手 CLI 的環(huán)境變量一般是OPENAI_API_KEY或ANTHROPIC_API_KEY。檢查方式echo $OPENAI_API_KEY如果沒有直接到 shell 配置里導(dǎo)出這個跟日常使用 AI 助手是一樣的。3. 核心功能拆解技能包、項(xiàng)目記憶與四階段工作流3.1 技能包Skills讓助手學(xué)會分步做事技能包是 superpowers 最核心的擴(kuò)展單位。init之后你的項(xiàng)目里會生成這樣一個目錄.superpowers/ skills/ unit-test/ # 每個技能一個文件夾 SKILL.md # 技能描述與默認(rèn)提示詞 templates/ # 可選模板 scripts/ # 可選腳本 code-review/ SKILL.mdSKILL.md的格式我見過兩種一種是 YAML 頭加正文一種是純 Markdown 約定。核心字段都差不多name是技能名description是一兩句話說清楚這個技能是干嘛的以及什么樣的需求會觸發(fā)它keywords是觸發(fā)詞列表比如單測、unit test、coverageprompt是真正注入給模型的提示詞正文。用一個我一直在用的寫單測技能舉例它的 description 是這么寫的當(dāng)用戶要求為某個類或方法補(bǔ)充單元測試時(shí)自動加載。 適用新增測試、修復(fù)失敗測試、提高覆蓋率。 不適用生產(chǎn)代碼開發(fā)、性能優(yōu)化。這個描述至關(guān)重要。因?yàn)?superpowers 是拿這個描述去跟用戶需求做匹配的寫得太泛它會在不恰當(dāng)?shù)臅r(shí)機(jī)被觸發(fā)寫得太窄又永遠(yuǎn)匹配不上。我的經(jīng)驗(yàn)是在 description 里同時(shí)寫清什么情況適用和什么情況不適用匹配準(zhǔn)確率會明顯提高。技能里還可以帶腳本。比如我寫過一個生成 JUnit 5 測試骨架的技能里面放了一個 Node 腳本用來掃描指定類的方法簽名自動生成測試方法的空殼。這樣模型就不需要靠記憶去猜方法列表直接讀腳本輸出即可。這個設(shè)計(jì)很妙——它把模型不擅長的精確枚舉交給代碼把理解意圖和寫合理斷言留給模型各司其職。3.2 項(xiàng)目上下文注入寫好 AGENTS.md助手不再問廢話在沒有 superpowers 的時(shí)候我每次打開新會話都要手動貼一段項(xiàng)目說明這是 Maven 項(xiàng)目JDK 17測試用 JUnit 5類路徑在 src/main/java…… 煩不勝煩而且經(jīng)常貼不全。superpowers 解決這個問題的方式非常優(yōu)雅它會在每次會話初始化時(shí)自動讀取項(xiàng)目根目錄的AGENTS.md把它注入到系統(tǒng)提示里。這個文件就是這個項(xiàng)目的使用說明書建議包含四塊內(nèi)容項(xiàng)目結(jié)構(gòu)核心目錄和模塊職責(zé)最好是樹狀圖構(gòu)建與測試命令精確到可直接執(zhí)行代碼約定包命名、異常處理風(fēng)格、是否允許 Lombok、日志規(guī)范約束與紅線哪些文件不能改、哪些目錄是生成代碼、外部依賴來源限制我自己的AGENTS.md開頭是這樣的# 項(xiàng)目約定 這是一個 Java 17 Maven 工程業(yè)務(wù)代碼在 src/main/java。 包名以 com.example 開頭禁止使用 Lombok。 構(gòu)建命令mvn -q package -DskipTests 測試命令mvn -q test 生成的文件放 target/ 目錄不要手工修改 target/ 下的任何內(nèi)容。寫完AGENTS.md之后最直觀的感受是助手不再問你們項(xiàng)目的測試命令是什么這種問題了也不再往 target/ 里改代碼了。它腦子里始終有這個文件的存在等于給模型接入了項(xiàng)目級記憶。提示AGENTS.md不是越長越好。模型上下文長度有限我建議把內(nèi)容控制在 60 行以內(nèi)把信息壓成短句。排序上把最重要的紅線放最前面因?yàn)樯舷挛氖乔爸米⑷氲脑娇壳霸讲蝗菀妆缓罄m(xù)對話沖淡。3.3 自動化工作流計(jì)劃、編碼、測試、評審superpowers 的默認(rèn)工作流是四階段Plan → Implement → Test → Review。我實(shí)際跑下來的感受是它帶來的最大價(jià)值不是自動干活而是強(qiáng)制節(jié)奏。Plan助手會先解析需求結(jié)合AGENTS.md寫一個簡短方案里面包含涉及文件、改動思路、風(fēng)險(xiǎn)點(diǎn)。這個方案默認(rèn)會打印出來等用戶確認(rèn)后才會進(jìn)入下一階段。如果不加干預(yù)它有時(shí)候會直接往下走所以我習(xí)慣在命令后面加--pause-after plan這類的參數(shù)強(qiáng)制它在方案階段停一下。Plan 階段的輸出大概長這樣[plan] 需求解析完成 影響文件OrderService.java修改、PricingService.java新增 改動思路 1. 將價(jià)格計(jì)算私有方法遷移至 PricingService 2. OrderService 通過構(gòu)造函數(shù)注入 PricingService 3. 保持對外方法簽名不變 風(fēng)險(xiǎn)點(diǎn)MQ 事件發(fā)送邏輯必須保留在 OrderService 確認(rèn)方案后進(jìn)入實(shí)施階段 (y/N)Implement方案確認(rèn)后助手開始按文件列表逐個修改。這里的細(xì)節(jié)是它要求一次只改動一個邏輯單元并隨時(shí)輸出進(jìn)度摘要。用完幾次之后我明顯發(fā)現(xiàn)它的中途錯誤變少了因?yàn)槊坎蕉荚谛r?yàn)上下文。Test代碼寫完只是第一步Test 階段會直接執(zhí)行你在 init 時(shí)填寫的測試命令。如果失敗它會讀取失敗日志決定是修復(fù)代碼還是補(bǔ)充測試然后重跑最多重試三次。Review全部通過后進(jìn)入復(fù)審。它會比對自己改了什么、哪些行為發(fā)生了變化輸出一份變更清單。我在 Review 階段最常用到的就是讓助手生成diff 摘要方便直接貼到 commit message 里。這套流程讓我最受益的一點(diǎn)是當(dāng)任務(wù)失敗時(shí)我知道該去看哪個階段。如果 Plan 階段方案就錯了重心是拉齊需求如果 Test 階段才失敗問題多半出在實(shí)現(xiàn)細(xì)節(jié)定位成本大幅下降。4. Java 重構(gòu)實(shí)測12 分鐘拆掉一個 1200 行的上帝類4.1 任務(wù)準(zhǔn)備一個 1200 行的上帝類光講概念不夠我記錄一次完整的實(shí)測。我之前遇到一個老舊的 Java 服務(wù)OrderService一個類里塞了 1200 行既連數(shù)據(jù)庫、又發(fā) MQ、還算價(jià)格三個職責(zé)攪在一起。需求是把價(jià)格計(jì)算邏輯拆到獨(dú)立的PricingService保證對外行為不變并且給新舊邏輯各補(bǔ)兩個單測。準(zhǔn)備工作很關(guān)鍵。傳統(tǒng)做法是我自己寫任務(wù)拆分文檔再一段段喂給助手。用 superpowers 之后我先在項(xiàng)目根目錄寫好AGENTS.md然后在命令里精確描述需求superpowers run 重構(gòu) OrderService將價(jià)格計(jì)算邏輯提取到 PricingService 保持對外方法簽名不變補(bǔ)充 JUnit 5 單元測試原有行為不得改變這里我特意寫清楚了三個約束位置提取到新類、接口簽名不變、質(zhì)量要求補(bǔ)測試。越明確Plan 階段的方案就越貼近現(xiàn)實(shí)。4.2 執(zhí)行過程中值得記錄的三個細(xì)節(jié)第一次執(zhí)行Plan 階段給了很漂亮的方案列出PricingService建議的接口、需要從OrderService遷移的私有方法清單、以及測試的斷言思路。但進(jìn)入 Implement 階段后問題來了——它把OrderService里一個原本 package-private 的靜態(tài)方法直接復(fù)制過去卻忘了在PricingService里顯式聲明它原本所在的包。編譯直接失敗。這里有個很有意思的細(xì)節(jié)Test 階段立刻抓住了錯誤。mvn test在編譯期就報(bào)了找不到符號助手讀取失敗日志之后自己做了修正把新類的包路徑補(bǔ)齊重跑通過。換作以前我手工拿助手一次一次改可能來回三輪才發(fā)現(xiàn)是包名問題這套流程一次就抓住了。第二個細(xì)節(jié)是測試設(shè)計(jì)。助手生成的第一個測試?yán)镉袀€斷言寫得太寬松只校驗(yàn)了返回值大于 0這在重構(gòu)場景下意義不大。我在 Review 階段看到變更清單后追加了一條指令測試屬于回歸保護(hù)斷言要能區(qū)分重構(gòu)前后的錯誤行為。 它隨即把斷言改成精確的比較并補(bǔ)了邊界用例。所以Review 階段不要直接點(diǎn)通過要帶著質(zhì)疑去看。第三個細(xì)節(jié)關(guān)于副作用。OrderService里原來算完價(jià)格之后會直接發(fā)送一個價(jià)格變更的 MQ 事件重構(gòu)后這個事件仍然由OrderService自己發(fā)PricingService只負(fù)責(zé)純計(jì)算。這個邊界在 Plan 階段其實(shí)寫過但助手 Implement 時(shí)一度把 MQ 發(fā)送也搬去了新類。我是在審查計(jì)劃時(shí)發(fā)現(xiàn)的反饋后它立刻撤回。這里的重要教訓(xùn)是涉及副作用的邊界必須在 Plan 階段反復(fù)確認(rèn)不能只在提示詞里帶一句。4.3 復(fù)盤結(jié)果、耗時(shí)與方法論沉淀重構(gòu)完成之后我跑了全量測試45 個用例全部通過mvn package無告警。改動文件只有 4 個新增PricingService.java和它的測試修改OrderService.java和它的測試。整體耗時(shí)約 12 分鐘其中大部分時(shí)間花在 Test 階段的三次重跑上。對比我過去手動操作的流程最大的省心點(diǎn)在于以前讓助手干這種活我得在旁邊盯著每生成一段代碼就自己編譯一次出問題再針對性提問整體至少半小時(shí)起步?,F(xiàn)在相當(dāng)于把編譯-報(bào)錯-修復(fù)的閉環(huán)交給了工作流本身我只在開頭定義任務(wù)、在中間檢查方案、在最后審查 diff。時(shí)間上的對比如下維度過去手動喂代碼superpowers 流程我的介入全程盯、反復(fù)編譯三次介入確認(rèn)方案、補(bǔ)斷言、審 diff耗時(shí)約 30-45 分鐘約 12 分鐘中間錯誤容易遺漏、人肉發(fā)現(xiàn)Test 階段自動抓結(jié)果記錄散落在聊天記錄里方案、變更清單自動落盤對于經(jīng)常做重構(gòu)的人來說這種可追溯性其實(shí)比速度更重要。因?yàn)橹貥?gòu)的核心風(fēng)險(xiǎn)不是改得慢而是改完之后不知道動了哪些地方、影響哪些調(diào)用方。superpowers 在 Review 階段輸出的變更清單恰好就是重構(gòu)評審里最需要的那份材料。5. 踩坑實(shí)錄安裝、運(yùn)行與上下文問題的排查方法5.1 安裝與依賴問題速查我總結(jié)了這張表基本覆蓋了我在 Mac 和 Linux 上遇到過的安裝問題現(xiàn)象原因解決辦法npm install 報(bào)esbuild二進(jìn)制下載失敗本地網(wǎng)絡(luò)或 Node 版本過低升級到 Node 20 LTS刪除 node_modules 重裝運(yùn)行superpowers提示命令不存在npm 全局路徑不在 PATH 里執(zhí)行npm config get prefix并把對應(yīng) bin 目錄追加到 PATHEACCES: permission denied權(quán)限不足不要用 sudo 硬裝改用 nvm 管理 Node 版本init 時(shí)找不到 Java 項(xiàng)目類型目錄里缺少pom.xml或build.gradle先確認(rèn)項(xiàng)目文件結(jié)構(gòu)完整再執(zhí)行 initWindows 下腳本路徑報(bào)錯原生 shell 與 POSIX 腳本不兼容換 WSL2在 Ubuntu 環(huán)境里跑第二個問題我特別說一下。Node 用官方安裝包裝的時(shí)候npm link出來的全局命令默認(rèn)在/usr/local/bin這通常沒問題。但如果你的 shell 配置里自定義了PATH而且把某個目錄放到前面就可能出現(xiàn)命令找不到。排查命令是which node which npm which superpowers三個命令的結(jié)果必須在同一套安裝目錄下只要發(fā)現(xiàn)某個指向了別的路徑就沿著那個路徑去清理。5.2 運(yùn)行期異常模板不觸發(fā)、助手犯迷糊怎么辦比起安裝問題運(yùn)行期的問題更隱蔽也更耗時(shí)間。我把最常見三類整理一下。模板匹配失靈。我遇到過技能包一直不觸發(fā)排查半天才發(fā)現(xiàn)是 description 里用了中文單測但項(xiàng)目里大家口頭都叫unit test用戶自然語言里根本不會出現(xiàn)單測。關(guān)鍵詞覆蓋面要寬且要看你項(xiàng)目里實(shí)際怎么說不要只寫自己習(xí)慣的說法。上下文越長越健忘。大項(xiàng)目里會話進(jìn)行到 Implement 中段時(shí)助手開始忘記AGENTS.md里最開始的約束。這不是 superpowers 的 bug是上下文窗口的物理規(guī)律。緩解辦法有兩個一是把最重要的紅線寫在AGENTS.md最前面二是把任務(wù)拆小一次superpowers run只干一件事不把十個修改點(diǎn)塞進(jìn)一個任務(wù)里。計(jì)劃階段被跳過。我前面提過一旦任務(wù)描述里出現(xiàn)直接改某些模型會跳過 Plan 直接實(shí)現(xiàn)。我的做法是命令里顯式要求分階段例如加上先輸出修改方案等待確認(rèn)后再實(shí)施?;蛘咧苯佑?-pause-after plan等參數(shù)把節(jié)奏鎖死。5.3 上下文溢出與大任務(wù)拆解技巧最后聊一個所有 AI 輔助編程工具都會碰到的天花板上下文窗口。superpowers 對上下文的消耗其實(shí)比裸聊天更省因?yàn)樗葱杓虞d技能但有幾種場景還是會快速撐爆超大文件單個文件超過 800 行、大范圍重構(gòu)一次改幾十個文件、日志測試輸出過多。我的實(shí)操經(jīng)驗(yàn)是三個動作。第一改需求描述而不是改代碼。把重構(gòu) OrderService 并優(yōu)化所有相關(guān)調(diào)用方改成先只在 OrderService 內(nèi)部做提取調(diào)用方不動把一個大任務(wù)拆成幾個有先后依賴的小任務(wù)。這是成本最低、見效最快的辦法。第二在技能里啟用摘要。比如 Test 階段讓助手只讀取測試日志里的 ERROR 級別內(nèi)容而不是整段 stdout。很多集成工具里有專門的日志過濾配置花 5 分鐘配好能省下大量 token。第三隔離超大文件。如果某個類 1200 行別讓助手一口氣全讀進(jìn)去先用 grep 或腳本把關(guān)鍵方法簽名提取出來做成中間摘要文件再讓助手基于摘要操作。這個思路跟人類看代碼一樣先了解接口再決定要不要看實(shí)現(xiàn)。另外如果你是在某些圖形化的應(yīng)用里調(diào)用這套工作流原理也是一樣的本質(zhì)上就是項(xiàng)目上下文文件 技能目錄 按階段執(zhí)行的命令。只要宿主應(yīng)用允許你指定項(xiàng)目根目錄和讀取本地文件就能把 superpowers 的工作方式平移到任何環(huán)境里并不局限于命令行。最后再分享一個小技巧。我每次跑完一個任務(wù)都會去改一下對應(yīng)技能的 description把這次遇到的邊界情況補(bǔ)進(jìn)去。比如跑完那次 Java 重構(gòu)后我在單測技能的 description 里加了一句注意斷言必須能區(qū)分行為差異不要只判斷返回值為正。這樣下次再觸發(fā)時(shí)模型默認(rèn)就會沿用這條經(jīng)驗(yàn)。superpowers 用久了之后這套技能文件會越來越像你自己的編碼手冊——這才是它真正值錢的地方。