Mục tiêu học tập
Sau bài này, bạn sẽ có thể:- ✅ Giải thích CLAUDE.md là gì, khi nào file được load, và tại sao nó là “bộ nhớ dài hạn” của Claude
- ✅ Viết một CLAUDE.md tốt phù hợp với project thực tế của mình
- ✅ Dùng đúng 4 variants: project-level, user-level, local, và nested theo từng tình huống
- ✅ Reference file khác trong CLAUDE.md bằng @ syntax để tránh duplicate
- ✅ Biết khi nào nên dùng /init để generate draft và khi nào nên viết tay từ đầu
Mở đầu: 2 giờ onboard, rồi 30 giây
Hãy tưởng tượng bạn quay lại một project Next.js sau 6 tháng nghỉ. Project của người khác handoff cho bạn từ trước Tết. Bạn mở Claude Code và gõ: “Implement feature dark mode.” Claude hỏi lại: “Project này dùng framework CSS gì? Tailwind hay styled-components? Bạn có một design system chưa? Test command là gì?” Bạn phải tìm lại. Scroll qua package.json, đọc README.md (nếu có — và nó thường outdated), mở next.config.js, tìm hiểu cấu trúc thư mục. Phải mất gần 2 giờ để trả lời được những câu hỏi đó cho Claude, và câu trả lời thì bị rải rác trong prompt, trong file Claude đọc, trong context mà session sau sẽ không còn nhớ. Rồi bạn tạo CLAUDE.md. Bạn ghi vào đó: stack là Next.js 15 App Router + Tailwind + Drizzle ORM. Test command là pnpm test —run. Migration phải chạy qua pnpm db:migrate, không được gọi drizzle-kit migrate trực tiếp. Named exports only. Server Actions ưu tiên hơn API routes. Ngày hôm sau, bạn mở Claude Code. Bạn gõ: “Implement feature dark mode.” Claude bắt đầu viết code ngay. Đúng Tailwind. Đúng App Router pattern. Đúng named export. Không hỏi gì thêm. 30 giây thay vì 2 giờ.“CLAUDE.md is Claude’s memory across sessions and across team.”— Boris Cherny, AnthropicĐó là điểm mấu chốt. Claude Code không có memory tự nhiên giữa các session — mỗi khi bạn mở terminal mới, Claude bắt đầu từ zero. CLAUDE.md là cách bạn cho Claude “nhớ” project của mình trước khi bạn gõ prompt đầu tiên.
CLAUDE.md là gì?
CLAUDE.md là một file Markdown bình thường — không có magic format, không có schema đặc biệt. Điều đặc biệt là cách Claude Code xử lý nó: file được đọc tự động và prepend vào system prompt mỗi khi bạn bắt đầu một session mới. Hiệu ứng thực tế: Claude “đã biết” về project của bạn trước khi bạn gõ bất kỳ prompt nào. Không cần giải thích lại stack, không cần nhắc lại conventions, không cần paste lại build commands.Lifecycle của CLAUDE.md trong một session
Nội dung CLAUDE.md không phải là “hint” hay “suggestion” — nó là một phần của system prompt, nghĩa là Claude nhìn thấy nó với cùng độ ưu tiên như các instruction core của Claude Code. Claude 4 đặc biệt tốt trong việc tuân theo CLAUDE.md — team Anthropic ghi nhận bước nhảy rõ rệt từ Claude 3.7 (thường bỏ qua) sang Claude 4 (“my CLAUDE.md is being followed way more closely”).Bảng “4 Variants của CLAUDE.md”
Không phải chỉ có một CLAUDE.md. Có 4 variants, mỗi cái phục vụ một mục đích khác nhau:| Variant | Đường dẫn | Ai dùng | Share team | Typical content | Khi nào tạo |
|---|---|---|---|---|---|
| Project-level | ./CLAUDE.md | Cả team | ✅ Commit vào git | Stack, build commands, architecture decisions, code conventions, gotchas chung | Ngay khi setup project mới hoặc khi team bắt đầu dùng Claude Code |
| User-level | ~/.claude/CLAUDE.md | Chỉ bạn | ❌ Personal | Code style cá nhân, commit message format, language preference, personal workflow | Ngay khi cài Claude Code lần đầu |
| Local | ./CLAUDE.local.md | Chỉ bạn, cho project này | ❌ Gitignored | Local path overrides, personal dev env setup, debug notes tạm thời | Khi bạn có preference riêng không muốn ảnh hưởng team |
| Nested | ./api/CLAUDE.md hoặc ./apps/web/CLAUDE.md | Team (cho module đó) | ✅ Commit | Module-specific rules, API contract, package conventions | Khi project đủ lớn để các module cần context riêng (monorepo, microservices) |
Lưu ý quan trọng về Local variant
CLAUDE.local.md cần được thêm vào .gitignore thủ công — Claude Code không tự làm điều này:Anatomy của một CLAUDE.md tốt
Đây là CLAUDE.md thực tế cho một Next.js project. Từng section đều có lý do tồn tại:Tại sao từng section tồn tại
Section # Project: Một đoạn mô tả ngắn giúp Claude không phải đọc package.json để đoán stack. Tiết kiệm 2-5 lần tool call mỗi session. Section # Commands: Đây là thông tin thay đổi nhiều nhất giữa các project. pnpm test —run vs pnpm test là ví dụ điển hình — không có CLAUDE.md, Claude hay chạy watch mode rồi bị stuck chờ. Notes như “KHÔNG dùng drizzle-kit migrate” là gotcha mà Claude không thể đoán từ code — bạn phải ghi tường minh. Section # Code Style: Conventions mà Claude sẽ phải “guess” nếu không có. Named exports, indent style, TypeScript strict — những thứ này nhất quán xuyên suốt codebase nhưng không visible trong một file đơn lẻ. Section # Architecture: High-level map giúp Claude tìm đúng chỗ để đọc và đặt code, thay vì phải grep toàn project. Section # Gotchas: Những thứ counter-intuitive mà chỉ người làm project mới biết. Đây là phần quan trọng nhất và thường bị bỏ qua nhất. Section # References với @ syntax: Thay vì paste nội dung README vào CLAUDE.md (duplicate, outdated ngay), dùng @README.md để Claude đọc file gốc khi cần. Claude sẽ load file đó vào context on-demand.Hierarchy và Composition
Khi bạn có nhiều CLAUDE.md variants cùng lúc, Claude tổng hợp tất cả: Conflict resolution: Specific beats general. Nếu user-level CLAUDE.md nói “Always use 4-space indent” nhưng project-level nói “2-space indent” — project-level thắng. Logic này hợp lý: project conventions quan trọng hơn personal preference khi làm việc trong context của project đó. Nested discovery: Khi bạn đang làm việc ở subdir ./api/, Claude tự động discover ./api/CLAUDE.md và merge vào. Khi bạn ở ./apps/web/, nó discover ./apps/web/CLAUDE.md. Bạn không cần làm gì thêm.Ví dụ step-by-step: Setup CLAUDE.md cho project mới
Bước 1: Bắt đầu không có CLAUDE.md (observe pain points trước)
Đây là best practice thực sự counter-intuitive: đừng tạo CLAUDE.md ngay từ ngày đầu. Thay vào đó, làm việc trong 3-5 ngày và observe:- Bạn phải nhắc Claude điều gì mỗi session?
- Claude hay làm sai điều gì dù bạn đã nói?
- Những lệnh nào bạn phải giải thích lặp đi lặp lại?
- Gotchas nào của project khiến Claude ra kết quả không mong muốn?
Bước 2: Identify 5-10 things bạn phải repeat
Sau 1 tuần, nhìn lại notes. Bạn sẽ thấy pattern. Thường sẽ có:- 2-3 build/test commands bị Claude chạy sai
- 1-2 architecture decision mà Claude hay “sáng tạo” lại thay vì follow
- 3-5 conventions về code style
- 1-2 gotchas quan trọng (thứ tự init, dependency injection pattern, env config…)
Bước 3: Run /init để generate draft
Bước 4: Edit draft, thêm observations từ Bước 2
Mở file vừa generate, thêm vào:- Những commands bị viết sai (với note giải thích tại sao version đúng)
- Architecture patterns team đang follow
- Gotchas từ pain points đã observe
- References đến docs quan trọng bằng @ syntax
Bước 5: Test với session mới
Đóng Claude Code. Mở lại. Gõ một task cụ thể mà trước đây hay bị làm sai. Observe Claude có apply đúng conventions không mà không cần bạn nhắc. Nếu Claude vẫn làm sai một thứ — thêm rule đó vào CLAUDE.md, cụ thể hơn.Bước 6: Commit và tạo user-level CLAUDE.md
Case studies theo industry
Backend team — Node.js microservices
Team 5 engineers, 8 services, monorepo với pnpm workspaces. Thách thức: mỗi service có rules khác nhau về error handling, logging format, database access pattern. Cách dùng CLAUDE.md:- ./CLAUDE.md (root): monorepo structure, shared packages, CI commands, deployment policy
- ./services/payments/CLAUDE.md: Payment-specific rules (PCI compliance notes, currency handling, idempotency keys)
- ./services/notifications/CLAUDE.md: Queue patterns, retry logic, template conventions
- Mỗi dev có ~/.claude/CLAUDE.md cho personal style (một số prefer functional, một số prefer OOP)
Mobile team — React Native
Team iOS + Android chung codebase. Gotchas rất nhiều: native module rebuild, platform-specific code, env setup phức tạp. CLAUDE.md project-level focus:Data team — Python ML/analytics
Team dùng Python + Jupyter + Poetry. Venv activation là nguồn gốc của 80% lỗi ngớ ngẩn. CLAUDE.md project-level:COBOL modernization — legacy system
Case study thực từ AWS demo: một hệ thống tín dụng 100 file COBOL, gần như zero documentation. CLAUDE.md được tạo để bootstrap phân tích:Open source library maintainer
CLAUDE.md focus vào contribution guidelines và version policy — thứ bạn phải nhắc mọi người (và Claude) lặp đi lặp lại:Anti-patterns
Anti-pattern 1: CLAUDE.md quá dài (200+ dòng)
Vấn đề: CLAUDE.md load vào context window ở mọi session, kể cả khi task không liên quan. Một CLAUDE.md 200 dòng tốn ~3-5k token mỗi lần — không nhiều, nhưng nhân với tần suất dùng, và nhất là khi 60% nội dung không relevant cho task hiện tại. Triệu chứng: Bạn thêm “PR review checklist 30 điểm” vào CLAUDE.md vì “tiện lợi”. Checklist này load ngay cả khi bạn chỉ đang debug một bug đơn giản. Cách đúng: CLAUDE.md chứa những gì luôn relevant cho mọi task trong project — build commands, stack, conventions cốt lõi. Những gì chỉ relevant cho task cụ thể (PR review, commit message format) thì đặt vào Skill (xem Bài 2.9). Skill load on-demand, không load khi bạn không cần. Target size: 40-80 dòng cho hầu hết project. Trim mỗi quý.Anti-pattern 2: Hardcode personal preferences vào project CLAUDE.md
Vấn đề: Bạn thêm “Always respond in Vietnamese” hoặc “I prefer functional programming style” vào ./CLAUDE.md rồi commit lên git. Triệu chứng: Teammate mở project, Claude bắt đầu trả lời bằng tiếng Việt (teammate người nước ngoài). Hoặc Claude enforce functional style với người quen class-based. Cách đúng: Personal preferences thuộc về ~/.claude/CLAUDE.md (user-level, không bao giờ share) hoặc ./CLAUDE.local.md (local, gitignored). Project CLAUDE.md chỉ chứa những gì cả team nên follow.Anti-pattern 3: Không update CLAUDE.md khi tech stack thay đổi
Vấn đề: Team migrate từ Jest sang Vitest 3 tháng trước, nhưng CLAUDE.md vẫn nói “Test: jest —run”. Claude tiếp tục dùng Jest syntax cho test mới. Triệu chứng: Bạn phát hiện Claude hay viết test sai framework, phải nhắc lại mỗi lần. Cách đúng: CLAUDE.md là living document. Mỗi khi có tech decision đáng kể (đổi framework, đổi ORM, đổi deployment), cập nhật CLAUDE.md ngay trong cùng PR. Tốt hơn: thêm “Update CLAUDE.md if applicable” vào PR checklist của team.Anti-pattern 4: Generate /init rồi không bao giờ edit
Vấn đề: /init generate một draft tốt nhưng generic — nó chỉ đọc được những gì có trong file (package.json, config files). Nó không biết về những gotchas bạn discover sau 3 tháng làm việc, không biết về architectural decisions được quyết định trong Slack thread 6 tháng trước. Triệu chứng: CLAUDE.md trông đầy đủ nhưng Claude vẫn hay làm sai những thứ project-specific. Cách đúng: /init là điểm khởi đầu, không phải điểm kết thúc. Sau khi generate, edit ngay để thêm gotchas, conventions, và decisions mà chỉ bạn (và team) mới biết.Anti-pattern 5: Chỉ dùng project CLAUDE.md, bỏ qua user-level
Vấn đề: Bạn có 8 project đang làm. Mỗi project bạn phải nhắc Claude “respond in English”, “prefer named exports”, “commit message format: feat/fix/docs” — những thứ apply cho tất cả project của bạn. Triệu chứng: Bạn copy-paste một đoạn giống nhau vào CLAUDE.md của mọi project. Cách đúng: Tạo ~/.claude/CLAUDE.md một lần. Đặt personal prefs vào đó. Claude áp dụng cho tất cả project, không cần repeat.Anti-pattern 6: Đẩy “PR review checklist” vào CLAUDE.md
Vấn đề: Bạn có checklist 20 điểm để review PR. Đặt vào CLAUDE.md để “tiện”. Giờ 20 điểm đó load vào context mọi lúc — kể cả khi bạn đang viết migration script không liên quan gì đến PR. Cách đúng: PR review checklist là Skill (xem Bài 2.9). Skill chỉ activate khi Claude nhận diện request liên quan đến review — không load khi không cần. Tiết kiệm context, tập trung hơn.Mẹo nâng cao
Memory mode với # shortcut
Trong khi Claude đang làm việc, bạn có thể gõ # đầu dòng để tạo note:@filename syntax để reference docs
Thay vì copy-paste nội dung vào CLAUDE.md (duplicate, sẽ outdated):Nested CLAUDE.md cho monorepo
Monorepo với nhiều apps/packages — đây là pattern phổ biến nhất cho nested: Khi Claude đang làm việc ở apps/web/, nó load:- Root CLAUDE.md (monorepo structure)
- apps/web/CLAUDE.md (web-specific rules)
- ~/.claude/CLAUDE.md (your personal prefs)
Ask Claude save rule sau correction
Sau khi correct Claude một điều gì đó:Trim CLAUDE.md định kỳ
Mỗi quý, bạn nên đọc lại CLAUDE.md và hỏi cho từng dòng: “Rule này còn đúng không? Còn relevant không?” Ví dụ stale rules:- “Dùng Yarn 1.x” — team đã migrate sang pnpm 6 tháng trước
- “JWT expiry 24 giờ” — đã đổi thành 7 ngày trong sprint vừa rồi
- Gotcha về một thư viện đã uninstall
Áp dụng ngay
Bài tập 1: Generate, edit, và test (20 phút)
Chọn một project đang dùng thường xuyên. Nếu chưa có CLAUDE.md: Bước 1: Mở Claude Code trong project đó. Bước 2: Chạy /init. Đọc kết quả — note những gì đúng và những gì thiếu. Bước 3: Edit file vừa tạo:- Thêm 3-5 gotchas bạn đã biết từ kinh nghiệm
- Thêm architecture decisions quan trọng
- Xóa những gì generic hoặc obvious (Claude đã biết rằng npm install cài dependencies — không cần ghi)
- Target: 40-60 dòng max
Bài tập 2: Tạo user-level CLAUDE.md (10 phút)
Tạo file ~/.claude/CLAUDE.md với personal preferences áp dụng mọi project:- Language preference (Respond in Vietnamese / English)
- Commit message format bạn follow
- Code style personal (4-space vs 2-space, functional vs OOP)
- Personal workflow rules (“Always propose a plan before implementing”, “Run tests after each change”)
- Thứ bạn hay phải nhắc Claude ở mọi project
Tóm tắt
🎯 CLAUDE.md là bộ nhớ dài hạn của Claude — prepend vào system prompt mỗi session, giúp Claude “biết” project của bạn trước khi bạn gõ prompt đầu tiên. Không có nó, Claude bắt đầu từ zero mỗi lần. 🎯 4 variants phục vụ 4 mục đích khác nhau: project-level (team shared), user-level (personal, cross-project), local (personal, gitignored), nested (module-specific trong monorepo). Dùng đúng variant, tránh đặt personal prefs vào project file. 🎯 CLAUDE.md tốt nhất xuất phát từ pain thực tế — bắt đầu không có CLAUDE.md, observe 1 tuần, rồi encode những gì gây ma sát. /init là điểm khởi đầu, không phải điểm kết thúc. 🎯 @filename syntax cho phép reference docs khác thay vì copy-paste — single source of truth, không bị outdated. 🎯 CLAUDE.md nhỏ gọn tốt hơn dài dòng — 40-80 dòng accurate beats 200 dòng có stale rules. Những gì chỉ relevant cho task cụ thể (PR review checklist, commit formatter) thuộc về Skill, không phải CLAUDE.md.Bài tiếp theo
Bạn đã biết cách dùng CLAUDE.md để trao cho Claude bộ nhớ xuyên session. Bài tiếp theo sẽ đi sâu hơn vào một pattern cực kỳ powerful: Subagents — cách Claude Code spawn ra các agent con để làm việc song song, mỗi agent có context window riêng và nhiệm vụ riêng, trong khi main thread của bạn vẫn sạch và focused. Bạn đã thoáng thấy subagents trong bài context management (Bài 2.5) khi dùng chúng để outsource exploration. Bài 2.8 sẽ đi vào toàn bộ capability: khi nào spawn subagent, cách configure, pattern phối hợp nhiều subagent, và case study thực tế với COBOL modernization — 94 file được phân tích song song trong 1 giờ. ➡️ Bài tiếp theo: Bài 2.8 — Subagents: Parallel intelligenceTài liệu tham khảo
- CLAUDE.md documentation — Official docs về memory types và hierarchy
- Claude Code best practices — Anthropic engineering blog, phần CLAUDE.md
- Boris Cherny — transcript “A conversation on Claude Code”: memory mode # shortcut, 3 variants
- Transcript “Claude Code best practices”: @ syntax, nested discovery, monorepo handling, Claude 4 better following instructions
- Transcript “Claude Code modernizes COBOL”: CLAUDE.md với “documentation expert” role, 94-file analysis
- Bài 2.4 (Workflow EPCC) — CLAUDE.md trong bước Explore, làm nền cho cả workflow
- Bài 2.5 (Quản lý Context) — CLAUDE.md tiết kiệm context bằng cách tránh repeat; trade-off kích thước CLAUDE.md vs context budget
- Bài 2.8 (Subagents) — CLAUDE.md configure role cho subagents (như COBOL case)
- Bài 2.9 (Skills) — Phân biệt rõ CLAUDE.md vs Skill: luôn-load vs on-demand
- Bài 2.10 (MCP) — CLAUDE.md có thể reference MCP server instructions để Claude biết tools nào có sẵn