If you're doing Agent development, the concept most worth spending time understanding over the past year may not be some new model, but an ordinary Markdown file called SKILL.md. It was initiated by Anthropic, released as an open standard under the name agentskills.io on December 18, 2025, and by March 2026 had been adopted by 32 platforms (including Microsoft, OpenAI, Google Gemini CLI, Cursor, and GitHub), covering entry points such as claude.ai, Claude Code, and the Claude developer platform (API). It requires no SDK, no API integration, and no deployment pipeline—just a folder plus a Markdown file, and an Agent can learn a new skill. This article is divided into two parts: Part 1 explains the definition of a Skill, the evolution of the standard, the directory structure, hard field constraints, and installation paths for 25+ platforms; Part 2 moves into the three-layer Token ledger of progressive loading, the boundary with MCP, an FAQ, and official best practices. By the end, you'll have a SKILL.md handbook you can apply directly to your team's projects.

What exactly is a Skill: a folder containing SKILL.md, and why it's like handing a new employee an onboarding guide

Let's nail down the definition first: an Agent Skill is just a folder, and the folder must contain a SKILL.md. This file is made up of two parts—at the top is a block of YAML frontmatter metadata wrapped in three dashes, which declares what the Skill is called and what it's for; below the dashes is the Markdown body, which carries the actual instructions, workflows, examples, and constraints. Besides SKILL.md, the folder can also hold scripts, templates, reference documents, and other resources for the body to reference as needed.

Why say it's like handing a new employee an onboarding guide? Imagine you've hired someone highly capable but completely unfamiliar with your team: they won't memorize all your internal documents right away. Instead, they first get a one-page role description (what this role is responsible for, when they should step in), then when they actually receive a task, they look up the corresponding operations manual, and when they need to fill out a form, they go get the template. The mechanism by which an Agent reads a Skill is exactly the same: it only reads and executes when the task is relevant. When it's not relevant, the Skill places almost no burden on its context. This is precisely the fundamental reason SKILL.md can pack a large amount of domain knowledge into a single file while still remaining scalable.

There's also a positioning issue that's often overlooked: SKILL.md is a plain-text open standard, and the same file can be used directly across 25+ compatible platforms without writing an adaptation layer for each one. This means the knowledge assets a team accumulates won't be locked into any single vendor's tool.

Initiated by Anthropic, open standard at agentskills.io: the adoption timeline from October 2025 to March 2026

The pace of Agent Skills' evolution can be seen clearly in a single timeline:

  • October 16, 2025: Agent Skills was released alongside the official PowerPoint, Excel, Word, and PDF Skills, putting "teaching an Agent to work using Markdown" on the table for the first time.
  • December 18, 2025: It was officially released as an open standard at agentskills.io, turning the format from an internal convention of one product into a de facto specification that any platform can implement.
  • March 2026: 32 platforms had already adopted the same SKILL.md format, including Microsoft, OpenAI, Google Gemini CLI, Cursor, and GitHub; meanwhile, the entry-point forms expanded from a single IDE plugin to claude.ai, Claude Code, and the Claude developer platform (API).

The engineering implication of this timeline is: writing SKILL.md in 2025 was still "early adoption," but by today, September 2026, it has become the de facto standard carrier for team knowledge assets. The description you write today may be read and matched by the same parsing logic across Agents from a dozen different vendors.

Why Skills Are Worth Writing: Domain Knowledge Packaging, Capability Completion, Auditable Processes, Cross-Platform Interoperability, and Team Knowledge Accumulation

The official value proposition lists five points, each corresponding to a real need:

  1. Packaging domain expertise. Legal review processes, data analysis pipelines, financial modeling methods, a certain personality trait—these things that were once scattered across documents, passed down by word of mouth, or locked in personal experience are solidified into a package that an Agent can read and execute. In the past, you had to repeatedly restate them in prompts; now you write once and reuse.
  2. Granting capabilities that were not originally available. Agents cannot create presentations, process PDFs, build MCP servers, or analyze datasets according to your custom schema on their own. Skills write "how to do it" as steps and scripts, and the capability is filled in.
  3. Turning multi-step tasks into consistent, auditable processes. Take database migration as an example: the same validation steps are followed every time, without relying on the model's mood and improvisation in that particular conversation. The results are naturally more stable, and it is easier to trace back "which step went wrong."
  4. Cross-platform interoperability. Write once, use without modification on 25+ platforms, with extremely low sunk cost.
  5. Team knowledge sharing. Put institutional knowledge into a version-controlled package. When people leave, the knowledge remains in the Skill—this is the trigger for many teams to truly commit to writing Skills.

Minimal Directory and Complete Directory: SKILL.md Is Required; scripts/, references/, and assets/ Are All Optional

The directory structure is not as complex as you might imagine; there are only two forms:

FormDirectory CompositionContents CarriedRequired
Minimal structureOnly SKILL.md under my-skill/Metadata + Markdown instructionsSKILL.md required
Complete structureSKILL.md + scripts/ + references/ + assets/Instructions + executable code + documentation + templates and static assetsThe latter three are all optional

The three optional directories each have clear responsibilities: scripts/ holds executable code, which is what the Agent actually "runs" when needed; references/ holds documentation, which is supplementary knowledge the Agent "reads" when needed; assets/ holds templates and static assets, such as form templates and style files. **Here is a high-frequency pitfall:** the body text must clearly state whether a resource is meant to be "read" or "run"; otherwise, the Agent may execute a reference document as a script, or read through a script as documentation, wasting a large number of tokens.

Four-step creation workflow: create a directory, write SKILL.md, add resources as needed, copy into the skills directory

There are only four steps to get it working:

  1. Create a directory: mkdir my-skill && cd my-skill. The directory name may only use lowercase letters, digits, and hyphens, because it will later be validated for consistency against the name in the frontmatter.
  2. Write SKILL.md: the frontmatter requires name and description, and the Markdown instruction body goes after the delimiter.
  3. Optionally add resources: add the three directory types scripts/, references/, and assets/ as needed, and reference them in the body.
  4. Copy into the target platform's skills directory: here you need to distinguish two scopes—a project-level Skill is shared with the whole team via git, while a user-level Skill is only available on your own machine.

Breaking down a minimal working example: the frontmatter of code-review and the When to use / Process body

The following code-review is a minimal Skill you can use right away:

---
name: code-review
description: Review code changes and provide actionable feedback. Use when the user submits a PR, requests a code review, or asks to check the quality of a piece of code.
---

## When to use

Use when the user submits a pull request, asks to review a file, or says "help me check whether there are any problems with this code."

## Process

1. Read the target code and first build an understanding of the overall intent.
2. Look for defects and boundary conditions: null values, out-of-bounds, concurrency, missing error handling.
3. Check for security vulnerabilities: injection, privilege escalation, sensitive information leakage, insecure deserialization.
4. Provide actionable feedback: pair each issue with a minimal fix example and mark its severity.

There are three key points: first, the description must clearly state both "what it does" and "when it triggers"—"Review code changes and provide actionable feedback" is what it does, and "Use when the user submits a PR..." is when to use it; neither part can be missing. Second, the body uses ## When to use to restate the trigger scenario, helping the model stay on track even in the loaded body. Third, ## Process pins down the workflow with a numbered list: read the code → check defects and boundaries → find security vulnerabilities → provide actionable feedback and examples. The more specific the steps, the higher the consistency across repeated runs.

Hard constraints on required fields: name's 64-character and hyphen rules, description's 1024-character dual elements

The validation rules can be checked programmatically, so don't rely on memory:

  • name: at most 64 characters; only lowercase letters, digits, and hyphens are allowed; must match the parent directory name; consecutive hyphens are not allowed; it cannot start or end with a hyphen.
  • description: at most 1024 characters; it must describe both "what this Skill does" and "when to activate it"; both parts are essential for reliable Skill discovery.

The reason description is a mandatory two-part element is that it gets injected into the system prompt at startup and directly participates in routing decisions. Many cases of "a Skill clearly exists but never gets triggered" trace back to a description that only states capabilities without specifying trigger scenarios.

How to use the optional fields: what license, compatibility, and metadata each carry

The three optional fields address three kinds of engineering concerns: compliance, environment, and attribution:

  • license: Write the license name, such as MIT or Apache-2.0; you can also write it as a path reference pointing to a license file bundled with the package, which facilitates compliance auditing during distribution.
  • compatibility: Declare environment requirements, including the target platform, required dependency packages, and whether network access is needed, so that the Agent or user knows before loading whether it can actually run.
  • metadata: An arbitrary key-value mapping used to store additional attributes such as author, version, and homepage; it is the place where teams anchor asset management and version tracking.

Complete example pdf-processing: license, compatibility, metadata, and how Quick start / Advanced features are organized

Putting the optional fields together with layered body content is what a production-grade SKILL.md looks like:

---
name: pdf-processing
description: Extract text and form data from PDFs and generate structured output. Use when the user needs to parse PDFs, batch-extract fields, or fill out PDF forms.
license: Apache-2.0
compatibility: Requires Python 3.10+, depends on pdfplumber and pypdf, no network access needed
metadata:
  author: platform-team
  version: 1.4.0
---

## Quick start

```python
import pdfplumber

with pdfplumber.open("input.pdf") as pdf:
    for page in pdf.pages:
        print(page.extract_text())
```

## Advanced features

For form filling, see [FORMS.md](FORMS.md).

The teaching point of this example is layering: the frontmatter uses license to state the license, uses compatibility to specify the dependencies pdfplumber and pypdf as well as the compatible host environment, and uses metadata to record author and version; the body then puts the "most commonly taken path" into ## Quick start with a directly copyable code snippet, and tucks low-frequency but complex capabilities into ## Advanced features, linking to the FORMS.md form-filling guide. This way, the body loaded by default is very short, and heavy documentation is only read when truly needed.

description Is the Trigger: The Agent Uses It to Decide Whether to Activate This Skill

This sentence must be emphasized on its own: description is the most critical part of any Skill. It is precisely on this basis that the Agent decides whether to activate the Skill, not on name, and not on the body text. Countless engineering practices have repeatedly confirmed the same conclusion: no matter how well a Skill is written, if the description does not sufficiently capture the trigger scenarios, it is as if it does not exist.

What is even more striking is that this has already been quantitatively verified. The August 2026 arXiv paper "What Keeps Agent Skills from Being Reusable?" analyzed 138,133 public SKILL.md files, dividing defects into two tiers: Tier 1 "specification compliance" with 14 checks, and Tier 2 "best-practice compliance" with 17 checks; the conclusion is that specification-compliance defects dominate, while routing (triggering) defects directly reduce the quality with which Skills are discovered. The paper also provides a very specific empirical finding: Skills whose description uses the pattern "[verb] [what it does]. Use when [trigger scenario]" have an average of 1.83 detected defects, while "specification-unaware" phrasing averages 3.00, with Cliff's δ = −0.40, a medium effect size. In other words, writing the description according to the template is a quantifiably verifiable quality gain, not a stylistic preference. In addition, Skills labeled as AI-generated differ in quality distribution from unlabeled ones, showing that labeling and human review still have value.

The following Python validation script can be placed directly into CI to check all the hard constraints above and the two-part sentence pattern:

import os
import re
import sys

NAME_RE = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
TRIGGER_HINT = ("use when", "when the user", "当用户", "当任务")

def parse_frontmatter(text):
    if not text.startswith("---"):
        raise ValueError("SKILL.md 必须以 YAML frontmatter 开头")
    parts = text.split("---", 2)
    if len(parts)  3:
        raise ValueError("frontmatter 未正确闭合")
    meta = {}
    for line in parts[1].strip().splitlines():
        if ":" in line:
            key, value = line.split(":", 1)
            meta[key.strip()] = value.strip()
    return meta, parts[2]

def validate(skill_path):
    errors = []
    skill_dir = os.path.dirname(os.path.abspath(skill_path))
    dir_name = os.path.basename(skill_dir)
    meta, body = parse_frontmatter(open(skill_path, encoding="utf-8").read())

    name = meta.get("name", "")
    desc = meta.get("description", "")

    if not name:
        errors.append("缺少必填字段 name")
    else:
        if len(name) > 64:
            errors.append("name 超过 64 字符")
        if not NAME_RE.match(name):
            errors.append("name 只允许小写字母/数字/连字符,且不能首尾为连字符")
        if name != dir_name:
            errors.append(f"name({name}) 与父目录名({dir_name}) 不一致")

    if not desc:
        errors.append("缺少必填字段 description")
    else:
        if len(desc) > 1024:
            errors.append("description 超过 1024 字符")
        full = (desc + body).lower()
        if not any(hint in full for hint in TRIGGER_HINT):
            errors.append("description 未体现触发场景,建议写成「[动词] [做什么]. Use when [触发场景]」")

    return errors

if __name__ == "__main__":
    issues = validate(sys.argv[1])
    if issues:
        print("校验未通过:")
        for item in issues:
            print(" - " + item)
        sys.exit(1)
    print("校验通过")

This script covers four high-frequency failure points: name length and character set, name identical to the parent directory, description length, and whether the "what it does + when to use it" two-part sentence pattern is missing. Hooking it into CI is far more reliable than relying on human review after the fact.

25+ Platform Compatibility Matrix and Default Install Directories: .claude/skills/, .cursor/skills/, .agents/skills/, .windsurf/skills/

Let's name the full list of compatible platforms first: Claude Code, Claude.ai, Cursor, OpenAI Codex, VS Code / GitHub Copilot, Windsurf, Gemini CLI, Amp, Roo Code, Goose, Cline, OpenCode, TRAE, Kiro, JetBrains, OpenHands, Replit, Factory, Manus, Zed, Qodo, Letta, Mistral Vibe, Agentman, VT Code, Piebald. The same SKILL.md can be copied over and used as-is; there's no need to rewrite the content for each platform.

PlatformDefault Install DirectoryTypical Install Command
Claude Code.claude/skills/ or ~/.claude/skills/cp -r my-skill .claude/skills/
Cursor.cursor/skills/cp -r my-skill .cursor/skills/
OpenAI Codex.agents/skills/ or ~/.agents/skills/cp -r my-skill .agents/skills/
Windsurf.windsurf/skills/cp -r my-skill .windsurf/skills/

Note the difference between project-level and user-level: project-level directories (such as .claude/skills/) are committed with git, so team members automatically get the same set of Skills after pulling; user-level directories (such as ~/.claude/skills/) only take effect for the current user and are suitable for personal-preference Skills. **A common pitfall:** if you place project-level and user-level Skills with the same name in a project at the same time, confirm the target platform's precedence convention to avoid the situation where "I clearly updated the Skill but it seems like it didn't take effect." On the Claude Code side, there's also a validation entry point: claude plugin validate can be used to check structural validity, and it's recommended to run it once before committing.

Also worth mentioning is the latest change in Claude Code: Skills and slash commands have been unified into a single system—both .claude/commands/review.md and .claude/skills/review/SKILL.md will produce /review. When names collide, the Skill takes precedence, and Skills support accompanying files and more frontmatter fields. In addition to the open standard fields (name / description / license / compatibility / metadata / allowed-tools), Claude Code also provides a set of extension fields: allowed-tools (tool allowlist), model (specify the model), context: fork (spawn an isolated context), agent (specify a subagent), user-invocable, disable-model-invocation, argument-hint, as well as hooks lifecycle hooks (PreToolUse / PostToolUse / Stop). These extension fields do not affect the portability of SKILL.md, because other platforms will ignore optional fields they don't recognize, but within Claude Code they unlock finer-grained control.

By now, you have mastered the definition of a Skill, the evolution of the standard, the directory structure, field constraints, example syntax, and installation paths. But what truly determines whether a Skill library can be maintained over the long term is not the format—it's the Token budget. In the next section, we move into the three-layer ledger of progressive loading, calculating exactly how many tokens each layer should spend, then compare the boundaries between Skills and MCP, answer six high-frequency FAQs, and settle on the four official best practices along with the community's second wave of practice themes: auditing, pruning, and rebuilding Skill libraries.

In the previous section, we already broke down the directory structure of SKILL.md, the frontmatter field specifications, and cross-platform installation paths one by one, and also walked through the four-step creation process of our first Skill hands-on. In this part, we shift our perspective to the runtime "ledger": at exactly what moments does the Agent read how many tokens, why can 25+ platforms use the same file so lightly, and what are the latest engineering disciplines and validation methods emerging in the 2026 ecosystem.

Three layers of progressive loading and the Token ledger: metadata at about 100 tokens, body recommended under 5000 tokens, resources with virtually no upper limit

The reason Skills can be installed in ever-greater numbers without dragging down the context is not compression, but the loading mechanism of progressive disclosure. It splits a Skill into three layers with different timings and different costs: at startup it reads only the "catalog," when triggered it reads the "body," and only the things explicitly named in the body get their "resources" read.

LayerLoading timingToken budgetContent carried
Layer 1: MetadataAlways loaded · injected into the system prompt when the Agent startsAbout 100 tokens/SkillThe name and description in frontmatter, letting the Agent know "what capabilities exist and when to use them"
Layer 2: InstructionsLoaded into context when a user request matches the Skill description and the Skill is triggeredRecommended no more than 5000 tokensThe Markdown body of SKILL.md—the actual workflow, best practices, and examples
Layer 3: ResourcesLoaded on demand · only when explicitly referenced by SKILL.md instructionsEffectively no upper limitScripts, reference docs, templates, schemas, static assets

There are three key engineering implications. First, startup cost is approximately linear in the number of Skills but extremely low—installing 40 Skills consumes only about 4000 tokens of metadata budget, and the model's perception of context is barely affected. Second, the body text is the real cost center: it determines how many extra words must be stuffed into the context the moment a Skill is triggered, so 5000 tokens is a red line that must be actively defended. Third, the "no upper limit" of the third layer is not a free lunch: its lack of an upper limit is premised on not preloading—scripts and reference documents enter the context only when referenced, which also means the SKILL.md body must clearly state "when encountering scenario X, go read references/Y.md"; otherwise the model has no idea those files exist.

A common pitfall is this: pasting the complete API documentation for PDF parsing and dozens of pages of a company's coding standards verbatim into the SKILL.md body. The result is that every time this Skill is triggered, it pays a fixed tax of 8000 tokens for knowledge that is useful in only a few tasks. The correct approach is to push them down into references/ and point to them with a single line of link in the body.

Five-dimensional comparison table of Skill and MCP: instructions and knowledge vs. external tool connections, and how the two combine

The question most often asked after Skill appeared is "is it going to replace MCP?" The answer is no—they solve two completely different engineering problems.

DimensionSkillMCP
PurposeInstructions and knowledge: teach the Agent how to do the job wellExternal tool connection: give the Agent an external capability it can call
FormatMarkdown file (with YAML frontmatter)JSON-RPC protocol
ComplexityLow—essentially just a fileRelatively high—requires a resident server
Applicable scenariosWorkflows, persona distillation, best-practice accumulationAPIs, databases, real-time data access
StateStatelessStateful connection

The two are in a complementary relationship, and many real workflows use both at the same time: MCP is responsible for connecting to BigQuery, while Skill is responsible for telling the Agent "when querying data, first confirm the time partition, then filter by business definitions, and finally use which template to output the report." Furthermore, Skill can reference MCP tools by fully qualified name, for example writing in the body "during the data verification stage, call BigQuery:query to pull the base table," thereby allowing the same Agent to connect the knowledge layer and the tool layer within a single task.

This is also why Skill's portability is so important: a Skill describing "how to do financial modeling" should behave consistently across the three entry points of claude.ai, Claude Code, and the API, provided only that the runtime environment satisfies the dependencies it declares. Whether the tool side switches MCP implementations usually does not affect the logic of the Skill body.

A defect study of 138,000 SKILL.md files: Tier 1 specification compliance and Tier 2 best-practice compliance

When Skills go from being written by a few people to being written by hundreds of thousands, quality issues are no longer a matter of personal style but a measurable corpus problem. An August 2026 arXiv paper, "What Keeps Agent Skills from Being Reusable?", analyzed 138,133 public SKILL.md files and divided defects into two categories:

  • Tier 1 "Specification Compliance": 14 checks in total, corresponding to hard constraints explicitly defined by the open standard, such as the length and character set of name, whether it matches the parent directory, and whether description is too long.
  • Tier 2 "Best Practice Compliance": 17 checks in total, corresponding to writing recommendations summarized by the official team and the community, such as whether trigger scenarios are included, whether the body is too long, and whether resource references are clear.

One of the paper's core findings is: specification-compliance defects dominate in public corpora. In other words, a large number of Skills do not even pass the bar of "being reliably discoverable." What engineering teams should be even more wary of are routing (triggering) defects—when description is written vaguely, explaining neither what it does nor when to use it, the Agent's matching becomes inaccurate; the Skill may be written in great detail, yet it is almost never activated, ultimately directly lowering the "quality of being discovered." This empirically echoes the point emphasized in the previous paragraph that "description is the most critical part of any Skill."

Quantified benefit of the description sentence pattern: [verb] [what it does]. Use when [trigger scenario] averages 1.83 defects vs 3.00

The paper's most widely shared data comes from a comparison of sentence patterns. The researchers divided description writing into two categories: one uses the structured template "[verb] [what it does]. Use when [trigger scenario]", and the other is a "specification-unaware" free-form style. The statistical results are:

  • Skills using the template sentence pattern: 1.83 defects detected on average;
  • Specification-unaware writing: 3.00 defects detected on average;
  • Effect size Cliff’s δ = −0.40, a medium effect size.

In other words, writing description according to the template is a quantifiably verifiable quality gain, not an aesthetic preference. For teams, this means putting the sentence pattern into the code review checklist is worthwhile: it turns "whether description is well written" from a subjective judgment into an automatically checkable rule. The paper also mentions that Skills labeled as AI-generated differ in quality distribution from unlabeled ones—this suggests that teams automatically generating Skills need explicit validation tools even more, rather than relying on a model to get it right in one shot.

Below is a validation script that can run directly in CI. It checks the three most commonly overlooked categories in Tier 1: name length and character set, whether name matches the parent directory name, and description length plus the two-part structure of "what it does + when to use it."

#!/usr/bin/env python3
"""validate_skill.py — validate Tier 1 specification compliance of SKILL.md in CI"""
import re
import sys
from pathlib import Path

import yaml  # pip install pyyaml

NAME_MAX = 64
DESC_MAX = 1024
WHEN_RE = re.compile(r"(use when|when to use|何时使用|适用于)", re.IGNORECASE)


def fail(msg: str) -> None:
    print(f"[FAIL] {msg}")
    sys.exit(1)


def load_frontmatter(skill_md: Path) -> dict:
    text = skill_md.read_text(encoding="utf-8")
    if not text.startswith("---"):
        fail("SKILL.md must start with the YAML frontmatter delimiter '---'")
    _, fm, _ = text.split("---", 2)
    return yaml.safe_load(fm) or {}


def check(skill_md: Path) -> None:
    fm = load_frontmatter(skill_md)
    name = fm.get("name", "")
    desc = fm.get("description", "")

    # 1) name length and character set
    if not isinstance(name, str) or not name:
        fail("name is required and must be a string")
    if len(name) > NAME_MAX:
        fail(f"name too long: {len(name)} > {NAME_MAX}")
    if not re.fullmatch(r"[a-z0-9-]+", name):
        fail("name may only contain lowercase letters, digits, and hyphens")
    if name.startswith("-") or name.endswith("-") or "--" in name:
        fail("name must not start/end with a hyphen, and consecutive hyphens are not allowed")

    # 2) name must match the parent directory name
    parent = skill_md.parent.name
    if name != parent:
        fail(f"name({name}) must match the parent directory name({parent})")

    # 3) description length + two-part structure
    if not isinstance(desc, str) or not desc.strip():
        fail("description is required")
    if len(desc) > DESC_MAX:
        fail(f"description too long: {len(desc)} > {DESC_MAX}")
    if not WHEN_RE.search(desc):
        fail("description lacks a trigger scenario; recommended pattern: '[verb][what it does]. Use when [scenario]'")
    if len(desc.strip()) < 20:
        fail("description is too short to support reliable routing decisions")

    print(f"[OK] {name}: name={len(name)} chars, description={len(desc)} chars")


if __name__ == "__main__":
    target = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(".")
    md = target / "SKILL.md" if target.is_dir() else target
    check(md)

Hooking this script into pre-commit or PR checks lets you block the cheapest yet most fatal classes of errors before merging. Note that it deliberately performs only mechanically decidable checks: the semantic question of whether a task should be handed to a Skill at all still requires human judgment.

Token budget discipline and common pitfalls: treat context as a shared resource, and community thresholds are more conservative than the official ones

The official 5000 tokens is a ceiling, not a target. Truly mature teams manage the context window as a shared resource: every Skill draws from this common budget, and any piece of content written in is charging against other Skills and the current task itself. So every time you write, it's worth asking three questions:

  1. Does the model really need this information to complete the task?
  2. Can it reasonably be assumed the model already learned this during training?
  3. Is the token cost of this content worth the price?

Community tools offer more conservative reference thresholds than the official ones, which are worth adopting as defaults for internal standards:

  • First layer name + description: target < 200 characters / < 30 tokens;
  • Second layer body: target < 50 lines / < 1,000 words / < 680 tokens.

There are several typical pitfalls: pasting an entire "example output" into the body (it should be pushed down to references/); cramming mutually exclusive scenarios into the same Skill (for example, teaching both code review and code generation, which makes the description unable to route accurately); failing to specify whether a script is meant to be "read" or "run" (the model may treat a reference implementation meant to be read as an executable command); and over-relying on implicit knowledge that "the model should understand," resulting in a lack of key context even after it is triggered.

Latest Claude Code practices: unified Skill and slash commands, extension fields, hooks, and claude plugin validate

Claude Code in 2026 merged Skills and slash commands into a single system: both .claude/commands/review.md and .claude/skills/review/SKILL.md produce /review; when both share the same name, Skill takes priority, because Skills support accompanying files and richer frontmatter fields. In addition to the open standard fields (name / description / license / compatibility / metadata / allowed-tools), Claude Code also provides several extension fields and lifecycle hooks:

  • allowed-tools: a tool allowlist, restricting the range of tools this Skill can invoke;
  • model: specify a model for this Skill;
  • context: fork: fork an independent context to avoid polluting the main conversation;
  • agent: designate a subagent to take on the task;
  • user-invocable and disable-model-invocation: control whether it is explicitly invoked by the user or whether the model is forbidden from activating it automatically;
  • argument-hint: a hint for the slash command's arguments;
  • hooks: three lifecycle hooks PreToolUse / PostToolUse / Stop, used to insert validation or logging before and after tool calls and at the end point.

At the structural level, you can use claude plugin validate for validation, catching low-level errors such as field spelling and directory layout before submission. Below is an example of a SKILL.md containing all frontmatter fields, which can be used directly as a template.

---
name: pdf-processing
description: Extract structured data from PDF documents and fill in forms. Use when the user provides a PDF and asks for text extraction, table parsing, or form completion.
license: Apache-2.0
compatibility: Requires Python 3.10+, pdfplumber and pypdf installed, host agent supporting the agentskills.io standard.
metadata:
  author: data-platform-team
  version: 1.3.0
  homepage: https://example.internal/skills/pdf-processing
allowed-tools:
  - Read
  - Bash
  - Write
---

# PDF Processing

## Quick start

Use pdfplumber to extract text page by page, then normalize whitespace.

```python
import pdfplumber

with pdfplumber.open("input.pdf") as pdf:
    for page in pdf.pages:
        print(page.extract_text() or "")
```

## Advanced features

- Form filling and AcroForm handling: see [FORMS.md](references/FORMS.md)
- Table extraction edge cases: see [TABLES.md](references/TABLES.md)
- When the user asks to *run* a batch job, execute exactly one script:
  `scripts/batch_extract.py` — do not treat the snippets above as runnable files.

## When to use

- The user uploads a PDF and asks for its contents.
- The user needs specific fields pulled from a filled form.

## Process

1. Confirm the PDF path and whether forms or plain text are needed.
2. Extract text with pdfplumber; fall back to pypdf for encrypted files.
3. Validate extracted fields against the requested schema.
4. Return results plus any pages that failed, with the reason.

Microsoft Agent Framework's Four-Stage Disclosure: Advertise, Load, read_skill_resource, run_skill_script

Microsoft Agent Framework adopts a more fine-grained "four-stage" progressive disclosure formulation, breaking down the three layers commonly described in academia into something closer to runtime actions:

  1. Advertise: about 100 tokens/Skill, injecting the name and description into the system prompt so the Agent knows the capability list;
  2. Load: when a task matches, retrieving the full SKILL.md via the load_skill tool, with the official recommendation of < 5,000 tokens;
  3. read_skill_resource: a separate action for reading resource files;
  4. run_skill_script: a separate action for executing scripts.

Modeling "reading resources" and "executing scripts" as two independent actions is a very important design for safety and observability—reading a reference document and running a piece of code carry completely different risk levels, and they should also be recorded separately during auditing. The framework simultaneously supports four Skill sources: file-based (SKILL.md in a directory), code-defined, class-defined, and MCP-based. The first three lean toward static distribution, while the last turns Skill into an object that can also be dynamically provided by a server, suitable for centralized hosting and canary releases within an enterprise.

Official Best Practices and Design Principles: Start from Evaluation, Structure for Scale, Stand in the Model's Shoes, Iterate Together with the Model

The four best practices given officially are essentially an iterative methodology:

  1. Start from evaluation: first run on real tasks, observe where the Agent gets stuck and what context it lacks, then incrementally build Skills, rather than first designing a perfect knowledge system;
  2. Structure for scale: when SKILL.md becomes bloated, split it into separate files and reference them, keep the main body within about 5k words, separate mutually exclusive scenarios, and clearly state whether a script is meant to be "read" or "run";
  3. Stand in the model's shoes: name and description determine triggering, so observe real usage traces rather than judging by assumption whether it will be invoked;
  4. Iterate together with the model: distill successful practices and common pitfalls back into the Skill, letting it evolve with practice.

Three design principles accompany these: progressive disclosure (minimize token usage), composability (multiple Skills will be loaded simultaneously, so do not assume you have exclusive capabilities), and portability (the same Skill behaves consistently across claude.ai / Claude Code / API, provided the runtime environment satisfies its dependencies). Composability is especially easy to overlook: if a Skill asserts in its main body that "this Agent is only responsible for X," it will conflict when coexisting with other Skills; a better approach is to write boundaries as preconditions and check steps.

The Kitchen Analogy and Ecosystem Signals: MCP Gives the Kitchen, Skill Gives the Recipe, and the Coming Second Wave of Auditing and Pruning

The official documentation uses a very apt analogy: MCP provides the "professional kitchen"—tools, ingredients, and equipment; Skill provides the "recipe"—how to turn those ingredients into something valuable. With MCP but no Skill, users still don't know what to do next after connecting a connector; every session starts from scratch, results are inconsistent, and ultimately the connector gets blamed. This attribution error is extremely common in practice: teams think the tool is unusable, when in fact they're missing the knowledge layer that strings tools together into a workflow.

At the ecosystem level, early commentators like Simon Willison called Agent Skills "bigger than MCP"—not because it replaces MCP, but because it solves a different problem: teaching the Agent how to do the job well, rather than just handing it a tool. By the second half of 2026, a clear second wave of practice is emerging, centered on auditing, pruning, and rebuilding previously installed Skill libraries: teams are starting to take stock of which Skills have never been triggered (description routing failures), which have overly long bodies (out-of-control token budgets), and which are no longer compatible with new platform fields. This aligns with the conclusion of the earlier study of 138,000 corpus entries—once scale is reached, governance is scarcer than creation.

Six-Question Quick FAQ: Do you need to program, can it work across Claude/Cursor/Codex, how it differs from system prompts, how many to install, what kinds you can build, and where to find them

  • Do you need to program to create a Skill?No. It's just a Markdown file—if you can write text, you can write one. There's no SDK, no build step, no deployment process; only when the body references a script does someone need to write that script.
  • Can the same Skill be used on Claude, Cursor, and OpenAI Codex?Yes. SKILL.md is an open standard initiated by Anthropic and published at agentskills.io. By 2026, 32 platforms have adopted the same format; just copy the same folder into each tool's skills directory.
  • What's the difference between a Skill and a system prompt?A system prompt is a static block of instructions that is always loaded; a Skill is a structured package loaded on demand, reading its body only when the task is relevant. Multiple Skills can coexist with minimal context consumption.
  • How many Skills can be installed?Any number—at startup, each loads only about 100 tokens of metadata, so installing dozens has minimal impact.
  • What types of Skills can be created?Technical (code review, PDF processing, testing), process-oriented (database migration, deployment), and persona-based (colleagues, celebrities, historical figures) are all possible.
  • Where can I find installable Skills?Skill libraries, GitHub, or create your own from scratch.

Summary and Best Practices

Condensing the content of these two parts into an actionable checklist:

  1. Evaluate first, then build the Skill. Observe where the Agent gets stuck on real tasks, then decide what context this Skill needs to fill in.
  2. Write the description as an interface. Use the pattern "[verb] [what it does]. Use when [trigger scenario]", which has been empirically shown to reduce average defects from 3.00 to 1.83; it also determines whether the Agent will activate you.
  3. Hold the Tier 1 hard constraints. name ≤ 64 characters, lowercase letters/digits/hyphens only, same name as the parent directory, no consecutive hyphens, no leading or trailing hyphen; description ≤ 1024 characters and answers both "what it does" and "when to use it". Hook the validation script into CI.
  4. Use three-tier loading for token budgeting. Metadata is resident at about 100 tokens/Skill; the body is recommended to be < 5000 tokens, with the community's more conservative target being < 50 lines / < 1000 words / < 680 tokens; resources are loaded on demand with virtually no upper limit.
  5. Slim the body by pushing content down. Put long documents, templates, and schemas into references/ and assets/, leaving only a one-line reference in the body; and clearly state whether the script is meant to be "read" or "run".
  6. Split by scale. If SKILL.md is bloated, split the files; split mutually exclusive scenarios into different Skills, avoiding a single Skill carrying conflicting trigger conditions.
  7. Stay composable and portable. Don't assume exclusive capabilities, and don't hardcode host-specific behavior into the body; the same Skill should behave consistently across claude.ai / Claude Code / API.
  8. Make good use of platform extension capabilities. In Claude Code, you can leverage allowed-tools, model, context: fork, agent, user-invocable, argument-hint, and PreToolUse/PostToolUse/Stop hooks, and validate the structure with claude plugin validate.
  9. Recognize the new division of labor. MCP gives the kitchen, Skill gives the recipe; a Skill can reference MCP tools using fully qualified names like BigQuery:query, collaborating within the same Agent.
  10. Regularly audit your Skill library. Check which have never been triggered, which have bodies over budget, and which fields are outdated; write successful practices and pitfalls back into the Skill to form an iterative loop.