TL;DR

Cơ chế quan trọng nhất của Agent Skills là Progressive Disclosure 3 tầng: AI chỉ load đúng phần cần thiết của Skill vào context, nên bạn có thể cài hàng chục Skills mà không bùng nổ context window. Dynamic context injection dùng cú pháp ! để chạy lệnh shell trước khi AI đọc - inject dữ liệu thật (git diff, PR data, API response) vào prompt tự động. YAML frontmatter kiểm soát chi tiết: ai được trigger Skill, khi nào, và bằng tool gì.

Cấu trúc file của một Skill

Một Skill hoàn chỉnh trông như sau:

ten-skill/
├── SKILL.md          (bắt buộc)
├── scripts/          (tùy chọn: code Python/Bash)
├── references/       (tùy chọn: tài liệu tham chiếu)
└── assets/           (tùy chọn: template, file mẫu)

Chỉ có SKILL.md là bắt buộc. Ba thư mục còn lại giải quyết ba vấn đề khác nhau nhưng cùng phục vụ một mục tiêu: tiết kiệm context và đảm bảo chất lượng đầu ra.

scripts/ chứa code thực thi. LLM không giỏi tính toán xác định - sắp xếp danh sách bằng token generation tốn kém và không đáng tin. Code thực thi nhanh, chính xác, và không tiêu thụ context window. Ví dụ: skill xử lý PDF của Anthropic có sẵn script Python đọc và trích xuất form fields - Claude chạy script thay vì cố đọc PDF qua token.

references/ chứa tài liệu chỉ load khi cần. Thay vì nhồi toàn bộ API spec vào SKILL.md, bạn tách ra file riêng và Claude chỉ đọc khi task yêu cầu. Giữ SKILL.md dưới 500 dòng.

Progressive Disclosure: linh hồn của Skill

Đây là cơ chế giải thích tại sao bạn có thể cài 17 Skills cùng lúc mà context không bị ngốn hết.

Hãy hình dung như một cuốn sách hướng dẫn có 3 phần:

  • Tầng 1 - Mục lục: Khi Claude Code khởi động, AI chỉ đọc namedescription của mọi Skill đã cài vào system prompt. Đây là tất cả thông tin AI cần để quyết định Skill nào phù hợp với task hiện tại.
  • Tầng 2 - Chương chính: Khi AI phán đoán Skill X phù hợp với yêu cầu của bạn, nó mới load toàn bộ nội dung SKILL.md vào context.
  • Tầng 3 - Phụ lục: Trong quá trình thực thi, nếu task cần thông tin từ references/, AI điều hướng đến đúng file đó - và chỉ file đó.

Kết quả: lượng context một Skill tiêu thụ về mặt lý thuyết là không giới hạn - vì các file phụ chỉ được đọc khi thực sự cần. Claude không cần đọc toàn bộ cuốn sổ tay khi chỉ cần làm một việc nhỏ.

YAML frontmatter - trung tâm điều khiển

File SKILL.md phải bắt đầu bằng YAML frontmatter giữa hai dấu ---. Hai trường cơ bản là namedescription. Các trường nâng cao kiểm soát hành vi chi tiết:

---
name: ten-skill
description: Mô tả skill làm gì và khi nào dùng. Đây là yếu tố quyết định trigger.
allowed-tools: Bash, Read, Grep
when_to_use: Khi người dùng nhắc đến X, Y, Z.
disable-model-invocation: false
user-invocable: true
---

description là trường quan trọng nhất. Claude dùng description để quyết định trigger hay không - và dùng semantic matching, không phải keyword matching. Mô tả mơ hồ dẫn đến trigger accuracy chỉ khoảng 55%. Viết rõ cả WHAT và WHEN, liệt kê trigger phrase bằng cả tiếng Anh lẫn ngôn ngữ bạn dùng. Description + when_to_use bị truncate ở 1.536 ký tự - viết concise.

allowed-tools pre-approve tool cho Skill - Claude dùng mà không cần hỏi permission mỗi lần.

disable-model-invocation: true ngăn Claude tự động trigger Skill. Dùng cho workflow có side effect như deploy, commit, gửi Slack - những thứ bạn muốn kiểm soát thời điểm chạy.

user-invocable: false ẩn Skill khỏi menu /. Dùng cho background knowledge - Claude biết và áp dụng ngầm, nhưng không phải lệnh người dùng gọi trực tiếp.

paths: glob pattern giới hạn Skill chỉ kích hoạt khi làm việc với file khớp pattern. Ví dụ: paths: "**/*.tsx" giúp Skill React chỉ trigger khi mở file TypeScript.

Dynamic context injection

Đây là tính năng phân biệt Skills với prompt thông thường rõ nhất.

Trong nội dung SKILL.md, bất kỳ dòng nào bắt đầu bằng ! sẽ được Claude Code chạy như shell command - trước khi AI đọc bất kỳ thứ gì. Output của command thay thế dòng lệnh đó. AI nhận kết quả, không nhận lệnh.

Ví dụ thực tế - Skill tóm tắt thay đổi code:

---
name: summarize-changes
description: Tóm tắt uncommitted changes trong git repo
---

Diff hiện tại:
!`git diff HEAD`

Hãy tóm tắt những thay đổi trên và chỉ ra điểm rủi ro nếu có.

Khi bạn gọi /summarize-changes, Claude Code chạy git diff HEAD ngay lập tức, lấy output và inject vào prompt. AI nhận được diff thật - không phải lệnh để tự chạy, không cần đoán từ file đang mở. Đây là preprocessing, không phải tool call của AI.

Ứng dụng khác: lấy PR diff từ GitHub CLI, đọc output của test suite, query trạng thái hệ thống. Bất cứ dữ liệu nào lấy được bằng shell command đều có thể inject vào ngữ cảnh của AI trước khi nó bắt đầu làm việc.

Nơi đặt Skill - 4 cấp độ

Claude Code tìm Skills theo thứ tự ưu tiên, cấp cụ thể hơn ghi đè cấp chung hơn:

  • Enterprise: Quản trị viên cài cho toàn tổ chức
  • Personal: ~/.claude/skills/ - áp dụng cho mọi project của bạn
  • Project: .claude/skills/ trong repo - chia sẻ qua git với team
  • Plugin: Dùng namespace plugin-name:skill-name, không xung đột với cấp khác

Claude Code theo dõi thay đổi file trong session - bạn edit Skill đang chạy, thay đổi có hiệu lực ngay mà không cần restart.

Kết

Progressive Disclosure, dynamic context injection và YAML frontmatter tạo thành bộ ba cơ chế cho phép Skills vừa nhẹ (không tốn context khi không dùng), vừa mạnh (inject dữ liệu thật), vừa linh hoạt (kiểm soát chính xác ai trigger và khi nào).

Cấu trúc file Skill và Dynamic Context Injection

Bài tiếp theo sẽ đi thực hành: từng bước tạo Skill đầu tiên, dùng skill-creator của Anthropic, và những lỗi hay gặp khi mới bắt đầu.