Claude Code 不照 CLAUDE.md 做?問題出在傳遞機制,不是你的規則寫太少(2026)
Claude Code 的作者 Boris Cherny 在一篇被轉發 8 百萬次的推文裡說,他自己的 CLAUDE.md 設定是「surprisingly vanilla(出乎意料地簡單)」。
這件事讓我想了很久。我們在 Shareuhack 跑著一個由 8 個 autonomous agent 構成的內容系統,CLAUDE.md 超過 300 行,還有獨立的 skill 目錄和 per-agent operational memory。這樣的複雜度對一般開發者來說值得嗎?而那些一直在 CLAUDE.md 裡堆規則、但 Claude 還是不照做的人,問題到底出在哪?
這篇文章的答案讓很多人出乎意料:指令被忽略不是 bug,是你需要理解的設計。知道機制之後,你會發現大多數人一開始就跑錯方向了。
時效聲明:本文基於 2026 年 5 月的 Claude Code 官方文件和社群實踐(最新版本 v2.1.126,2026-05-01 發布)。Claude Code 更新頻繁,具體 API、hooks 語法、設定結構可能隨版本變動,建議搭配 Anthropic 官方文件使用。
TL;DR
- 規則一直被忽略? CLAUDE.md 是以用戶訊息傳遞,不是系統設定。Claude 會自行判斷相關性,跟當前任務無關的規則可能直接跳過,這是設計,不是 bug
- 想要 100% 強制執行? 把機械性規則搬到
hooks(shell 層級,不過 LLM 判斷)。CLAUDE.md 只留隱性知識和架構脈絡。安全阻擋用settings.json。2026 年 4 月新增的 hooks 條件式if欄位和mcp_tool類型讓 hooks 更精準實用 - 不知道該寫什麼? 從
/init開始,然後砍掉 Claude 從程式碼看得出來的東西。50 行寫真正 Gotchas 的 CLAUDE.md,比 300 行明顯常識更有效(研究證實:寫差了比不寫更糟)
「指令被忽略」不是 bug:你需要知道的傳遞機制
先說最多人搞錯的一件事。
CLAUDE.md 的內容是以「系統提示詞之後的用戶訊息」方式傳遞給 Claude,而不是強制執行的系統層級設定。這意味著什麼?Claude 會自行判斷 CLAUDE.md 的內容與當前任務的相關性,如果判斷不相關,它可能會忽略。GitHub issue #18660 的社群討論明確指出:「Claude 承認規則的存在,但 task completion 的優先順序高於 process compliance。」
這不是一個可以用「寫更多規則」解決的問題。
更關鍵的是指令均勻退化的機制:根據 HumanLayer 的分析和多個社群開發者的觀察,LLM 可靠遵循的指令上限大約在 150-200 條(這是社群估算,非官方數據),而 Claude Code 本身的系統提示詞估計佔用約 50 個配額,留給 CLAUDE.md 的預算實際上只有 100-150 條。超過這個數量之後,退化是均勻分佈的,每加入一條低價值規則,所有高價值規則的遵守機率都被均勻稀釋。
重要提醒:「200 行上限」是社群共識(由 HumanLayer 和多個 Reddit 高票討論印證),不是 Anthropic 官方的硬性規定。沒有「CLAUDE.md 超過 201 行就會崩潰」這種硬邊界,但退化的趨勢是真實的,而且官方也建議保持在 200 行以內。
Token 成本補充(給用 Claude API 付費的開發者):CLAUDE.md 每 100 行約消耗 500-800 個 tokens,每次 session 開啟時完整載入,不是增量扣費。100 行的 CLAUDE.md 在 Claude Sonnet 4.6 大約每次多消耗 $0.0003-$0.0006,不是大錢,但如果你的自動化 agent 每天跑幾十次,這個數字會累積。值得注意的是,2026 年 4 月發布的 Claude Opus 4.7 使用了新的 tokenizer,相同輸入文字可能產生多達 35% 的額外 tokens,雖然 API 單價不變($5/$25 per MTok),實際成本可能上升。
決策點:遇到指令被忽略時,先問自己:這是傳遞層級問題,還是規則品質問題?
一個快速診斷方法:把那條規則直接貼到 session 的第一條訊息裡(不透過 CLAUDE.md,直接手動輸入),如果 Claude 這樣就照做了,是傳遞層級問題,考慮升級到 hooks 或 --append-system-prompt。如果還是不照做,是規則本身的品質問題,需要重寫得更具體。
三層架構不是「繼承」而是「累加」:global / project / local 正確用法
很多人以為 project CLAUDE.md 會「覆蓋」global CLAUDE.md,就像 CSS 的 specificity 一樣。這個理解是錯的。
三層都會被讀取,內容累加:
| 層級 | 路徑 | 適合放什麼 | Git commit? |
|---|---|---|---|
| Global(個人) | ~/.claude/CLAUDE.md | 個人偏好、跨專案工具習慣 | 否 |
| Project(團隊) | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 架構決策、程式碼規範、建置測試指令 | 是 |
| Local(個人覆寫) | CLAUDE.local.md | 個人在此專案的臨時設定(已棄用,官方建議改用 @imports 引用個人設定檔) | 否(加入 .gitignore) |
| Managed Policy | /Library/Application Support/ClaudeCode/CLAUDE.md(macOS) | 企業合規強制規範 | 由 IT 管理 |
幾個容易踩的坑:
子目錄的 CLAUDE.md 是延遲載入的。Claude Code 啟動時只完整載入工作目錄及其上方祖先目錄的 CLAUDE.md。位於子目錄下的 CLAUDE.md,要等 Claude 的工具實際去讀取該子目錄的檔案時才會按需載入。如果你把重要規則放在子目錄的 CLAUDE.md 裡,Claude 一開始可能真的看不到它。
HTML 註解不消耗 token:如果你想在 CLAUDE.md 裡留人類可讀的維護筆記,用 <!-- 維護備注:這條規則是因為 X 事件加入的 --> 區塊級註解,Claude Code 在載入前會自動剝離這些內容,不佔用指令預算。
CLAUDE.md 必要結構:從最小可行版到完整模板
Claude Code 的 /init 指令能分析你的程式碼庫,自動生成包含技術堆疊、建置指令、現有慣例的基礎 CLAUDE.md。它是好的起點,但生成的內容往往充滿「Claude 本來就知道」的明顯常識。
CLAUDE.md 真正需要的是 Claude 從程式碼看不出來的隱性知識。
必要段落結構(依掃描效率排序,headers + bullet points 比段落文字快很多):
- WHAT:用一句話說明這是什麼專案、技術堆疊(語言、框架、主要工具)
- HOW:建置、測試、部署的具體指令(
npm run dev、npm test等),不要讓 Claude 自己猜 - Code Style:你最重要的幾個程式碼偏好,必須具體可執行(「函數不超過 30 行,超過就拆分」,而不是「寫清楚的程式碼」)
- Gotchas:Claude 從程式碼看不出來的地雷和非直覺設計決策(「不要修改
src/generated/目錄,它由 codegen 自動生成」)
indie maker 的最小可行版三件事(從 /init 出發後的第一步):
- 技術堆疊 + 核心指令:框架版本、啟動/測試/部署指令
- 你最重要的一個代碼偏好:選你最在乎的那一條,寫得具體,帶反例
- 一個真實的 Gotcha:你上週或上個月踩過的坑,讓 Claude 不要重蹈
Side project 先從這三件事開始,不要試圖在 CLAUDE.md 裡規劃出一個完美的未來。
可直接複製的最小可行模板:
# [你的專案名]
## 技術堆疊
Next.js 15 + TypeScript + PostgreSQL + Prisma
## 指令
- 開發:`npm run dev`
- 測試:`npm test`
- 建置:`npm run build`
## 程式碼規範
- Component 使用 function declaration,不用 arrow function export
- 所有 API route 必須做 input validation(用 zod)
## Gotchas
- `src/generated/` 目錄由 Prisma 自動生成,不要手動修改
- 環境變數在 `.env.local`,不要 commit 到 git
把上面的內容換成你自己的專案資訊,就是一份有效的起點。
進階模組化(當單一 CLAUDE.md 超過 300 行時才考慮):把主檔保持精簡,用 @imports 或 .claude/rules/ 資料夾做分層。.claude/rules/ 下的檔案只在 Claude 存取對應目錄時才按需載入(例如 frontend.md 在 Claude 讀取 src/components/ 時觸發)。Side project 不需要這種分層,那是多人團隊或 multi-agent 場景才值得維護的複雜度。
settings.json vs CLAUDE.md:兩個系統,兩種強制力
這兩個常被混淆,但職責完全不同:
settings.json = 防火牆(技術強制,不過 LLM)
- 由 Claude Code 客戶端直接執行,Claude 的判斷介入不了
- 適合:安全控制(
permissions.deny黑名單)、sandbox 設定、env var 注入
CLAUDE.md = 員工手冊(行為引導,過 LLM 判斷)
- 作為文字上下文傳遞,塑造 Claude 的行為方式
- 適合:架構決策脈絡、程式碼風格規範、工作流說明、非直覺 Gotchas
決策流程:
- 需要絕對阻止(例如:禁止
rm -rf、禁止直接修改 prod DB)→settings.json permissions.deny - 需要注入 API key 或環境變數 →
settings.json env - 需要 Claude 理解並遵循的工作方式 → CLAUDE.md
一句話:settings.json 保護系統,CLAUDE.md 教育 Claude。
規則 vs Hooks:職責分工,不是二選一
Reddit 用戶 u/DevMoses(536 pts)的觀察很精準:「我停止往 CLAUDE.md 加規則,改為建立 infrastructure。」他的案例是規則從 45 行堆到 190 行,但合規率反而下降。
這是因為他把「機械性規則」放進了「行為引導」系統。
hooks 的定位:物理強制(shell 執行,不過 LLM 判斷)。適合客觀可判斷的規則:格式檢查、測試覆蓋、特定指令攔截。hooks 有三種類型:command(直接執行 shell script)、prompt(LLM 評估,注意:這種 hook 仍依賴 LLM,不是 100% 可靠)、以及 2026 年 4 月新增的 mcp_tool(直接呼叫已連接的 MCP server 工具,例如任務完成後自動發 Slack 通知)。在 PreToolUse 事件中設定 exit code 2 可以阻斷操作;但 PostToolUse 的 exit code 2 無法回溯阻止已執行的動作,只會把 stderr 回饋給 Claude。
2026 年 4-5 月 hooks 重大更新:
- 條件式
if欄位(v2.1.85+):用 permission rule 語法精確過濾 hook 觸發條件。matcher選定工具名稱,if進一步縮小到特定呼叫情境,例如Bash(git *)只攔截 git 指令,Write(src/**/test_*.py)只攔截測試檔案寫入 PostToolUse輸出替換(v2.1.121+):透過hookSpecificOutput.updatedToolOutput可以替換任何工具的輸出結果PreCompacthook(v2.1.105+):在 context compaction 前觸發,用 exit code 2 可以阻止壓縮PermissionDeniedhook(v2.1.89+):auto mode 權限拒絕後觸發,回傳{retry: true}可重試duration_ms欄位(v2.1.110+):PostToolUse和PostToolUseFailure現在包含工具執行時間,方便效能監控
三步驟分流決策:
- Linter/CI 能做到?→ 交給 Linter,不要浪費指令配額
- 客觀可判斷、不需理解脈絡?→
hooks command(shell 強制) - 需要 LLM 理解架構意圖或商業邏輯?→ CLAUDE.md
一個最小可運行的 hooks 設定範例(在 settings.json 的 hooks 欄位):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "npm run lint 2>&1 | head -20"
}
]
}
]
}
}
這個範例在每次 Claude 執行 Bash 指令前先跑 lint 檢查。lint 失敗時回傳非零 exit code,Claude 就會停下來修正問題再重試。
進階範例:條件式 hook + MCP 工具通知(v2.1.85+):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"if": "Bash(rm *)",
"hooks": [
{
"type": "command",
"command": "echo '禁止刪除檔案' >&2 && exit 2"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "mcp_tool",
"server": "slack",
"tool": "send_message",
"input": { "channel": "#dev", "text": "Claude 完成任務" }
}
]
}
]
}
}
第一個 hook 用 if 條件只攔截刪除操作(而非所有 Bash 指令),第二個用 mcp_tool 在任務結束時自動發 Slack 通知。
不熟悉 shell script,但想讓規則更被遵守的技巧(不用 hooks 的替代方案):
- 具體化,帶反例:不說「寫乾淨的函數」,說「函數超過 30 行時必須拆分(❌ 不要在現有函數裡繼續塞邏輯,✅ 提取成獨立函數並更新呼叫端)」
- 標注後果:在重要規則後加「違反此規則時,停下來問我而不是自行決定」
- 精簡到只剩最重要的:規則少但具體,比規則多但模糊更有效
hooks 的坑:
commandhook 有 shell 環境依賴(PATH、env var),在 cron 排程或遠端執行場景可能因為環境不同而失效,需要特別注意。另外,hook 設定檔中出現未識別的 event name 不再導致整個檔案失效(v2.1.89+ 修復),但仍建議只使用官方文件列出的事件名稱。
Multi-agent Fleet 設計:以 Shareuhack 8-agent 系統為例
我們自己就在跑這樣的系統,所以可以給第一手的設計說明。
Shareuhack 的 8 個 autonomous agent(CEO/Researcher/Scout/Writer/Reviewer/Developer/Auditor/Data Analyst)共享一份 project CLAUDE.md 作為「憲法」。這份憲法定義了所有 agent 都必須遵守的硬性規則(禁止虛構、內部連結格式、frontmatter 規範等),以及整個系統的信息架構。
實際的目錄結構:
project CLAUDE.md ← 所有 agent 的共同規範(憲法)
.claude/skills/ ← 各 agent 的技能定義(各自的 SKILL.md)
agents/memory/ ← per-agent 操作記憶(各自學習,互不污染)
agents/system-state.yaml ← 系統狀態(CEO 維護)
Anthropic Docs 的技術支持:Project CLAUDE.md 透過 git 共享,所有 subagent 都從它獲得基礎上下文。各 subagent 可維護自己的 Auto Memory,不會污染主 agent 的記憶。自 v2.1.117 起,forked subagent 可透過 CLAUDE_CODE_FORK_SUBAGENT=1 在外部建置中啟用,已命名的 subagent 也支援 @ mention 自動完成。
Agent Teams:超越 subagent 的多 session 協作(實驗性功能,2026 年 2 月推出):
如果你的場景需要多個 agent 平行工作且互相溝通,Agent Teams 是比 subagent 更進階的選擇。核心差異:subagent 在單一 session 內運行,只能向主 agent 回報結果;Agent Teams 的成員各自擁有獨立的 context window(每個 1M tokens),透過 mailbox 系統和 shared task list 直接互相溝通,不需要經過 team lead 中轉。
啟用方式:在 settings.json 或環境變數中設定 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1(需要 v2.1.32+)。我在實測中觀察到,Agent Teams 適合需要跨領域協調的大型任務(例如前端和後端 agent 同步 API contract),但對 solo 開發者來說,subagent 仍然是更實用的起點。
zero-HITL 場景的特殊考量:在沒有人工監督的 cron 排程場景下,指令被忽略的風險更高。關鍵技術:
--append-system-prompt參數:將指令提升至系統提示詞層級,大幅提高強制力。注意:這個參數需要在每次呼叫時傳遞,適合 CI/CD 或 cron 腳本,不適合日常互動。CLI flag 在版本更新中可能變動,使用前建議確認最新官方文件- hooks 比 CLAUDE.md 規則更可靠(hooks 是機械執行,不依賴 LLM 判斷)
- v2.1.120 新增
claude ultrareview [target],可在 CI/scripts 中執行非互動式的全面程式碼審查
不同規模的設定建議:
| 規模 | 建議配置 |
|---|---|
| Solo 開發者 | project CLAUDE.md(300 行以內)+ 1-2 個 subagent skill + /recap 管理 session 記憶 |
| 小團隊 | project CLAUDE.md(git 共享)+ .claude/rules/ 模組分類 + /ultrareview 做 code review |
| Multi-agent fleet | 憲法分層 + skill 目錄 + per-agent memory + Agent Teams(實驗性) |
8-agent fleet 不是每個人都需要的設定。關鍵原則是按比例縮放,一個 solo 開發者可以從一份 300 行以內的 project CLAUDE.md + 1 個 subagent skill 開始。Subagent skill 的概念很簡單:在 .claude/skills/ 建立一個 .md 檔案,定義一個常重複的任務(例如「code review」或「draft blog post」),Claude 就會在執行該任務時自動載入這份指導。你用一個 skill 就能受益於相同的架構思維,不需要複製整個 fleet。v2.1.121 還新增了 /skills 的搜尋過濾功能,skill 清單變長時也能快速找到需要的。
2026 年 4 月新增的實用 slash commands:
/recap:離開 session 一段時間後回來,用這個指令快速回顧之前在做什麼,不用重讀整段對話/ultrareview [target]:透過雲端執行全面的多 agent 平行 code review/usage:合併了舊的/cost和/stats,一站式查看 token 用量和費用/effort:互動式滑桿調整推理深度,Claude Opus 4.7 支援新的xhigh等級
多工具環境補充:如果你同時使用 Cursor、Zed 等工具,它們用的是 AGENTS.md(跨工具標準)。Claude Code 預設不讀 AGENTS.md,但你可以在 CLAUDE.md 中用 @AGENTS.md 引用共用規範,再追加 Claude 專屬設定。
避開過度工程化陷阱:規模合適才是好架構
回到開頭的問題:Claude Code 作者自己用「surprisingly vanilla」的設定,核心三要素是:past errors(踩過的坑)+ conventions(既有慣例)+ rules(必要規則)。
Hacker News 上有一個著名案例:有人從 10,000 行語義記憶系統退回到 1,500 行 CLAUDE.md + bash scripts,速度提升 10 倍。代價包括:指令均勻退化、token 消耗激增、規則之間的衝突。
三個需要考慮簡化的信號:
- CLAUDE.md 超過 300 行(單一檔案)
- Claude 開始頻繁忽略你確定寫了的規則
- 你自己也記不清某條規則還有沒有在發揮作用
簡化流程:
- 審查每條規則:「沒有這行,Claude 會犯什麼具體的錯?」答不出來的就刪掉
- 把靜態檢查(格式、Lint)交回給 Linter 或 hooks,釋放指令配額
- 過長的 CLAUDE.md 拆分到
@imports或.claude/rules/,讓 Claude 按需載入
Side project 的實用上限:300 行以內的單一 CLAUDE.md 完全足夠。.claude/rules/ 分層是多人協作或 multi-agent 場景才值得的複雜度。
結論
CLAUDE.md 是「教育 Claude 的最高槓桿點」,這是 HumanLayer 的原話,我完全同意。但最高槓桿點也最容易被浪費在低品質的規則上。
一個值得保留的規則,必須是「Claude 從程式碼和上下文看不出來的隱性知識」。其他的,交給 Linter、交給 hooks、或者直接刪掉。
如果你正在用 Claude Code(截至 2026 年 5 月,最新版 v2.1.126),我推薦的起點:
- 用
/init生成基礎 CLAUDE.md - 用「沒這行 Claude 會犯錯嗎?」篩掉一半內容
- 補上你真正踩過的 Gotchas
- 識別出哪些規則應該升級到 hooks,善用條件式
if欄位精確控制觸發時機 - 需要管理多 session 記憶時,善用
/recap快速回顧上下文
從這五步開始,剩下的讓 CLAUDE.md 有機地成長。隨著 Agent Teams、mcp_tool hooks 等新功能持續推出,CLAUDE.md 的角色會越來越聚焦在「只有人類知道的隱性知識」上,機械性的規則交給 hooks 和 subagent,是 2026 年下半年值得持續關注的趨勢。
你現在的 CLAUDE.md 是怎麼設計的?踩過什麼坑?歡迎在評論分享。
FAQ
/init 生成的 CLAUDE.md 夠用嗎?如何系統性改進?
/init 會分析你的程式碼庫,自動生成包含技術堆疊、建置指令、現有慣例的基礎 CLAUDE.md,是很好的起點。問題是它生成的內容往往充滿「Claude 本來就知道」的明顯常識。建議的改進策略:大刀刪除顯而易見的段落,只保留 Claude 從程式碼看不出來的隱性知識和 Gotchas;然後採用「有機進化」方式,每次遇到 Claude 做出錯誤假設時,立即告訴它「把這點加入我的 CLAUDE.md」,讓文件反映真實踩過的坑,而非憑空預測規則。
CLAUDE.md 的 # 鍵快捷更新功能還存在嗎?
已在 Claude Code v2.0.70 版本正式移除。現在的標準做法是直接用自然語言要求 Claude 更新:「把這個加入我的 CLAUDE.md」,或使用 /memory 指令在介面中直接編輯。推薦方式是養成「有機成長」習慣,在 session 中發現問題時立即更新,而不是定期批次整理。



