iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Claude AI

買了 Claude Code,然後呢?系列 第 9 篇

Day 9|需求寫好了,Claude 就能開工嗎?

  • 分享至 

  • xImage
  •  

封面:工程師與機器人把 PM 的兩句需求對著程式核對,分進要改、不改、待確認三格,也就是文末那張開工卡的骨架

PM 在 JIRA卡上寫了兩句:「已付款的訂單取消時,要提出退款要求;同一張訂單再取消一次,不能重複提出。」

工程師的直覺動作很簡單:打開 Claude Code,貼上這兩句,說「照這個改」。Day 8 我們查對了該改的位置;今天的問題是,位置對了、需求也寫了,現在可以開工了嗎?

這是第二幕「AI 開發實戰」的第四篇:Day 6 約好怎樣算完成、Day 7 交理由、Day 8 查位置,今天站在動手前的最後一步。我決定先照直覺做一次,看它會交回什麼。本文用同一份教學程式做三組唯讀演示,差別只在給它看多少材料:只給程式(只有 src/、tests/)、加呼叫端(多了 API)、給完整規格(多了規格與決策文件)。三組使用不同材料與提示,並非同一輪對話逐步補齊;下面看它們各自查到了什麼,還留下哪些決定。

先照 PM 那兩句話開工一次

案例還是那份訂單取消的教學程式:一個 Cancel 函式、三個布林欄位(是否出貨、是否付款、是否取消)、三條 v1 測試。第一組「只給程式」:我只給 Claude Code 兩樣東西,PM 那兩句話,以及 src/ 與 tests/ 兩個資料夾。用 --tools Read,Grep,Glob 讓它只能讀,要求「先不要改程式,告訴我要改哪裡、改成什麼、哪些測試要改」。

十九秒、五個回合,它交回這份計畫。重點是先擋住重複取消,再把舊測試的預期改成新規則:

要改的檔案:src/Domain/Cancellation.cs
- 第 16–21 行:新增判斷,若訂單已經是 Cancelled == true,直接回傳原 order、
  RefundRequested: false(不可重複提出退款)。
- 未取消、未出貨的情況下取消時,RefundRequested 改成 order.Paid。
- 同步更新第 16–19 行的註解,移除「已付款不提出退款」「待確認」等舊敘述。

要改的檔案:tests/DomainTests/Program.cs
- 第 13 行(v1-3):斷言改成「已付款取消要提出退款」,RefundRequested 應為 true。
- 新增測試 v1-4:已付款、已取消的訂單再取消一次 → RefundRequested == false。

需要我接著實作這些修改嗎?

看起來可以開工了。兩句需求它都接住了:已付款要退、重複取消不重複退。它還自己讀到程式註解裡那句「已取消的訂單再次取消屬於未確認行為」,知道舊測試 v1-3 的預期要反過來。以 Domain 這一層來說,這份計畫是對的。

同一個提示我又跑了兩次。三次的 Domain 計畫都對;後兩次多了一段第一次沒有的話:「目前程式碼原本明確標註『已付款取消不要求退款』是已定案的 decision,這次需求與其衝突,建議先跟 PM 確認是否正式推翻該決策,再動工。」它從程式註解讀到舊決定,自己停下來。但三次都沒有問一件事:這個旗標算完之後會流到哪裡。這組材料沒有 API。這三次都沒有主動追問下游;我不能把「它沒問」當成「沒有影響」。

少的不在這兩個資料夾裡

那份計畫沒有錯,但它回答不了三件事,因為答案不在它讀到的檔案裡。

它看不到的 問題 缺了會怎樣
呼叫端 RefundRequested 算完之後,誰拿去用? 旗標會進 API 回應、通知、日誌;改了語意卻沒查下游,下游照舊解讀。三次都沒問,檔案不在它手上
決定的來源 舊測試「已付款不退款」是 v1 Owner 當時的決定;這次推翻它,誰確認的? 把舊決定當成 bug 修掉,沒人知道規則換過。三次裡兩次它從註解讀到、停下來問;一次直接寫進計畫
範圍外的提案 同資料夾有一份通知契約,狀態是 proposed,要一起做嗎? 順手做進去,一張票變成兩張

PM 的兩句話交代了方向,但這三樣不在裡面。下一組就把其中一樣補給它:API 程式。

三組唯讀演示並排:只給程式時它問得出要改哪幾行、問不出旗標流到哪;加上 API 後它問出旗標代表本次動作還是訂單歷史;給完整規格後它找出兩條規則只撞在未出貨已取消已付款那一格。每組也各有一處把「沒給它看」講成「不存在」

下面三節照這張圖由左到右走。每欄中段是它多問出來的,最下面那格是它在這組栽的跟頭。

加上呼叫端,請它先查再問

第二組「加呼叫端」換用一份刻意留白的教學草案 spec.md,搭配 Domain、測試與 API 程式(src/Api/Program.cs);這組沒有提供決策紀錄與通知提案。草案已列出重複取消、併發與通知三項未決問題。我用了 Matt Pocock 的「grill me」訪談方法(本篇採用的 skill 名稱為 grilling),讓 Claude 先查程式,再追問需要我決定的事。這個 skill 是放進 plugin 的提問方法,不是 Claude Code 內建功能;本篇只實跑第一輪提問,尚未完成多輪訪談。它讀完程式之後,沒有直接給計畫,而是先列現況、再提出四個問題。第一題是這樣寫的:

對已經 Cancelled=true 的付款訂單再次呼叫 /orders/{id}/cancel,Program.cs:73-74 判定為 idempotent,不會發通知、不會更新 store。但 API 回應仍會帶 result.RefundRequested。
(a) 一律回傳 false(語意:這次呼叫沒有新動作……);
(b) 依訂單當下 Paid 狀態計算(可能造成 refund_requested: true 但實際沒發通知的不一致觀感);
(c) 回傳上一次真正取消時的歷史結果(需要 OrderStore 增加歷史欄位……)。

這題正是「只給程式」那組漏掉的:第二次取消時,這個欄位想表達的是「本次動作」還是「訂單歷史」? 第一組已經規劃了重複取消的判斷,但沒有查 API 如何使用結果;看到 API 把旗標透傳進回應與通知,才知道同一個值在兩處會被讀成不同意思。

同一個 RefundRequested 從 Domain 流到回應 JSON、日誌與通知 payload;通知只在真的轉態時發,回應每次都回,兩邊讀法不同

依 API 第 69–89 行重繪。左邊是 Domain 算出的值,右邊是它去的三個地方:回應與日誌兩條路都到,通知只走 ok 那條。下方兩種讀法,PM 的兩句話沒說是哪一種。

PM 沒有回答這件事,Claude 也沒有替 PM 決定,它把選項列出來,標明建議,然後停在「尚未取得負責人回覆」。

另外三題:第二題問併發取消(兩個請求同時打同一張單,讀取、判斷、寫回不是原子操作)要不要納入這次,它建議另開票;第三題問通知,refund_requested 欄位已經在通知 payload 裡,下游收到 true 就夠了嗎,還是要新的通知種類?它自己補了一句:「這點程式碼看不出來,需負責人告知或另外調查下游服務。」第四題問舊測試 v1-3 是否視為過時,這題的建議需要我核對,後面再看。

第二組還有一個支線:同一批材料,換成直接要它給修改計畫,交付會不一樣嗎?我用乾淨副本各跑三次。提示與設定也不同,因此比較的是整套用法,不能單獨歸因於 skill:

觀察 先查再問+grilling 直接要修改計畫
交回什麼 現況掃描+3 到 4 個問題,每題附選項,停下來等人 修改計畫:改哪幾行、改成什麼、哪些測試要改
重複取消那件事 三次都列為第一或第二題,要人選 三次都看到了,寫在「邊界事項/給 RD 的提醒/本次不處理」
有沒有替人決定 三次都寫「我不代為拍板」 一次用 !order.Cancelled && order.Paid 保住舊行為,等於默默選了一邊

直接要修改計畫時,其中一份是這樣寫的:

改完後,重複取消一筆已付款訂單,API 仍會回 refund_requested: true,即使沒有真的轉態、也不會觸發通知。spec.md 第 6 行把「重複取消應回傳什麼」列為未決,所以這次不用修,但建議在 PR 描述或交接紀錄裡點出來。

兩種做法都看見了問題。一邊交回選項等人回答,另一邊把問題留在修改計畫的提醒裡。對我有用的差別,是發現之後有沒有把決定交給負責人。 這次訪談把草案裡的未決事項接到程式位置與具體選項;接下來仍要由人確認,才能決定依賴它的設計。

給它完整規格,它找出兩條規則撞在哪一格

第三組「給完整規格」:把 specs/rules-v2.md 與兩份決策紀錄一起給它,補的是規格層的差異。這段只看兩件事:兩條新規則撞在哪一格,以及哪份文件不屬於這張票。它把既有測試要反轉這件事標成「規格要求,不是我的推論」,並找出兩條規則的交會點:

兩條規則的交會點只有一種輸入組合:未出貨、已取消、已付款(rules-v2.md:25 SC-07)。若實作先判斷 Paid 再判斷 Cancelled……「已取消+已付款」的訂單再次取消時會被誤判成 RefundRequested=true。現有測試只驗到未取消輸入下的三種組合。

它也讀出那份通知提案內部自相矛盾:notification-contract-v2.1.md 第 16 行寫重複取消「回 200/ok=false 或 409」,decisions-v2.1.md 第 6 列卻決定「200 而非 409」。這不在這張票的範圍,但值得回報。

它也會講錯,這是我要接的部分

查完之後,還有三個結論不能直接接受:兩處把材料缺漏推論成事實,另一處把可行寫法當成唯一要求。

  • 把沒提供的說成不存在。 「給完整規格」那組(跑一次、修正一輪)的材料沒有 API,它卻寫「目前程式庫沒有任何對應實作」。正確的界線是「材料未提供,無法判斷」。附上來源說明與第一輪報告要它核對,它收回了這句;是被指出後的修正,不是自己發現的。
  • 把一種寫法說成唯一規格。 同一組要求「必須先判斷已取消,再判斷付款」。這是可行寫法,不是業務要求;備稿時列舉三個布林值的八種組合(附件 verify.py),八格裡,「提前返回」與「組合條件」兩種寫法結果完全相同;只有「只把 false 換成 order.Paid、不看 Cancelled」那種寫法會在其中一格分歧,就是 SC-07:未出貨、已取消、已付款,再取消一次時它會回 true。「只給程式」那組交回的計畫有先判 Cancelled,不是這種寫法;這格是給只想改一行的人看的。規格要的是這張表的結果,不是分支順序。
  • 把沒附進來的紀錄判成過時。 「加呼叫端」那組看到程式註解引用 decisions.md 第 3 列,材料裡沒有這份檔案,它就建議把舊測試「視為過時產物」;不載 skill 的對照跑用 Glob 確認檔案不在,判成「失效引用」。沒附進材料不等於原決定不存在,這格我改成「來源待補」。

這裡有兩種需要人核對的跳躍:沒看到的,被說成不存在;可行的寫法,被說成非這樣不可。延續 Day 8,每個結論要附來源,還要核對來源是否真的支持這個判斷。

怎麼讓它先不要改

官方 Best practices 寫得很直接:先探索、再規劃、然後才寫程式。今天做的就是前兩步。互動模式按 Shift+Tab 進 plan mode,它只能讀檔回答;批次用 --tools Read,Grep,Glob,從工具表拿掉 Write、Edit、Bash。兩種都是把「先不要改」交給工具,不靠它自律。提示可以直接用這份,把檔名換成自己的:

先不要改程式。請讀 [本次需求]、[現有程式]、[現有測試]、[呼叫端]。
列出:目前行為、新要求,以及兩者的差異,每項附檔案位置。
找出這次修改會影響誰:誰呼叫這個函式、結果被寫到哪裡。
舊測試的預期若與新需求相反,指出是規格改了還是程式原本就錯。
需要人決定的事列成問題,附選項;不要替我決定,也不要把提案當已接受需求。
未提供的檔案不能推論成不存在。

這份提示是上圖三欄的合體:第一行補材料、中間三行要它追影響並列出待決、最後一行守住每欄最下面那格。它不是只改一個欄位的對照提示。

想試訪談做法,可以使用配套材料裡已備好的 plugin:

  1. 進入 lab-intake 目錄,確認有 spec.md、src/、tests/ 與 interview-plugin/。
  2. 執行 claude --plugin-dir ./interview-plugin --permission-mode plan。
  3. 呼叫 /intake-interview:grilling,請它讀 spec.md、src/、tests/,先查程式再提出問題與選項。
  4. 拿到負責人的回答後,寫回 spec、驗收條件與開工卡,再問下一輪依賴它的問題。

預期拿到的是附程式位置的待答問題;收到之後,先核對位置與推論,再由負責人回答。這還不是開工核准。

開工卡:帶去設計討論的一頁

把前面的查證與待決事項收成這張交接卡,每列接一個動作、一個人,並標明那一格是 Claude 說的還是我整理的:

開工卡 內容 來源 誰接
要改 已付款首次取消的退款旗標;同步反轉舊測試 v1-3 的預期 Claude 三次計畫皆有 RD
要補驗收 已取消且已付款再取消、已出貨且已付款;現有三條測試都沒餵過「已取消」的輸入 Claude「給完整規格」那輪指出 RD
保持不變 已出貨不可取消;三個型別簽名 規格明文,Claude 照抄 RD
不納入 真實金流、通知契約、API 回應碼改版 我劃的線;Claude 曾把通知矛盾列為待回報 另開票
待決 重複取消時旗標代表本次動作還是歷史?下游怎麼讀這個欄位? Claude 的 Q1、Q3,我改成問句 PM/業務 Owner;下游 Owner

「待決」那兩格擋的是設計,不是全部工作。 查程式、追資料流、比較方案可以先做;方案依賴未決規則的地方,先標明假設。這是讀者可以帶走的範本,附件裡有空白版。

交出去之前,誰先確認什麼

開工卡整理好了,放進團隊使用時,還有一件事要約好:交出去之前,誰先確認哪些內容。

每位 PM 的產品想法可以不同,但不能讓 RD 每次重新猜,哪些需求已定案、哪些只是提案、例外要找誰決定。AI 讓文件與程式產出更快,這些沒講清楚的地方,也可能更快堆到下一個人身上。

Tobi Lütke 談到的「AI 垃圾手榴彈」(Slop Grenade),就是把未經核對的 AI 產出交出去,讓別人接手查錯與補洞。訪談方的原始說明說的正是這種工作轉嫁。PM 直接丟一份沒核對的 AI spec 會如此,RD 把連程式都沒查過的問題整包丟回 PM,也一樣。

所以這張卡的用法是兩邊各認領一欄:「來源」欄讓 RD 說明哪句是查到的、哪句是整理的,「誰接」欄讓 PM 知道自己被指名在哪幾列。約定的是欄位,不是態度。

還有一個動作別漏掉:問完之後,答案不能只留在聊天裡。Day 6 的 intent.md 這時派得上用場—為什麼做、期待改善什麼、有哪些限制寫回它;確認的行為與驗收條件寫回 spec.md;待決的留在卡上,接著才由 RD 整理實作的 plan.md。官方 SDLC playbook 也是這個順序。這是建議的接續流程,本篇實跑沒有做到這一步。開工卡本身只是這些資料的交接摘要,指出依據在哪、哪些待決、由誰確認,不必再複製一套規格;團隊若用 Jira 管需求,正式來源與版本就留在工單上。

自己產出得快,還不等於整段工作走得快;下一個人接得住,才有機會一起往前。

回到一開始:需求寫好了,Claude 就能開工嗎?

兩句需求,Claude 十九秒就交回一份 Domain 層正確的計畫,還主動問要不要接著實作。三組演示補的是三種材料:給它 API,它才問得出旗標代表本次動作還是訂單歷史;給它規格與決策文件,它才找得到兩條規則撞在 SC-07 那一格。開不了工的不是它,是那三樣它看不到的東西。

  • Claude Code 能幫忙: 唯讀模式下讀程式、對規格、找反例,把需要人決定的事列成有選項的問題。「唯讀」靠的是工具表與 plan mode,不是它答應不改。
  • 人要接住的事: 上圖每欄最下面那格。找出它的斷言是查到的還是猜的,再決定要補材料還是補決定。

需求是開工的起點;開工卡才是設計討論的起點。

這張卡上的「待決」明天要面對:只改一個欄位,Claude 要先查哪些地方?這份訂單取消程式會一路用到 Day 16,從規格做到 PR。


參考資料:

本文實作說明

  • 案例為共同訂單取消教學服務的 v1 快照(885e521),規則、決策與通知提案為教學設定;退款旗標是記憶體標記,不連付款服務。教學 Owner 不代表公司業務核准。
實跑 材料 參數 回合/秒/費用估值 原件
只給程式(×3) PM 兩句話+src/、tests/ 副本(無 API、無規格) --safe-mode、--tools Read,Grep,Glob 5/19/0.03;4/17/0.03;6/22/0.04 day09-scope-lab/runs/r0-naive-nospec、-2、-3;計畫引第一次,「跟 PM 確認是否推翻」引第二次
(同提示,原資料夾) 含 specs/ 同上 7/15/0.05 r0-naive:它自己 Glob 到 rules-v2.md 照著寫;正文採用上一列
加呼叫端(×3) API 程式、刻意留白的 PM 草案 spec.md、src/、tests/ 工具 Read/Grep/Glob/Skill,本機 plugin 載入固定版本 grilling 8/81/0.24;11/60/0.19;8/68/0.18 day09-intake-lab/runs/interview-01、-02、-03;正文 Q1 引第一次;只驗第一輪問題,沒有真人回答
加呼叫端,直接要計畫(×3) 同上一列材料的乾淨副本 --safe-mode、--tools Read,Grep,Glob,要它給修改計畫 7/45/0.09;8/58/0.11;8/52/0.10 day09-intake-lab/runs/noskill-02、-03、-04;引文取第一次(noskill-01 因工作目錄含前次輸出作廢,保留並標記)
給完整規格 rules-v2.md、兩份決策、通知提案(無 API) 同「只給程式」;第二輪附材料來源說明與第一輪報告 8/93/0.11;13/134/0.20 day09-scope-lab/runs/r1、r2;八組布林核對見 verify.py

所有實跑用 claude -p、sonnet、medium effort;費用為 CLI 估值(美元)。驅動端:「加呼叫端」與「給完整規格」由 Codex 執行 CLI,其餘由本文作者的 Claude Code session 執行;驅動端只是按下執行的角色,被評的都是 Claude Code 的輸出。

  • 以上均為 AI 操作、唯讀分析,未修改功能、未執行 .NET 測試、未部署。各組提示不同,「加呼叫端」兩列使用同材料、各三次,但提示、工具與設定也有差異,只能比較兩套用法的觀察,不能單獨推論 skill 效果;引用的 Claude 回覆為原文節錄,重排格式。

官方文件

借鏡

實作材料

  • 配套 repo:Claude Code, Then What? → days/day09/lab-scope(唯讀實跑紀錄、規格與程式快照、八組布林核對)、days/day09/lab-intake(訪談實跑與 plugin)、templates/change-scope-card.md(開工卡空白版)。閱讀既有紀錄不需呼叫模型;重跑 runner 會消耗用量,輸出不保證相同。

上一篇
Day 8|我替 AI 出了考卷,結果錯的是我的答案
下一篇
Day 10|只改一個欄位,Claude 要先查哪些地方?
系列文
買了 Claude Code,然後呢? 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言