iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
Claude AI

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

Day 7|把工程師腦中的「為什麼」交給 Claude

  • 分享至 

  • xImage
  •  

規則、理由、來源,一起留下

上一篇把 intent、spec、plan 三份檔擺出來,第一份是「為什麼做」。Day 2 把它寫在啟動卡上,Day 4 把規則補進 CLAUDE.md 時,只寫了規則,理由留在我腦袋裡。今天回頭把它接進規則。

一條規則,兩種寫法

Day 4 我在 CLAUDE.md 加了一條不變條件:宣稱外部資源不可用之前,必須先實際呼叫並附上回傳。

那條規則有兩種寫法。一種只寫規則:「禁止未實測就使用快照」。另一種多帶一句理由:「因為未驗證的宣稱會帶著假前提通過驗收,而且沒有人會回頭查」。原始條文偏向前者;Day 4 正文交代了背景理由,但不能因此把那段敘述當成模型當時已讀到的輸入。

回頭看,我認為那一句理由的價值在這裡:理由可能幫 Claude 理解規則要保護什麼,也讓人比較容易核對它的判斷。 只寫「禁止用快照」,下次它真的連不上時,可能直接停住什麼都不交;帶了理由,它知道要防的是「假前提」,比較可能附上錯誤訊息、回報 blocked、讓人決定。

這是我的推測,兩種寫法的行為差異我還沒有對照測過;Day 9 會做一次固定條件的比較。今天先處理更基本的問題:理由寫下去之後,怎麼知道它真的被讀到、被用上。

我當時以為,規則寫進 CLAUDE.md 就夠了

Day 4 把退件要求寫進 CLAUDE.md,讓下一輪有規則可循。但寫了幾條之後發現,規則清單越長,越像一份沒有人記得為什麼的公司規範。

老工程師腦中的東西不是規則,是「為什麼」。他知道這條限制是三年前哪次事故留下的、哪個例外是業務部門特別要求的、哪條其實已經過期只是沒人敢刪。這些東西不寫下來,Claude 拿到的就是一堆沒有脈絡的禁止,遇到邊界只能猜。

這也是 /init 幫不上全部忙的地方。Anthropic 在 Using CLAUDE.md files 提醒,產生的檔案只是起點,仍要人核對與補上專案特有的做法。Claude Code 可以從程式整理「現在怎麼做」,但程式若沒留下決策背景,它就未必知道「當時為什麼這樣選」。理由卡要補的是這段落差,不是再抄一次程式。

為了看 Claude Code 能不能正確使用規則背後的理由,這次換一個招募情境:一位已被拒絕的候選人,能不能重新進入面試? 這是本篇另外設計的教學示範案例,不是前幾天訂單取消案例的延續。

這份教學規格的約定是:不能直接改回面試中,但如果有人明確提出重新開啟,而且取得授權,就允許例外。理由是保留原本的拒絕決定,同時留下有意識重啟的空間;「明確要求」與「取得授權」兩個條件都要成立。

接下來,我把這條規則和理由一起交給 Claude Code,看它會不會把「避免繞過拒絕決定」誤解成「一律不能重開」。如果它因此禁止所有重開,看起來像是在保護流程,卻正好違反明示的例外。

理由是幫助理解規則,不是取代規則。 規則、理由與目前程式不一致時,它應該回報衝突,不是挑一個最合理的版本自己決定。

理由不能把例外抹掉:明確要求與取得授權都成立,才允許重開面試

教學示意;「避免繞過拒絕決定」不能被推成全面禁止重開,仍須保留規格明示的兩個條件。

為什麼要放在哪裡

Anthropic 的 AI-native SDLC playbook 把「為什麼」放在整條線最上游的一份檔(它叫 intent.md:問題、期待成果、影響範圍、限制、待決問題),寫一次,由需求方簽核,後面的 spec 與 plan 都對回它。本篇把「為什麼」放在每條規則旁邊的 reason 欄,寫在用得到的地方。

兩種放法各有代價。上游一份檔,改規則時容易和它漂開,三個月後沒人記得哪條規則對哪個 why;規則旁邊寫,同一個 why 會在好幾條規則裡重複出現,過期時要一條條改。playbook 的做法適合一個功能從想法走到上線;理由卡適合一條規則要被反覆讀的場合,例如 Claude 每次任務都會碰到的不變條件。Day 2 的啟動卡比 intent.md 多了衡量與回看,少了影響範圍與待決問題,兩者不是同一張表。

接下來才是載入入口。CLAUDE.md 有專門的載入機制;一般 intent.md 與理由卡,不會只因檔名或放進 repo 就保證被讀到。本篇選擇在提示中指定讀取理由卡,讓輸入比較容易核對。

拆檔也不一定能省上下文。官方記憶文件 說明,CLAUDE.md@path 匯入會把內容一起載入;拆成五份再全部匯入,主要改善的是組織方式。若要避開無關資料,仍得安排什麼任務需要讀哪份文件。

一張理由卡長什麼樣

我把規則整理成這種格式:

id: RULE-01
scope: 已拒絕候選人進入面試的狀態檢查
rule: 禁止直接返回;明確要求且經授權的重新開啟才允許(兩個條件都要成立)
reason: 直接返回會繞過既有的拒絕決定;明確且經授權的重開代表有意識的例外處理
source: 本系列教學規則,非公司政策
version: demo-v2
unknowns: 真實授權來源、稽核儲存、其他狀態規則不在示範內,不得自行補上

每一欄都有用途。scope 防止把局部限制套到整個系統;reason 說明要保護什麼;source 讓 Reviewer 知道該向哪裡核對;version 讓人辨認採用哪一版規則;unknowns 避免 Claude 把沒提供的部分補成事實。

在正式專案裡,source 應該指向可追查的需求、決策紀錄或程式證據。如果只有資深同仁的口述,先記成「待確認的工作筆記」,不要假裝已經是正式規範。

官方提醒的幾個坑,這張卡也可能踩到

把理由留下來,不代表寫得越多越好。Anthropic 的 Context engineering 文章 建議提供足夠且相關的資訊,避免空泛指令,也避免把複雜邏輯全塞進提示。對照 Claude Code best practices 與記憶文件,我會用下面幾點檢查:

容易踩的坑 我會怎麼處理
CLAUDE.md 越補越長 問刪掉這句是否會讓任務缺少必要依據。官方建議每份以 200 行內為目標,不是超過就失效;理由先寫清楚一句,必要背景另附來源。
每條都加 IMPORTANT 只強調真正關鍵的限制,避免所有句子都在搶注意力。
重抄程式可直接看出的資訊 刪逐檔清單與通用規範,留下非直覺的架構取捨、例外與踩坑原因;必要的導覽仍可保留。
把文件當成強制防線 提示提供判斷背景;必須阻止的操作,交給權限、適當的 hook 或程式檢查。
檔案放好了,就認為 Claude 讀過 /context 查 Memory files 的載入情況,再核對交付;普通理由卡則查本次的讀取紀錄。

官方也建議把可重複的程序放進 skill,並指定文件維護者、像程式一樣審查修改。Steering Claude Code 的分工提醒我:CLAUDE.md 留共通背景,任務程序和詳細資料依需要使用。不要每次出錯就加一句禁止,卻不處理相互衝突的舊規則。

這些是官方建議與我的整理方式,是否適合上面那張卡,仍要回到實跑:先驗證它有沒有被讀到,再比較精簡前後。

但我怎麼知道它真的讀了?

我要交出去的是規則背後的理由。但在討論理由有沒有幫助之前,得先確認 Claude 真的拿到這份背景,而且沒有把規則與例外讀錯。寫進檔案、載入上下文、正確用在判斷,是三件事。

本篇用指定 Read 的方式核對理由卡,不把這段 trace 當成 CLAUDE.md 自動載入的證據。「我已經理解文件」這種自我評價也不算,還要看它實際引用了什麼、怎麼判。

我做了一次小實驗。獨立目錄放一張理由卡,卡片裡另外埋一個辨識標記 RULE-CONTEXT-7-KITE-0911,任務指令裡沒有這個值。要求 Claude 用 Read 工具讀這張卡,然後回傳 JSON:標記、規則編號、五個情境的判斷、採用的理由、還不知道的事。限制只讀這一份,不讀其他檔案,不自行補完未提供的系統行為。

執行用 claude -p,參數 --model sonnet --effort low --safe-mode --strict-mcp-config --tools Read --allowedTools Read:只開 Read 工具、不載入任何 MCP;提示要求只讀指定卡片,trace 再核對實際讀取。Read 本身仍能讀其他允許存取的檔案,工具限制不等於單一檔案白名單。trace 回報的模型識別是 claude-sonnet-5。後來,我用同一張卡、同一段指令再跑兩次。

三次結果都有同樣三段可以互相核對的證據:

執行 讀取證據 引用證據 判斷結果
第一次 1 筆 Read,工具回傳含標記 回答帶回標記與 RULE-01 五項皆符合規則
第二次 1 筆 Read,工具回傳含標記 回答帶回標記與 RULE-01 五項皆符合規則
第三次 1 筆 Read,工具回傳含標記 回答帶回標記與 RULE-01 五項皆符合規則

讀到的檔案。 trace 裡有一筆 Read 工具呼叫,工具回傳的內容包含那個標記。

回覆中的引用。 最終 JSON 帶回同一個標記與 RULE-01。標記不在指令裡,它只可能來自讀到的卡片。

具體判斷。 五個情境依序:

直接返回                 → false
有要求、沒授權           → false
有授權、沒明確要求       → false
有要求、也有授權         → true
非拒絕狀態               → true(只代表這道 guard 不阻擋)

三次十五項全部符合預先固定的答案,三次 trace 都只有一筆 Read、工具回傳都含標記、回覆都帶回標記與 RULE-01。理由那段三次用字不同,意思相同:只有兩個條件同時成立,才構成刻意進行的例外,而不是無紀錄的繞過。未知那段都列了真實授權來源、稽核、其他狀態規則沒有提供,沒有自己編。

第一次跑的時候 API 連線被拒,用量為零,那次保留但不算成模型答錯。

我還做了一組負對照:同一張卡放在目錄裡、同一段指令,但 --tools "",一個工具都不給。兩次都是 1 回合、不到兩秒、exit code 0;trace 裡沒有任何工具呼叫,回覆裡沒有標記、沒有 RULE-01、沒有 JSON。它交回來的是「Read tool call」這幾個字,第二次多了一段「我需要實際呼叫 Read 工具才能回答」。它沒有憑空編一個標記,這是好消息;但 exit code 0、有回覆,內容卻是一句假裝在呼叫工具的話。只看退出碼和「有沒有回答」的流程,會把這兩次記成成功。三段核對裡的第一段「trace 有沒有 Read」,就是擋這種情況的。

有無 Read 工具的實跑對照:退出碼正常,仍須核對讀取與交付證據

依本文有工具與無工具實跑整理的示意圖,非操作截圖;這裡比較交付是否具備證據,不代表理由寫法的效果。

照官方建議精簡,再跑一次看看

官方說要精簡,我沒有另外造一份很差的長文件來陪跑。原英文卡片本來就只有七行;這次保留規則編號、標記、版本、適用範圍與未知事項,只縮短規則和理由的重複敘述。例如:

欄位 修改前(中文意譯) 修改後(中文意譯)
規則 禁止從已拒絕直接返回;明確且經授權的重開,只有兩個條件都成立才允許;非拒絕狀態不在此檢查範圍 已拒絕時,只有明確要求且取得授權才允許;其他狀態由這道檢查放行
理由 直接返回會繞過拒絕決定;明確且經授權的重開記錄有意識的例外 避免繞過拒絕決定;允許有意識、明確且經授權的例外

上面的中文理由卡是教學展示;歷史英文實跑卡沒有獨立的 source 欄。本次把教學來源留在實驗說明,沒有為了補欄位改動原件,也沒有替精簡版添加新規則。兩版沿用同一規則版本,另以原版、精簡版區分措辭。

我在新 session 交錯跑兩版,各三次。CLI 為 2.1.277,指定 claude-sonnet-5、low effort,六次 trace 的模型識別一致;提示、五個情境與工具設定固定,先定好答案再執行。沿用 --safe-mode,停用包含 CLAUDE.md 在內的自訂載入,讓這次比較集中在指定 Read 的卡片。

核對項目 原版 精簡版
英文卡片長度(含換行,非 token 數) 537 字元 416 字元
Read 回傳含標記,回答帶回標記與規則編號 3/3 次 3/3 次
五項判斷符合預先答案 每次 5/5 每次 5/5
保留授權來源、稽核、API 與其他規則未知 3/3 次 3/3 次
回答明說避免繞過拒絕/有意識的例外(人工核對) 2/3 次 2/3 次

卡片縮短了,這五個情境的判斷沒有變化;沒有觀察到退步,也沒有觀察到提升。 最後一列是事後人工閱讀,不是預先訂好的評分指標:兩版各有一次理由欄只重述條件,沒有明說條件背後要保護什麼。答案全對,不保證理由被完整解釋。時間與費用都有保存,但六次的快取與回答長度不同,不拿差額宣稱省成本或省工時;這也不是「有理由/無理由」實驗。精簡不是把字刪少,而是辨認哪些背景不能刪,再確認刪完沒有把例外一起刪掉。

這次證明了什麼,沒證明什麼

證明的是:明確要求讀檔之後,Claude 能在這個小任務裡引用並應用那條規則,三次都是,而且讀檔、引用、判斷三段可以交叉核對。 這比「我讀過了」好檢查得多。

沒證明的是自動載入。這次是明確叫它 Read;CLAUDE.md 在 session 開始時的自動讀取有沒有同樣效果,是另一個問題,Day 13 處理。也不能把一次正確回答當成「理由讓模型變好」的因果證明。這張卡把「兩個條件都要成立」寫得很白,Day 9 的實驗輸入沒寫這麼白,兩篇的分數不能互比。精簡那一輪加上去的只有一句:卡片短了 121 字元,這五個情境的判斷沒有變化;沒有觀察到退步,也沒有觀察到提升。

卡片之外:資料跟著任務選,規則也要定期回看

這次任務只處理一個狀態判斷,我給的就是那條規則、目前的函式、五個情境。薪資計算、部署流程、其他模組的文件再重要,對這件事沒幫助。

依任務選相關資料,再確認規則來源、版本與複查責任

概念示意,非執行截圖;只帶本次判斷需要的背景,並由人確認規則來源與適用版本。版本號本身不等於有效期限。

選資料的標準是「它能不能改變這次判斷」,不是「它存在於知識庫」。資料不足就補,來源衝突就停。這比要求模型「自己看完整個專案」更容易知道它缺了什麼,出問題時也更容易追是哪一段背景沒給。

一條規則可能曾經正確,後來流程改了。versionsource 就是為了讓人有機會發現這件事。更新時保留原理由與變更原因,標清新版本的適用範圍。不是讓舊規則永遠存在,是讓下一個人知道為什麼現在做法不同。

這裡的管理工作是:決定哪些知識值得變成可重用的依據、誰能確認、衝突時怎麼處理。工具幫忙整理,責任還是要有人接。

如果你只有一個人:今天就做一張卡

一個人也會忘記為什麼。三個月前自己寫的那條「不要動這個設定」,現在還記得原因嗎?

先做一張卡就好。挑一條你最常對 Claude 重複講的限制,填上七欄,放進 repo。埋一個只有卡片裡有的標記,下次任務要求它回傳那個標記。回傳了,再核對標記是否只存在於卡片、trace 是否有對應讀取;沒回傳則查工具結果與最終回答,可能沒讀,也可能讀了卻漏答。單靠標記缺失,還不能診斷原因。

一段可以直接貼進 Claude Code 的提示(操作範例,不是歷史實跑的原文;情境與預期答案要自己給,跑完照下面三件事核對):

請讀取 rule-card.md,依卡片判斷我提供的情境。
回覆規則編號、卡片標記、各情境判斷與依據。
未提供的授權或業務規則請列為未知,不要自行補上。

本文的卡片、指令、trace 與回覆已保存,公開附件仍在整理;開放狀態見文末。重跑會呼叫 Claude、消耗用量,不保證輸出逐字相同。

跑完看三件事:trace 裡有沒有 Read 的工具呼叫,工具回傳裡有沒有標記;回覆裡有沒有同一個標記;五個判斷對不對。三段都對上,才算「讀了也用了」。如果回覆有標記但 trace 沒有 Read,那是警訊。它從別的地方拿到了,可能是你的指令漏了,可能是有別的檔案被讀進來。

回到一開始:把「為什麼」交給 Claude Code

  • 為什麼可以放上游一份檔,也可以放規則旁邊。 各有代價;要安排載入或讀取入口,並核對實際使用情況。
  • 理由卡留下規則、原因、來源與版本,讓下一次工作有可核對的依據;/init 整理出的起點,仍需要人補上決策背景。
  • 文件精簡後也要重跑。 本次兩版判斷相同,但理由說明仍有缺漏;短不是目的,必要背景與例外不能丟。
  • 讀取紀錄、引用內容與實際判斷要分開核對。 標記本身不足以證明正確使用;三次全對只支持本次情境的結果,不是理由讓模型變好的證明。
  • 有無工具與精簡前後,是不同的比較。 本篇沒有「有理由/無理由」對照,不能據此宣稱理由改善了判斷。

還有一個更尷尬的問題。這次我準備的五個答案是對的,所以能拿來評 Claude。如果我準備的標準答案本身就錯了呢?


參考資料:

本文實作說明

  • 教學示範案例: 候選人重新進入面試的規則為教學設計,非公司政策;Claude Code 的讀卡與判斷有實際執行。Day 4 的查證規則來自作者真實工作,但本文兩種理由寫法的行為差異仍是推測。
  • 讀取驗證: 保存三次讀卡實跑與兩次不提供工具的負對照,核對 Read、辨識標記與五項判斷。首次連線失敗不計為模型答錯;回合、時間與費用取自執行紀錄,費用為 CLI 估值。
  • 精簡比較: 另開六個新 session,原版與精簡版各三次。兩版判斷皆符合預期,但各有一次未明說理由背後的目的;後者是事後人工觀察。結果不代表理由的因果效果、自動載入成效或團隊省時。

配套 repo 已建立:Claude Code, Then What?。本篇實驗附件整理中,公開後補上可核對及重跑的直接連結。

方法參考


上一篇
Day 6|別再猜我要什麼,先約好怎樣才算完成
系列文
買了 Claude Code,然後呢?7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言