用 LLM 跑 Spec Review — 兩段式 Prompt 把模糊需求釣出來
Spec review checklist 跑久了會累、會漏掉。LLM 在「列出可能性」這件事比人類強 — 但判斷哪些重要還是人類的工作。這篇講怎麼設計兩段式 prompt,讓 LLM 出粗草、QA 收細工。
為什麼要用 LLM
人工 spec review 的盲點:
- 熟悉的 domain 反而會跳過 — 你太熟,覺得「這當然會處理」,但實作可能沒
- 疲勞時漏看 — 連續 review 第 3 份 spec 就會掃過去
- 缺少非 happy-path 想像力 — 寫 spec 的人本來就少寫異常
LLM 的補位:
- 沒有「太熟」的盲點 — 它會把你忽略的問題都列出來
- 不會累
- 訓練資料涵蓋大量異常情境
配合:LLM 出 30 個問題,你用 [[spec-review-checklist]] 判斷哪 10 個真的重要。
兩段式 Prompt 設計
直接問「找漏洞」效果差 — LLM 會給你一坨泛泛的建議。先澄清、再挑戰才有用。
Stage 1:先列「需澄清」問題
你是資深 QA。以下是一份產品需求 spec。
【Spec】
<貼整份 spec、user story、或 PRD>
【任務】
不要急著找漏洞。先列出這份 spec 中**所有需要澄清的點**。
重點問:
1. 模糊用詞(「適時」、「自動」、「合理的」)→ 該追問什麼?
2. 沒明說的前提(角色、權限、依賴功能)
3. 數字 / 限制沒寫的(長度、數量、時間、金額)
4. 沒列舉完的(「等」、「之類」、「包含但不限於」)
5. 多人協作沒寫的(衝突、race、同時改)
【輸出格式】
| 編號 | spec 原文(引用片段) | 澄清問題 | 為什麼這重要 |
|------|---------------------|----------|-------------|
只列「需問」不列「假設」。如果你已經知道答案、就不算需澄清的。
【限制】
- 至少 15 個問題
- 用繁體中文
- 不要編造 spec 沒提到的東西
為什麼這個 Stage 重要:把 spec 的「模糊面積」量化。看到 30 個澄清問題 → 你心理就有底「這份 spec 還不能進開發」。
Stage 2:基於 Stage 1,列邊界與漏洞
基於剛才那份 spec 和你列出的澄清問題,現在進入第二輪。
假設 PM 對你剛才所有問題都回答「依預設值處理」、「跟舊功能一致」、「使用者體驗合理即可」。
請列出在「PM 這樣回答的情況下」,這個功能上線後最可能爆炸的 15 個情境。
每個情境包含:
1. 觸發條件(具體值)
2. 預期會發生什麼
3. 我們應該補哪些 test case
【特別關注】
- 邊界值(0、負數、極大、空值、null)
- 狀態機(不合法的狀態轉換)
- Race condition(兩個請求同時)
- 錯誤處理(網路 / DB / 第三方 fail)
- 資料一致性(多寫入點、cache 失效、歷史資料)
- 跨平台(瀏覽器、裝置、語系)
- 安全(injection、權限繞過、敏感資料外洩)
【輸出格式】
## 場景 N: <一句話描述>
- 觸發:具體操作 + 資料
- 風險:會發生什麼
- 影響:使用者 / 營收 / 法遵
- 建議測試:1-3 個 test case 標題
【限制】
- 用繁體中文
- 不要重複 Stage 1 已提的問題
- 找「會爆炸」的,不是「UX 可以更好」的
為什麼分兩段:
- 一段式 prompt LLM 會混在一起 → 「這裡模糊」「這裡會爆」攪和、難分類
- 兩段式 → 第一輪做 spec 品質檢查、第二輪做風險探測
實際範例
Spec(簡化版)
功能:會員等級系統
- 使用者依累積消費分為 銅 / 銀 / 金 / 鑽 四級
- 升等規則:累積消費滿一定金額自動升等
- 等級享有不同折扣:銅 0%、銀 5%、金 10%、鑽 15%
- 等級降級:一年內消費未達標自動降級
- 使用者可以查詢自己的等級歷史
Stage 1 LLM 輸出(節錄)
| # | 引用 | 澄清問題 | 為什麼重要 |
|---|---|---|---|
| 1 | 「累積消費」 | 是「歷年累積」還是「滾動 12 個月」?退費要扣回去嗎? | 影響升等邏輯與資料模型 |
| 2 | 「累積消費滿一定金額」 | 各級門檻具體數字?台幣?要含稅? | 沒寫等於無法實作 |
| 3 | 「自動升等」 | 即時 vs 次日批次?升等時通知方式? | 影響使用者體驗 + 推播設計 |
| 4 | 「銅 0%」 | 折扣是全品項?特價品也算?跟其他優惠券能疊嗎? | 折扣疊加是常見 bug 來源 |
| 5 | 「一年內消費未達標」 | 一年定義?1/1-12/31 還是滾動?降級到哪一級(降一級或全降銅)? | 影響降級頻率與爭議 |
| 6 | 「使用者可以查詢自己的等級歷史」 | 多久?分頁?匯出?欄位有什麼? | UX + 隱私 + 效能 |
| ... | ... | ... | ... |
價值:拿這份去問 PM,強制 spec 補完整。如果 PM 嫌煩、就回他「我不問現在,將來 5 個 bug 都得回到這個點解」。
Stage 2 LLM 輸出(節錄)
## 場景 1: 升等與退費衝突
- 觸發:使用者買 5000 元升金,退費 1000 後累積剩 4000(金門檻 4500)
- 風險:等級該不該降回銀?折扣已用過怎處理?
- 影響:客訴 + 客服人工處理成本
- 建議測試:
- test_upgrade_then_refund_below_threshold
- test_used_discount_with_demoted_user
- test_refund_partial_within_24h
## 場景 2: 升等同時下單(race condition)
- 觸發:使用者下單觸發升等的瞬間、用同個 session 再下另一單
- 風險:第二單按舊等級結帳、但 DB 已升等 → 折扣不一致
- 影響:少收錢 or 多收錢,客訴
- 建議測試:
- test_concurrent_upgrade_and_order
- test_idempotent_upgrade_check
## 場景 3: 跨年降級時間
- 觸發:使用者 12/31 23:59 下單,剛好達標
- 風險:1/1 00:00 跑批次降級,未保護剛達標的人
- 影響:剛升等馬上降、極差體驗
- 建議測試:
- test_year_boundary_purchase
- test_demote_grace_period
## 場景 4: 等級顯示不一致
- 觸發:升等後沒清 cache、客戶端看到舊等級
- 風險:顯示銀但結帳金折扣(或反之)
- 影響:客訴、信任度
- 建議測試:
- test_cache_invalidation_after_upgrade
- test_concurrent_browsing_after_upgrade
...
價值:直接拿來變 test case backlog。
進階:第三輪反問
如果 spec 比較大,可以加 Stage 3:
你剛才列出的 15 個風險,請挑出**最容易被開發團隊忽略**的 5 個,
並說明為什麼「資深開發也會忽略」。
接著對這 5 個各寫一段「給 PM / 開發看的說服文字」,
解釋為什麼這次 sprint 一定要處理、不能等下版。
用途:你帶這段去 sprint planning,當作「QA 否決進開發」的理由。
品質檢核:LLM 輸出後必做
- 濾掉 LLM 編造的欄位 / API — 「呼叫
POST /api/users/upgrade」可能根本不存在,依實際 code 為準 - 濾掉重複 — 不同編號講同件事,合併
- 濾掉「UX 可以更好」 — 那是設計 review,不是品質 review
- 補上 LLM 漏的 domain 規則 — 例如金管會、個資法、特定產業規範
- 排序:依「被觸發機率 × 影響大小」打分數
反模式
- 直接把 LLM 輸出貼到 spec review 會議 — 沒篩過、品質參差 → 信用扣分
- 用 LLM 輸出去質問 PM — 對話會變很臭。自己內化、用自己的話問
- LLM 輸出當 ground truth — 它會編造,要對 code / spec
- 每份 spec 都跑 — 簡單 spec 不需要、有些只需 Stage 1。依複雜度決定
工作流建議
[PM 寫 spec]
↓
[QA 自己讀一遍、心裡有底]
↓
[Stage 1 LLM 跑 → 你篩 → 整理 5-10 個關鍵問題]
↓
[Spec review 會議:用問題形式問 PM]
↓
[PM 補 spec]
↓
[Stage 2 LLM 跑 → 你篩 → 轉成 test case backlog]
↓
[Sprint planning:用 backlog 估點 / 加 QA 工時]
整個流程省下「會議中現場思考」的壓力,把判斷力留到實質的取捨上。
最後
LLM 在 spec review 的角色是「有耐心的列舉者」、不是「判斷者」。用對位置 = 你變得更敏銳;用錯位置 = 你變懶又不準。永遠保留人工最後一道篩。