docs: thêm §4 cạm bẫy khi .md phản tác dụng (model yếu), thêm slide demo

This commit is contained in:
2026-07-20 15:08:10 +07:00
parent 852c9bc9c8
commit 5eb89fe4c2
2 changed files with 37 additions and 6 deletions
BIN
View File
Binary file not shown.
@@ -8,8 +8,9 @@
1. [Ba loại CLAUDE.md — đặt ở đâu, dùng cho gì](#1-ba-loai-claudemd) 1. [Ba loại CLAUDE.md — đặt ở đâu, dùng cho gì](#1-ba-loai-claudemd)
2. [Phân cấp & scope](#2-phan-cap--scope) 2. [Phân cấp & scope](#2-phan-cap--scope)
3. [Cấu trúc chuẩn (8 phần)](#3-cau-truc-chuan-8-phan) 3. [Cấu trúc chuẩn (8 phần)](#3-cau-truc-chuan-8-phan)
4. [Tự động cập nhật (ít sửa tay)](#4-tu-dong-cap-nhat) 4. [Cạm bẫy: khi .md phản tác dụng (nhất là model yếu)](#4-cam-bay)
5. [Cập nhật thủ công](#5-cap-nhat-thu-cong) 5. [Tự động cập nhật (ít sửa tay)](#5-tu-dong-cap-nhat)
6. [Cập nhật thủ công](#6-cap-nhat-thu-cong)
--- ---
@@ -56,7 +57,7 @@ Phần 1, 2, 4, 5, 6 là cốt lõi; 3, 7 tùy dự án; 8 tự lớn theo thờ
* **[2] Lệnh hay dùng** **(bắt buộc):** build / test / lint / dev / deploy — để AI chạy đúng thay vì đoán. * **[2] Lệnh hay dùng** **(bắt buộc):** build / test / lint / dev / deploy — để AI chạy đúng thay vì đoán.
* **[3] Cấu trúc thư mục** *(tùy chọn):* chỉ ghi thư mục dễ nhầm (ví dụ: logic ở `services/`, không ở `api/`). * **[3] Cấu trúc thư mục** *(tùy chọn):* chỉ ghi thư mục dễ nhầm (ví dụ: logic ở `services/`, không ở `api/`).
* **[4] Quy ước code** **(bắt buộc):** naming, pattern, error handling — những rule linter không bắt được. * **[4] Quy ước code** **(bắt buộc):** naming, pattern, error handling — những rule linter không bắt được.
* **[5] Business rules** **(bắt buộc):** logic nghiệp vụ AI không thể tự đoán (ví dụ: không cancel order đã "shipped"). **Quan trọng nhất** * **[5] Business rules** **(bắt buộc):** logic nghiệp vụ AI không thể tự đoán (ví dụ: không cancel order đã "shipped"). **Quan trọng nhất** — viết dạng **ràng buộc/cấm**, không phải mô tả (xem §4).
* **[6] Do / Don't** **(bắt buộc):** dạng cấm rõ ràng, ngắn, dứt khoát (ví dụ: KHÔNG commit `.env`). * **[6] Do / Don't** **(bắt buộc):** dạng cấm rõ ràng, ngắn, dứt khoát (ví dụ: KHÔNG commit `.env`).
* **[7] References** *(tùy chọn):* import file ngoài bằng `@[...].md` để giữ file chính gọn. * **[7] References** *(tùy chọn):* import file ngoài bằng `@[...].md` để giữ file chính gọn.
* **[8] Learned patterns** *(tự cập nhật):* phần Claude tự ghi sau mỗi phiên, kèm ngày. * **[8] Learned patterns** *(tự cập nhật):* phần Claude tự ghi sau mỗi phiên, kèm ngày.
@@ -65,9 +66,38 @@ Phần 1, 2, 4, 5, 6 là cốt lõi; 3, 7 tùy dự án; 8 tự lớn theo thờ
> Thứ tự viết lần đầu: làm 1, 2, 6 trước (~30 phút), rồi bổ sung 4, 5 dần theo lúc thấy AI làm sai. Không cần hoàn hảo ngay. > Thứ tự viết lần đầu: làm 1, 2, 6 trước (~30 phút), rồi bổ sung 4, 5 dần theo lúc thấy AI làm sai. Không cần hoàn hảo ngay.
---
<a id="4-cam-bay"></a>
## 4. Cạm bẫy: khi .md phản tác dụng (nhất là model yếu)
Bài học thực tế: `/init` và model tự sinh file **mô tả CÁI ĐANG CÓ**, không phải **RÀNG BUỘC phải giữ**. Đó là lý do file tự sinh hay phản tác dụng — càng rõ với model yếu (minimax-m3, ...).
**Vì sao ngược:** model yếu đọc một *fact* như "logic mã hóa userId lặp ở 3 template + `PagesController`" thành **lời mời refactor** → tự gộp/xóa code nhạy cảm không ai yêu cầu. (Case thật repo này: m3 xóa cả 2 block mã hóa AES trùng trong `PagesController` chỉ vì file .md "tả" chúng trùng nhau.)
**Nguyên tắc: mô tả → ràng buộc.** Mỗi dòng phải là cái model KHÔNG đọc code ra được: intent, invariant, gotcha, cấm. Fact thuần (model tự đọc được) = nhiễu → xóa.
| ❌ Mô tả (fact — model tự đọc được) | ✅ Ràng buộc + ý đồ (đáng giữ) |
|---|---|
| "`canAccessAnniCoupon()` join `anni_coupon_register_info`" | "Whitelist anniversary CHỈ quyết ở `canAccessAnniCoupon()`. KHÔNG hardcode danh sách chỗ khác." |
| "Mã hóa userId lặp ở 3 template + controller" | "3 block mã hóa userId là CỐ Ý (mỗi surface khác param). KHÔNG gộp/xóa trừ khi task yêu cầu." |
| "`LotteryService` dùng `getUserIndex() % ratioCycle`" | "Lottery deterministic CÓ CHỦ ĐÍCH, KHÔNG phải random. Đừng 'sửa' thành `rand()`." |
**Viết cho model yếu:**
- Câu **cấm mệnh lệnh** (KHÔNG / CHỈ / PHẢI), không phải câu tả. Model yếu làm theo lệnh, không tự suy ý đồ.
- Mỗi gotcha kèm **hậu quả** ("...nếu không, request bị Gateway chặn trước khi tới action").
- "Trông như bug nhưng cố ý" → nói thẳng + lý do. Không nói → model sẽ "sửa" cho gãy.
**Checklist trước khi commit mỗi file .md** — mỗi dòng tự hỏi:
1. Model đọc code ra được dòng này không? → Được thì **xóa** (nhiễu).
2. Có phải invariant / intent / gotcha / cấm không? → Không thì **xóa**.
3. Đặt đúng scope chưa (rule module ↔ nằm trong file của module đó)?
**`/init` = bản nháp, KHÔNG phải bản cuối.** Bắt buộc 1 lượt người sửa: xóa fact, đổi "tả" thành "cấm", thêm ý đồ. Commit thẳng output `/init` chính là nguồn "hiệu quả ngược".
--- ---
**[Claude Code]** **[Claude Code]**
## 4. Tự động cập nhật <a id="5-tu-dong-cap-nhat"></a>
## 5. Tự động cập nhật
Tools AI **không** tự viết lại các file AGENTS.md hoàn toàn — và đó là điều tốt, vì file tự phình liên tục thì sẽ nhiều rác --> sẽ làm hỏng `/code-review`. Nếu chúng ta muốn muốn cập nhật các file .md mà *gần như không phải sửa tay* thì sẽ có một số cách: Tools AI **không** tự viết lại các file AGENTS.md hoàn toàn — và đó là điều tốt, vì file tự phình liên tục thì sẽ nhiều rác --> sẽ làm hỏng `/code-review`. Nếu chúng ta muốn muốn cập nhật các file .md mà *gần như không phải sửa tay* thì sẽ có một số cách:
@@ -77,9 +107,10 @@ Tools AI **không** tự viết lại các file AGENTS.md hoàn toàn — và đ
--- ---
## 5. Cập nhật thủ công <a id="6-cap-nhat-thu-cong"></a>
## 6. Cập nhật thủ công
* **`/init`:** quét codebase sinh CLAUDE.md nháp. Nếu đã có file, nó **bổ sung chứ không ghi đè**, nhưng có thể sắp xếp lại — nên `git commit` trước khi chạy để dễ rollback. Hợp cho lúc khởi tạo / làm mới toàn diện. * **`/init`:** quét codebase sinh CLAUDE.md nháp. Nếu đã có file, nó **bổ sung chứ không ghi đè**, nhưng có thể sắp xếp lại — nên `git commit` trước khi chạy để dễ rollback. Hợp cho lúc khởi tạo / làm mới toàn diện. ⚠️ Output là **nháp** — bắt buộc sửa tay theo §4 trước khi commit.
* **`/memory`:** liệt kê các file memory và mở ra sửa trực tiếp; dùng khi muốn dọn/sắp xếp lại. * **`/memory`:** liệt kê các file memory và mở ra sửa trực tiếp; dùng khi muốn dọn/sắp xếp lại.
* **Sửa file như thường:** CLAUDE.md chỉ là markdown — mở editor sửa, lưu, lần sau Claude tự đọc lại (không cần restart). * **Sửa file như thường:** CLAUDE.md chỉ là markdown — mở editor sửa, lưu, lần sau Claude tự đọc lại (không cần restart).
* **Giữ gọn:** thêm rule mới thì xóa rule lỗi thời; mỗi rule một dòng; phần dài thì tách file rồi `@import`. * **Giữ gọn:** thêm rule mới thì xóa rule lỗi thời; mỗi rule một dòng; phần dài thì tách file rồi `@import`.