- Custom command: tự tạo slash command bằng file Markdown trong .claude/commands/ (tên file = tên lệnh, VD audit.md → /audit; tự nhận, không cần restart). Nhận tham số qua placeholder $ARGUMENTS (string bất kỳ, không chỉ file path). Lợi ích: automation, consistency, context, flexibility; commit vào repo để cả team dùng chung.
- Skill: một FOLDER chứa skill.md (name + description + procedure) trong .claude/skills; khác custom command ở chỗ TỰ FIRE khi task khớp description (không phải gõ /tên). Chỉ description load vào context tới khi cần → đóng gói bao nhiêu procedure cũng không tốn context. Folder mang thêm reference.md (Claude chỉ đọc khi cần chiều sâu) và SCRIPT (Claude chạy, không nạp nội dung) → giữ skill.md lean, đẩy phần nặng ra side file. Verification là skill nên xây ĐẦU TIÊN: nó gỡ sự phụ thuộc "phải nhớ kiểm" — tự chạy test, đọc diff, kiểm test không bị âm thầm nới lỏng, báo pass/fail kèm bằng chứng. Done = gate được CHẠY và QUAN SÁT, không phải "code nhìn ổn". Rule of thumb: gõ cùng chỉ thị nhiều-bước hai lần → làm skill. Bộ ba: convention luôn-đúng → CLAUDE.md; procedure theo loại task → skill; luật không được skip → hook (code chạy thật, không phải instruction làm theo).
TL;DR — Hai cách đóng gói việc lặp: custom command là một file Markdown trong
.claude/commands/(có$ARGUMENTS) — nhanh, hợp việc một bước; skill là một folder cóskill.mdmô tả cả quy trình, hợp việc nhiều bước. Skill nên xây đầu tiên là verification — định nghĩa "Done" nghĩa là gì, vì đó là thứ Claude hay tự cho qua nhất.
Phần 5/7 của ghi chú khoá Claude Code in Action — đề thi thử 219 câu (chấm điểm + giải thích) nằm ở tab "Đề thi thử" trên trang tổng quan.
Custom command — tự đóng gói slash command của riêng mình
Claude Code có sẵn nhiều built-in command (gõ / để xem). Nhưng ta còn tự tạo được custom command để tự động hoá các task lặp đi lặp lại hay chạy.
Tạo một custom command
Chỉ cần dựng đúng cấu trúc thư mục trong project:
- Tìm thư mục
.claudetrong project. - Tạo thư mục con
commandsbên trong. - Tạo một file Markdown đặt tên theo command muốn có (VD
audit.md).
Tên file = tên command: audit.md sinh ra lệnh /audit. Claude Code tự nhận ngay — KHÔNG cần restart.
Ví dụ: lệnh /audit
Một command soi lỗ hổng dependency, làm 3 việc:
- Chạy
npm audit— tìm package đã cài có lỗ hổng. - Chạy
npm audit fix— áp update. - Chạy test — verify update không làm vỡ gì.
Nội dung file chỉ là văn bản chỉ thị (prompt) dặn Claude làm 3 bước đó.
Command có tham số — $ARGUMENTS
Custom command nhận argument qua placeholder $ARGUMENTS → linh hoạt, tái dùng được. VD write_tests.md:
Write comprehensive tests for: $ARGUMENTS
Testing conventions:
* Use Vitest with React Testing Library
* Place test files in a __tests__ directory in the same folder as the source file
* Name test files as [filename].test.ts(x)
* Use @/ prefix for imports
Coverage:
* Test happy paths
* Test edge cases
* Test error states
Chạy: /write_tests the use-auth.ts file in the hooks directory → phần chuỗi sau lệnh được thế vào $ARGUMENTS. Argument không nhất thiết là file path — bất kỳ string nào để cấp context/direction cho task.
Bốn lợi ích
- Automation — workflow lặp → gói thành một lệnh.
- Consistency — đảm bảo cùng các bước mỗi lần.
- Context — nhét sẵn chỉ thị + convention của project.
- Flexibility — dùng argument cho input khác nhau.
Đặc biệt hợp cho workflow riêng của dự án: chạy test suite, deploy code, hay sinh boilerplate theo convention của team.
Ngoài project-level
.claude/commands/, còn có user-level~/.claude/commands/cho lệnh cá nhân dùng xuyên mọi project — đúng cặp phân cấp nhưCLAUDE.md. (Khoá gốc không nhắc; biết để linh hoạt.)
Áp dụng thực tế: custom command = đóng gói một SOP thành một nút bấm. Đặt cạnh hai cơ chế đã học: hook là việc bắt buộc, tất định (luôn chạy); custom command là quy trình gọi-khi-cần, lại nhận được tham số. Vì file nằm trong
.claude/commands/commit được vào repo, cả team dùng chung một bộ lệnh — y như cách chia sẻCLAUDE.md/hooks. Tôi hay dùng để chuẩn hoá những thứ đội dễ làm lệch tay: một/reviewbám đúng checklist, một/deploy-checkchạy đúng thứ tự bước trước khi ship. Nó biến "tài liệu quy trình mà không ai đọc" thành "một lệnh ai cũng gõ".
Skill — đóng gói việc lặp lại, bắt đầu từ verification
Custom command ở trên phải anh gõ /tên mới chạy. Skill là bước tiến hơn: nó tự fire khi task khớp description của nó — anh khỏi phải nhớ gọi.
Một skill là một folder chứa skill.md: một name, một description (thứ kích hoạt nó), và procedure (các bước). Điểm hay về context: chỉ description được load vào context tới khi skill thật sự cần → đóng gói bao nhiêu procedure cũng không tốn context. Check vào .claude/skills của project → cả team thừa hưởng cùng một "nước đi".
| Custom command | Skill | |
|---|---|---|
| Nằm ở | .claude/commands/<tên>.md |
.claude/skills/<tên>/skill.md (cả folder) |
| Kích hoạt | User gõ /tên |
Tự fire khi task khớp description |
| Mang theo | 1 file prompt | skill.md + reference.md + script |
Vì sao verification là skill nên xây ĐẦU TIÊN
Nghĩ cách anh thường kiểm việc của Claude: nhờ nó refactor, xong rồi anh phải nhớ kiểm lại — bảo nó chạy test, hoặc tự đọc diff. Vấn đề: việc kiểm phụ thuộc anh NHỚ yêu cầu. Quên một lần → code lỗi lọt lưới.
Một verification skill gỡ bỏ sự phụ thuộc đó. Hình dạng của nó: anh nhờ refactor, xong → thay đổi khớp description của skill → skill tự fire, rồi:
- Chạy test suite.
- Đọc diff.
- Kiểm không có test nào bị âm thầm nới lỏng để pass.
- Báo pass/fail, kèm bằng chứng.
Cả luồng chạy không cần anh yêu cầu, và đi đúng các bước đó mỗi lần.
Chú ý bước 3: chạy test thấy xanh là chưa đủ — một test có thể bị nới lỏng lặng lẽ cho pass bất kể gì. Nên skill đọc diff xác nhận test không bị làm yếu. "Done" không phải "code nhìn ổn" khi chỉ đọc diff — Done là các cổng (gates) được CHẠY và QUAN SÁT, kết quả nêu tường minh.
Cùng hình dạng này gánh mọi quy trình đội lặp lại: release checklist, migration recipe, pre-PR check. Rule of thumb: gõ cùng một chỉ thị nhiều-bước HAI lần → đó là một skill.
Folder skill chứa nhiều hơn instruction
Đây là chỗ skill mạnh cho verification — folder quanh skill.md mang thêm được:
reference.mdđặt cạnh,skill.mdlink tới. Claude chỉ đọc khi thật sự cần chiều sâu → file chính giữ ngắn.- Script để trong folder. Claude chạy nó, KHÔNG nạp nội dung vào context → skill mang tooling riêng, VD
check.shchạy hết gates.
Chốt: giữ skill.md lean; đẩy phần nặng (giải thích dài + script chạy được) ra side file. File lean mô tả làm gì; side file giữ chiều sâu + công cụ.
Mặt nào sở hữu luật nào — CLAUDE.md vs Skill vs Hook
Giờ có ba nơi đặt instruction, dễ lẫn. Cách phân cho gọn:
- Convention lúc-nào-cũng-đúng (naming, file đặt đâu) →
CLAUDE.md. - Procedure/reference gắn một LOẠI task → skill.
- Luật Claude KHÔNG được phép skip → hook, không phải hai cái trên. Vì
CLAUDE.mdvà skill đều là instruction Claude làm theo; hook là code thật sự chạy. Nếu skip là không chấp nhận được → đừng phó cho instruction-following.
Áp dụng thực tế: repo này là ca gần-thành-skill điển hình. Tôi đã có gate (
npm run validate:learn,validate-pages-js, cả chuỗibuild) và đã có reference (docs/learn.md) — nhưng chúng rải ở 3 nơi: luật "nhớ chạy validate" trongCLAUDE.md, chi tiết trongdocs/, script trongscripts/. Đúng bài học, tôi có thể gói thành một.claude/skills/verify-learn/:skill.mdlean (description tự-fire khi đụngsrc-learn/),reference.mdtrỏdocs/learn.md,check.shchạy validate + build. "Check test không bị nới lỏng" trong thế giới của tôi chính là: đọc diff xem perf contract có bị phá âm thầm không (ai đó thêm lạidisplay:nonevào#learn-ssr-body, bỏcontent-visibility), và đề thi có lộanswer/explainra SSR không — validator bắt một phần, còn lại là kỷ luật quan sát diff. Và luật thật sự không được skip (validate phải pass trước push) thì thuộc về hook, không phải chữ trongCLAUDE.md: skill lo lúc đang làm, hook là phòng tuyến cuối lúc push. Với Delivery, đây đúng là "Definition of Done" đóng thành hạ tầng: không còn "tôi tin là đã kiểm", mà là gate chạy + quan sát + nêu bằng chứng, và cả đội thừa hưởng vì skill commit vào repo.
Phần tiếp theo: Claude Code: MCP server & tích hợp GitHub
Nguồn: Claude Code in Action (Anthropic Academy) — Copyright Anthropic. Phần đề thi thử cho khoá này nằm ở tab "Đề thi thử" trên trang tổng quan khoá.