多數 Context 檔案在幫倒忙
2026 年 2 月,蘇黎世聯邦理工學院(ETH Zurich)發表了 Evaluating AGENTS.md,是第一篇嚴格研究 AI coding agent 上下文檔案的論文。最關鍵的發現:LLM 生成的 context 檔案讓任務成功率下降了 3%,比完全不提供還差。人工撰寫的檔案也僅提升約 4%,推理成本卻增加超過 20%。
結論不是 context 檔案沒用,而是多數人寫得太爛。太長、太冗餘、塞滿 agent 讀程式碼就能找到的資訊。
這篇指南教你從零寫出一個落在正確那一側的 CLAUDE.md,同時避開把你推向負面影響的寫法。如果你已經有 CLAUDE.md 想先除錯,請從 10 個讓 AI Agent 變笨的 CLAUDE.md 錯誤 開始。
前提條件
開始撰寫前,你需要:
- Claude Code 已安裝且可運作。 還沒裝的話,Claude Code 第一個小時 教學涵蓋安裝流程。
- 一個真實專案。 不要抽象地寫 CLAUDE.md。打開你每天在寫的那個專案。
- 10 分鐘。 好的 CLAUDE.md 很短。如果超過 10 分鐘,你寫太多了。
Claude Code 如何讀取 CLAUDE.md
理解載入機制,才知道什麼該放哪裡。
Claude Code 在多個層級讀取 CLAUDE.md,全部合併生效:
- 全域 —
~/.claude/CLAUDE.md對所有專案載入。放你的個人偏好(語言、溝通風格、通用限制)。 - 專案根目錄 —
./CLAUDE.md在 session 啟動時載入。這是主檔案。架構、慣例、指令。 - 子目錄 —
./packages/api/CLAUDE.md在 Claude 存取該目錄的檔案時按需載入。用在 monorepo 的套件專屬 context。 - 個人覆寫 —
.CLAUDE.local.md會被 gitignore。放不該與團隊共享的個人偏好。
各層級是合併而非取代。更具體的層級在衝突時優先。所以專案根目錄的 CLAUDE.md 不該重複全域檔案的內容,子目錄檔案不該重複根目錄的內容。
Claude 也會讀取 ~/.claude/rules/*.md 作為模組化規則集。rules 目錄適合分離關注點 — 溝通風格一個檔案、禁用套件一個檔案、工作流程一個檔案 — 不用全部擠進同一個 CLAUDE.md。
五區塊範本
好的 CLAUDE.md 有五個區塊。不是每個專案都需要全部,但這個結構涵蓋了 agent 真正無法從程式碼推斷的完整範圍。
區塊 1:Architecture(架構)
這是什麼專案、怎麼組合在一起、有哪些程式碼本身看不出來的決策。
## Architecture
- Next.js 15 App Router, TypeScript strict, Tailwind CSS
- Database: PostgreSQL 16 via Drizzle ORM
- Auth: NextAuth.js v5 (GitHub + Google providers)
- Monorepo: apps/web, apps/api, packages/shared
- API layer: tRPC — all client-server calls go through tRPC routers
這個區塊回答 agent 冷啟動時的問題:「這是什麼類型的專案?」程式碼顯示個別檔案,這個區塊顯示它們如何連接。
不該放的東西: 每個依賴的版本號(agent 會讀 package.json)、你用標準方式使用的框架功能(如果你的 Next.js App Router 用法跟官方文件一樣,agent 知道)、或 package.json 一掃就能發現的資訊。
區塊 2:Conventions(慣例)
Agent 該遵循但 linter 或 type checker 不會強制的模式。
## Conventions
- Server components by default; 'use client' only for interactivity or browser APIs
- Error handling: Result<T, E> pattern (see src/lib/result.ts)
- Named exports preferred; default exports only for pages/layouts
- Database queries live in src/repositories/ — never in route handlers or components
- All new API endpoints need an integration test in tests/integration/
每行陳述一個偏好,並在適當處說明例外。「偏好 X;僅在 Z 時使用 Y」是正確格式。避免裸用 ALWAYS 和 NEVER,它們不留合理例外的空間,讓 agent 變得僵硬。詳細範例請看常見錯誤指南的錯誤 5。
區塊 3:Constraints(限制)
硬性邊界。Agent 絕對不能做的事,因為做了會造成修復成本極高的損害。
## Constraints
- Never modify files in prisma/migrations/ — generate new migrations instead
- Never change the signature of functions exported from src/api/public/
- Never delete test fixture files in tests/fixtures/ (loaded dynamically by name)
- Never commit .env files or hardcode secrets
- GraphQL schema changes require running pnpm codegen after modification
Conventions 是「偏好這樣」。Constraints 是「永遠別碰」。差別很重要。Constraints 該短、具體,針對可恢復但成本高的錯誤。如果一條 constraint 超過一行,它可能該放在 skill 裡而不是 CLAUDE.md。
區塊 4:Commands(指令)
如何 build、測試、lint、啟動專案。Agent 不該用猜的。
## Commands
- Install: pnpm install
- Dev: pnpm dev (starts all apps)
- Test unit: pnpm test:unit
- Test e2e: pnpm test:e2e (requires running dev server)
- Lint: pnpm lint
- Build: turbo build
- DB migrate: pnpm db:migrate
- DB seed: pnpm db:seed
如果你的專案用標準的 npm test 和 npm run build,可以跳過這個區塊,agent 知道預設值。但只要你有 monorepo、自訂 script、或非標準 test runner,這些指令就是整個檔案中價值最高的內容。
區塊 5:Patterns(模式,選用)
跨任務重複出現的專案專屬模式。只有在模式不明顯、且 agent 之前做錯過時才加入。
## Patterns
- New pages: create route in app/(dashboard)/[route]/page.tsx, add nav entry in src/config/navigation.ts
- New API endpoint: define tRPC router in src/server/routers/, register in src/server/root.ts
- Feature flags: use src/lib/flags.ts — check with `isEnabled('flag-name')`, never hardcode booleans
這個區塊是選用的,因為很多專案沒有複雜到需要記錄的重複模式。如果你發現自己加超過 5 個 pattern,把它們移到 skills — 那是任務專屬的知識,該按需載入,不是永遠常駐。完整的分層架構請看 context engineering 與 skill 分層。
完整範例
以下是一個中型 Next.js SaaS 應用的完整 CLAUDE.md,五個區塊全部包含:
## Architecture
- Next.js 15 App Router, TypeScript strict, Tailwind CSS
- Database: PostgreSQL 16 via Drizzle ORM
- Auth: NextAuth.js v5 (GitHub + Google providers)
- API: tRPC routers in src/server/routers/
- Payments: Stripe SDK, webhooks in src/app/api/webhooks/stripe/
## Conventions
- Server components by default; 'use client' only for interactivity
- Error handling: Result<T, E> pattern (src/lib/result.ts)
- Named exports; default exports only for pages/layouts
- DB queries in src/repositories/, never in handlers or components
- New endpoints need integration tests in tests/integration/
## Constraints
- Never modify files in drizzle/migrations/
- Never change exported function signatures in src/lib/public-api/
- Never delete test fixtures in tests/fixtures/
- All Stripe webhook handlers must verify signature first
## Commands
- Dev: pnpm dev | Test: pnpm test | Lint: pnpm lint
- Build: pnpm build | DB migrate: pnpm db:migrate
## Patterns
- New page: app/(dashboard)/[route]/page.tsx + src/config/nav.ts
- New tRPC router: src/server/routers/ → register in root.ts
- Feature flag: isEnabled('name') from src/lib/flags.ts
28 行。涵蓋架構、慣例、限制、指令、模式。Agent 從冷啟動做出正確結構決策所需的一切。其他所有東西 — 詳細的 migration 工作流、部署檢查表、API 文件 — 屬於 skills 或獨立的文件檔案。
Token 預算:多大算太大?
你的 CLAUDE.md 每次 session 都會載入。裡面的每個 token 都在與 agent 的推理能力以及你實際任務可用的 token 競爭。
算法很直接:
| 檔案大小 | 預估 Token 數 | 佔 200K Context Window 的比例 |
|---|---|---|
| 30 行(精簡) | ~450 | 0.2% |
| 100 行(建議上限) | ~1,500 | 0.75% |
| 300 行(太長) | ~4,500 | 2.3% |
| 1000 行(有害) | ~15,000 | 7.5% |
ETH Zurich 的研究發現 context 檔案讓推理成本增加超過 20%,但效益微乎其微。根本原因:多數檔案是 200-500 行品質參差的內容。實用的天花板是 5% 原則 — 你的常駐 context(CLAUDE.md 加所有全域規則)應該佔模型有效 context window 的 5% 以下。以 200K token 的模型來說,就是 10,000 token 以下。
控制在 30-100 行,一個寫得好的 CLAUDE.md 佔不到 1%,幾乎把所有 context window 留給你的程式碼和 agent 的推理。
何時該把內容移到 skills: 如果 CLAUDE.md 的某個區塊只適用於一種任務(database migration、部署、code review),它屬於 SKILL.md。Skills 按需載入,不用時零 token 成本。
測試你的 CLAUDE.md
寫完檔案是一半。測試它是另一半。
步驟 1:冷啟動測試。 在你的專案開一個新的 Claude Code session。請 agent 描述你的專案架構。如果它在不讀額外檔案的情況下正確辨識出你的 stack、模式、限制,你的 CLAUDE.md 有效。
步驟 2:限制測試。 請 agent 做一件你的 constraints 禁止的事。「修改 migration 檔案來修正這個欄位型別。」如果 agent 拒絕並解釋原因,constraint 有被讀到。如果它直接修改了,代表 constraint 要麼埋在太多文字裡,要麼措辭模糊。
步驟 3:指令測試。 請 agent 跑你的測試套件。如果第一次就用了正確的指令,commands 區塊有效。如果你需要 pnpm test:unit 它卻猜 npm test,代表 commands 區塊缺少或不夠醒目。
步驟 4:慣例測試。 請 agent 建立一個新的 component 或 endpoint。檢查它是否遵循你陳述的模式 — 檔案放對目錄、用對的 error handling、遵循你的 export 慣例。如果偏離了,conventions 區塊需要更精準的措辭。
步驟 5:噪音測試。 移除一個你懷疑冗餘的區塊。跑同樣的任務。如果 agent 行為沒變,那個區塊就是浪費 token。積極地刪減。
持續維護
CLAUDE.md 是活的文件,不是寫一次就不管的產出。以下是何時增加、何時刪減。
增加的時機:
- Agent 犯了同一個錯兩次。第一次是巧合,第二次代表你需要一條 constraint 或 convention。
- 你引入新的架構模式(新的 auth provider、新的 API 層、新的資料庫)。
- 新的團隊成員加入,agent 給了他們錯誤引導 — 這暴露了缺口。
刪減的時機:
- 某條 convention 在 20 次以上的 session 中都被完美遵循。Agent 可能已經從程式碼本身學會了。試著移除那行並檢查。
- 某個工具或模式已被棄用。關於舊 library 的死掉 constraints 只會混淆 agent。
- 檔案超過 100 行。裡面有東西不需要永遠常駐。
審查頻率: 每 2 週檢查你的 CLAUDE.md。逐行閱讀。對每一行問:「拿掉這行,agent 會犯一個它讀程式碼也無法自己恢復的錯誤嗎?」如果答案是否定的,刪掉。
CLAUDE.md vs AGENTS.md vs SKILL.md
這三個檔案解決不同問題。簡要說明何時使用哪個:
| 檔案 | 用途 | 載入時機 | 最適合 |
|---|---|---|---|
| AGENTS.md | 跨工具的專案 context | 每次 session | 架構、慣例、限制(所有 AI CLI 工具都讀) |
| CLAUDE.md | Claude Code 專屬 context | 每次 session | Claude 專屬行為(compaction、subagent)加上對 AGENTS.md 的引用 |
| SKILL.md | 任務專屬能力 | 按需載入 | 只適用於特定任務的工作流、檢查表、範本 |
如果你的團隊只用 Claude Code,可以把所有東西放在 CLAUDE.md。但只要有人用 Codex CLI、Gemini CLI 或 Cursor,可攜的 context 就該移到 AGENTS.md。
完整比較和詳細範例請看 SKILL.md vs CLAUDE.md vs AGENTS.md。進階分層模式 — 漸進式揭露、跨層 token 預算、monorepo 設定 — 請看 context engineering 與 skill 分層。
撰寫檢查清單
Commit 你的 CLAUDE.md 之前,驗證:
| 檢查項目 | |
|---|---|
| 總共 100 行以下 | |
| 有 Architecture 區塊,包含不明顯的決策 | |
| 有 Constraints 區塊,針對高成本的錯誤 | |
| 有 build/test/lint 的 Commands | |
| 沒有 agent 在 package.json 或 tsconfig 能找到的內容 | |
| 沒有重述 linter 規則(agent 會自己跑 linter) | |
| Conventions 用「prefer」搭配例外,不是裸用 ALWAYS/NEVER | |
| 任務工作流已移到 skills,不是內嵌在 CLAUDE.md | |
| 檔案已 commit 到版本控制 | |
| 至少用 3 個代表性任務測試過 |
超過 2 項不通過,commit 之前先修。壞的 CLAUDE.md 比沒有 CLAUDE.md 更糟 — ETH Zurich 的研究用數據證明了這一點。
反覆測試 CLAUDE.md 修改時,多面板的終端機佈局很有幫助 — 在一個面板跑 agent、另一個面板看 CLAUDE.md、並排比較行為差異。Termdock 的分割面板工作區讓這個流程變快:修改檔案、在旁邊的面板重啟 session、立即測試。
開始寫
打開你的專案。在根目錄建立 CLAUDE.md。寫五個區塊。初稿控制在 50 行以下 — 之後隨時能加,但拿掉比不加更難。用三個真實任務測試它。刪掉 agent 不需要的部分。
目標不是一份全面的文件。而是 agent 從冷啟動做出正確決策所需的最小 context。超過這個最小值的一切都是噪音 — 而噪音,如研究所示,會讓你的 agent 變差。
所有主要 AI CLI 工具的完整 context engineering 全局觀,請看 AI CLI 工具完整指南。
Ready to streamline your terminal workflow?
Multi-terminal drag-and-drop layout, workspace Git sync, built-in AI integration, AST code analysis — all in one app.