CLAUDE.md 設計
精通系統提示工程和專案指令設計。
你將學到什麼
如果你只能改變 Claude Code 設定中的一件事來獲得顯著更好的結果,那就是你的 CLAUDE.md 檔案。這個單一檔案塑造了 AI 在你的專案中做出的每個決定 — 從程式碼風格到架構選擇到測試方法。
完成後,你將了解:
- 為什麼 CLAUDE.md 是你專案中最具槓桿效果的檔案
- 三層指令階層結構
- 有效專案指令的設計原則
- 使用
paths:frontmatter 的作用域規則 - 浪費 token 和困惑 AI 的常見反模式
- 如何為不同專案類型結構化 CLAUDE.md
問題是什麼
當你帶一個新開發者進入專案時,你會花數小時入職培訓:解釋技術棧、慣例、測試方法、東西放在哪裡、要避免什麼。沒有這些上下文,他們寫的程式碼雖然能運作,但不適合專案。
Claude Code 面臨同樣的問題。沒有指令,它會:
- 使用訓練時的預設值(可能不符合你的技術棧)
- 猜測慣例(tab 或空格、命名模式、測試框架)
- 做出與你現有模式衝突的架構決定
- 在 session 之間重複同樣的錯誤
你可以在每次對話中重新解釋一切。或者你可以寫下來一次。
如何運作
三層階層結構
Claude Code 從三個層級載入指令,每個層級有不同的作用範圍:
┌──────────────────────────────────────────────┐
│ Instruction Hierarchy │
│ │
│ Tier 1: User CLAUDE.md (global) │
│ ┌───────────────────────────────────────┐ │
│ │ ~/.claude/CLAUDE.md │ │
│ │ │ │
│ │ Applies to ALL projects │ │
│ │ Personal preferences, global rules │ │
│ │ Example: "Always use TypeScript strict │ │
│ │ mode. Prefer functional patterns." │ │
│ └───────────────────────────────────────┘ │
│ │
│ Tier 2: Project CLAUDE.md (repo-level) │
│ ┌───────────────────────────────────────┐ │
│ │ <project-root>/CLAUDE.md │ │
│ │ │ │
│ │ Applies to THIS project │ │
│ │ Tech stack, architecture, conventions │ │
│ │ Checked into version control │ │
│ │ Shared with the whole team │ │
│ └───────────────────────────────────────┘ │
│ │
│ Tier 3: Scoped Rules (pattern-specific) │
│ ┌───────────────────────────────────────┐ │
│ │ .claude/rules/*.md │ │
│ │ │ │
│ │ Activated by file path patterns │ │
│ │ Fine-grained instructions │ │
│ │ Example: rules for tests only, │ │
│ │ rules for API routes only │ │
│ └───────────────────────────────────────┘ │
│ │
│ Loading order: │
│ User → Project → Rules (later overrides) │
│ │
└──────────────────────────────────────────────┘
當不同層級的指令發生衝突時,更具體的層級優先。Project CLAUDE.md 覆蓋 User CLAUDE.md,而作用域規則在匹配的檔案範圍內覆蓋 Project CLAUDE.md。
每個層級應該包含什麼
Tier 1:User CLAUDE.md (~/.claude/CLAUDE.md)
你的個人預設值,適用於所有地方:
# Personal Preferences
- Use TypeScript strict mode in all projects
- Prefer functional programming patterns over class-based
- Write tests before implementation (TDD)
- Use conventional commits for commit messages
- Always run the linter before considering code complete
保持簡短。它適用於每個專案,所以放入專案特定的內容會造成問題。
Tier 2:Project CLAUDE.md (<project-root>/CLAUDE.md)
核心專案上下文。這是最重要的層級:
# Project: E-Commerce API
## Tech Stack
- Runtime: Node.js 20 + TypeScript 5.4
- Framework: Express 4 with express-async-errors
- Database: PostgreSQL 16 via Prisma ORM
- Testing: Vitest + Supertest
- Auth: JWT with refresh tokens
## Dev Commands
- `pnpm dev` — start dev server (port 3000)
- `pnpm test` — run all tests
- `pnpm test:watch` — watch mode
- `pnpm lint` — ESLint + Prettier check
- `pnpm db:migrate` — run Prisma migrations
- `pnpm db:seed` — seed test data
## Architecture
- Routes: src/routes/<resource>.ts
- Services: src/services/<resource>.ts (business logic)
- Models: prisma/schema.prisma (single source of truth)
- Middleware: src/middleware/ (auth, validation, error)
- Tests: src/__tests__/<resource>.test.ts
## Conventions
- All route handlers delegate to services (no business logic in routes)
- Use Zod schemas for request validation
- Error responses follow RFC 7807 (Problem Details)
- Database queries only in services, never in routes
- Every public endpoint needs an integration test
Tier 3:Scoped Rules (.claude/rules/*.md)
只在特定檔案模式下啟用的規則:
---
paths:
- "src/__tests__/**"
- "**/*.test.ts"
---
# Testing Rules
- Use describe/it blocks (not test())
- Each test file tests one service or route
- Use factory functions for test data, not raw objects
- Always clean up database state in afterEach
- Mock external services, never the database
paths: frontmatter 使用 glob 模式。規則只在 AI 處理符合這些模式的檔案時才會載入:
┌─────────────────────────────────────────────────┐
│ Scoped Rule Activation │
│ │
│ Working on src/routes/auth.ts │
│ → Loads: api-routes.md rule │
│ → Skips: testing.md rule │
│ │
│ Working on src/__tests__/auth.test.ts │
│ → Loads: testing.md rule │
│ → Skips: api-routes.md rule │
│ │
│ Working on both files simultaneously │
│ → Loads: api-routes.md AND testing.md │
│ │
└─────────────────────────────────────────────────┘
設計原則
1. 清晰勝於巧妙
撰寫指令時,像是向一個能力強但第一天到職的開發者解釋。對非顯而易見的事情要明確:
# Good: Explicit and actionable
- Error responses use RFC 7807 format: { type, title, status, detail }
- Database IDs are UUIDs, never auto-increment integers
- All timestamps are ISO 8601 in UTC, converted to local time only in the frontend
# Bad: Vague and unhelpful
- Use good error handling
- Follow best practices for IDs
- Handle time correctly
2. 許可而非限制
告訴 AI 它可以做什麼。列出它不能做的所有事情是無限的,而且浪費 token:
# Good: Grant permissions clearly
- You can modify any file in src/ directly
- You can run `pnpm test` and `pnpm lint` without asking
- You can create new files in src/services/ and src/routes/
# Bad: Endless restrictions
- Do not modify package.json
- Do not change the database schema
- Do not edit the CI configuration
- Do not touch the deployment scripts
- ... (goes on forever)
3. 結構化以便掃描
AI 在每個對話回合都會處理你的 CLAUDE.md。用標題、表格和簡短的要點使其可以快速掃描:
## API Conventions
| Pattern | Example | Notes |
|---------|---------|-------|
| Route files | `src/routes/users.ts` | One file per resource |
| Service files | `src/services/users.ts` | Business logic here |
| Test files | `src/__tests__/users.test.ts` | Mirrors service structure |
| Validators | `src/validators/users.ts` | Zod schemas |
## Key Decisions
- **ORM**: Prisma (not TypeORM) — chosen for type safety
- **Auth**: JWT with 15min access + 7day refresh tokens
- **Queue**: BullMQ for background jobs (Redis-backed)
4. 包含「為什麼」
當一個慣例有不明顯的原因時,解釋它。AI 理解意圖時會做出更好的決定:
# We use UUIDs instead of auto-increment IDs because:
# 1. Prevents ID enumeration attacks
# 2. Allows offline ID generation (mobile clients)
# 3. Safe for multi-region database replication
反模式
文字之牆 — 把整個架構文件傾倒到 CLAUDE.md 中。AI 每個回合都得處理所有內容。Project CLAUDE.md 保持在 200 行以內,其餘使用作用域規則。
矛盾的指令 — 當 Tier 1 說「使用 Jest」而 Tier 2 說「使用 Vitest」時,AI 會困惑。審核你的層級以發現衝突。
過度規範 — 規定每個函式簽名和變數名稱。讓 AI 在你的慣例範圍內使用判斷。規定模式,而不是每個實例。
顯而易見的指令 — 寫「使用正確的縮排」或「處理錯誤」之類的東西。AI 本來就會做這些事。CLAUDE.md 專注於你的專案特有的內容。
過時的指令 — 留著三個月前資料庫遷移的指令。定期檢視和修剪,就像你對文件所做的一樣。
關鍵洞見
CLAUDE.md 是為你的專案做系統提示工程。 Anthropic 撰寫的系統提示控制 AI 的一般行為。你的 CLAUDE.md 控制它的專案特定行為。你的 CLAUDE.md 越好,你在每次對話中就越不需要重複自己。
可以這樣理解:
Without CLAUDE.md:
Session 1: "We use Vitest, not Jest. And Prisma, not TypeORM. And..."
Session 2: "Remember, we use Vitest, not Jest. And Prisma..."
Session 3: "I already told you, we use Vitest..."
With CLAUDE.md:
Session 1: "Add a password reset endpoint" → (it already knows the stack)
Session 2: "Add rate limiting to auth routes" → (it already knows the patterns)
Session 3: "Write tests for the new service" → (it already knows the test framework)
三層階層結構之所以強大,是因為它分離了關注點:你的個人偏好不會污染共享的專案設定,而檔案特定的規則不會膨脹全域上下文。
Tier 3 中的作用域規則對大型專案特別有價值。AI 不必為每次對話載入 500 行指令,而是只載入與當前處理的檔案相關的 30 行。
實作範例
完整的 Next.js + Prisma 專案 CLAUDE.md
# Project: SaaS Dashboard
## Tech Stack
- Framework: Next.js 14 (App Router)
- Language: TypeScript 5.4 (strict mode)
- Database: PostgreSQL 16 via Prisma
- Auth: NextAuth.js v5 with GitHub + Google providers
- Styling: Tailwind CSS + shadcn/ui components
- Testing: Vitest (unit) + Playwright (e2e)
## Commands
- `pnpm dev` — local server at localhost:3000
- `pnpm test` — run Vitest
- `pnpm test:e2e` — run Playwright
- `pnpm lint` — ESLint check
- `pnpm db:push` — push schema changes
- `pnpm db:studio` — open Prisma Studio
## Architecture
- `app/` — Next.js pages and layouts (App Router)
- `app/api/` — API routes (Route Handlers)
- `components/` — React components (shadcn/ui based)
- `lib/` — Shared utilities and configurations
- `lib/db.ts` — Prisma client singleton
- `prisma/schema.prisma` — database schema
## Conventions
- Server Components by default; add "use client" only when needed
- API routes return NextResponse.json() with appropriate status codes
- Use server actions for form mutations (not API routes)
- Prisma queries in lib/db/ modules, not directly in components
- Tailwind classes: use cn() helper for conditional classes
- Component files: PascalCase.tsx (e.g., UserProfile.tsx)
## Current Sprint
- Implementing team invitation flow
- Migrating from pages/ to app/ router (80% done)
API Routes 的作用域規則
建立 .claude/rules/api-routes.md:
---
paths:
- "app/api/**"
---
# API Route Rules
- Always validate request body with Zod before processing
- Return standardized error format: { error: string, code: string }
- Use middleware pattern for auth: wrap handler with withAuth()
- Rate limit public endpoints with the rateLimit() wrapper
- Log all 5xx errors with structured logging (lib/logger.ts)
- Never expose internal error messages to clients
檢查你的 CLAUDE.md 效果
問自己這些問題:
1. Could a new developer read this and start contributing?
→ If no, add more context about architecture and conventions
2. Is anything here obvious or generic?
→ If yes, remove it (saves tokens every turn)
3. Are there project-specific gotchas not mentioned?
→ If yes, add them (e.g., "the legacy user table uses
'userid' not 'user_id' — Prisma maps this in schema")
4. Is it under 200 lines?
→ If no, move file-specific rules to .claude/rules/
5. Would any instruction conflict with your global CLAUDE.md?
→ If yes, resolve the conflict explicitly
前後對比
| 沒有 CLAUDE.md | 有三層 CLAUDE.md |
|---|---|
| 每個 session 重新解釋慣例 | 慣例自動載入 |
| AI 猜測技術棧和模式 | AI 知道確切的技術棧和模式 |
| 指令散落在各個提示中 | 單一事實來源,版本控制 |
| 所有檔案類型相同的規則 | 作用域規則按檔案模式啟用 |
| 新團隊成員得到不同的 AI 行為 | 共享 CLAUDE.md 確保一致性 |
下一堂課
有了 session 儲存和專案指令的定義,模組 3 的最後一塊拼圖是信任。第 18 堂課介紹權限模型與安全性 — 深入了解 Claude Code 的多層安全模型如何運作,從沙箱到核准閘道到組織政策。