CLAUDE.md là file Markdown mà Claude Code tự nạp vào context ở mỗi phiên. Vì lần nào cũng được đọc, mỗi dòng trong đó tốn token ở mọi lượt và cạnh tranh sự chú ý với yêu cầu thật của bạn. CLAUDE.md tốt thì ngắn, cụ thể và kiểm chứng được. Vị trí file và lệnh /init, /memory đã có trong Claude Code cheatsheet. Trang này bàn về nội dung.
CLAUDE.md nằm ở đâu trong context
flowchart TD A["Managed (do admin cài)"] --> D[Context phiên] B["~/.claude/CLAUDE.md (user)"] --> D C["./CLAUDE.md (project, commit)"] --> D E["subdir/CLAUDE.md"] -->|"nạp khi làm việc trong subdir"| D F["@docs/x.md (import)"] --> C D --> G[Model] H["settings.json + hooks"] -->|"cưỡng chế, không phụ thuộc model"| G
CLAUDE.md là chỉ dẫn: model thường làm theo nhưng không có gì bảo đảm. Điều gì bắt buộc (cấm git push --force, cấm commit lên router prod) thì đặt vào permissions.deny hoặc hook (settings và hooks). CLAUDE.md chỉ nên giải thích lý do.
Nên ghi / không nên ghi
| Nên ghi | Không nên ghi |
|---|---|
Lệnh build/test/lint chính xác: ansible-lint, pytest -q tests/unit |
Mô tả từng file, từng thư mục (model tự ls/grep được) |
Quy ước không suy ra được từ code: "hostname dạng <role><n>-<site>" |
Kiến thức chung: "YAML dùng 2 space", "viết code sạch" |
Điều cấm và lý do: "không chạy playbook thiếu --check trên group prod" |
Secret, token, IP quản trị thật |
Quy trình xác nhận xong việc: "chạy make lint test rồi mới báo xong" |
Lịch sử dự án, changelog, biên bản họp |
Bẫy riêng của repo: "inventory prod nằm ở inventory/prod/, không phải hosts.yml" |
Nội dung đã nằm trong README (dùng @README.md nếu thật sự cần) |
Công cụ ưu tiên: "dùng uv run, không dùng pip install" |
Hướng dẫn dài cho một tác vụ hiếm (đưa thành skill) |
| Định dạng output team muốn: "commit message theo Conventional Commits" | Chỉ dẫn mâu thuẫn nhau giữa các file |
Mỗi dòng hãy tự hỏi: "Bỏ dòng này đi thì Claude có làm sai không?" Nếu không thì xoá.
Phạm vi
| File | Ghi gì | Ai sửa |
|---|---|---|
~/.claude/CLAUDE.md |
Sở thích cá nhân dùng ở mọi repo: ngôn ngữ trả lời, công cụ quen dùng | Bạn |
./CLAUDE.md |
Quy ước team, lệnh build/test, điều cấm của repo | Cả team, review qua PR |
roles/bgp/CLAUDE.md |
Quy tắc chỉ đúng trong thư mục con: "role này hỗ trợ cả IOS XR và Junos, test cả hai" | Người phụ trách thư mục |
@path/file.md (import) |
Tách tài liệu dài, chỉ import thứ thật sự cần ở mọi phiên | Cả team |
Monorepo nhiều mảng (ansible/, terraform/, mcp-servers/) thì giữ CLAUDE.md gốc thật ngắn và đặt CLAUDE.md riêng trong từng thư mục. Model chỉ nạp phần liên quan khi làm việc trong thư mục đó.
Ví dụ
# netauto
## Lệnh
- Lint: `make lint` (yamllint + ansible-lint). Test: `make test`. Chạy cả hai trước khi báo xong.
- Python: `uv run ...`, không `pip install` vào system.
## Quy ước
- Hostname: `<role><n>-<site>`, vd `pe1-hni`. Biến thiết bị trong `host_vars/<hostname>.yml`.
- Template Jinja2 cho IOS XR ở `templates/iosxr/`, Junos ở `templates/junos/` (dạng `set`).
## Điều cấm
- Không chạy playbook lên group `prod` nếu thiếu `--check --diff`. Lý do: không có lab cho mọi platform.
- Không sửa `inventory/prod/`: file này sinh tự động từ NetBox.Ví dụ trên khoảng 15 dòng, và mỗi dòng đều thay đổi hành vi của model.
Bảo trì
- Bắt đầu bằng
/init, sau đó cắt bớt: bản sinh tự động thường liệt kê cấu trúc thư mục, phần này nên bỏ. - Mỗi khi Claude làm sai cùng một kiểu lần thứ hai, thêm một dòng nêu đúng chỗ sai đó.
- Review CLAUDE.md như code: nó ảnh hưởng tới mọi phiên của mọi người trong team.
- File phình to thì chuyển các quy trình dài thành skill hoặc subagent. Skill chỉ nạp khi cần.
- Dùng
/contextđể xem memory files đang chiếm bao nhiêu token.
Khi nào dùng
- CLAUDE.md: sự thật ổn định, áp dụng ở hầu hết phiên (lệnh, quy ước, điều cấm).
- Skill: quy trình nhiều bước, chỉ cần cho một loại việc.
- settings.json / hook: thứ phải cưỡng chế, không chấp nhận "model quên".
- Prompt trong phiên: chỉ dẫn dùng một lần cho việc đang làm.