SKILL.md
Skill của bạn không bao giờ tự trigger? Vì bạn đang viết SKILL.md sai chỗ quan trọng nhất
Mình bắt đầu một series nhỏ để chia sẻ những gì đã học được khi sử dụng Claude Code trong thực tế.
Thật ra mình cũng chưa biết series này sẽ dài bao nhiêu bài, hay sẽ đi hết những chủ đề nào. Nhưng có một điều mình chắc chắn: có rất nhiều thứ “nhỏ nhưng quan trọng” mà nếu không trải qua, rất khó nhận ra — và cũng rất dễ làm sai. Okay bắt đầu thôi nào.
73% nhóm kỹ thuật đã dùng AI coding tools hàng ngày vào năm 2026, tăng từ 18% năm 2024. Nhưng có một vấn đề mà mình thấy lặp đi lặp lại: người ta viết skill xong, deploy xong, rồi skill đó nằm im không trigger bao giờ.
Không phải vì code sai. Mà vì họ đang viết field quan trọng nhất theo kiểu hoàn toàn sai mục đích.
Field đó là
description.
Trước hết, Claude Code đọc SKILL.md như thế nào?
Hiểu cơ chế này rất quan trọng, vì nó giải thích tại sao description lại quyết định tất cả.
Claude Code dùng lazy-loading: lúc startup, nó chỉ đọc name và description từ mỗi SKILL.md — không đọc gì thêm. Toàn bộ nội dung còn lại chỉ được load khi skill đó thực sự được kích hoạt.
Có nghĩa là mọi công sức bạn bỏ vào phần hướng dẫn chi tiết bên trong SKILL.md đều vô nghĩa nếu skill không bao giờ được chọn ngay từ đầu.
Lifecycle của một skill gồm 3 bước:
Startup scan — Claude quét tất cả skill directories, chỉ đọc
namevàdescription.Semantic matching — Khi bạn nhập request, Claude so ngữ nghĩa của request với descriptions đã load. Nếu đủ khớp, skill được chọn.
Full load + execution — Claude load toàn bộ SKILL.md và bắt đầu thực thi.
Thêm một ràng buộc kỹ thuật cần biết: tổng budget cho tất cả skill descriptions trong một session là 15,000 ký tự (Mikhail Shilkov, 2025). Vượt ngưỡng đó, skill có độ ưu tiên thấp hơn bị cắt khỏi context. Viết ngắn gọn, đặt từ khoá quan trọng lên đầu.
11 frontmatter fields của SKILL.md — cái nào thực sự quan trọng?
SKILL.md có 11 frontmatter fields. Chỉ 2 field ảnh hưởng đến việc skill có được phát hiện hay không. Số còn lại chỉ có tác dụng sau khi skill đã được kích hoạt rồi.
Ba biến môi trường bạn có thể dùng trực tiếp trong SKILL.md:
$ARGUMENTS— arguments truyền vào từ slash command${CLAUDE_SKILL_DIR}— đường dẫn đến thư mục skill (dùng cái này thay vì hardcode path)${CLAUDE_SESSION_ID}— ID session hiện tại
Vấn đề thực sự: bạn đang viết description cho người đọc, không phải cho model
Đây là sai lầm mình thấy nhiều nhất.
description không phải là nơi để bạn mô tả tính năng của skill. Nó là trigger specification — tức là bạn đang nói với Claude: “Đây là những tình huống mà mày nên kích hoạt skill này.”
Kết quả từ 200+ prompt tests của Mellanon (2026) rất rõ ràng:
Claude không đọc toàn bộ SKILL.md để hiểu bạn viết gì hay ho bên trong. Nó chỉ nhìn vào name + description rồi quyết định có nên sử dụng skill đó hay không. Chart này hiểu một cách đơn giản:
Viết description kiểu cho có → gần như không bao giờ được chọn (20%)
Viết rõ ràng khi nào nên dùng thì nhảy lên khoảng 50%
Nói cách khác, description không phải mô tả mà là trigger, chỉ cần viết đúng thì bạn đã tăng gấp 2.5 lần khả năng skill được trigger đúng lúc.
Anti-pattern vs. pattern tốt:
# Tệ — quá chung chung, không có trigger signal
description: Helps with documentation
# Tốt — rõ trigger, third-person, action verbs, có "Use when..."
description: Writes and reformats technical documentation for software projects.
Use when the user asks to write docs, update a README, document a function,
or create API documentation.Mọi description tốt cần trả lời được 2 câu hỏi:
Skill làm gì? — Dùng động từ hành động cụ thể: writes, analyzes, validates, generates.
Khi nào dùng? — Liệt kê ít nhất 3–4 trigger phrases phổ biến nhất mà người dùng hay nhập.
Viết ở ngôi thứ ba, thì hiện tại. “Analyzes...” thay vì “I analyze...” hay “Use this to analyze...”.
Tip nếu dùng Tiếng Việt:
Có một điều thú vị, nếu dùng skill tiếng Anh nhưng khi gửi prompt ban đầu tiếng Việt thì liệu có match không? Yên tâm là có nhé, đó là cơ chế semantic matching của Claude, dù bạn nhập tiếng Việt vẫn có thể tìm được skill chính xác, nhưng nếu muốn tốt hơn thì sao?
Thêm cụm tiếng Việt tương đương vào phần “Use when”. Ví dụ: “Use when the user asks to write docs, viết tài liệu, hoặc cập nhật README.” Claude sẽ khớp cả hai ngôn ngữ.
Kiểm soát ai được kích hoạt skill
Có 2 independent toggles bạn cần nắm: disable-model-invocation và user-invocable. Kết hợp chúng tạo ra 4 modes:
Ví dụ thực tế:
User-only dùng cho các skill nhạy cảm như
/careful(block destructive commands) hay/freeze(giới hạn edit operations) — những thứ bạn muốn chủ động ra lệnh, không để Claude tự quyết.Model-only dùng cho background skills như tự động validate code style sau mỗi lần edit — user không cần biết nó tồn tại.
Tổ chức skill phức tạp: đừng nhét tất cả vào một file
Giữ SKILL.md dưới 500 dòng. Với skill phức tạp, dùng progressive disclosure: Claude chỉ đọc thêm file khi thực sự cần.
Cấu trúc khuyến nghị:
~/.claude/skills/my-skill/
├── SKILL.md # Core instructions + chỉ dẫn load file nào khi nào
├── references/ # Chi tiết kỹ thuật, chỉ load khi cần
│ └── api-guide.md
├── scripts/ # Chạy trực tiếp, không tốn context
│ └── validate-env.sh
└── assets/ # Templates, data files
└── template.mdTrong SKILL.md, bạn chỉ dẫn Claude khi nào cần đọc gì:
- If the user asks about system design, read `references/architecture-guide.md`
- Run `scripts/validate-env.sh` to check the environment before proceeding.
- Use `${CLAUDE_SKILL_DIR}/assets/template.md` as the base template.Scripts chạy trực tiếp, chỉ output mới tiêu thụ token — bản thân script không chiếm context window. Đây là một trong những lý do mình thích tách logic ra scripts thay vì nhét hết vào SKILL.md.
Test skill — quy trình 4 bước
Một điều nhiều người không biết: mọi thay đổi vào SKILL.md yêu cầu restart Claude Code mới có hiệu lực. Không có hot-reload. Nhiều người mất hàng giờ debug mà không biết lý do đơn giản chỉ là chưa restart.
4 bước kiểm tra sau mỗi lần thay đổi:
Restart Claude Code — không có bước nào thay thế được bước này.
Gõ
/để kiểm tra skill có trong menu không — (trừ khi bạn setuser-invocable: false).Thử ít nhất 5 câu request tự nhiên khác nhau, bao gồm cả paraphrase. Nếu trigger được 3/5 lần trở lên, description đang ổn.
Nếu không trigger — rewrite description theo công thức “Use when...”, restart, test lại.
Về priority khi trùng tên skill: Enterprise > Personal (~/.claude/skills/) > Project (.claude/skills/) > Plugin.
Personal thắng Project — đặt tên rõ ràng và duy nhất để tránh conflict không mong muốn.
Bonus: Từ 18/12/2025, Agent Skills là open standard. Cùng một SKILL.md chạy được trên Claude Code, Cursor, Gemini CLI, và Codex CLI thông qua agentskills.io. Viết một lần, deploy khắp nơi.
Tóm lại
description là thứ duy nhất Claude đọc trước khi quyết định có kích hoạt skill của bạn hay không. Đó không phải nơi để bạn giải thích skill làm gì với người dùng — đó là instruction cho model về khi nào nên chọn skill này.
Ba điểm cần nhớ:
Viết
descriptionnhư trigger specification: verb + object + “Use when...” + 3–4 trigger phrases cụ thể.Budget 15,000 ký tự là giới hạn cứng cho tất cả descriptions. Ngắn gọn, từ khoá quan trọng lên đầu.
Mọi thay đổi SKILL.md yêu cầu restart Claude Code.
Bước tiếp theo đơn giản: lấy một skill bạn đang có, test với 5 câu request tự nhiên. Nếu dưới 3/5 lần trigger — rewrite description theo công thức trên, restart, test lại. Lặp cho đến khi đạt ngưỡng đó.
Nếu bạn thấy bài này hữu ích, thì hãy cho mình 1 like + 1 subscribe nhé. Nếu bạn có tips nào hay để build skill thì hãy comment bên dưới chia sẻ cùng mình.






