前言¶
用 AI 寫代碼時,常見的一幕是:Agent 改完一版,跑一下測試,掛了幾條;你讓它再修,又掛;來回幾輪,對話還沒結束,上下文已經很長,人也累了。很多時候失敗原因並不複雜——斷言對不上、類型報錯、lint 違規——真正耗時間的是「修 → 跑 → 看輸出 → 再修」這個循環本身。
grinding-until-pass 就是把這個循環寫成可複用的 Agent Skill:指定一條以退出碼判定成敗的命令,讓 Agent 在本地自主循環,直到測試通過、構建成功或 lint 乾淨,而不是改一次就停下來等你催下一輪。
這是什麼¶
grinding-until-pass(文檔裏也寫作 Grind Until Pass)來自 Spencer Pauly 維護的開源合集 awesome-cursor-skills,目錄爲 resources/grinding-until-pass/,核心是一份標準的 SKILL.md。它不替代測試框架,也不發明新的 CI,而是約束 Agent 的工作方式:在明確的成功條件(命令退出碼爲 0)下,持續執行「修復 → 運行 → 檢查 → 重複」,直到目標達成或觸達安全上限。
這類 Skill 基於通用 SKILL.md 格式,在 Cursor、Codex CLI、Claude Code 等支持 Agent Skills 的工具裏都可以安裝使用;各工具的目錄名可能不同,但文件形態一致。
核心流程與約束¶
官方 SKILL.md 把流程拆成四步,邏輯很直白:
- 定義目標命令:用哪條命令的退出碼判斷「綠了」。例如測試用
npm test或npx vitest run,構建用npm run build,lint 用npm run lint,類型檢查用npx tsc --noEmit;也可以串起來,例如:
npm run lint && npx tsc --noEmit && npm test && npm run build
-
運行命令:執行並保留完整輸出。
-
失敗則分析並最小修復:讀錯誤、定位根因(斷言失敗、類型錯誤、lint、import 等),只做最小改動,不做順手重構,然後回到第 2 步。
-
通過則停止並彙報:說明修了什麼、迭代了幾輪、改動摘要。
循環還有幾條硬規則,這也是它和「隨便讓 AI 修到能跑」的差別:
- 最多 10 輪:10 次後仍失敗就停,向人彙報卡點,避免空轉燒 token。
- 一次只修一件事:先修第一個錯誤再重跑,下游錯誤有時會連帶消失。
- 不要刪測試:測試掛了就改實現;只有測試明顯寫錯(例如測的是已故意廢棄的舊行爲)才改測試。
- 不要靠壓制過關:禁止用
@ts-ignore、eslint-disable、隨意any等方式把錯誤悶掉。 - 盯住錯誤數量:若錯誤越改越多,停下來重新評估思路。
安裝與啓用¶
倉庫說明:在 Cursor 裏,Skill 一般放在項目的 .cursor/skills/(或個人全局目錄)下,由 Agent 自動發現。官方合集也推薦用社區 CLI npx skills 安裝。
方式一:CLI 安裝(推薦)
安裝單個 Skill:
npx skills add spencerpauly/awesome-cursor-skills --skill grinding-until-pass
若在 Claude Code 中使用,可指定 agent,安裝到當前項目的 .claude/skills/:
npx skills add spencerpauly/awesome-cursor-skills --skill grinding-until-pass --agent claude-code
方式二:手動拷貝
從倉庫取出 resources/grinding-until-pass/SKILL.md,放到本機對應目錄,例如:
# Cursor 項目級
.cursor/skills/grinding-until-pass/SKILL.md
# 或個人全局(Cursor)
~/.cursor/skills/grinding-until-pass/SKILL.md
Cursor 還會兼容讀取 .agents/skills/、.claude/skills/、.codex/skills/ 以及對應的用戶主目錄路徑;Codex / Claude Code 則按各自約定使用 .codex/skills/、.claude/skills/。以你當前工具文檔爲準即可。
啓用後,在對話裏用 /grinding-until-pass,或用 @ 附上該 Skill,再說明目標命令;也可以直接描述「按 grinding-until-pass,把 npm test 磨到全綠」。
典型用法¶
大重構後測試一片紅、依賴升級帶出類型錯誤、合完分支要清衝突相關失敗時,都可以把目標說清楚,讓 Agent 按 Skill 循環。例如:
按 grinding-until-pass 執行。
目標命令:npm test
要求:一次只修一個失敗;不要刪測試;不要用 @ts-ignore / eslint-disable 壓制。
最多 10 輪;通過後彙報改了什麼、迭代次數。
若希望類型、lint、測試、構建一起過:
目標命令:npm run lint && npx tsc --noEmit && npm test && npm run build
用 grinding-until-pass 磨到全部通過。
官方還給出進階做法:用 Cursor Hooks,在 Agent 本輪結束後自動再跑測試;若仍失敗,通過 hook 腳本返回 followup_message 繼續催下一輪。示例配置寫在項目的 .cursor/hooks.json:
{
"hooks": [
{
"event": "stop",
"command": "bash .cursor/scripts/check-tests.sh",
"description": "Re-run tests after agent stops and send follow-up if failing"
}
]
}
其中 check-tests.sh 需自行實現:檢查測試退出碼,失敗時返回 follow-up 消息。這樣可以把「磨到綠」從對話裏的一次請求,延伸成回合結束後的自動接力。
適用場景與注意點¶
適合的場景與官方說明一致:大重構後多測失敗、依賴升級引入類型錯誤、合併衝突後要清編譯/測試、以及你信任測試套件、只想「先變綠」時把機械循環交給 Agent。
使用前注意幾點:
- 測試要快:官方寫明,套件動輒 5 分鐘以上時,整段循環會很慢;優先用單元測試或帶
--bail/--fail-fast的命令,儘早停在第一個失敗上。 - 綠不等於設計對:Skill 強調 Agent 會比較「死磕」但不擅長大改架構;需要產品或設計層面的調整時,仍要人來定方向。
- 成功標準要可機器判定:目標必須是退出碼明確的一條(或一組)命令;沒有穩定測試/構建命令時,這個 Skill 施展不開。
- 10 輪是保險絲:反覆修不好往往說明根因不在局部補丁,該停下來看環境、數據或需求本身。
小結¶
grinding-until-pass 把「修到綠」從口頭催促,落成可安裝、可複用的 Agent 工作流:目標命令清晰、最小修復、禁止刪測和壓制錯誤,並帶 10 輪上限。對日常「測試紅了、類型炸了、lint 不過」這類機械債,它能明顯減少人肉來回;對需要換設計的問題,它會誠實地停在卡點上把球交回給你。
官方地址:https://github.com/spencerpauly/awesome-cursor-skills/tree/main/resources/grinding-until-pass