目錄
1 分鐘閱讀 2026

使用 Claude Code 和 Codex 之前,先建立三個規格檔案

我花了一年時間從 Claude Code 和 Codex 得到反覆無常的結果。三個職責分明的規格檔案解決了這個問題。

用 AI 編程代理幾乎每天工作將近一年,困擾我的不是幻覺程式碼或呼叫錯誤的 API,而是結果的不一致性。同樣的任務,措辭稍有不同,某天跑出來乾淨俐落,隔天卻一塌糊塗。會話越長情況越差,因為代理會把二十條訊息之前達成的共識忘得一乾二淨。

根本原因是結構性的。我沒有一套跨會話向代理傳達意圖的框架,所以每次對話都從零開始,漂向難以預測的方向。

改變結果的三個層次

把指令拆分成三個職責分明的檔案,一致性問題幾乎在一夜之間得到了解決。

第一層 CLAUDE.md 在每次會話時自動載入。它存放專案層級的常數:建置命令、技術棧版本、目錄結構、編碼規範,以及行為邊界(必須做、先確認再做、絕對不做)。

第二層 SPEC.md 記錄某個具體功能的「做什麼」和「為什麼做」。目的、需求、成功標準、技術限制、範疇邊界。不涉及任何實作細節。

第三層 plan.md 將規格拆解成每個耗時兩到五分鐘的可執行任務,附上明確的檔案路徑、測試優先的執行順序,以及提交檢查點。

把所有東西塞進一個檔案為什麼行不通

研究 LLM 指令跟隨能力的論文把這個現象稱為「指令詛咒」(Curse of Instructions)。單一脈絡中的指令數量越多,模型對每條個別指令的遵守率就跌得越厲害。我親自驗證過:把專案規則、功能規格、任務清單全塞進一個檔案,代理大約忽略了後半段將近一半的指令。

按職責分離解決了這個問題。代理從第一層讀取全域規則,從第二層讀取功能意圖,從第三層讀取執行步驟。每個檔案都短到足以讓模型完整關注。

CLAUDE.md 保持精簡效果最好

由於這個檔案在每次會話都會載入,它只需要包含普遍適用的內容。建置命令、棧版本、目錄結構、命名規範。加上三階行為邊界:必須做、先確認再做、絕對不做。

效果最好的做法是從最小化開始,每當發現代理反覆犯同一個錯誤時再增量新增規則。一開始就試圖寫出面面俱到的 CLAUDE.md,反而會導致臃腫,觸發我本想避免的遵守率下降。

幾個具體的陷阱:不要把 API 金鑰或程式碼片段放進來,它們會很快過期。不要重複 linter 已經在強制執行的規則。把任何只針對單一功能的內容移入第二層。

規格檔案專注於「做什麼」和「為什麼」,把「怎麼做」留給代理

與傳統 PRD 的差異在於,這些規格是為代理消費而結構化的。五個部分就夠了:目的、需求、成功標準、技術限制、邊界。

把實作決策交給代理。它可以分析現有程式碼庫,選擇合適的方案。當我試圖規定「怎麼做」時,代理要麼盲目照做導致與現有模式衝突,要麼直接無視。

手寫規格之外的另一種方式:讓代理來訪問你。設定兩條規則,每次只問一個問題,盡量用選擇題。這樣產出的規格,比我自己從頭寫的版本遺漏更少。

把完成的規格存到 docs/specs/YYYY-MM-DD-topic.md 並提交到 Git。這樣代理可以透過 git diff 追溯規格變更歷史,程式碼審查者也有了一份記錄程式碼變更背後意圖的文件。

會話分割是最容易被忽視的做法

規格撰寫過程中的腦力激盪和問答消耗了大量的脈絡視窗。從同一個會話直接跳入實作,意味著代理會逐漸失去對早期脈絡的存取能力。

我把工作重組成三個會話:會話 1 產出 SPEC.md,會話 2 建立 plan.md,會話 3 起逐條執行任務。準確度的提升在第一週內就感受得到。

讓這套方法發揮作用的三個習慣:在每個任務裡寫明確的檔案路徑,讓代理不再猜測;把 TDD 順序(測試、實作、驗證、提交)固定在 plan.md 裡;以及脈絡使用量達到大約 50% 時開啟新會話。

成熟度模型指向「規格即來源」

Martin Fowler 的團隊最近定義了一套基於代理的軟體開發成熟度模型,分三個層級。層級一:寫規格、實作、丟掉規格。層級二:把規格作為與程式碼並行演進的活文件來維護。層級三:規格成為唯一事實來源,程式碼是生成的產物。

我認識的大多數團隊和個人還沒到層級一。他們發一次性提示詞,然後期待結果。

從層級一升到層級二只需要一個習慣:把規格檔案提交到 Git。從層級二升到層級三意味著在改程式碼之前先更新規格。今天能邁出的最小一步,是為你的專案建立一個 CLAUDE.md,並在下一個功能開始前寫一份 SPEC.md。

訂閱電子報

獲取關於我最新專案、文章以及 AI 和 Web 開發實驗的更新。