用 Claude Code 開發的完整工作流設計
用 AI 寫程式不難,難的是讓它在第十個 session 還記得第一個 session 的決策。這篇記錄我怎麼設計一套文件系統,讓 AI 跨 session 保持一致,同時控制記憶空間的消耗。
用 Claude Code 開發的完整工作流設計
你開了一個新的 Claude Code session,跟 AI 說「繼續做昨天的報表匯出功能」。
AI 回你:「好的,請問報表匯出功能的規格是什麼?」
你昨天花了半小時跟它討論規格、確認 API 格式、決定用 CSV 而不是 PDF。今天全部忘了。因為每個 session 是獨立的,AI 的記憶不會跨 session 保留,即便用了 /resume 也有可能因為 context 壓縮而遺失記憶。
這就是用 AI 寫程式最大的問題: 不是它不夠聰明,是它記不住。
我參考了許多工作流後設計了一套系統,讓 AI 在每個 session 開始時就知道: 專案架構長什麼樣、現在做到哪、之前做了什麼技術決策、這個功能的介面規格是什麼。
這個工作流適合一人開發,想要對專案有一定掌握度,不追求極致 agentic 協作的朋友。
開發流程全貌
先看整個流程長什麼樣,後面逐步解釋每一步為什麼這樣設計:
┌─────────────────────────────────────────────────┐
│ /project-init │
│ 輸入你的目標 → 生成 SPEC.md + DECISION.md │
│ → subagent review → 你確認 │
└──────────────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────────────┐
│ Session 開始 │
│ hook 自動注入 [SPEC] 當前功能 │
│ agent 讀 Architecture + DECISION (各一次) │
│ 宣告「準備實作 FXXX-TXX」→ 你確認 │
└──────────────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────────────┐
│ 開發中 │
│ 寫 code → build 驗證 → Edit SPEC 標 [x] │
│ 改介面前 Grep 查引用 → 第三方 API 先驗證 │
│ ┌───────────────────────┐ │
│ │ 需求變動? → [PAUSE] │ │
│ │ 裝套件? → [PAUSE] │ │
│ │ 超出範圍? → [PAUSE] │ │
│ └───────────────────────┘ │
└──────────────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────────────┐
│ 功能完成 (驗收條件全 [x]) │
│ spawn Code Reviewer subagent → review 改動 │
│ 有問題 → 修 → 沒問題 → 等歸檔 │
└──────────────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────────────┐
│ 歸檔 (累積 3 個完成功能, hook 提醒) │
│ 你確認 → 搬到 SPEC-archive.md → SPEC 變短 │
└──────────────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────────────┐
│ Session 結束 │
│ 未完成 → handoff note (做到哪, 試過什麼) │
│ 有新決策 → 寫入 DECISION.md │
│ /compact → 先寫 DECISION, 壓縮後重讀架構+決策 │
└─────────────────────────────────────────────────┘
第一步: 用 /project-init 建立專案文件
整套系統只靠三個 markdown 檔案。在你開始寫任何一行 code 之前,先跑 /project-init 建立它們:
SPEC.md -- 專案的全貌。頂部放架構(tech stack, route 結構, data flow),下面是每個功能的規格、驗收條件、和任務清單。AI 每次開 session 就讀這個檔,知道專案長什麼樣、現在該做什麼。
DECISION.md -- 技術決策的記錄。「為什麼用 Supabase 不用 Prisma?」「為什麼 auth 用 API key 不用 session token?」這些跨 session 的決策寫在這裡,避免不同 session 的 AI 做出矛盾的選擇。
CLAUDE.md -- 專案的指令列表(怎麼 build, 怎麼 dev, 怎麼 deploy)。這個每個 session 自動載入,不用手動讀。
為什麼只要三個檔案? 我一開始用的是傳統的 PRD(規格文件) + TODO(任務清單)分開的做法。但分開會造成雙來源同步問題: 完成一個功能要改兩個檔案三個地方(任務標完成 + 規格目錄標完成 + 規格章節標完成)。AI 忘記同步的機率大約 15%。合成一個 SPEC.md,改一個地方就好,同步問題直接消失。
為什麼 Architecture 放在 SPEC.md 而不是 CLAUDE.md? 因為架構會隨功能開發而變(加了新的 route group, 改了 data flow)。放在 SPEC 裡,改架構跟改功能在同一個檔案,自然保持同步。CLAUDE.md 放的是不常變的東西(build 指令, deploy 指令)。
/project-init 會根據你的專案狀態自動選擇模式: 全新專案根據你的目標生成文件,既有專案分析 codebase 推斷,已有文件的跑健康檢查。生成完會 spawn 一個獨立的子代理 review SPEC 的品質(驗收條件可測試嗎? 功能規格完整嗎?),修正後給你確認。
第二步: Session 開始時自動載入 context
每次你開一個新的 session,AI 需要知道三件事: 現在做到哪(SPEC 進度)、專案長什麼樣(Architecture)、之前做了什麼決策(DECISION)。
手動交代太慢,也容易忘。所以我用了兩個機制:
Hook 自動注入: 一個 30 行的 bash 腳本,每次你送出對話時在背景自動跑。它掃 SPEC.md 找到目前進行中的功能,把摘要注入到對話裡:
---
[SPEC] ## F003 Blog 系統
驗收: 2/4 完成
- [x] F003-T01: 建立列表頁
- [ ] F003-T02: 建立文章頁
- handoff: markdown 渲染完成,TOC 還沒做
---
AI 看到這段就知道一切。不需要你口頭交代。
為什麼有快取機制? 這個腳本每次對話都跑。但一個 session 大約 30 次對話,只有 3-5 次進度真的變了(完成了一個任務)。其他 25 次注入的是一模一樣的內容。所以腳本會比對這次和上次的內容 hash,一樣就跳過。省了大約 80% 的注入消耗。
為什麼 DECISION 不用 hook 注入? 技術決策在一個 session 裡不會變。如果每次對話都注入,30 次 × ~200 tokens = 6000 tokens 浪費在重複內容。改成 session 開始時 AI 自己讀一次就好。
第三步: 開發中的防護機制
寫 code 的過程中,最怕 AI 做了你沒叫它做的事: 自己裝套件, 順手重構無關程式碼, 改了一個函式但沒注意到其他地方也在用。
光靠在設定檔裡寫「不要這樣做」不夠。我量化了 15 條規則的實際遵守率:
| 防護層 | 遵守率 | 例子 |
|---|---|---|
| 文件裡寫的規則 | 50-90% | 「不要重構沒叫你改的程式碼」 |
| 自動化腳本 | 95-99% | 自動注入進度、自動檢查文件一致性 |
| 權限系統 | 100% | 「禁止 git push」直接擋掉 |
為什麼要三層? 因為 AI 讀了規則不代表會遵守。壓力大的時候(任務複雜, context 快滿)它會忽略「建議」,但不可能繞過「系統限制」。所以重要的規則往上推: 從文字建議 → 自動化腳本 → 權限擋死。
幾個具體的防護:
- 改對外介面前先查引用: 改了一個 exported function 的參數,如果有 5 個檔案在用它,不先查就會漏改。規則: 改任何對外介面前,先用 Grep 查引用(只看匹配的行,不讀整個檔案)。
- 第三方 API 先驗證: 使用外部 API 時,先實際打一次確認回傳格式。不要憑印象猜規格,猜錯了後面全部要重做。
- 需求變動要暫停: AI 做到一半如果發現「這好像跟規格矛盾」或「這需要裝新套件」,必須停下來讓你決定,不能自己 assume。
第四步: 完成任務時的驗證
AI 說「做完了」不代表真的做完了。Anthropic 的工程團隊發現: AI 評估自己寫的 code 時傾向稱讚,即使品質有問題。
所以完成驗證有兩個層面:
可執行的驗證: 不能只靠 AI 判斷「應該沒問題」。必須 build pass, curl API 確認回傳, 或跑測試。驗證通過才能標 SPEC.md 的任務 [x]。
標記的效率: 標完成只是改 SPEC.md 的一行 [ ] → [x]。在 Claude Code 裡,Edit 工具只送改動的那幾行(~60 tokens),比覆寫整個檔案(~200+ tokens)便宜很多。如果這個任務之前有未完成的 handoff 記錄,用同一次 Edit 一併刪除,不要分兩次(每次 Edit 都有固定成本)。
第五步: 功能完成後的 Code Review
一個功能的所有驗收條件都打勾後,不是直接歸檔。先做獨立 review。
為什麼用子代理而不是 AI 自己 review? 因為 AI 不擅長 review 自己的產出。用一個沒寫過這段 code 的獨立 Code Reviewer 子代理來檢查,更容易找到遺漏。而且子代理讀檔案的過程不會吃你主對話的記憶空間,只有最終的 review 結果(~300 tokens)會回來。
review 完有問題就修,嚴重的停下來讓你決定。
第六步: 歸檔
做了 10 個功能後 SPEC.md 會很長。AI 每次啟動都要掃過所有已完成的功能,但它們不會再被修改,只是佔空間。
歸檔就是把完成的功能搬到 SPEC-archive.md,讓 SPEC.md 只保留進行中的工作。
為什麼累積 3 個才歸檔? 歸檔本身有成本(讀 SPEC + 搬內容 + 刪原本的 ≈ 1400 tokens)。如果每完成一個功能就歸檔,做 10 個功能歸檔 10 次。累積 3 個再歸檔,只歸檔 3-4 次。歸檔成本是一次性的,之後每個 session 都因為 SPEC 變短而省回來。
歸檔的觸發不靠 AI 記憶。一個自動化腳本(validate-docs.sh)在每次改 SPEC.md 後自動計算有幾個完成的功能,累積到 3 個就提醒你。
第七步: Session 結束時的交接
session 結束有兩種情況:
任務未完成: 在 SPEC.md 的任務下方加一行 handoff -- 做到哪了、試過什麼、下次從哪裡接。下次 session 開始,hook 會自動找到有 handoff 的任務優先注入。AI 不需要從頭摸索。
有新的技術決策: 開發過程中做了重要選擇(選了某個 library, 用了某種 pattern, 踩了某個坑),寫進 DECISION.md。下次 session 的 AI 讀到就知道為什麼這樣做,不會走回已經踩過的坑。
記憶壓縮 (/compact): Claude Code 的 /compact 會壓縮記憶釋放空間。壓縮後 AI 可能忘了一些東西。但問題是: 它不知道自己忘了什麼(因為已經忘了)。所以規則不是「如果忘了就重讀」,而是「壓縮後一律重讀架構和技術決策」。多花 ~500 tokens,但保證不出錯。
省記憶空間的設計
以上每個步驟都在問一個問題: 這個操作吃多少記憶空間? 有沒有更省的做法?
整理幾個關鍵的設計:
| 設計 | 省了什麼 | 為什麼有效 |
|---|---|---|
| Hook 注入帶 cache | 每次對話 ~150 tokens → 只在狀態變時注入 | 30 次對話只有 3-5 次有效注入 |
| DECISION 讀一次不重複注入 | 每 session 省 ~5800 tokens | 技術決策在 session 中不會變 |
| Edit 而不是 Write | 每次標 [x] 省 ~140 tokens | Edit 只送 diff, Write 送全文 |
| 歸檔完成功能 | SPEC.md 不會無限增長 | 1400 tokens 一次性成本, 之後每 session 省回 |
| 壓縮後一律重讀 | 多花 ~500 tokens | 比「忘了但不知道忘了」導致的錯誤決策便宜 |
整個工作流佔一個 session 記憶空間的 15-25%。剩下的 75-85% 留給你實際在寫的程式碼。
這套系統的代價和限制
不是零成本。每個 session 的工作流開銷:
| 操作 | 消耗 |
|---|---|
| Session 啟動(讀架構+決策) | ~700 tokens |
| 每完成一個任務 | ~110-410 tokens |
| 一個功能的 code review | ~700 tokens |
| 歸檔 3 個功能 | ~1400 tokens |
| 記憶壓縮後恢復 | ~600 tokens |
也有它不能解決的問題: AI 改了一個函式但沒注意到動態引用(grep 找不到的),或者 agent 對「這算不算超出範圍」的判斷跟你不同(遵守率 ~50-70% 的規則)。
但這些不完美是可以接受的 trade-off。換來的是: AI 跨 session 記得你的決策、知道專案架構、自動追蹤進度、完成後有獨立 review。
用 AI 寫程式不難。難的是讓第十個 session 的 AI 跟第一個 session 的 AI 做出一致的決策。這套系統解決的就是這件事。
