給趕時間的人
- 兩週前我跟 AI 一起寫一個社區管理 SaaS,跑 21 輪除錯都收不完。每輪都找到新 bug,修了還有新的。
- 診斷:不是 AI 不認真,是「靠 AI 在 40 個 API 都記得做對 5 件事」這個工作模式注定漏。40 × 5 = 200 個漏分點。
- 解法:4 招 + 6 條規矩(本文後半段是 6 條規矩的可貼可用 template)。
- 16 天後 AI 自己會寫嚴格 TDD,commit message 自動標
(green via test in <sha>)。新專案直接套同樣 6 條規矩。 - 最重要的觀察:AI 寫方法論時看不見自己盲區。每次升級都靠使用者一句質疑觸發,不是 AI 自己 reflect 出來。
本文兩部分:(1) 前半段是故事——我做了什麼,為什麼。(2) 後半段是規矩——你可以直接複製到自己專案的 6 個 template。最後是觀察 + 總結。
Part 1 — 故事:21 輪修不完的具體模樣
兩週前我開始一個個人專案——社區包裹/訪客管理 SaaS。後端 Go,前端 Flutter。我用 Claude 寫程式,然後派另一個 Claude 當 QA 測試員找 bug。
第一輪測試員找到 5 個 bug,工程師 Claude 修掉。再派一個新 QA。又找到 5 個。修掉。再派。又是 5 個。跑了 21 輪。每輪都有新 bug。幾天時間沒收尾。
診斷:200 個漏分點
不是 AI 不認真。後端有 40 個 API,每個都要做同樣 5 件事:
- 檢查使用者有權限
- 檢查使用者能看的範圍(自己家 vs 整個社區)
- 寫稽核紀錄
- 過濾掉已停用的資料
- 包在交易裡保證一致性
每個 API 都是 AI 手寫這 5 件事。40 × 5 = 200 個漏分點。AI 偶爾漏一件 = 一個 bug。不同 API 漏不同件 = 看起來像 40 個不同 bug,實際是同一類錯誤。LLM 擅長照範例寫單一段,但要求它在 40 個地方都「記得做對 5 件事」就是靠機率。
4 招解法(高層次概覽)
- 把 5 件事打包成一個函式。每個 API 開頭必須呼叫它+明確宣告自己屬於哪種範圍。沒呼叫 = 編譯不過。「人記得」變「系統強制」。
- 寫紅線清單(invariants)。每修一個 bug 學一條教訓,寫進編號 INV-XXX-NNN。新功能寫好之後 QA 對著清單跑紅藍對抗,違反 = bug。規矩 3 提供模板。
- QA 測試員只能講人話。不准標 P0/P1。只能回 ✅/❌/⚠️ OPEN 三種。嚴重度由你做 30 秒判斷。規矩 4 提供 prompt。
- 測試要真的紅過。test 先寫先 commit (red),fix 後寫後 commit (green via test in <red-sha>)。commit log 自帶證據,不靠良心。規矩 2 寫進專案根。
16 天後 AI 自己會走這套流程。新功能 commit message 自動標 (green via test in <sha>)——我已經沒在提醒。下個專案(訪客系統)第一個 cycle 直接套同樣紀律,沒重新爬坡。
Part 2 — 規矩:6 個可貼可用 template
下面 6 條規矩是你下個專案開工直接可以複製貼上的東西。前 5 條是檔案 / prompt,第 6 條是日常對話紀律。
- 規矩 1:Day 1 開工 prompt
- 規矩 2:
CLAUDE.md專案根(AI 每次自動讀) - 規矩 3:
docs/invariants.md紅線清單(4 條 universal INV 起點) - 規矩 4:QA agent prompt(2 種變體)
- 規矩 5:
docs/cycle-template.mdPR cycle 8-stage 模板 - 規矩 6:跟 AI 的日常對話紀律(5 條)
規矩 1 — Day 1 開工 prompt
新專案第一句話給 Claude / ChatGPT / 任何 LLM 的 prompt。把 4 個角色分工 + 5 條紀律明文化:
我要跟你協作開發 [你的專案類型]。我們的合作規則:
1. 我寫規格,你寫程式。修改規格必須先跟我討論,不能自己加需求。
2. 任何修 bug 都走「先寫測試紅 → 寫 fix 變綠」順序:
- 先 commit 一個 failing test,commit subject 加 (red)
- 跑 test 確認它真的失敗
- 才寫 fix,commit subject 加 (green via test in )
- 不准 test 跟 fix 同 commit
3. 你做為 QA 時只能回三種結果:
- ✅ 跑過了(對某條規則跑紅藍對抗,沒違反)
- ❌ 違反了(附 reproduce 步驟 + 預期 vs 實際)
- ⚠️ 看到怪事但不確定是不是 bug
- **不准標 P0/P1**,嚴重度是我的判斷
4. 每修一個 bug 必須:
(a) 寫進 docs/invariants.md 一條 INV-XXX-NNN
(b) 對應寫一個 invariant test
(c) 才算修完。少做任一件 = 沒修完。
5. 我每次 ✅/❌ 你要懷疑——9 個 ✅ 不代表程式對。
涵蓋面外的東西永遠是 Schrödinger 狀態。
開工前先讀 CLAUDE.md + docs/invariants.md。
完成上述理解後回覆「協作規則已確認」,然後我們開始。
規矩 2 — CLAUDE.md 專案根
專案根目錄放這個檔。Claude Code 每次開工自動讀。把規矩 1 的內容固化成檔案,不必每次貼 prompt:
# [專案名] — AI 工作指引
## 重要原則(不可違反)
1. **規格收斂**: 修改規格 → 先討論。不可自加需求。
2. **TDD 紅綠**: 任何 fix 必須先 commit failing test (red) 才寫 fix。
3. **QA 不標 P 級**: 只回 ✅/❌/⚠️。嚴重度由人類 PM 判斷。
4. **修 bug 順序**: fix → 加 INV 進 docs/invariants.md → 寫 test → 才算修完。
5. **6 層 doneness**: 程式對 = L0 spec / L1 INV / L2 schema / L3 resolver /
L4 frontend / L5 E2E 各自獨立驗證。✅ 必須帶 evidence。
## 必讀文件(開工前)
- docs/invariants.md (紅線清單)
- docs/cycle-template.md (PR cycle 8-stage 模板)
- docs/agent-prompts/qa-verification.md
- docs/agent-prompts/qa-deep-probe.md
## 修 bug 工作流
1. 找到 bug
2. 開 docs/cycles/Cn-shortname.md(從 template)
3. Stage 5a: 寫 failing test → commit "(red)"
4. Stage 5b: 寫 fix → commit "(green via test in )"
5. Stage 5c: 補對應 INV 進 docs/invariants.md
6. Stage 6: regression(原 test 全綠)
7. Stage 7: 派 fresh agent 重走確認(可省)
8. Stage 8: merge gate(6 層 evidence 對齊)
## 紀律警告(常見偷懶 pattern)
- ❌ test 跟 fix 同 commit = test 沒驗證過,不算 TDD
- ❌ 「我覺得這顯然是 bug 直接改」= 沒走 cycle file 紀律
- ❌ QA 自己標 P0 給工程師 = 跳過 PM triage 閘
規矩 3 — invariants.md 紅線清單
專案開頭預先寫 4 條 universal INV 當起點,每修一個 bug 加一條:
# [專案名] Invariants Catalogue
> 「永遠不能違反什麼」紅線清單。每條 INV 一個編號。
> 修一個 bug 加一條。CI 跑這份的 test。
## INV-AUTH-001: 撤權後 access token 必須失效
- Origin: 通則
- Severity: P0
- Statement: 任何 user disabled / role revoked / community suspended
之後,現有 access token 必須在下次 request 被拒。
- Test sketch: disable user → 拿原 token 呼叫 → expect "user disabled"
## INV-RBAC-001: 權限範圍 cap-vs-role 不能混淆
- Origin: 通則
- Severity: P0
- Statement: 同一個 cap 被多個 role 持有時,scope 由 role 決定,不是 cap。
例: parcel.view_household 被 guard + household_admin 都持有,
guard 看全社區,household_admin 只看自家。
- Test sketch: guard.parcels 回 N 筆;household_admin.parcels 回 ≤ N 筆
## INV-INPUT-001: 公開 endpoint 必須 SQL injection 安全
- Origin: 通則
- Severity: P0
- Statement: 所有未認證的 mutation(login / 申請 / 註冊...)
都必須用 parameterized query。SQL injection payload 必須當文字儲存,不執行。
- Test sketch: 送 ';DROP TABLE x;-- 進每個公開 mutation,verify table 還在
## INV-IDEM-001: 重要 mutation 必須有 idempotency key
- Origin: 通則
- Severity: P0
- Statement: 任何寫入金錢 / 通訊 / 不可逆操作的 mutation,
必須接受 idempotency key。同 key 多次呼叫 = 一次效果。
- Test sketch: concurrent 5 個相同 key 呼叫 → DB 只 1 row,API 5 個一樣 response
怎麼擴充:每修一個 bug → 加一條 INV-CATEGORY-NNN。category 自己定(AUTH / RBAC / INPUT / IDEM / RLS / RATE / UI…)。修到 50+ 條時就有完整的紅線網。
規矩 4 — QA agent prompt(2 種變體)
當你想派一個 AI 當 QA 時,給它這段 prompt。第一個是規則導向 (對著 INV 跑紅藍):
你是 QA agent。任務:對 [專案] 的 [INV-XXX-NNN] 跑紅藍對抗。
## 規矩(不可違反)
1. 你只能回 ✅ / ❌ / ⚠️ OPEN 三種結果。
- ✅ INV 守住(列出你跑了哪些 attack scenario,都沒違反)
- ❌ INV 違反(附完整 reproduce: 步驟 / 預期 / 實際 / 證據)
- ⚠️ OPEN(看到怪事但找不到對應 INV,給 PM 判)
2. 不准標 P0/P1/P2。嚴重度是 PM 的判斷,不是你的。
3. 不准提 fix 方案。你的工作是發現,不是解決。
4. 不准動 code。
5. 如果 INV 統計 9/10 ✅,1 ❌ — 該回報 1 ❌ 不是 90% pass。
## 工作步驟
1. 讀 INV-XXX-NNN 的 statement
2. 列 3-5 個 attack scenario,試圖讓系統違反這條 INV
3. 對每個 scenario 跑 reproduce
4. 結束時報告:✅/❌ 數量 + ⚠️ OPEN 列表
## 你要讀的檔案
- docs/invariants.md(找 INV-XXX-NNN)
- docs/specs/...(找對應規格)
- 任何相關 brain entries
請確認你看完上述規則後再開始。
第二個是場景導向 (派 persona 隨便走找深層 bug):
你是 deep-probe QA agent。任務:對 [專案] 的 [target flow,如「訪客登記」]
走真實用戶 walk-through,找 INV-based QA 漏掉的東西。
## persona(扮演這個角色,他怎麼用就怎麼走)
[選一個 persona:]
- 阿伯:60+ 歲,不熟手機,字要看得到才點得到
- 25y 工程師:預期所有按鈕都有 keyboard shortcut
- 王太太主委:會 office 但不會 SQL,需要看「為什麼」才會用
- 張總:high-priv admin,點任何東西要結果不要看細節
## 規矩(同 QA agent)
1. 只能回 ✅/❌/⚠️ OPEN,不准標 P 級
2. 不准提 fix
3. 找到問題附 reproduce + screenshot
## 工作步驟
1. 從 [起始畫面] 開始
2. 走完整 [target flow]
3. 每一步問:這個 persona 真的能理解嗎?會點對嗎?
4. 結束時報告:這個 flow 對這個 persona 是否 work
「測不出 bug」常常是「測得不夠深」。Happy path 過 = 測試開始,不是結束。
規矩 5 — Cycle file 模板
放在 docs/cycle-template.md。每個 PR 複製成 docs/cycles/Cn-shortname.md:
# Cycle Cn — [短標題]
**Cycle Type**: T-PR-cycle / T-regression-fix / T-feature / T-user-smoke
**Owner**: [engineer agent / 你]
**Started**: YYYY-MM-DD HH:MM
**PR**: commit [sha 或 branch]
## Verification scope
- Layers covered: L1 INV, L3 resolver, L4 frontend (etc)
- INVs verified: INV-XXX-NNN, INV-YYY-MMM
- Layers deferred: [哪些不在這 cycle 範圍 + 理由]
---
## Stage 0.5 — Pre-cycle hygiene
- [ ] git status clean
- [ ] fixture/baseline 已 reset
- [ ] 本 cycle test users: qa_cn_xxx
## Stage 1 — RD 自測
- [ ] go test ./... 全綠
- [ ] live smoke 1 條 happy path
## Stage 2 — QA wave
派 [N] 個 QA agent 平行,每個 cover 1-3 INV。
- agent A: INV-X,結果 ✅/❌/⚠️
- agent B: INV-Y,結果
- ...
## Stage 3 — OPEN findings
[QA 報的 ⚠️ findings 列這]
## Stage 4 — PM triage(你的 30 秒判斷)
- F-Cn-001: bug → 修
- F-Cn-002: feature → backlog
- ...
## Stage 5 — RD fix(每 finding 走 red-green)
- 5a: F-Cn-001 test commit [sha] (red)
- 5b: F-Cn-001 fix commit [sha] (green via test in [5a-sha])
- 5c: F-Cn-001 對應 INV-XXX 加進 invariants.md
## Stage 6 — Regression
原 QA agent 重跑,fix commit 為 input。預期之前的 ❌ 變 ✅。
## Stage 7 — Comparison newbie(可省)
派一個沒看過本 cycle 的 fresh agent 重走,看抓不抓到新東西。
0 new finding = spec/INV 寫得清楚;≥1 = spec 有黑洞。
## Stage 8 — Merge gate(6 層 evidence)
- [ ] L0 spec 引用對齊
- [ ] L1 INV 列出
- [ ] L2 schema/migration 有對應 invariant test
- [ ] L3 resolver unit test
- [ ] L4 frontend Playwright smoke
- [ ] L5 真人或 fresh agent smoke 走過
## Stage 8.5 — Post-cycle cleanup
- [ ] disposable test users DELETE
- [ ] fixture 復原 canonical state
- [ ] git status clean
規矩 6 — 跟 AI 的日常對話紀律(5 條)
前 5 條規矩(檔案 / prompt)準備好之後,日常跟 AI 對話再加 5 條紀律:
- 新需求先寫進規格,不要直接讓 AI 改 code。需求寫成一段話 → AI 確認理解 → 才開工。
- 修 bug 一律先問「會違反哪條 INV」。沒對應 INV → 先補 INV。不可以光修 code 不加 INV。
- AI 給你 ✅ 主動懷疑。問「這個 ✅ 涵蓋什麼,沒涵蓋什麼?」9/10 ✅ 也要追那 1/10。
- 定期派 deep-probe(規矩 4 第二個)。每幾個 cycle 派一個 persona walk,專找「真人會踩但 INV 沒寫」的東西。Happy path 永遠不夠。
- 主動挑戰 AI 的方法論。AI 自己寫的方法論,你要從框架外問「漏了什麼」。AI 看不見自己的盲區,要靠你挑戰。
適用什麼專案?ROI 分級
- 🟢 多租戶 SaaS / 高合規(金融、醫療、隱私):最值得。INV/audit/SCN 本來就是合規的具體形式。
- 🟢 個人專案要長期維護:值得。紅線清單跨專案累積。
- 🟡 2-5 人小團隊用 AI 輔助:中等。要花時間教同事,前期慢後期快。
- 🟡 既有 codebase 想改善:中等。前期蒸餾既有 spec → INV 比較花時間。
- 🔴 純探索性 prototype:低。沒累積教訓 → 紅線清單空 → 機制空轉。
- 🔴 一次性 script:低。沒 ship gate 就沒 cycle。
綠色專案直接把 6 條規矩貼進去開工。第一個 cycle 預期會踩坑(過度信任 AI 的 ✅、規格邊修邊膨脹、test 跟 fix 同 commit…)。沒關係 — 踩了就加 INV、改 prompt。整套就是設計來「邊踩邊長」的。
最重要的觀察:AI 看不見自己的盲區
這 16 天有個反直覺的發現——每次方法論升級,都是我一句質疑觸發,不是 AI 自己想到。
- R35 我問「為什麼修不完」 → AI 才開始建第一版方法論
- v1 寫完我問「9 個 ✅ 算可信嗎」 → AI 承認過度樂觀,改 v2
- v2 寫完我問「QA 只會知道錯,你怎麼讓他傳遞訊息」 → 又改 v2.1
- v2.2 寫完我問「我們不是有寫測試情境嗎」 → AI 才發現自己漏算 110 條場景
- v2.2 結論發出我問「為什麼說不是 TDD」 → AI 承認「沒 TDD」過絕對
AI 寫方法論時系統性偏向「框架完善」——在自己定的框架內找證據確認框架對,看不到框架外的盲區。要使用者從框架外挑戰,框架才會演化。
沒有這幾次質疑,我那套方法論會 stuck 在 v2 過度耦合的狀態,而且還會洋洋得意覺得自己 73% 完成。這是這 16 天最值得記住的一條——對所有用 AI 協作的工作都適用。
總結
16 天前我以為「AI 寫程式」就是「丟需求 AI 幫我寫」。16 天後我發現:AI 寫程式真正會出問題的不是技術,是工作流。技術上 AI 完全有能力寫對,但工作流錯了就一直繞圈。
本文 6 條規矩可以直接複製到你下個專案。預期會踩坑,沒關係,踩坑後加 INV 改 prompt 就好。系列上一篇關於底層原則的「未驗即不可信」也可以一起看。