利用 grill-me, Example Mapping 和決策表逼出高鐵購票的條驗收條件

三段高鐵官網上的購票規則,不到 200 字,最後逼出了 21 條驗收條件。這篇文章記錄整個過程:先用 Matt Pocock 的 grill-me 在 Claude Code 裡盤問需求,再用 Example Mapping 把規則展開成範例,最後用決策表把範例收斂成可驗收的清單。

三個工具的分工很清楚。grill-me 負責找出「規則沒說的事」;Example Mapping 負責用具體範例證明每條規則的解讀是對的;決策表負責保證條件組合沒有漏掉。單獨用任何一個都會有缺口,接起來才完整。

全文的對話記錄以 【人】 標記 DavidKo 輸入的內容,以 【AI】 標記 Claude Code 的回覆。為了讓文章獨立可讀,grill-me 的建議答案在本文中一律視為正確並採納;實務上你會在那些地方停下來跟 PO 確認。

起點是這三段原始需求:

  1. 每筆交易最多以 10 張乘車票為限,去回票每筆交易最多可訂購去回程各 5 張。
  2. 旅客可預訂 29 天內(含乘車當日)至發車前 5 分鐘為止之車次,且每逢週五及週六至多可預訂四週後至週日之車票(如因特殊事由調整開放時間,本公司將另行公告)。
  3. 座位偏好功能僅適用於單人乘客,系統係依列車訂位概況媒合您期望的座位,如該車次已無合適座位時,為讓您仍可順利完成訂票作業,將由系統自動配置座位。

第一步:grill-me 盤問,三輪問出 16 個規則沒說的事

grill-me 的做法是把需求攤成一棵決策樹,每輪只問「前提已經確定、現在可以問」的問題,每題附上它自己的建議答案。查得到的事實它自己查,只有決策才問人。這次沒有 repo,所以它沒有任何事實可查,第一輪就直接問決策。

安裝與啟動只有兩行:先在 Claude Code 裡 claude plugin install mattpocock-skills@claude-plugins-official,再在任意資料夾打 /grill-me。

第一輪

【人】

/grill-me 請用繁體中文訪談我。我要定義台灣高鐵一般對號座的訂票規則,需求如下:

  1. 每筆交易最多以 10 張乘車票為限,去回票每筆交易最多可訂購去回程各 5 張。
  2. 旅客可預訂 29 天內(含乘車當日)至發車前 5 分鐘為止之車次,且每逢週五及週六至多可預訂四週後至週日之車票(如因特殊事由調整開放時間,本公司將另行公告)。
  3. 座位偏好功能僅適用於單人乘客,系統係依列車訂位概況媒合您期望的座位,如該車次已無合適座位時,為讓您仍可順利完成訂票作業,將由系統自動配置座位。

【AI】

這三段規則各自獨立,第一輪我把三段的根問題都放上來,共 7 題。

❓ Q1 – 「每筆交易」的邊界:「交易」是一次結帳產生的一張訂單,還是一次登入 session?同一人連續結帳兩筆、各 10 張,是否合法?

➡️ 定義為「一次結帳產生的一張訂單」。張數上限只在單張訂單內檢查,跨訂單不限制。

❓ Q2 – 10 張與去回各 5 張的關係:去回票是否同時受 10 張總量限制?去程 5 張、回程 3 張可以嗎?

➡️ 單程票上限 10 張;去回票去程、回程各自上限 5 張,不另外檢查總量(最多本來就是 10)。去 5 回 3 合法。

❓ Q3 – 「29 天內(含乘車當日)」怎麼數:今天 11/02(一)可訂到 11/30 還是 12/01?日界以什麼時區切換?

➡️ 今天算第 1 天,可訂的最後乘車日是今天 + 28 天,即 11/30。日界以 Asia/Taipei 的 00:00 切換。

❓ Q4 – 「發車前 5 分鐘」以哪一站為準:旅客的起程站表定發車時間,還是該車次始發站?

➡️ 旅客起程站的表定發車時間。

❓ Q5 – 週五及週六的延伸規則:「四週後至週日」指哪一個週日?週五幾點開放?週日 00:00 之後就收回 29 天規則嗎?

➡️ 延伸上限為「本週的週日 + 28 天」。週五 00:00 開放,週六 23:59:59 結束,週日 00:00 起回到 29 天規則。範例:11/06(五)用 29 天規則只能訂到 12/04,延伸後可訂到 12/06(日)。

❓ Q6 – 「單人乘客」的定義:是整筆交易只有 1 張票,還是單一行程只有 1 張票?去回票去程 1 張、回程 1 張算不算?

➡️ 以「單一行程只有 1 張票」判斷,去程與回程各自判斷。去 1 回 1 的去回票,兩個行程都可以使用座位偏好。

❓ Q7 – 自動配位要不要告知旅客:偏好未滿足時,是付款前就顯示實際座位,還是只在票面上呈現?

➡️ 付款前顯示實際配到的座位,並標示「未能符合您的座位偏好」。

【人】

Q1 同意。Q2 同意。Q3 同意。Q4 同意。Q5 同意。Q6 同意。Q7 同意。

第二輪

【AI】

第一輪的答案打開了 7 個下游問題。

❓ Q8 – 超過上限時的處理:單程 11 張、或去回票去程 6 張時,整筆拒絕並提示上限,還是自動截到上限?

➡️ 整筆拒絕,提示「單程最多 10 張」或「去程最多 5 張」。不自動截斷,避免旅客在不知情下少買。

❓ Q9 – 張數下限:單程 0 張、去回票去程 2 張回程 0 張,是否合法?

➡️ 單程至少 1 張;去回票去程、回程各至少 1 張。回程 0 張應改買單程票,系統拒絕並提示。

❓ Q10 – 「發車前 5 分鐘」的邊界:恰好剩 5 分 0 秒時可以訂嗎?

➡️ 「現在時刻 ≤ 起程站表定發車時刻 − 5 分」可訂。14:00 發車,13:55:00 可訂,13:55:01 不可。

❓ Q11 – 回程是否也受預訂窗口限制:去回票的回程乘車日,是否獨立適用 29 天與週末延伸規則?回程能否早於去程?

➡️ 去程、回程各自獨立檢查預訂窗口;兩者都通過才接受。回程乘車日不得早於去程乘車日。

❓ Q12 – 乘車當日的車次:29 天含當日,所以今天的車次可訂,此時只受「發車前 5 分鐘」限制?

➡️ 是。乘車日 = 今天時,窗口規則一定通過,只檢查 5 分鐘截止。

❓ Q13 – 多張票時座位偏好的 UI:2 張以上時,是不顯示偏好選項,還是顯示但忽略?

➡️ 不顯示。「僅適用於單人乘客」解讀為功能不提供,而非提供後忽略。

❓ Q14 – 特殊事由調整開放時間:要不要在這次範圍內做成可設定的開放時間表?

➡️ 不在範圍內。這次只實作 29 天與週末延伸兩條規則,公告調整留到下一個 story。

【人】

Q8 同意。Q9 同意。Q10 同意。Q11 同意。Q12 同意。Q13 同意。Q14 同意,先不做。

第三輪

【AI】

剩 2 題,都是上一輪答案的收尾。

❓ Q15 – 延伸期間訂到的票,週日之後怎麼處理:週五訂到 12/06 的票,週日 00:00 窗口縮回 12/04 後,這張票是否受影響?

➡️ 不受影響。窗口規則只在「建立訂單」當下檢查,已成立的訂單不回溯。

❓ Q16 – 車次完全無空位時:座位偏好無法滿足會自動配位,但如果整個車次沒有任何空位呢?

➡️ 拒絕訂票並提示「該車次已無座位」。自動配位的前提是還有空位。

這兩題確認後,決策樹上沒有未訪問的分支了。我整理的共識如下,請確認:

  • 交易 = 一張訂單;單程 1–10 張,去回票去程、回程各 1–5 張;超量整筆拒絕。
  • 預訂窗口 = 今天 ≤ 乘車日 ≤ 今天 + 28;週五、週六延伸至本週日 + 28;去程、回程各自檢查;回程不早於去程。
  • 乘車當日的車次只檢查「現在 ≤ 起程站發車時刻 − 5 分」。
  • 窗口只在建單時檢查,不回溯。特殊事由調整不在範圍內。
  • 座位偏好只在「該行程 1 張票」時提供;無法滿足時自動配位並在付款前告知;車次無空位則拒絕。

我們是否已達成共識?確認後我才會繼續。

【人】

Q15 同意。Q16 同意。確認,我們達成共識了。

16 題裡沒有一題是原始需求寫明的,但每一題都會影響程式怎麼寫。這就是 grill-me 的價值:它不產出驗收條件,它產出「驗收條件應該涵蓋哪些決策」。

第二步:Example Mapping,7 條規則、30 個範例、2 張紅卡

grill-me 結束時留下的是一串「決策」,還不是規則。Example Mapping 的工作是把決策整理成規則(藍卡),再為每條規則配上具體範例(綠卡)證明解讀無誤;配不出範例、或範例之間互相矛盾的地方,就是紅卡。

這一步仍在同一個 Claude Code 對話裡進行,不需要額外的 skill。

【人】

請用 Example Mapping 的方式,把我們剛才確認的共識整理成規則與範例。Story 是「旅客訂購一般對號座」。每條規則至少 3 個範例,範例要用具體日期和數字,今天是 2026/11/02(一)。規則無法用範例說清楚的地方列為問題。

【AI】

Story:旅客訂購一般對號座。

規則 1 — 單程票每筆交易 1 到 10 張

  • 訂 1 張 → 接受
  • 訂 10 張 → 接受
  • 訂 11 張 → 拒絕,提示「單程最多 10 張」
  • 訂 0 張 → 拒絕

規則 2 — 去回票去程、回程各 1 到 5 張,回程不早於去程

  • 去 5 回 5 → 接受
  • 去 5 回 3 → 接受
  • 去 6 回 4 → 拒絕,提示「去程最多 5 張」
  • 去 2 回 0 → 拒絕,提示「回程至少 1 張,或改購單程票」
  • 去程 11/10、回程 11/09 → 拒絕,提示「回程不得早於去程」

規則 3 — 預訂窗口為今天起 29 天(含今天)

  • 今天 11/02 訂 11/02 的車次 → 通過窗口檢查
  • 今天 11/02 訂 11/30 的車次 → 通過(今天 + 28)
  • 今天 11/02 訂 12/01 的車次 → 拒絕,提示「尚未開放預訂」
  • 今天 11/02 訂 11/01 的車次 → 拒絕,提示「乘車日已過」

規則 4 — 週五、週六延伸至本週日 + 28 天

  • 11/05(四)訂 12/04 → 拒絕(29 天規則只到 12/03)
  • 11/06(五)訂 12/06(日) → 接受(本週日 11/08 + 28 = 12/06)
  • 11/06(五)訂 12/07(一) → 拒絕
  • 11/07(六)訂 12/06 → 接受
  • 11/08(日)訂 12/06 → 接受(29 天規則本身就到 12/06)
  • 11/08(日)訂 12/07 → 拒絕

規則 5 — 乘車當日的車次,截止於起程站發車前 5 分鐘

  • 車次 14:00 從台中發車,現在 13:55:00 → 接受
  • 同車次,現在 13:55:01 → 拒絕,提示「已停止售票」
  • 車次 13:30 從台北始發、14:00 到台中,旅客從台中上車,現在 13:40 → 接受(以台中 14:00 計)

規則 6 — 座位偏好只在該行程 1 張票時提供

  • 單程 1 張 → 顯示偏好選項
  • 單程 2 張 → 不顯示偏好選項,系統自動配位
  • 去回票去 1 回 1 → 去程、回程都顯示偏好選項
  • 去回票去 1 回 2 → 去程顯示、回程不顯示

規則 7 — 偏好無法滿足時自動配位並告知;車次無空位則拒絕

  • 選靠窗,車次有靠窗空位 → 配到靠窗
  • 選靠窗,車次只剩靠走道 → 配到靠走道,付款前顯示「未能符合您的座位偏好」
  • 未選偏好 → 系統自動配位,不顯示提示
  • 車次無任何空位 → 拒絕,提示「該車次已無座位」

問題(紅卡)

  • 座位偏好有哪些選項?目前只知道靠窗、靠走道,需求沒列舉。
  • 「特殊事由調整開放時間」已確認不在範圍內,但上線後若公告延伸到 35 天,規則 3 的 28 要可設定還是改程式?

【人】

規則 4 的第 5 個範例我原本以為週日應該拒絕,看了範例才發現 29 天規則自己就涵蓋到了。這個範例留著。兩張紅卡先記錄,不擋這個 story。

規則 4 那個範例正是 Example Mapping 存在的理由。grill-me 在 Q5 問清楚了「週日 00:00 回到 29 天規則」,但只有把 11/08 和 12/06 這兩個日期真的擺出來,才看得出週日的延伸與不延伸結果相同。規則對了,但人對規則的直覺是錯的;範例把這個落差攤在桌上。

第三步:決策表,4 張表收斂成 21 條驗收條件

Example Mapping 的範例是人想出來的,涵蓋度靠直覺。決策表把條件列出來做組合,用「不相關(–)」合併,保證每一種條件組合都有對應的結果。這一步我請 Claude Code 用決策表技法整理,並要求條件之間獨立的部分拆成不同的表,避免一張表爆到上百欄。

【人】

請用決策表測試技法,把 7 條規則整理成決策表,再從每一欄導出一條驗收條件。條件互相獨立的規則分成不同的表。驗收條件用 Given / When / Then,數值要具體。

【AI】

7 條規則分成 4 個獨立的判斷面向:單程張數、去回票張數、預訂窗口、座位配置。4 張表,合併後共 21 欄,對應 21 條驗收條件。

表 A:單程票張數

條件A1A2A3
張數01–1011 以上
結果拒絕接受拒絕,提示單程最多 10 張

表 B:去回票張數與日期

條件B1B2B3B4B5B6
去程張數06 以上1–51–51–51–5
回程張數––06 以上1–51–5
回程乘車日 ≥ 去程乘車日––––是否
結果拒絕拒絕,提示去程最多 5 張拒絕,提示回程至少 1 張拒絕,提示回程最多 5 張接受拒絕,提示回程不得早於去程

表 C:預訂窗口(每個行程各自套用一次)

條件C1C2C3C4C5C6C7
乘車日 ≥ 今天否是是是是是是
乘車日 ≤ 今天 + 28–是是是否否否
乘車日 = 今天–否是是–––
現在 ≤ 起程站發車時刻 − 5 分––是否–––
今天為週五或週六––––是是否
乘車日 ≤ 本週日 + 28––––是否–
結果拒絕,乘車日已過接受接受拒絕,已停止售票接受(週末延伸)拒絕,尚未開放拒絕,尚未開放

表 D:座位配置(每個行程各自套用一次,張數與窗口都通過後)

條件D1D2D3D4D5
車次尚有空位否是是是是
該行程張數 = 1–否是是是
旅客選了座位偏好––否是是
有符合偏好的空位–––是否
結果拒絕,該車次已無座位不顯示偏好選項,自動配位自動配位配置符合偏好的座位自動配位,付款前告知未符合偏好

21 條驗收條件

每一欄一條,欄號即驗收條件編號。日期以今天 = 2026/11/02(一)為基準。

單程票張數

  • AC-A1 Given 旅客選購單程票 When 張數為 0 Then 系統拒絕建單
  • AC-A2 Given 旅客選購單程票 When 張數為 10 Then 系統接受並進入座位配置
  • AC-A3 Given 旅客選購單程票 When 張數為 11 Then 系統拒絕並提示「單程最多 10 張」

去回票張數與日期

  • AC-B1 Given 旅客選購去回票 When 去程 0 張 Then 系統拒絕建單
  • AC-B2 Given 旅客選購去回票 When 去程 6 張、回程 4 張 Then 系統拒絕並提示「去程最多 5 張」
  • AC-B3 Given 旅客選購去回票 When 去程 2 張、回程 0 張 Then 系統拒絕並提示「回程至少 1 張,或改購單程票」
  • AC-B4 Given 旅客選購去回票 When 去程 3 張、回程 6 張 Then 系統拒絕並提示「回程最多 5 張」
  • AC-B5 Given 旅客選購去回票,去程 11/10、回程 11/12 When 去程 5 張、回程 3 張 Then 系統接受並進入座位配置
  • AC-B6 Given 旅客選購去回票,去程 11/10、回程 11/09 When 去程 1 張、回程 1 張 Then 系統拒絕並提示「回程不得早於去程」

預訂窗口

  • AC-C1 Given 今天 11/02 When 選擇 11/01 的車次 Then 系統拒絕並提示「乘車日已過」
  • AC-C2 Given 今天 11/02 When 選擇 11/30 的車次 Then 系統接受
  • AC-C3 Given 今天 11/02,車次 14:00 從台中發車,現在 13:55:00 When 選擇該車次從台中上車 Then 系統接受
  • AC-C4 Given 今天 11/02,車次 14:00 從台中發車,現在 13:55:01 When 選擇該車次從台中上車 Then 系統拒絕並提示「已停止售票」
  • AC-C5 Given 今天 11/06(五) When 選擇 12/06(日)的車次 Then 系統接受
  • AC-C6 Given 今天 11/06(五) When 選擇 12/07(一)的車次 Then 系統拒絕並提示「尚未開放預訂」
  • AC-C7 Given 今天 11/05(四) When 選擇 12/04(五)的車次 Then 系統拒絕並提示「尚未開放預訂」

座位配置

  • AC-D1 Given 旅客選購 1 張單程票 When 該車次無任何空位 Then 系統拒絕並提示「該車次已無座位」
  • AC-D2 Given 旅客選購 2 張單程票,車次有空位 When 進入座位配置 Then 不顯示座位偏好選項,系統自動配位
  • AC-D3 Given 旅客選購 1 張單程票,車次有空位 When 未選擇座位偏好 Then 系統自動配位,不顯示偏好相關提示
  • AC-D4 Given 旅客選購 1 張單程票,車次有靠窗空位 When 選擇偏好「靠窗」 Then 系統配置靠窗座位
  • AC-D5 Given 旅客選購 1 張單程票,車次只剩靠走道空位 When 選擇偏好「靠窗」 Then 系統配置靠走道座位,並在付款前顯示「未能符合您的座位偏好」

需求待釐清清單

  • 座位偏好的選項有哪些?本表只以靠窗、靠走道為例。
  • 去回票的去程、回程在表 C、表 D 各自套用一次,意味一筆去回票最多會出現兩次「未能符合偏好」的提示。這是否符合預期?
  • 「特殊事由調整開放時間」不在本次範圍。表 C 的「28」若未來需調整,建議做成設定值。

【人】

表 C 的欄位合併得不錯。但 AC-C3 和 AC-C4 我想補一個始發站與起程站不同的案例,確認是以起程站計算。

【AI】

補上一條:

  • AC-C3b Given 今天 11/02,車次 13:30 從台北始發、14:00 抵達台中,現在 13:40 When 選擇該車次從台中上車 Then 系統接受(以台中 14:00 為截止基準)

這條不是新的決策表欄位,是 C3 的補充案例,用來鎖定「起程站」的解讀。

決策表沒有多找出新的規則,這很正常,因為前兩步已經把規則問乾淨了。它找出的是表 C 第 1 列:「乘車日 ≥ 今天」。Example Mapping 的規則 3 有「11/01 已過」這個範例,但只有在決策表裡把它和週五週六延伸規則並排時,才會發現如果少了這個條件,週五訂過去的日期會被延伸規則誤判為接受。範例看得到單一情境,決策表看得到條件之間的交互作用。

結語:三個工具各自補了什麼

工具輸入輸出它找到了什麼
grill-me3 段原始需求16 個決策規則沒寫的事:交易邊界、日期怎麼數、哪一站發車、超量怎麼處理
Example Mapping16 個決策7 條規則、30 個範例、2 張紅卡人對規則的直覺哪裡是錯的:週日的延伸與不延伸結果相同
決策表7 條規則4 張表、21 條驗收條件條件之間的交互作用:少了「乘車日 ≥ 今天」,延伸規則會放行過去的日期

三步的順序不能換。先做決策表,條件還沒問清楚,表會建在錯的假設上;先做 Example Mapping,範例會圍繞你自己的解讀打轉,問不出 Q4、Q5 那種你沒想到的分歧。grill-me 的價值在它完全不產出驗收條件,只產出「驗收條件應該回答哪些問題」。

反過來說,grill-me 停在決策這一層也是它的極限。它問出「週日 00:00 回到 29 天規則」,但不會自己擺出 11/08 和 12/06 來看結果;它問出「乘車日已過要拒絕」,但不會把這個條件和週五延伸規則並排,看出兩者的交互。那兩件事分別要靠範例和決策表。

整個過程人只打了 8 段文字,其中 5 段是「同意」。工作量不在打字,在每一輪停下來判斷 AI 的建議答案能不能接受。這篇文章假設全部能接受;真實專案裡,Q2、Q5、Q13 這三題大概要拉 PO 進來才能定案。

發佈留言