feat: add AI code review documentation, demonstration project, and update guidelines
This commit is contained in:
+112
-73
@@ -1,25 +1,46 @@
|
|||||||
# Cách Review Code Với AI
|
# Cách Review Code Với AI
|
||||||
|
|
||||||
Hướng dẫn dùng AI tự review code trước khi giao cho người khác. Áp dụng cho mọi tool (Claude Code, Cursor, Codex, Copilot, Antigravity). Nguyên tắc chung như nhau, chỉ khác tên lệnh và file cấu hình.
|
Hướng dẫn cách dùng AI để **tự review code với AI trước khi tạo PR**, áp dụng cho mọi tool (Claude Code, Cursor, Codex, Copilot, Antigravity...). Tài liệu tập trung vào **cách làm và tư duy**, không phụ thuộc một công cụ cụ thể — vì nguyên tắc giống nhau ở tất cả, chỉ khác tên lệnh và file cấu hình.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Mục lục
|
## Mục lục
|
||||||
1. [AI Review Gate — review trước khi tạo PR](#1-ai-review-gate)
|
1. [Vấn đề: AI review nhưng vẫn sai](#1-van-de)
|
||||||
2. [File rules — bộ luật cho AI](#2-file-rules)
|
2. [Tư tưởng: Context tốt > Prompt tốt](#2-context-tot)
|
||||||
3. [Cách review đúng (không bị sai)](#3-cach-review-dung)
|
3. [AI Review Gate — review trước khi tạo PR](#3-ai-review-gate)
|
||||||
4. [Mẹo & tư duy khi review](#4-meo--tu-duy)
|
4. [File rules — bộ luật cho AI](#4-file-rules)
|
||||||
5. [Các tool & cách kích hoạt](#5-cac-tool)
|
5. [Cách review đúng (5 nguyên tắc)](#5-cach-review-dung)
|
||||||
|
6. [Persona agents — nhiều agent thay vì một AI](#6-persona-agents)
|
||||||
|
7. [/code-review của Claude Code](#7-code-review)
|
||||||
|
8. [Các tool & cách kích hoạt](#8-cac-tool)
|
||||||
|
9. [Demo: Before vs After](#9-demo)
|
||||||
|
10. [Tóm lại](#10-tom-lai)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. AI Review Gate
|
## 1. Vấn đề
|
||||||
|
|
||||||
Đặt một cổng AI giữa "code xong" và "tạo PR".
|
Dùng AI hỗ trợ code lâu nay, nhưng kết quả thường lệch theo những kiểu quen thuộc:
|
||||||
|
|
||||||
|
* **Code sai yêu cầu** — tự suy diễn phần thiếu, làm lệch mục tiêu ban đầu.
|
||||||
|
* **Viết lại hàm đã có** — đẻ hàm mới trùng chức năng với hàm đã có.
|
||||||
|
* **Báo lỗi rác** — sai business logic, báo các lỗi không liên quan.
|
||||||
|
* **Không hỏi trước khi code** — lao vào làm ngay, không xác nhận ý định của người dùng.
|
||||||
|
> Gốc rễ: AI không thấy đúng thứ cần thấy, và không bị buộc dừng lại đúng lúc.
|
||||||
|
|
||||||
* **Trước:** code xong đẩy thẳng PR → người review gánh cả lỗi vặt lẫn lỗi logic → nhiều vòng comment–sửa.
|
---
|
||||||
* **Sau:** AI quét diff trước, lỗi rõ ràng được sửa ngay → người review chỉ còn xét kiến trúc & business.
|
|
||||||
* **Lợi ích:** giảm vòng lặp review, rút ngắn thời gian merge, người review dành sức cho việc giá trị cao.
|
## 2. Context tốt > Prompt tốt
|
||||||
|
|
||||||
|
**Cùng một model — khác nhau ở cách mình đưa context và đóng khung bài toán trong câu lệnh.**
|
||||||
|
|
||||||
|
Lưu ý quan trọng: context tốt nghĩa là **ĐÚNG và SẠCH, không phải NHIỀU**. Nhồi cả repo còn làm AI loãng tín hiệu và dễ lạc đề hơn. Cả tài liệu này xoay quanh việc đưa context đúng cho việc review.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. AI Review Gate
|
||||||
|
|
||||||
|
**Tư duy cốt lõi:** đặt một "AI Gate" xen giữa *code xong* và *tạo PR*. Mục tiêu là code sau phiên của bạn đã sạch, để người review chỉ tốn sức cho kiến trúc, business, đánh đổi thiết kế — chứ không phải dò lỗi vặt.
|
||||||
|
|
||||||
Quy trình 3 gate:
|
Quy trình 3 gate:
|
||||||
|
|
||||||
@@ -27,85 +48,103 @@ Quy trình 3 gate:
|
|||||||
Code xong → [Gate 1] AI review → Fix → [Gate 2] Tự review / AI review lần 2 → Fix → [Gate 3] Người review → Fix & merge
|
Code xong → [Gate 1] AI review → Fix → [Gate 2] Tự review / AI review lần 2 → Fix → [Gate 3] Người review → Fix & merge
|
||||||
```
|
```
|
||||||
|
|
||||||
* **Gate 1 – AI review:** quét diff/commit, bắt lỗi logic, cú pháp, vi phạm convention, hàm viết trùng.
|
* **Gate 1 – AI review:** soi diff để bắt lỗi logic, convention, hàm viết trùng.
|
||||||
* **Gate 2 – Tự review / AI lần 2:** đọc lại bằng mắt người; hoặc chạy AI lại sau khi fix để chặn lỗi mới phát sinh.
|
* **Gate 2 – Tự review / AI Review lần 2:** review thủ công; hoặc chạy AI lại sau khi fix để chắc không phát sinh lỗi mới.
|
||||||
* **Gate 3 – Người review:** chỉ còn xử lý cái máy không phán được.
|
* **Gate 3 – Người khác review:** chỉ còn tập trung vào những thứ mà AI không đánh giá và review được.
|
||||||
|
|
||||||
> **Nguyên tắc nền:** mỗi lần review một phạm vi rõ ràng (diff/commit/PR), không đổ cả repo. Phạm vi hẹp = chính xác hơn, ít lạc đề, ít tốn token.
|
**Vì sao đáng làm:** chi phí cho gate AI rất rẻ nhưng cắt được phần lớn vòng lặp "sếp comment → sửa → review lại".
|
||||||
|
|
||||||
|
> **Nguyên tắc số 1:** mỗi lần review một **phạm vi rõ ràng** (diff/commit/PR), không đổ cả repo vào. Phạm vi hẹp = AI chính xác, đỡ lạc đề, đỡ tốn token.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. File rules
|
## 4. File rules — bộ handbook cho AI
|
||||||
|
|
||||||
Mã hóa convention + business logic vào một file, dùng lại ở mọi session.
|
**Tư duy cốt lõi:** AI review chỉ tốt khi có **chuẩn để đối chiếu và đánh giá**. File rules là nơi bạn thông tin, quy ước, business logic của dự án một lần rồi dùng về sau cho dự án đó, và cả team đều có thể sử dụng chung, không cần phải giải thích lại mỗi lần cho dự án.
|
||||||
|
|
||||||
* **Trước:** mỗi session phải giải thích lại convention; AI tự đoán business logic → code sai yêu cầu, viết hàm trùng chức năng.
|
Mỗi tool có file rules riêng, vai trò như nhau:
|
||||||
* **Sau:** rule nằm sẵn trong file, nạp tự động mỗi lần; AI bám chuẩn dự án.
|
|
||||||
* **Lợi ích:** hết lặp lại chỉ dẫn; đề xuất khớp codebase ngay lần đầu; giảm sửa đi sửa lại.
|
|
||||||
|
|
||||||
**Xu hướng hiện tại — hội tụ về một chuẩn chung:** `AGENTS.md` là định dạng mở, ví như "README cho agent", được nhiều coding agent cùng đọc. Một `AGENTS.md` thay cho nhiều file riêng lẻ.
|
| Tool | File rules |
|
||||||
|
|------|-----------|
|
||||||
| Phạm vi | File rules |
|
|
||||||
|---------|-----------|
|
|
||||||
| Chuẩn chung (nhiều agent) | `AGENTS.md` — định dạng mở, đa tool |
|
|
||||||
| Claude Code | `CLAUDE.md` |
|
| Claude Code | `CLAUDE.md` |
|
||||||
| Cursor | `.cursor/rules/*.mdc` (Project Rules; `.cursorrules` là bản cũ) |
|
| Cursor | `.cursor/rules/*.mdc` (hoặc `.cursorrules` cũ) |
|
||||||
| Codex (OpenAI) | `AGENTS.md` |
|
| Codex (OpenAI) | `AGENTS.md` |
|
||||||
| Copilot / Gemini | file hướng dẫn repo của tool |
|
| Copilot / Gemini | cấu hình hướng dẫn repo của tool |
|
||||||
|
|
||||||
> Hợp nhất nhiều tool: giữ một `AGENTS.md` làm nguồn chân lý, cho file riêng của tool trỏ tới (symlink hoặc `@import` `CLAUDE.md` → `AGENTS.md`) — mức hỗ trợ tùy tool, cần kiểm tra.
|
**Nên ghi gì:** quy ước code (naming, pattern, error handling), **business rules** (những logic AI không tự đoán được hoặc những đặc trưng riêng của doanh nghiệp), và liệt kê những viết nên làm và tuyệt đối không làm cụ thể, dứt khoát. Hoặc các hướng dẫn như luôn kiểm tra xem hàm trong diff có bị trùng chức năng với hàm đã có không. Phong cách code phải ngắn gọn, có thể tái sử dụng nhiều lần cho cả dự .
|
||||||
|
|
||||||
**Nội dung nên có:** quy ước code (naming, pattern, error handling), business rules (logic AI không tự đoán được), do/don't dứt khoát. Loại bỏ thứ hiển nhiên hoặc linter tự bắt.
|
**Hai tư duy quan trọng:**
|
||||||
|
* **Bộ luật, không phải tài liệu:** giữ cho file luôn ngắn. File dài làm loãng context, khiến AI dễ bị sai.
|
||||||
**Hai nguyên tắc:**
|
* **Scope phân cấp:**
|
||||||
* **Bộ luật, không phải tài liệu:** giữ ngắn. File dài làm loãng tín hiệu, tăng báo sai.
|
* Rule cá nhân (dùng cho mọi project) → ở `.claude` (hoặc tương tự cho mỗi tool).
|
||||||
* **Scope phân cấp:** rule chung ở gốc repo; rule riêng module ở thư mục con. AI áp đúng rule cho đúng vùng code → review đúng trọng tâm.
|
* Rule chung → ở root dự án.
|
||||||
|
* Rule riêng của từng module → ở thư mục con.
|
||||||
> Chi tiết viết & duy trì file rules: xem *Hướng Dẫn Viết & Duy Trì CLAUDE.md*.
|
|
||||||
|
|
||||||
|
> Chi tiết cách viết & duy trì: xem tài liệu *Hướng dẫn viết & maintain các file AGENTS.md*.
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Cách review đúng
|
## 5. Nhiều persona agent > một AI đơn lẻ
|
||||||
|
|
||||||
"Sai" gồm hai kiểu: **lạc trọng tâm** (báo lỗi ngoài phần đang làm) và **báo lỗi không đúng** (false positive, hiểu sai business logic).
|
**Một AI không thể ôm hết context của dự án → phải chú ý dàn mỏng. Chia vai → mỗi agent đào sâu một lăng kính** (như một hội đồng review). Chọn persona theo loại thay đổi, không cần dùng hết:
|
||||||
|
|
||||||
* **Trước:** AI soi cả code cũ, hiểu sai ý định thay đổi, đẩy ra hàng loạt false positive → báo cáo mất niềm tin, tốn công sàng lọc.
|
| Persona | Soi gì |
|
||||||
* **Sau:** chỉ còn lỗi high-signal, đúng phạm vi, đúng business.
|
|---------|--------|
|
||||||
* **Lợi ích:** báo cáo đáng tin, dùng được ngay; thời gian dồn vào sửa lỗi thật.
|
| **Security** | Injection, phân quyền, secret, validate input |
|
||||||
|
| **Performance** | N+1 query, vòng lặp tốn kém, cache |
|
||||||
Năm điều kiện cần đảm bảo — đúng cho mọi tool:
|
| **Maintainability** | Trùng lặp, đặt tên, độ phức tạp |
|
||||||
|
| **Business logic** | Khớp đúng yêu cầu/spec, edge case |
|
||||||
* **Khóa review vào diff:** chỉ soi code vừa thay đổi → bỏ lỗi pre-existing của người khác.
|
| **Test & reliability** | Coverage code mới, xử lý lỗi |
|
||||||
* **Cung cấp ý định:** ghi rõ title/description hoặc mục tiêu thay đổi → không báo ngược lại điều cố tình làm.
|
| **Tổng hợp & lọc** | Gom kết quả, loại trùng, xếp ưu tiên |
|
||||||
* **File rule đúng scope:** AI dựa vào sự thật dự án thay vì đoán → tránh báo sai convention/business.
|
|
||||||
* **Lọc false positive:** yêu cầu chỉ báo lỗi chắc chắn; bỏ nitpick, lỗi linter tự bắt, vấn đề chung chung trừ khi rule yêu cầu.
|
> **Cách làm:** Claude Code định nghĩa mỗi persona là subagent trong `.claude/agents/`; tool khác thì chạy nhiều lượt prompt theo persona. Sau cùng luôn có **bước tổng hợp** để gom/loại trùng. Lưu ý: tốn token hơn (dành cho PR quan trọng), và **đừng để agent vừa viết code tự review chính nó**.
|
||||||
* **Ngưỡng tin cậy cao:** thà bỏ sót vài lỗi nhỏ còn hơn ngập báo cáo sai.
|
|
||||||
|
|
||||||
> Một số tool (ví dụ `/code-review` của Claude Code) cài sẵn các cơ chế này: khóa diff, kiểm định lại từng issue, danh sách "không flag". Tool chưa có thì đưa các yêu cầu trên vào prompt hoặc file rules.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 6. 5 nguyên tắc để review chuẩn hơn
|
||||||
|
|
||||||
|
* **Học theo tư duy của sếp:** cung cấp rõ context cho AI trước khi bắt nó làm việc.
|
||||||
|
* **Khóa review vào diff:** AI chỉ soi phần code có thay đổi → không đụng lỗi cũ của người khác.
|
||||||
|
* **Cho biết ý định:** nói rõ PR này định làm gì → AI không bị đoán mò mục tiêu của mình.
|
||||||
|
* **Có các file rule đúng scope:** AI dựa vào thông tin có sẵn về dự án thay vì tự đoán mò.
|
||||||
|
* **Luôn kiểm tra kết quả review:** đừng tin tưởng, dựa dẫm hoàn toàn vào AI — phải luôn double check dù kết quả chạy được. AI rất hay lấp liếm kết quả bằng cách này hay cách khác.
|
||||||
|
> "Sai" gồm hai kiểu cần chặn: **lạc trọng tâm** (báo lỗi ngoài phần đang làm) và **báo lỗi không đúng** (false positive, hiểu sai business logic).
|
||||||
|
|
||||||
## 4. Mẹo & tư duy
|
|
||||||
|
|
||||||
* **Chia PR nhỏ:** diff gọn → review chính xác, nhanh. PR lớn làm loãng tín hiệu.
|
|
||||||
* **Review bằng subagent độc lập:** agent vừa viết code thường thiên vị, mặc định code mình đúng. Dùng subagent "reviewer" riêng (Claude Code: `.claude/agents/`; Cursor/Codex có cơ chế tương tự) hoặc session mới để có góc nhìn khách quan.
|
|
||||||
* **Kết quả AI là điểm khởi đầu, không phải phán quyết:** vẫn cần mắt người ở Gate 2.
|
|
||||||
* **Audit toàn cục khác review diff:** kiểm tra tính đồng bộ module/UI/DB cần chia theo từng mối quan tâm, cấp "bản đồ" kiến trúc trước, dùng subagent riêng theo lăng kính (DB, UI, API) — không soi cả source một lần.
|
|
||||||
* **Rule "luôn áp dụng" để trong file rules, không để trong prompt:** prompt dễ trôi trong session dài; file rules nạp lại mỗi lần.
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. /code-review của Claude Code
|
||||||
|
|
||||||
|
Pipeline có **kiến trúc multi-agent + tầng kiểm định** — chính là tư duy persona agent ở mục 5 đã được làm sẵn:
|
||||||
|
|
||||||
|
```
|
||||||
|
Sàng lọc → Ngữ cảnh (CLAUDE.md) → Multi-agent song song → Kiểm định lại issue → Lọc false positive → Kết quả
|
||||||
|
```
|
||||||
|
|
||||||
|
> Nó **cố tình khóa vào diff**, đối chiếu `CLAUDE.md` theo scope, và **kiểm định lại từng issue** → chỉ giữ lỗi chắc chắn, ít false positive.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Review với các tool khác
|
||||||
|
|
||||||
|
Nguyên tắc giống nhau — khác tên lệnh & file rules:
|
||||||
|
|
||||||
|
| Tool | File rules | Kích hoạt review |
|
||||||
|
|------|-----------|------------------|
|
||||||
|
| Claude Code | `CLAUDE.md` | `/code-review` hoặc hỏi agent |
|
||||||
|
| Cursor | `.cursor/rules/*.mdc` | `/bugbot` hoặc hỏi agent trong editor |
|
||||||
|
| Codex (OpenAI) | `AGENTS.md` | `/review` của Codex hoặc hỏi agent |
|
||||||
|
| GitHub Copilot | cấu hình repo | Copilot review trên PR |
|
||||||
|
| Antigravity (Google) | `gemini.md` | agent-first, tự review |
|
||||||
|
|
||||||
|
> ⚠️ Các tính năng của tools bây giờ phát triển rất nhanh — mình cần theo dõi, đọc docs và patch notes để cập nhật.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Các tool
|
## 9. Tóm lại
|
||||||
|
|
||||||
| Tool | Kích hoạt review |
|
Chất lượng review quyết định bởi 3 điều:
|
||||||
|------|------------------|
|
|
||||||
| Claude Code | `/code-review` (PR/diff; multi-agent + lọc false positive) |
|
1. **Gate trước khi tạo PR** — dùng AI Review TRƯỚC khi tạo PR.
|
||||||
| Cursor | Bugbot (review PR trên GitHub) hoặc agent review trong editor |
|
2. **File rules tốt** — bộ quy ước, thông tin ngắn, đúng scope, có business logic.
|
||||||
| Codex (OpenAI) | tính năng review của Codex; đọc `AGENTS.md` |
|
3. **Ép AI review đúng** — 5 nguyên tắc + dùng nhiều persona agent.
|
||||||
| GitHub Copilot | Copilot code review trên Pull Request |
|
> **"Cùng một model, khác ở cách đưa AI context để xử lý vấn đề."**
|
||||||
| Gemini Code Assist | review PR tự động trên GitHub |
|
|
||||||
| Antigravity (Google) | IDE agent-first — giao agent tự review |
|
|
||||||
|
|
||||||
**Khác biệt chính:** đa số tool chạy một lượt prompt trên diff; Claude Code có kiến trúc multi-agent + tầng kiểm định để lọc false positive. Dù tool nào, chất lượng review vẫn quyết định bởi ba yếu tố: gate đúng lúc, file rules tốt, ép review đúng.
|
|
||||||
|
|
||||||
> ⚠️ Tính năng và tên lệnh các tool thay đổi nhanh, một số mới hơn mốc kiến thức tài liệu (đặc biệt Cursor Bugbot, Codex, Antigravity) — kiểm chứng tại trang chính thức trước khi trình bày.
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
## Business rules — Order
|
||||||
|
- KHÔNG được cancel order đã ở trạng thái `shipped` hoặc `delivered`.
|
||||||
|
Phải kiểm tra `order.status` trước; nếu đã shipped thì throw lỗi.
|
||||||
|
- Refund (hoàn tiền) xử lý async qua queue, không inline trong hàm cancel.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
- Format tiền tệ: LUÔN dùng `formatCurrency()` ở `src/lib/format.js`.
|
||||||
|
KHÔNG tự viết hàm format tiền mới.
|
||||||
|
- Số tiền lưu dưới dạng VND nguyên (integer).
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# PR: Thêm tính năng hủy đơn hàng (cancel order)
|
||||||
|
|
||||||
|
Diff thêm vào cuối `src/services/orderService.js`:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
@@ src/services/orderService.js @@
|
||||||
|
+function toMoney(n) { // hàm format tiền tự viết
|
||||||
|
+ return n.toLocaleString('vi-VN') + ' đ';
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+export async function cancelOrder(id) {
|
||||||
|
+ const order = await getOrder(id);
|
||||||
|
+ order.status = 'cancelled'; // cập nhật trạng thái
|
||||||
|
+ await db.orders.save(order);
|
||||||
|
+ return `Đã hủy đơn. Hoàn ${toMoney(order.total)}`;
|
||||||
|
+}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hai lỗi được cài (đáp án cho người trình bày — KHÔNG chiếu)
|
||||||
|
1. **Lỗi business:** `cancelOrder` không kiểm tra `order.status` → hủy được cả đơn đã `shipped`,
|
||||||
|
vi phạm rule trong CLAUDE.md. Chỉ phát hiện được nếu AI đọc business rule.
|
||||||
|
2. **Lỗi maintainability:** `toMoney()` trùng chức năng `formatCurrency()` đã có ở `src/lib/format.js`.
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# Prompt Cheat-Sheet (copy-paste khi demo)
|
||||||
|
|
||||||
|
Dùng được cho mọi tool (Claude Code, Cursor, Codex, ChatGPT...). Mở sẵn file này, demo chỉ việc copy.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ① BEFORE — cách làm sai (sẽ bỏ lọt lỗi business)
|
||||||
|
|
||||||
|
> Dán **cả file** `orderService.js` (bản đã thêm code mới), prompt mơ hồ, KHÔNG kèm CLAUDE.md, KHÔNG nói ý định:
|
||||||
|
|
||||||
|
```
|
||||||
|
Review giúp tôi file orderService.js này xem có vấn đề gì không:
|
||||||
|
|
||||||
|
<dán toàn bộ nội dung orderService.js vào đây>
|
||||||
|
```
|
||||||
|
|
||||||
|
Kết quả điển hình: vài góp ý chung chung (thêm try/catch, kiểm tra null, đặt tên...) và **bỏ lọt** lỗi cancel đơn đã shipped.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ② AFTER — đúng phương pháp (bắt đúng lỗi business)
|
||||||
|
|
||||||
|
> Kèm **CLAUDE.md**, chỉ đưa **diff**, nói rõ **ý định**, ép **lọc false positive**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Bạn review CHỈ phần code MỚI THÊM (diff) dưới đây.
|
||||||
|
Mục tiêu của PR: thêm tính năng hủy đơn hàng (cancel order).
|
||||||
|
Đối chiếu với rule trong CLAUDE.md (đính kèm).
|
||||||
|
Chỉ báo lỗi bạn CHẮC CHẮN, kèm dòng code + lý do (trích rule nếu vi phạm).
|
||||||
|
Bỏ qua nitpick và lỗi linter tự bắt.
|
||||||
|
|
||||||
|
--- CLAUDE.md ---
|
||||||
|
<dán nội dung CLAUDE.md>
|
||||||
|
|
||||||
|
--- DIFF ---
|
||||||
|
<dán phần diff trong PR-diff.md>
|
||||||
|
```
|
||||||
|
|
||||||
|
Kết quả mong đợi: bắt đúng **lỗi cancel đơn shipped** (trích rule) + chỉ ra **toMoney trùng formatCurrency**, bỏ hết nitpick.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ③ PERSONA AGENTS — chia vai để đào sâu (tùy chọn, ấn tượng)
|
||||||
|
|
||||||
|
Chạy 2 lượt riêng, mỗi lượt một vai (hoặc tạo subagent trong `.claude/agents/`):
|
||||||
|
|
||||||
|
**Business-logic agent:**
|
||||||
|
```
|
||||||
|
Bạn là reviewer chuyên về BUSINESS LOGIC.
|
||||||
|
Đối chiếu diff dưới đây với phần "Business rules" trong CLAUDE.md.
|
||||||
|
Chỉ ra mọi chỗ code đi ngược rule, kèm trích dẫn rule.
|
||||||
|
<đính kèm CLAUDE.md + diff>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Maintainability agent:**
|
||||||
|
```
|
||||||
|
Bạn là reviewer chuyên về MAINTAINABILITY.
|
||||||
|
Kiểm tra code mới có viết trùng hàm/util đã tồn tại trong repo không
|
||||||
|
(gợi ý: xem src/lib/format.js). Đề xuất tái sử dụng.
|
||||||
|
<đính kèm diff + nội dung src/lib/format.js>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ④ (Tùy chọn) Claude Code /code-review trên PR thật
|
||||||
|
Nếu muốn demo lệnh native: chạy `setup.sh` để tạo branch + diff, push lên GitHub tạo PR, rồi chạy `/code-review`.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Runbook Demo — 5 phút
|
||||||
|
|
||||||
|
## Chuẩn bị trước (KHÔNG làm live)
|
||||||
|
- Mở sẵn: `PROMPTS.md`, `CLAUDE.md`, `PR-diff.md`, `orderService.js`.
|
||||||
|
- Chạy thử 1 lần trước buổi nói, **quay màn hình** làm backup (AI live đôi khi chậm/khác).
|
||||||
|
- Diff đã đủ nhỏ (~10 dòng) để khán giả đọc hết trong 10 giây.
|
||||||
|
|
||||||
|
## Kịch bản
|
||||||
|
| Thời gian | Làm gì | Thông điệp |
|
||||||
|
|-----------|--------|-----------|
|
||||||
|
| 0:00–0:30 | Chiếu PR-diff, đọc to "feature hủy đơn, ~10 dòng". Đừng nói có lỗi. | Bối cảnh |
|
||||||
|
| 0:30–2:00 | Chạy prompt **① BEFORE** | Góp ý linh tinh, **bỏ lọt** lỗi nguy hiểm |
|
||||||
|
| 2:00–3:30 | Chạy prompt **② AFTER** | Bắt đúng lỗi cancel-shipped + trích rule, bỏ nitpick |
|
||||||
|
| 3:30–4:30 | Chạy **③ persona** (maintainability) | Tóm `toMoney` trùng `formatCurrency` |
|
||||||
|
| 4:30–5:00 | Slide so sánh + chốt | "Cùng một model, khác ở cách đưa context" |
|
||||||
|
|
||||||
|
## Mẹo chống "chết" trên sân khấu
|
||||||
|
- Tuyệt đối không gõ tay — copy từ PROMPTS.md.
|
||||||
|
- Nếu "before" lỡ bắt được lỗi: nhấn mạnh nó vẫn báo kèm nhiều nitpick vô nghĩa, còn "after" thì gọn & trúng.
|
||||||
|
- Có thể chia màn hình chạy song song before/after cho tương phản tức thì.
|
||||||
|
|
||||||
|
## Đáp án 2 lỗi cài sẵn (cho người trình bày)
|
||||||
|
1. cancelOrder không check `status === 'shipped'` → vi phạm business rule.
|
||||||
|
2. `toMoney()` trùng `formatCurrency()` đã có.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Tùy chọn: tạo git repo + branch có diff để demo /code-review trên PR thật
|
||||||
|
set -e
|
||||||
|
git init -q && git add . && git commit -qm "base: order service"
|
||||||
|
git checkout -qb feature/cancel-order
|
||||||
|
cat >> src/services/orderService.js << 'JS'
|
||||||
|
|
||||||
|
function toMoney(n) {
|
||||||
|
return n.toLocaleString('vi-VN') + ' đ';
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cancelOrder(id) {
|
||||||
|
const order = await getOrder(id);
|
||||||
|
order.status = 'cancelled';
|
||||||
|
await db.orders.save(order);
|
||||||
|
return `Đã hủy đơn. Hoàn ${toMoney(order.total)}`;
|
||||||
|
}
|
||||||
|
JS
|
||||||
|
git add . && git commit -qm "feat: thêm cancelOrder"
|
||||||
|
echo "Xong. 'git diff main' để xem diff, hoặc push lên GitHub tạo PR rồi chạy /code-review."
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// src/lib/format.js — tiện ích format đã có sẵn trong repo
|
||||||
|
export function formatCurrency(amount, currency = 'VND') {
|
||||||
|
return new Intl.NumberFormat('vi-VN', { style: 'currency', currency }).format(amount);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// src/services/orderService.js
|
||||||
|
import { db } from '../db.js';
|
||||||
|
import { formatCurrency } from '../lib/format.js';
|
||||||
|
|
||||||
|
export async function getOrder(id) {
|
||||||
|
return db.orders.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function orderSummary(order) {
|
||||||
|
return `Đơn ${order.id}: ${formatCurrency(order.total)}`;
|
||||||
|
}
|
||||||
+26
-30
@@ -1,6 +1,6 @@
|
|||||||
# Hướng Dẫn Viết & Duy Trì CLAUDE.md
|
# Hướng dẫn viết & maintain các file AGENTS.md
|
||||||
|
|
||||||
`CLAUDE.md` là **bộ luật ngắn gọn** Claude Code nạp vào context khi làm việc. Nó quyết định Claude hiểu dự án đến đâu và là nguồn rule chính cho `/code-review`. Nguyên tắc số một: đây là **bộ luật, không phải tài liệu** — mỗi dòng thừa làm loãng tín hiệu và khiến AI dễ lạc đề.
|
`AGENTS.md` là **bộ quy ước, thông tin, business logic ngắn gọn** mà AI/Tools (như Claude Code, Codex, Cursor, Antigravity, ...) nạp vào context khi làm việc. Nó quyết định AI/tools hiểu dự án đến đâu và là nguồn rule chính cho `/code-review` (hoặc các hàm tương tự). Nguyên tắc số một: đây là **bộ luật, không phải tài liệu** — mỗi dòng thừa làm loãng tín hiệu và khiến AI dễ lạc đề.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -17,63 +17,61 @@
|
|||||||
|
|
||||||
| Loại | Vị trí | Phạm vi | Theo git? |
|
| Loại | Vị trí | Phạm vi | Theo git? |
|
||||||
|------|--------|---------|-----------|
|
|------|--------|---------|-----------|
|
||||||
| **Cá nhân (global)** | `~/.claude/CLAUDE.md` | Mọi dự án trên máy bạn | Không |
|
| **Cá nhân (global)** | Nằm trong thư mục của tools như `~/.claude/CLAUDE.md` hoặc `.cursor/rules/*.mdc` | Mọi dự án trên máy bạn | Không |
|
||||||
| **Dự án (root)** | `./CLAUDE.md` (gốc repo) | Cả dự án đó | Có (cả team thấy) |
|
| **Dự án (root)** | `./CLAUDE.md` hoặc `AGENTS.md`, ... (nằm ở folder root repo) | Cả dự án đó | Có (cả team thấy và sử dụng chung được) |
|
||||||
| **Thư mục con** | `<module>/CLAUDE.md` | Chỉ code trong thư mục đó | Có |
|
| **Thư mục con** | `<module>/*.md` | Chỉ code trong thư mục đó | Có |
|
||||||
|
|
||||||
### a) Cá nhân — `~/.claude/CLAUDE.md`
|
### a) Cá nhân — `~/.claude/CLAUDE.md` (tương tự ở folder khác cho các tools khác)
|
||||||
* **Dùng cho:** phong cách & nguyên tắc làm việc của *riêng bạn*, áp cho mọi dự án (ví dụ: nguyên tắc Karpathy, "ưu tiên dùng skill", "lập kế hoạch & hỏi trước khi code").
|
* **Dùng cho:** phong cách & nguyên tắc làm việc của *riêng bạn*, áp cho mọi dự án (ví dụ: nguyên tắc Karpathy, "ưu tiên dùng skill", "lập kế hoạch & hỏi trước khi code").
|
||||||
* **KHÔNG để:** lệnh build/test hay business rule riêng của một dự án — vì nó áp cho tất cả.
|
* **KHÔNG để:** lệnh build/test hay business rule riêng của một dự án — vì nó áp cho tất cả.
|
||||||
* **Lưu ý:** chỉ tồn tại trên máy bạn, không đi theo repo nên đồng đội không thấy.
|
* **Lưu ý:** chỉ tồn tại trên máy bạn, không đi theo repo nên đồng đội không thấy.
|
||||||
|
|
||||||
### b) Dự án — `./CLAUDE.md` ở gốc repo
|
### b) Dự án — `./CLAUDE.md` ở gốc repo (tương tự ở folder khác cho các tools khác)
|
||||||
* **Dùng cho:** mọi thứ thuộc về dự án — tổng quan, lệnh build/test/lint, convention, **business rules**, do/don't.
|
* **Dùng cho:** mọi thứ thuộc về dự án — tổng quan, lệnh build/test/lint, quy ước, **business rules**, nên làm gì và không được làm gì.
|
||||||
* **Đặt ở gốc repo** (không phải trong `.claude/`), được commit nên cả team clone về là có.
|
* **Đặt ở gốc repo** (không phải trong `.claude/`), được commit nên cả team clone về là có.
|
||||||
* Đây là vị trí **chắc chắn được nạp** và quan trọng nhất cho chất lượng `/code-review`.
|
* Đây là vị trí **chắc chắn được nạp** và quan trọng nhất cho chất lượng `/code-review`.
|
||||||
|
|
||||||
### c) Thư mục con — `<module>/CLAUDE.md`
|
### c) Thư mục con — `<module>/CLAUDE.md` (tương tự ở folder khác cho các tools khác)
|
||||||
* **Dùng cho:** rule chỉ đúng cho một phần (ví dụ `src/payment/CLAUDE.md`: rule về idempotency, xử lý refund).
|
* **Dùng cho:** rule chỉ dùng cho một module cụ thể (ví dụ `src/payment/CLAUDE.md`: rule về idempotency, xử lý refund).
|
||||||
* **Vì sao quan trọng:** `/code-review` chỉ áp rule có **cùng path hoặc thư mục cha** của file đang xét. Đặt rule đúng chỗ → review đúng trọng tâm, không lôi rule chỗ khác vào.
|
* **Vì sao quan trọng:** `/code-review` chỉ áp rule có **cùng path hoặc thư mục cha** của file đang xét. Đặt rule đúng chỗ → review đúng trọng tâm, không lôi rule chỗ khác vào.
|
||||||
|
|
||||||
> Lưu ý về `.claude/` trong dự án: thư mục này chứa `settings.json`, `commands/`, `agents/` — **không** phải nơi để file memory. File memory của dự án để ở **gốc repo** (`./CLAUDE.md`). Vị trí global đáng tin là `~/.claude/CLAUDE.md` (trong home).
|
> Các file được **cộng dồn**: khi làm trong một thư mục con, ví dụ như: Claude sẽ nạp đồng thời CLAUDE.md cá nhân + gốc dự án + thư mục con.
|
||||||
|
|
||||||
> Các file được **cộng dồn**: khi làm trong một thư mục con, Claude nạp đồng thời CLAUDE.md cá nhân + gốc dự án + thư mục con.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Phân cấp & scope
|
## 2. Phân cấp & scope
|
||||||
|
|
||||||
* **Rule chung** → gốc repo (`./CLAUDE.md`).
|
* **Rule chung** → gốc repo (`./AGENTS.md`).
|
||||||
* **Rule riêng module** → `<module>/CLAUDE.md`. Đừng nhồi hết vào root.
|
* **Rule riêng module** → `<module>/AGENTS.md`. Đừng nhồi hết vào root.
|
||||||
* **Rule cá nhân, mọi dự án** → `~/.claude/CLAUDE.md`.
|
* **Rule cá nhân, mọi dự án** → `~/.claude/CLAUDE.md` hoặc `.cursor/rules/*.mdc` hoặc tương tự với các tools khác.
|
||||||
* `/code-review` xét rule theo **scope phân cấp** — đặt sai chỗ thì hoặc bị bỏ qua, hoặc áp nhầm sang code không liên quan.
|
* `/code-review` xét rule theo **scope phân cấp** — đặt sai chỗ thì hoặc bị bỏ qua, hoặc áp nhầm sang code không liên quan.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Cấu trúc chuẩn (8 phần)
|
## 3. Cấu trúc chuẩn (8 phần)
|
||||||
|
|
||||||
Phần 1, 2, 4, 5, 6 là cốt lõi; 3, 7 tùy dự án; 8 tự lớn theo thời gian. (File **cá nhân** chủ yếu dùng phần 4 + 6; file **dự án** dùng đủ; file **thư mục con** chỉ phần liên quan module.)
|
Phần 1, 2, 4, 5, 6 là cốt lõi; 3, 7 tùy dự án; 8 tự lớn theo thời gian. (File **cá nhân** chủ yếu dùng phần 4 + 6; file **dự án** dùng đủ; file **thư mục con** chỉ phần thông tin liên quan về module.)
|
||||||
|
|
||||||
* **[1] Tổng quan dự án** *(bắt buộc):* tên, mô tả ngắn, tech stack, env. 3–5 dòng.
|
* **[1] Tổng quan dự án** **(bắt buộc):** tên, mô tả ngắn, tech stack, env. 3–5 dòng.
|
||||||
* **[2] Lệnh hay dùng** *(bắt buộc):* build / test / lint / dev / deploy — để Claude 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 để /code-review không báo sai.**
|
* **[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**
|
||||||
* **[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 `@docs/....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.
|
||||||
|
|
||||||
> Mẹo giữ gọn: phần dài thì tách ra file riêng rồi `@import` (ví dụ `@KarpathyCodeGuidelines.md`). Dùng import cho cả file cá nhân lẫn dự án.
|
> Mẹo giữ gọn: phần dài thì tách ra file riêng rồi `@import` (ví dụ `@KarpathyCodeGuidelines.md`). Dùng import cho cả file cá nhân lẫn dự án.
|
||||||
|
|
||||||
> 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 Claude 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
**[Claude Code]**
|
||||||
## 4. Tự động cập nhật
|
## 4. Tự động cập nhật
|
||||||
|
|
||||||
Claude Code **không** tự viết lại CLAUDE.md hoàn toàn — và đó là điều tốt, vì file tự phình rác sẽ làm hỏng `/code-review`. Mục tiêu là *gần như không phải sửa tay*:
|
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:
|
||||||
|
|
||||||
* **Phím `#` (ít ma sát nhất):** gõ tin nhắn bắt đầu bằng `#`, ví dụ `# luôn dùng dayjs thay vì moment` → Claude tự ghi vào memory và hỏi bỏ vào file nào (cá nhân / dự án / thư mục con).
|
* **Dùng `#` (ít ảnh hưởng nhất):** gõ tin nhắn bắt đầu bằng `#`, ví dụ `# luôn dùng dayjs thay vì moment` → Claude tự ghi vào memory và hỏi bỏ vào file nào (cá nhân / dự án / thư mục con).
|
||||||
* **Lệnh `/update-memory` (tự tạo):** tạo `.claude/commands/update-memory.md` yêu cầu Claude rà `git log` + phiên gần đây, đề xuất rule high-signal cho bạn duyệt. Chạy cuối ngày hoặc sau mỗi feature.
|
* **Lệnh `/update-memory` (tự tạo):** tạo `.claude/commands/update-memory.md` yêu cầu Claude rà `git log` + phiên gần đây, đề xuất rule high-signal cho bạn duyệt. Chạy cuối ngày hoặc sau mỗi feature.
|
||||||
* **Hook (tùy chọn):** gắn hook sự kiện `Stop` để *nhắc* cập nhật. ⚠️ Đừng để hook tự ghi không qua duyệt — dễ tạo vòng lặp và làm file rác.
|
* **Hook (tùy chọn):** gắn hook sự kiện `Stop` để *nhắc* cập nhật. ⚠️ Đừng để hook tự ghi không qua duyệt — dễ tạo vòng lặp và làm file rác.
|
||||||
|
|
||||||
@@ -88,6 +86,4 @@ Claude Code **không** tự viết lại CLAUDE.md hoàn toàn — và đó là
|
|||||||
|
|
||||||
> Quy trình khuyên dùng: `/init` (1 lần) → dùng `#` bắt rule trong lúc làm → chạy `/update-memory` định kỳ & duyệt.
|
> Quy trình khuyên dùng: `/init` (1 lần) → dùng `#` bắt rule trong lúc làm → chạy `/update-memory` định kỳ & duyệt.
|
||||||
|
|
||||||
> Lưu ý về session dài: context đầy dần sẽ làm rule bị "loãng" và Claude dễ quên — chia nhỏ session (`/clear` sau mỗi task) và giữ file ngắn giúp rule "nặng ký" hơn.
|
> Lưu ý về session dài: context đầy dần sẽ làm rule bị "loãng" và Claude dễ quên — chia nhỏ session (`/clear` sau mỗi task là tốt nhất, nếu vẫn muốn giữ context hiện tại cho task tiếp theo thì hãy `/compact` nhé) và giữ file và context ngắn giúp rule được ưu tiên hơn.
|
||||||
|
|
||||||
> Chi tiết sản phẩm có thể thay đổi theo phiên bản — đối chiếu tại https://docs.claude.com/en/docs/claude-code/overview
|
|
||||||
Reference in New Issue
Block a user