用 grinding-until-pass:讓 Agent 自己修到測試全綠

前言

用 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 把流程拆成四步,邏輯很直白:

  1. 定義目標命令:用哪條命令的退出碼判斷「綠了」。例如測試用 npm testnpx vitest run,構建用 npm run build,lint 用 npm run lint,類型檢查用 npx tsc --noEmit;也可以串起來,例如:
npm run lint && npx tsc --noEmit && npm test && npm run build
  1. 運行命令:執行並保留完整輸出。

  2. 失敗則分析並最小修復:讀錯誤、定位根因(斷言失敗、類型錯誤、lint、import 等),只做最小改動,不做順手重構,然後回到第 2 步。

  3. 通過則停止並彙報:說明修了什麼、迭代了幾輪、改動摘要。

循環還有幾條硬規則,這也是它和「隨便讓 AI 修到能跑」的差別:

  • 最多 10 輪:10 次後仍失敗就停,向人彙報卡點,避免空轉燒 token。
  • 一次只修一件事:先修第一個錯誤再重跑,下游錯誤有時會連帶消失。
  • 不要刪測試:測試掛了就改實現;只有測試明顯寫錯(例如測的是已故意廢棄的舊行爲)才改測試。
  • 不要靠壓制過關:禁止用 @ts-ignoreeslint-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

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜