把 CLAUDE.md 當憲法寫:禁忌、行為指令、預設決策。5 天 92 commits 不偏航。
我用 5 天寫了 92 個 commit,做出一個上線的產品(github.com/defi-io/smarts)。中間沒翻車、沒回滾、沒大重構。能做到這件事,靠的不是 Claude 多聰明,靠的是專案根目錄那份 565 行的 CLAUDE.md。
這篇講一份能當憲法用的 CLAUDE.md 該怎麼寫、寫完之後會發生什麼。
很多人把 CLAUDE.md 寫得跟 README 差不多——介紹專案是什麼、怎麼跑起來。這是浪費。
README 是給人看的,CLAUDE.md 是給 Claude 看的。Claude 每次開 session 會自動載入它。這意味著你寫進去的每一句話,會成為它接下來所有決策的前置約束。
當 README 思路寫 CLAUDE.md,你得到的是:Claude 知道專案大概是什麼、知道怎麼跑測試,但每次它做技術選擇都是從零判斷。
當憲法思路寫 CLAUDE.md,你得到的是:Claude 知道哪些路不能走、哪些約定必須遵守、遇到分叉預設走哪邊、什麼情況下要停下來問。
差別是:前者會「順手」幫你引入一個新依賴、加一層抽象、改一下 Gemfile;後者不會。
我最近做的專案叫 smarts.md,一個為智能合約產生 live docs 和 MCP server 的平台。CLAUDE.md 565 行,分成這幾塊:
1. 專案身分(5 行)
2. 產品核心(一句話定義 + 與競品的結構性差異)
3. 技術棧(硬性約束,YAML 格式)
4. 禁忌(明確的 ❌ 列表)
5. 支援範圍(MVP 硬邊界)
6. 架構(含 ASCII 圖)
7. 目錄結構(含每個檔案的職責)
8. Ruby 編碼約定(含正反例程式片段)
9. 快取策略(表格)
10. 測試要求
11. 部署細節
12. Git 工作流
13. Claude Code 使用約定(行為指令)
14. 90 天里程碑
15. 核心原則
每一塊都不是裝飾。下面挑幾塊講清楚為什麼要這麼寫。
我的禁忌列表長這樣:
❌ 不引入 TypeScript / Node.js 服務
❌ 不引入 ethers.js / web3.js
❌ 不引入 Sidekiq(用 Solid Queue)
❌ 不引入 React / Vue / Svelte(用 Hotwire)
❌ 不引入 Redis(用 Solid Cache / Solid Queue / Solid Cable 全覆蓋)
❌ 不做未驗證合約(只接受 Etherscan 已驗證)
❌ 不做 Solana / Bitcoin / Move 系(僅 EVM)
這是個 Web3 專案。Web3 圈預設 TypeScript + ethers.js + Redis + React。我反著來,理由我自己有,但 Claude 不知道。如果不寫禁忌,Claude 會基於訓練資料裡的「業界共識」給你建議——很可能就是 TypeScript 那條路。
寫了禁忌之後,Claude 不會再問「要不要加個 Node 服務跑 web3.js」。它預設這條路被堵死。
禁忌的關鍵:每一條都要 明確 和 絕對。不要寫「盡量不要用 TypeScript」,要寫「不引入 TypeScript」。模糊會被 Claude 當作可商量。
CLAUDE.md 最後一大塊是「Claude Code 使用約定」,長這樣:
### 當我說「開始做 X」時
1. 先檢查 CLAUDE.md 的約束是否允許這個做法
2. 再檢查現有程式中是否有相關實作(不要重複造輪子)
3. 寫程式前先開一個新 branch
4. 實作完成後跑測試
5. 不要自動 git commit——改動寫完、測試跑綠後停下來回報,
等我明確說 "commit" 再提交
### 當我說「我有個想法」時
不要立刻寫程式。先:
1. 確認理解正確(複述一遍)
2. 評估是否符合 CLAUDE.md 約束
3. 指出潛在問題或更好的替代方案
4. 等我確認再動手
### 當遇到技術選擇分叉時
CLAUDE.md 沒有明確規定時:
1. 預設選「更 Rails 原生」的方案
2. 預設選「更少依賴」的方案
3. 預設選「能讓一人開發者更快迭代」的方案
4. 不確定時停下來問我
這部分比「用 snake_case 命名」重要十倍。
程式風格 Claude 看程式就能學。但「什麼時候該停下來問」、「聽到『我有個想法』要先複述確認而不是立刻寫程式」——這些是行為模式,光看程式學不到。
最關鍵的一條:預設行為遇到分叉時往哪走。這條決定了 Claude 在你不在場時(比如你只說「開始做 X」就走開)會做什麼。寫清楚這條,你就敢放手讓它幹活。
CLAUDE.md 開頭有一行:
這份文件是專案的「第一源」。每個 Claude Code session 開始時會被自動載入。修改技術決策時,先改這裡,程式再跟進。
這是個工作流約定。當我決定要換某個技術選擇,比如把主力 AI 模型從 gpt-5-mini 切成 gpt-5,第一步不是改 initializer,是改 CLAUDE.md 裡那一段:
ai:
fast: gpt-5-mini # 之前
fast: gpt-5 # 改完
改完之後再讓 Claude 順著 CLAUDE.md 改程式。
為什麼?因為程式裡的某個值改了、CLAUDE.md 沒跟上,下次 Claude 看 CLAUDE.md 還是舊的,它會「好心」把程式改回去。衝突的根源是單點失效——CLAUDE.md 是憲法,憲法落後於現實就會引起內亂。
把 CLAUDE.md 當憲法的關鍵含義:它永遠跑在程式前面。
smarts.md 這個專案,5 天 92 commits,包括:
每個 PR 平均壽命 30 分鐘。沒有大重構、沒有「剛才那個方向不對,回滾」。
不是因為 Claude 神。是因為它每次開 session 都在 565 行的軌道上跑。它知道不能引入 TypeScript,知道 Solid Queue 是預設佇列,知道 view 函數快取 60 秒,知道每個 service 要實作 call 類別方法,知道 commit 前要等我確認。
這些約束去掉一半,你會得到:每天花 30 分鐘解釋「為什麼不能用 X」、5 分鐘 review「順手」加進來的依賴、一個崩壞的 Gemfile。
不要從空白檔案開始。從你最痛的那個決策開始。
如果你最近被 Claude 折騰的事情是「老引入新依賴」,寫禁忌列表。
如果是「動不動就改架構」,寫架構圖 +「新增微服務、換資料庫等需要確認」。
如果是「測試不寫」,寫「必須單測的部分」。
如果是「提交太激進」,寫「不要自動 git commit,等明確指示」。
每痛一次,加一條。別的暫時不寫。
3 個月之後你會有一份 500 行的 CLAUDE.md,每一行背後都是一次具體的「我不要它再這麼幹」。這份文件比任何範本都有用,因為它精確對齊你這個專案、這種工作流、這個團隊(即使只有一個人)的真實約束。
憲法不是一次寫好的。是一次次具體衝突結晶下來的。