File: README.md
Agent Skills
A standardized way to give AI agents new capabilities and expertise.
What are Agent Skills?
Agent Skills are a lightweight, open format for extending AI agent capabilities with specialized knowledge and workflows.
At its core, a skill is a folder containing a SKILL.md file. This file includes metadata (name and description, at minimum) and instructions that tell an agent how to perform a specific task. Skills can also bundle scripts, reference materials, templates, and other resources.
my-skill/
โโโ SKILL.md # Required: metadata + instructions
โโโ scripts/ # Optional: executable code
โโโ references/ # Optional: documentation
โโโ assets/ # Optional: templates, resources
โโโ ... # Any additional files or directoriesWhy Agent Skills?
Agents are increasingly capable, but often don't have the context they need to do real work reliably. Skills solve this by packaging procedural knowledge and company-, team-, and user-specific context into portable, version-controlled folders that agents load on demand. This gives agents:
- Domain expertise: Capture specialized knowledge โ from legal review processes to data analysis pipelines to presentation formatting โ as reusable instructions and resources.
- Repeatable workflows: Turn multi-step tasks into consistent, auditable procedures.
- Cross-product reuse: Build a skill once and use it across any skills-compatible agent.
How do Agent Skills work?
Agents load skills through progressive disclosure, in three stages:
Discovery: At startup, agents load only the name and description of each available skill, just enough to know when it might be relevant.
Activation: When a task matches a skill's description, the agent reads the full
SKILL.mdinstructions into context.Execution: The agent follows the instructions, optionally executing bundled code or loading referenced files as needed.
Full instructions load only when a task calls for them, so agents can keep many skills on hand with only a small context footprint.
Where can I use Agent Skills?
Agent Skills are supported by a large number of AI tools and agentic clients โ see the Client Showcase to explore some of them!
Getting started
- Documentation โ Guides and tutorials
- Specification โ Format details
- Example Skills โ See what's possible
- Discord โ Share what you're building!
Open development
The Agent Skills format was originally developed by Anthropic, released as an open standard, and has been adopted by a growing number of agent products. The standard is open to contributions from the broader ecosystem โ see CONTRIBUTING.md for how to get involved.
License
Code in this repository is licensed under Apache 2.0. Documentation is licensed under CC-BY-4.0. See individual directories for details.
File: docs/client-implementation/adding-skills-support.mdx
title: "How to add skills support to your agent" sidebarTitle: "Adding skills support"
This guide walks through how to add Agent Skills support to an AI agent or development tool. It covers the full lifecycle: discovering skills, telling the model about them, loading their content into context, and keeping that content effective over time.
The core integration is the same regardless of your agent's architecture. The implementation details vary based on two factors:
- Where do skills live? A locally-running agent can scan the user's filesystem for skill directories. A cloud-hosted or sandboxed agent will need an alternative discovery mechanism โ an API, a remote registry, or bundled assets.
- How does the model access skill content? If the model has file-reading capabilities, it can read
SKILL.mdfiles directly. Otherwise, you'll provide a dedicated tool or inject skill content into the prompt programmatically.
The guide notes where these differences matter. You don't need to support every scenario โ follow the path that fits your agent.
Prerequisites: Familiarity with the Agent Skills specification, which defines the SKILL.md file format, frontmatter fields, and directory conventions.
The core principle: progressive disclosure
Every skills-compatible agent follows the same three-tier loading strategy:
| Tier | What's loaded | When | Token cost |
|---|---|---|---|
| 1. Catalog | Name + description | Session start | ~50-100 tokens per skill |
| 2. Instructions | Full SKILL.md body |
When the skill is activated | <5000 tokens (recommended) |
| 3. Resources | Scripts, references, assets | When the instructions reference them | Varies |
The model sees the catalog from the start, so it knows what skills are available. When it decides a skill is relevant, it loads the full instructions. If those instructions reference supporting files, the model loads them individually as needed.
This keeps the base context small while giving the model access to specialized knowledge on demand. An agent with 20 installed skills doesn't pay the token cost of 20 full instruction sets upfront โ only the ones actually used in a given conversation.
Step 1: Discover skills
At session startup, find all available skills and load their metadata.
Where to scan
Which directories you scan depends on your agent's environment. Most locally-running agents scan at least two scopes:
- Project-level (relative to the working directory): Skills specific to a project or repository.
- User-level (relative to the home directory): Skills available across all projects for a given user.
Other scopes are possible too โ for example, organization-wide skills deployed by an admin, or skills bundled with the agent itself. The right set of scopes depends on your agent's deployment model.
Within each scope, consider scanning both a client-specific directory and the .agents/skills/ convention:
| Scope | Path | Purpose |
|---|---|---|
| Project | /.<your-client>/skills/ |
Your client's native location |
| Project | /.agents/skills/ |
Cross-client interoperability |
| User | ~/.<your-client>/skills/ |
Your client's native location |
| User | ~/.agents/skills/ |
Cross-client interoperability |
The .agents/skills/ paths have emerged as a widely-adopted convention for cross-client skill sharing. While the Agent Skills specification does not mandate where skill directories live (it only defines what goes inside them), scanning .agents/skills/ means skills installed by other compliant clients are automatically visible to yours, and vice versa.
What to scan for
Within each skills directory, look for subdirectories containing a file named exactly SKILL.md:
~/.agents/skills/
โโโ pdf-processing/
โ โโโ SKILL.md โ discovered
โ โโโ scripts/
โ โโโ extract.py
โโโ data-analysis/
โ โโโ SKILL.md โ discovered
โโโ README.md โ ignored (not a skill directory)Practical scanning rules:
- Skip directories that won't contain skills, such as
.git/andnode_modules/ - Optionally respect
.gitignoreto avoid scanning build artifacts - Set reasonable bounds (e.g., max depth of 4-6 levels, max 2000 directories) to prevent runaway scanning in large directory trees
Handling name collisions
When two skills share the same name, apply a deterministic precedence rule.
The universal convention across existing implementations: project-level skills override user-level skills.
Within the same scope (e.g., two skills named code-review found under both /.agents/skills/ and /.<your-client>/skills/), either first-found or last-found is acceptable โ pick one and be consistent. Log a warning when a collision occurs so the user knows a skill was shadowed.
Trust considerations
Project-level skills come from the repository being worked on, which may be untrusted (e.g., a freshly cloned open-source project). Consider gating project-level skill loading on a trust check โ only load them if the user has marked the project folder as trusted. This prevents untrusted repositories from silently injecting instructions into the agent's context.
Cloud-hosted and sandboxed agents
If your agent runs in a container or on a remote server, it won't have access to the user's local filesystem. Discovery needs to work differently depending on the skill scope:
- Project-level skills are often the easiest case. If the agent operates on a cloned repository (even inside a sandbox), project-level skills travel with the code and can be scanned from the repo's directory tree.
- User-level and organization-level skills don't exist in the sandbox. You'll need to provision them from an external source โ for example, cloning a configuration repository, accepting skill URLs or packages through your agent's settings, or letting users upload skill directories through a web UI.
- Built-in skills can be packaged as static assets within the agent's deployment artifact, making them available in every session without external fetching.
Once skills are available to the agent, the rest of the lifecycle โ parsing, disclosure, activation โ works the same.
Step 2: Parse `SKILL.md` files
For each discovered SKILL.md, extract the metadata and body content.
Frontmatter extraction
A SKILL.md file has two parts: YAML frontmatter between --- delimiters, and a markdown body after the closing delimiter. To parse:
- Find the opening
---at the start of the file and the closing---after it. - Parse the YAML block between them. Extract
nameanddescription(required), plus any optional fields. - Everything after the closing
---, trimmed, is the skill's body content.
See the specification for the full set of frontmatter fields and their constraints.
Handling malformed YAML
Skill files authored for other clients may contain technically invalid YAML that their parsers happen to accept. The most common issue is unquoted values containing colons:
# Technically invalid YAML โ the colon breaks parsingConsider a fallback that wraps such values in quotes or converts them to YAML block scalars before retrying. This improves cross-client compatibility at minimal cost.
Lenient validation
Warn on issues but still load the skill when possible:
- Name doesn't match the parent directory name โ warn, load anyway
- Name exceeds 64 characters โ warn, load anyway
- Description is missing or empty โ skip the skill (a description is essential for disclosure), log the error
- YAML is completely unparseable โ skip the skill, log the error
Record diagnostics so they can be surfaced to the user (in a debug command, log file, or UI), but don't block skill loading on cosmetic issues.
What to store
At minimum, each skill record needs three fields:
| Field | Description |
|---|---|
name |
From frontmatter |
description |
From frontmatter |
location |
Absolute path to the SKILL.md file |
Store these in an in-memory map keyed by name for fast lookup during activation.
You can also store the body (the markdown content after the frontmatter) at discovery time, or read it from location at activation time. Storing it makes activation faster; reading it at activation time uses less memory in aggregate and picks up changes to skill files between activations.
The skill's base directory (the parent directory of location) is needed later to resolve relative paths and enumerate bundled resources โ derive it from location when needed.
Step 3: Disclose available skills to the model
Tell the model what skills exist without loading their full content. This is tier 1 of progressive disclosure.
Building the skill catalog
For each discovered skill, include name, description, and optionally location (the path to the SKILL.md file) in whatever structured format suits your stack โ XML, JSON, or a bulleted list all work:
<available_skills>
<skill>
<name>pdf-processing</name>
<description>Extract PDF text, fill forms, merge files. Use when handling PDFs.</description>
<location>/home/user/.agents/skills/pdf-processing/SKILL.md</location>
</skill>
<skill>
<name>data-analysis</name>
<description>Analyze datasets, generate charts, and create summary reports.</description>
<location>/home/user/project/.agents/skills/data-analysis/SKILL.md</location>
</skill>
</available_skills>The location field serves two purposes: it enables file-read activation (see Step 4), and it gives the model a base path for resolving relative references in the skill body (like scripts/evaluate.py). If your dedicated activation tool provides the skill directory path in its result (see Structured wrapping in Step 4), you can omit location from the catalog. Otherwise, include it.
Each skill adds roughly 50-100 tokens to the catalog. Even with dozens of skills installed, the catalog remains compact.
Where to place the catalog
Two approaches are common:
System prompt section: Add the catalog as a labeled section in the system prompt, preceded by brief instructions on how to use skills. This is the simplest approach and works with any model that has access to a file-reading tool.
Tool description: Embed the catalog in the description of a dedicated skill-activation tool (see Step 4). This keeps the system prompt clean and naturally couples discovery with activation.
Both work. System prompt placement is simpler and more broadly compatible; tool description embedding is cleaner when you have a dedicated activation tool.
Behavioral instructions
Include a short instruction block alongside the catalog telling the model how and when to use skills. The wording depends on which activation mechanism you support (see Step 4):
If the model activates skills by reading files:
The following skills provide specialized instructions for specific tasks.
When a task matches a skill's description, use your file-read tool to load
the SKILL.md at the listed location before proceeding.
When a skill references relative paths, resolve them against the skill's
directory (the parent of SKILL.md) and use absolute paths in tool calls.If the model activates skills via a dedicated tool:
The following skills provide specialized instructions for specific tasks.
When a task matches a skill's description, call the activate_skill tool
with the skill's name to load its full instructions.Keep these instructions concise. The goal is to tell the model that skills exist and how to load them โ the skill content itself provides the detailed instructions once loaded.
Filtering
Some skills should be excluded from the catalog. Common reasons:
- The user has disabled the skill in settings
- A permission system denies access to the skill
- The skill has opted out of model-driven activation (e.g., via a
disable-model-invocationflag)
Hide filtered skills entirely from the catalog rather than listing them and blocking at activation time. This prevents the model from wasting turns attempting to load skills it can't use.
When no skills are available
If no skills are discovered, omit the catalog and behavioral instructions entirely. Don't show an empty <available_skills/> block or register a skill tool with no valid options โ this would confuse the model.
Step 4: Activate skills
When the model or user selects a skill, deliver the full instructions into the conversation context. This is tier 2 of progressive disclosure.
Model-driven activation
Most implementations rely on the model's own judgment as the activation mechanism, rather than implementing harness-side trigger matching or keyword detection. The model reads the catalog (from Step 3), decides a skill is relevant to the current task, and loads it.
Two implementation patterns:
File-read activation: The model calls its standard file-read tool with the SKILL.md path from the catalog. No special infrastructure needed โ the agent's existing file-reading capability is sufficient. The model receives the file content as a tool result. This is the simplest approach when the model has file access.
Dedicated tool activation: Register a tool (e.g., activate_skill) that takes a skill name and returns the content. This is required when the model can't read files directly, and optional (but useful) even when it can. Advantages over raw file reads:
- Control what content is returned โ e.g., strip YAML frontmatter or preserve it (see What the model receives below)
- Wrap content in structured tags for identification during context management
- List bundled resources (e.g.,
references/*) alongside the instructions - Enforce permissions or prompt for user consent
- Track activation for analytics
User-explicit activation
Users should also be able to activate skills directly, without waiting for the model to decide. The most common pattern is a slash command or mention syntax (/skill-name or $skill-name) that the harness intercepts. The specific syntax is up to you โ the key idea is that the harness handles the lookup and injection, so the model receives skill content without needing to take an activation action itself.
An autocomplete widget (listing available skills as the user types) can also make this discoverable.
What the model receives
When a skill is activated, the model receives the skill's instructions. Two options for what exactly that content looks like:
Full file: The model sees the entire SKILL.md including YAML frontmatter. This is the natural outcome with file-read activation, where the model reads the raw file. It's also a valid choice for dedicated tools. The frontmatter may contain fields useful at activation time โ for example, compatibility notes environment requirements that could inform how the model executes the skill's instructions.
Body only (frontmatter stripped): The harness parses and removes the YAML frontmatter, returning only the markdown instructions. Among existing implementations with dedicated activation tools, most take this approach โ stripping the frontmatter after extracting name and description during discovery.
Both approaches work in practice.
Structured wrapping
If you use a dedicated activation tool, consider wrapping skill content in identifying tags. For example:
<skill_content name="pdf-processing">
# PDF Processing
## When to use this skill
Use this skill when the user needs to work with PDF files...
[rest of SKILL.md body]
Skill directory: /home/user/.agents/skills/pdf-processing
Relative paths in this skill are relative to the skill directory.
<skill_resources>
<file>scripts/extract.py</file>
<file>scripts/merge.py</file>
<file>references/pdf-spec-summary.md</file>
</skill_resources>
</skill_content>This has practical benefits:
- The model can clearly distinguish skill instructions from other conversation content
- The harness can identify skill content during context compaction (Step 5)
- Bundled resources are surfaced to the model without being eagerly loaded
Listing bundled resources
When a dedicated activation tool returns skill content, it can also enumerate supporting files (scripts, references, assets) in the skill directory โ but it should not eagerly read them. The model loads specific files on demand using its file-read tools when the skill's instructions reference them.
For large skill directories, consider capping the listing and noting that it may be incomplete.
Permission allowlisting
If your agent has a permission system that gates file access, allowlist skill directories so the model can read bundled resources without triggering user confirmation prompts. Without this, every reference to a bundled script or reference file results in a permission dialog, breaking the flow for skills that include resources beyond the SKILL.md itself.
Step 5: Manage skill context over time
Once skill instructions are in the conversation context, keep them effective for the duration of the session.
Protect skill content from context compaction
If your agent truncates or summarizes older messages when the context window fills up, exempt skill content from pruning. Skill instructions are durable behavioral guidance โ losing them mid-conversation silently degrades the agent's performance without any visible error. The model continues operating but without the specialized instructions the skill provided.
Common approaches:
- Flag skill tool outputs as protected so the pruning algorithm skips them
- Use the structured tags from Step 4 to identify skill content and preserve it during compaction
Deduplicate activations
Consider tracking which skills have been activated in the current session. If the model (or user) attempts to load a skill that's already in context, you can skip the re-injection to avoid the same instructions appearing multiple times in the conversation.
Subagent delegation (optional)
This is an advanced pattern only supported by some clients. Instead of injecting skill instructions into the main conversation, the skill is run in a separate subagent session. The subagent receives the skill instructions, performs the task, and returns a summary of its work to the main conversation.
This pattern is useful when a skill's workflow is complex enough to benefit from a dedicated, focused session.
File: docs/skill-creation/best-practices.mdx
title: "Best practices for skill creators" sidebarTitle: "Best practices"
Start from real expertise
A common pitfall in skill creation is asking an LLM to generate a skill without providing domain-specific context โ relying solely on the LLM's general training knowledge. The result is vague, generic procedures ("handle errors appropriately," "follow best practices for authentication") rather than the specific API patterns, edge cases, and project conventions that make a skill valuable.
Effective skills are grounded in real expertise. The key is feeding domain-specific context into the creation process.
Extract from a hands-on task
Complete a real task in conversation with an agent, providing context, corrections, and preferences along the way. Then extract the reusable pattern into a skill. Pay attention to:
- Steps that worked โ the sequence of actions that led to success
- Corrections you made โ places where you steered the agent's approach (e.g., "use library X instead of Y," "check for edge case Z")
- Input/output formats โ what the data looked like going in and coming out
- Context you provided โ project-specific facts, conventions, or constraints the agent didn't already know
Synthesize from existing project artifacts
When you have a body of existing knowledge, you can feed it into an LLM and ask it to synthesize a skill. A data-pipeline skill synthesized from your team's actual incident reports and runbooks will outperform one synthesized from a generic "data engineering best practices" article, because it captures your schemas, failure modes, and recovery procedures. The key is project-specific material, not generic references.
Good source material includes:
- Internal documentation, runbooks, and style guides
- API specifications, schemas, and configuration files
- Code review comments and issue trackers (captures recurring concerns and reviewer expectations)
- Version control history, especially patches and fixes (reveals patterns through what actually changed)
- Real-world failure cases and their resolutions
Refine with real execution
The first draft of a skill usually needs refinement. Run the skill against real tasks, then feed the results โ all of them, not just failures โ back into the creation process. Ask: what triggered false positives? What was missed? What could be cut?
Even a single pass of execute-then-revise noticeably improves quality, and complex domains often benefit from several.
For a more structured approach to iteration, including test cases, assertions, and grading, see Evaluating skill output quality.
Spending context wisely
Once a skill activates, its full SKILL.md body loads into the agent's context window alongside conversation history, system context, and other active skills. Every token in your skill competes for the agent's attention with everything else in that window.
Add what the agent lacks, omit what it knows
Focus on what the agent wouldn't know without your skill: project-specific conventions, domain-specific procedures, non-obvious edge cases, and the particular tools or APIs to use. You don't need to explain what a PDF is, how HTTP works, or what a database migration does.
## Extract PDF text
PDF (Portable Document Format) files are a common file format that contains
text, images, and other content. To extract text from a PDF, you'll need to
use a library. pdfplumber is recommended because it handles most cases well.
## Extract PDF text
Use pdfplumber for text extraction. For scanned documents, fall back to
pdf2image with pytesseract.
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
```Ask yourself about each piece of content: "Would the agent get this wrong without this instruction?" If the answer is no, cut it. If you're unsure, test it. And if the agent already handles the entire task well without the skill, the skill may not be adding value. See Evaluating skill output quality for how to test this systematically.
Design coherent units
Deciding what a skill should cover is like deciding what a function should do: you want it to encapsulate a coherent unit of work that composes well with other skills. Skills scoped too narrowly force multiple skills to load for a single task, risking overhead and conflicting instructions. Skills scoped too broadly become hard to activate precisely. A skill for querying a database and formatting the results may be one coherent unit, while a skill that also covers database administration is probably trying to do too much.
Aim for moderate detail
Overly comprehensive skills can hurt more than they help โ the agent struggles to extract what's relevant and may pursue unproductive paths triggered by instructions that don't apply to the current task. Concise, stepwise guidance with a working example tends to outperform exhaustive documentation. When you find yourself covering every edge case, consider whether most are better handled by the agent's own judgment.
Structure large skills with progressive disclosure
The specification recommends keeping SKILL.md under 500 lines and 5,000 tokens โ just the core instructions the agent needs on every run. When a skill legitimately needs more content, move detailed reference material to separate files in references/ or similar directories.
The key is telling the agent when to load each file. "Read references/api-errors.md if the API returns a non-200 status code" is more useful than a generic "see references/ for details." This lets the agent load context on demand rather than up front, which is how progressive disclosure is designed to work.
Calibrating control
Not every part of a skill needs the same level of prescriptiveness. Match the specificity of your instructions to the fragility of the task.
Match specificity to fragility
Give the agent freedom when multiple approaches are valid and the task tolerates variation. For flexible instructions, explaining why can be more effective than rigid directives โ an agent that understands the purpose behind an instruction makes better context-dependent decisions. A code review skill can describe what to look for without prescribing exact steps:
## Code review process
1. Check all database queries for SQL injection (use parameterized queries)
2. Verify authentication checks on every endpoint
3. Look for race conditions in concurrent code paths
4. Confirm error messages don't leak internal detailsBe prescriptive when operations are fragile, consistency matters, or a specific sequence must be followed:
## Database migration
Run exactly this sequence:
```bash
python scripts/migrate.py --verify --backup
```
Do not modify the command or add additional flags.Most skills have a mix. Calibrate each part independently.
Provide defaults, not menus
When multiple tools or approaches could work, pick a default and mention alternatives briefly rather than presenting them as equal options.
You can use pypdf, pdfplumber, PyMuPDF, or pdf2image...
Use pdfplumber for text extraction:
```python
import pdfplumber
```
For scanned PDFs requiring OCR, use pdf2image with pytesseract instead.Favor procedures over declarations
A skill should teach the agent how to approach a class of problems, not what to produce for a specific instance. Compare:
Join the `orders` table to `customers` on `customer_id`, filter where
`region = 'EMEA'`, and sum the `amount` column.
1. Read the schema from `references/schema.yaml` to find relevant tables
2. Join tables using the `_id` foreign key convention
3. Apply any filters from the user's request as WHERE clauses
4. Aggregate numeric columns as needed and format as a markdown tableThis doesn't mean skills can't include specific details โ output format templates (see Templates for output format), constraints like "never output PII," and tool-specific instructions are all valuable. The point is that the approach should generalize even when individual details are specific.
Patterns for effective instructions
These are reusable techniques for structuring skill content. Not every skill needs all of them โ use the ones that fit your task.
Gotchas sections
The highest-value content in many skills is a list of gotchas โ environment-specific facts that defy reasonable assumptions. These aren't general advice ("handle errors appropriately") but concrete corrections to mistakes the agent will make without being told otherwise:
## Gotchas
- The `users` table uses soft deletes. Queries must include
`WHERE deleted_at IS NULL` or results will include deactivated accounts.
- The user ID is `user_id` in the database, `uid` in the auth service,
and `accountId` in the billing API. All three refer to the same value.
- The `/health` endpoint returns 200 as long as the web server is running,
even if the database connection is down. Use `/ready` to check full
service health.Keep gotchas in SKILL.md where the agent reads them before encountering the situation. A separate reference file works if you tell the agent when to load it, but for non-obvious issues, the agent may not recognize the trigger.
Templates for output format
When you need the agent to produce output in a specific format, provide a template. This is more reliable than describing the format in prose, because agents pattern-match well against concrete structures. Short templates can live inline in SKILL.md; for longer templates, or templates only needed in certain cases, store them in assets/ and reference them from SKILL.md so they only load when needed.
## Report structure
Use this template, adapting sections as needed for the specific analysis:
```markdown
# [Analysis Title]
## Executive summary
[One-paragraph overview of key findings]
## Key findings
- Finding 1 with supporting data
- Finding 2 with supporting data
## Recommendations
1. Specific actionable recommendation
2. Specific actionable recommendation
```Checklists for multi-step workflows
An explicit checklist helps the agent track progress and avoid skipping steps, especially when steps have dependencies or validation gates.
## Form processing workflow
Progress:
- [ ] Step 1: Analyze the form (run `scripts/analyze_form.py`)
- [ ] Step 2: Create field mapping (edit `fields.json`)
- [ ] Step 3: Validate mapping (run `scripts/validate_fields.py`)
- [ ] Step 4: Fill the form (run `scripts/fill_form.py`)
- [ ] Step 5: Verify output (run `scripts/verify_output.py`)Validation loops
Instruct the agent to validate its own work before moving on. The pattern is: do the work, run a validator (a script, a reference checklist, or a self-check), fix any issues, and repeat until validation passes.
## Editing workflow
1. Make your edits
2. Run validation: `python scripts/validate.py output/`
3. If validation fails:
- Review the error message
- Fix the issues
- Run validation again
4. Only proceed when validation passesA reference document can also serve as the "validator" โ instruct the agent to check its work against the reference before finalizing.
Plan-validate-execute
For batch or destructive operations, have the agent create an intermediate plan in a structured format, validate it against a source of truth, and only then execute.
## PDF form filling
1. Extract form fields: `python scripts/analyze_form.py input.pdf` โ `form_fields.json`
(lists every field name, type, and whether it's required)
2. Create `field_values.json` mapping each field name to its intended value
3. Validate: `python scripts/validate_fields.py form_fields.json field_values.json`
(checks that every field name exists in the form, types are compatible, and
required fields aren't missing)
4. If validation fails, revise `field_values.json` and re-validate
5. Fill the form: `python scripts/fill_form.py input.pdf field_values.json output.pdf`The key ingredient is step 3: a validation script that checks the plan (field_values.json) against the source of truth (form_fields.json). Errors like "Field 'signature_date' not found โ available fields: customer_name, order_total, signature_date_signed" give the agent enough information to self-correct.
Bundling reusable scripts
When iterating on a skill, compare the agent's execution traces across test cases. If you notice the agent independently reinventing the same logic each run โ building charts, parsing a specific format, validating output โ that's a signal to write a tested script once and bundle it in scripts/.
For more on designing and bundling scripts, see Using scripts in skills.
Next steps
Once you have a working skill, two guides can help you refine it further:
- Evaluating skill output quality โ Set up test cases, grade results, and iterate systematically.
- Optimizing skill descriptions โ Test and improve your skill's
descriptionfield so it triggers on the right prompts.
File: docs/skill-creation/evaluating-skills.mdx
title: "Evaluating skill output quality" sidebarTitle: "Evaluating skills"
You wrote a skill, tried it on a prompt, and it seemed to work. But does it work reliably โ across varied prompts, in edge cases, better than no skill at all? Running structured evaluations (evals) answers these questions and gives you a feedback loop for improving the skill systematically.
Designing test cases
A test case has three parts:
- Prompt: a realistic user message โ the kind of thing someone would actually type.
- Expected output: a human-readable description of what success looks like.
- Input files (optional): files the skill needs to work with.
Store test cases in evals/evals.json inside your skill directory:
{
"skill_name": "csv-analyzer",
"evals": [
{
"id": 1,
"prompt": "I have a CSV of monthly sales data in data/sales_2025.csv. Can you find the top 3 months by revenue and make a bar chart?",
"expected_output": "A bar chart image showing the top 3 months by revenue, with labeled axes and values.",
"files": ["evals/files/sales_2025.csv"]
},
{
"id": 2,
"prompt": "there's a csv in my downloads called customers.csv, some rows have missing emails โ can you clean it up and tell me how many were missing?",
"expected_output": "A cleaned CSV with missing emails handled, plus a count of how many were missing.",
"files": ["evals/files/customers.csv"]
}
]
}Tips for writing good test prompts:
- Start with 2-3 test cases. Don't over-invest before you've seen your first round of results. You can expand the set later.
- Vary the prompts. Use different phrasings, levels of detail, and formality. Some prompts should be casual ("hey can you clean up this csv"), others precise ("Parse the CSV at data/input.csv, drop rows where column B is null, and write the result to data/output.csv").
- Cover edge cases. Include at least one prompt that tests a boundary condition โ a malformed input, an unusual request, or a case where the skill's instructions might be ambiguous.
- Use realistic context. Real users mention file paths, column names, and personal context. Prompts like "process this data" are too vague to test anything useful.
Don't worry about defining specific pass/fail checks yet โ just the prompts and expected outputs. You'll add detailed checks (called assertions) after you see what the first run produces.
Running evals
The core pattern is to run each test case twice: once with the skill and once without it (or with a previous version). This gives you a baseline to compare against.
Workspace structure
Organize eval results in a workspace directory alongside your skill directory. Each pass through the full eval loop gets its own iteration-N/ directory. Within that, each test case gets an eval directory with with_skill/ and without_skill/ subdirectories:
csv-analyzer/
โโโ SKILL.md
โโโ evals/
โโโ evals.json
csv-analyzer-workspace/
โโโ iteration-1/
โโโ eval-top-months-chart/
โ โโโ with_skill/
โ โ โโโ outputs/ # Files produced by the run
โ โ โโโ timing.json # Tokens and duration
โ โ โโโ grading.json # Assertion results
โ โโโ without_skill/
โ โโโ outputs/
โ โโโ timing.json
โ โโโ grading.json
โโโ eval-clean-missing-emails/
โ โโโ with_skill/
โ โ โโโ outputs/
โ โ โโโ timing.json
โ โ โโโ grading.json
โ โโโ without_skill/
โ โโโ outputs/
โ โโโ timing.json
โ โโโ grading.json
โโโ benchmark.json # Aggregated statisticsThe main file you author by hand is evals/evals.json. The other JSON files (grading.json, timing.json, benchmark.json) are produced during the eval process โ by the agent, by scripts, or by you.
Spawning runs
Each eval run should start with a clean context โ no leftover state from previous runs or from the skill development process. This ensures the agent follows only what the SKILL.md tells it. In environments that support subagents (Claude Code, for example), this isolation comes naturally: each child task starts fresh. Without subagents, use a separate session for each run.
For each run, provide:
- The skill path (or no skill for the baseline)
- The test prompt
- Any input files
- The output directory
Here's an example of the instructions you'd give the agent for a single with-skill run:
Execute this task:
- Skill path: /path/to/csv-analyzer
- Task: I have a CSV of monthly sales data in data/sales_2025.csv.
Can you find the top 3 months by revenue and make a bar chart?
- Input files: evals/files/sales_2025.csv
- Save outputs to: csv-analyzer-workspace/iteration-1/eval-top-months-chart/with_skill/outputs/For the baseline, use the same prompt but without the skill path, saving to without_skill/outputs/.
When improving an existing skill, use the previous version as your baseline. Snapshot it before editing (cp -r <skill-path> <workspace>/skill-snapshot/), point the baseline run at the snapshot, and save to old_skill/outputs/ instead of without_skill/.
Capturing timing data
Timing data lets you compare how much time and tokens the skill costs relative to the baseline โ a skill that dramatically improves output quality but triples token usage is a different trade-off than one that's both better and cheaper. When each run completes, record the token count and duration:
{
"total_tokens": 84852,
"duration_ms": 23332
}Writing assertions
Assertions are verifiable statements about what the output should contain or achieve. Add them after you see your first round of outputs โ you often don't know what "good" looks like until the skill has run.
Good assertions:
"The output file is valid JSON"โ programmatically verifiable."The bar chart has labeled axes"โ specific and observable."The report includes at least 3 recommendations"โ countable.
Weak assertions:
"The output is good"โ too vague to grade."The output uses exactly the phrase 'Total Revenue: $X'"โ too brittle; correct output with different wording would fail.
Not everything needs an assertion. Some qualities โ writing style, visual design, whether the output "feels right" โ are hard to decompose into pass/fail checks. These are better caught during human review. Reserve assertions for things that can be checked objectively.
Add assertions to each test case in evals/evals.json:
{
"skill_name": "csv-analyzer",
"evals": [
{
"id": 1,
"prompt": "I have a CSV of monthly sales data in data/sales_2025.csv. Can you find the top 3 months by revenue and make a bar chart?",
"expected_output": "A bar chart image showing the top 3 months by revenue, with labeled axes and values.",
"files": ["evals/files/sales_2025.csv"],
"assertions": [
"The output includes a bar chart image file",
"The chart shows exactly 3 months",
"Both axes are labeled",
"The chart title or caption mentions revenue"
]
}
]
}Grading outputs
Grading means evaluating each assertion against the actual outputs and recording PASS or FAIL with specific evidence. The evidence should quote or reference the output, not just state an opinion.
The simplest approach is to give the outputs and assertions to an LLM and ask it to evaluate each one. For assertions that can be checked by code (valid JSON, correct row count, file exists with expected dimensions), use a verification script โ scripts are more reliable than LLM judgment for mechanical checks and reusable across iterations.
{
"assertion_results": [
{
"text": "The output includes a bar chart image file",
"passed": true,
"evidence": "Found chart.png (45KB) in outputs directory"
},
{
"text": "The chart shows exactly 3 months",
"passed": true,
"evidence": "Chart displays bars for March, July, and November"
},
{
"text": "Both axes are labeled",
"passed": false,
"evidence": "Y-axis is labeled 'Revenue ($)' but X-axis has no label"
},
{
"text": "The chart title or caption mentions revenue",
"passed": true,
"evidence": "Chart title reads 'Top 3 Months by Revenue'"
}
],
"summary": {
"passed": 3,
"failed": 1,
"total": 4,
"pass_rate": 0.75
}
}Grading principles
- Require concrete evidence for a PASS. Don't give the benefit of the doubt. If an assertion says "includes a summary" and the output has a section titled "Summary" with one vague sentence, that's a FAIL โ the label is there but the substance isn't.
- Review the assertions themselves, not just the results. While grading, notice when assertions are too easy (always pass regardless of skill quality), too hard (always fail even when the output is good), or unverifiable (can't be checked from the output alone). Fix these for the next iteration.
Aggregating results
Once every run in the iteration is graded, compute summary statistics per configuration and save them to benchmark.json alongside the eval directories (e.g., csv-analyzer-workspace/iteration-1/benchmark.json):
{
"run_summary": {
"with_skill": {
"pass_rate": { "mean": 0.83, "stddev": 0.06 },
"time_seconds": { "mean": 45.0, "stddev": 12.0 },
"tokens": { "mean": 3800, "stddev": 400 }
},
"without_skill": {
"pass_rate": { "mean": 0.33, "stddev": 0.10 },
"time_seconds": { "mean": 32.0, "stddev": 8.0 },
"tokens": { "mean": 2100, "stddev": 300 }
},
"delta": {
"pass_rate": 0.50,
"time_seconds": 13.0,
"tokens": 1700
}
}
}The delta tells you what the skill costs (more time, more tokens) and what it buys (higher pass rate). A skill that adds 13 seconds but improves pass rate by 50 percentage points is probably worth it. A skill that doubles token usage for a 2-point improvement might not be.
Analyzing patterns
Aggregate statistics can hide important patterns. After computing the benchmarks:
- Remove or replace assertions that always pass in both configurations. These don't tell you anything useful โ the model handles them fine without the skill. They inflate the with-skill pass rate without reflecting actual skill value.
- Investigate assertions that always fail in both configurations. Either the assertion is broken (asking for something the model can't do), the test case is too hard, or the assertion is checking for the wrong thing. Fix these before the next iteration.
- Study assertions that pass with the skill but fail without. This is where the skill is clearly adding value. Understand why โ which instructions or scripts made the difference?
- Tighten instructions when results are inconsistent across runs. If the same eval passes sometimes and fails others (reflected as high
stddevin the benchmark), the eval may be flaky (sensitive to model randomness), or the skill's instructions may be ambiguous enough that the model interprets them differently each time. Add examples or more specific guidance to reduce ambiguity. - Check time and token outliers. If one eval takes 3x longer than the others, read its execution transcript (the full log of what the model did during the run) to find the bottleneck.
Reviewing results with a human
Assertion grading and pattern analysis catch a lot, but they only check what you thought to write assertions for. A human reviewer brings a fresh perspective โ catching issues you didn't anticipate, noticing when the output is technically correct but misses the point, or spotting problems that are hard to express as pass/fail checks. For each test case, review the actual outputs alongside the grades.
Record specific feedback for each test case and save it in the workspace (e.g., as a feedback.json alongside the eval directories):
{
"eval-top-months-chart": "The chart is missing axis labels and the months are in alphabetical order instead of chronological.",
"eval-clean-missing-emails": ""
}"The chart is missing axis labels" is actionable; "looks bad" is not. Empty feedback means the output looked fine โ that test case passed your review. During the iteration step, focus your improvements on the test cases where you had specific complaints.
Iterating on the skill
After grading and reviewing, you have three sources of signal:
- Failed assertions point to specific gaps โ a missing step, an unclear instruction, or a case the skill doesn't handle.
- Human feedback points to broader quality issues โ the approach was wrong, the output was poorly structured, or the skill produced a technically correct but unhelpful result.
- Execution transcripts reveal why things went wrong. If the agent ignored an instruction, the instruction may be ambiguous. If the agent spent time on unproductive steps, those instructions may need to be simplified or removed.
The most effective way to turn these signals into skill improvements is to give all three โ along with the current SKILL.md โ to an LLM and ask it to propose changes. The LLM can synthesize patterns across failed assertions, reviewer complaints, and transcript behavior that would be tedious to connect manually. When prompting the LLM, include these guidelines:
- Generalize from feedback. The skill will be used across many different prompts, not just the test cases. Fixes should address underlying issues broadly rather than adding narrow patches for specific examples.
- Keep the skill lean. Fewer, better instructions often outperform exhaustive rules. If transcripts show wasted work (unnecessary validation, unneeded intermediate outputs), remove those instructions. If pass rates plateau despite adding more rules, the skill may be over-constrained โ try removing instructions and see if results hold or improve.
- Explain the why. Reasoning-based instructions ("Do X because Y tends to cause Z") work better than rigid directives ("ALWAYS do X, NEVER do Y"). Models follow instructions more reliably when they understand the purpose.
- Bundle repeated work. If every test run independently wrote a similar helper script (a chart builder, a data parser), that's a signal to bundle the script into the skill's
scripts/directory. See Using scripts for how to do this.
The loop
- Give the eval signals and current
SKILL.mdto an LLM and ask it to propose improvements. - Review and apply the changes.
- Rerun all test cases in a new
iteration-<N+1>/directory. - Grade and aggregate the new results.
- Review with a human. Repeat.
Stop when you're satisfied with the results, feedback is consistently empty, or you're no longer seeing meaningful improvement between iterations.
File: docs/skill-creation/optimizing-descriptions.mdx
title: "Optimizing skill descriptions" sidebarTitle: "Optimizing descriptions"
A skill only helps if it gets activated. The description field in your SKILL.md frontmatter is the primary mechanism agents use to decide whether to load a skill for a given task. An under-specified description means the skill won't trigger when it should; an over-broad description means it triggers when it shouldn't.
This guide covers how to systematically test and improve your skill's description for triggering accuracy.
How skill triggering works
Agents use progressive disclosure to manage context. At startup, they load only the name and description of each available skill โ just enough to decide when a skill might be relevant. When a user's task matches a description, the agent reads the full SKILL.md into context and follows its instructions.
This means the description carries the entire burden of triggering. If the description doesn't convey when the skill is useful, the agent won't know to reach for it.
One important nuance: agents typically only consult skills for tasks that require knowledge or capabilities beyond what they can handle alone. A simple, one-step request like "read this PDF" may not trigger a PDF skill even if the description matches perfectly, because the agent can handle it with basic tools. Tasks that involve specialized knowledge โ an unfamiliar API, a domain-specific workflow, or an uncommon format โ are where a well-written description can make the difference.
Writing effective descriptions
Before testing, it helps to know what a good description looks like. A few principles:
- Use imperative phrasing. Frame the description as an instruction to the agent: "Use this skill when..." rather than "This skill does..." The agent is deciding whether to act, so tell it when to act.
- Focus on user intent, not implementation. Describe what the user is trying to achieve, not the skill's internal mechanics. The agent matches against what the user asked for.
- Err on the side of being pushy. Explicitly list contexts where the skill applies, including cases where the user doesn't name the domain directly: "even if they don't explicitly mention 'CSV' or 'analysis.'"
- Keep it concise. A few sentences to a short paragraph is usually right โ long enough to cover the skill's scope, short enough that it doesn't bloat the agent's context across many skills. The specification enforces a hard limit of 1024 characters.
Designing trigger eval queries
To test triggering, you need a set of eval queries โ realistic user prompts labeled with whether they should or shouldn't trigger your skill.
[
{ "query": "I've got a spreadsheet in ~/data/q4_results.xlsx with revenue in col C and expenses in col D โ can you add a profit margin column and highlight anything under 10%?", "should_trigger": true },
{ "query": "whats the quickest way to convert this json file to yaml", "should_trigger": false }
]Aim for about 20 queries: 8-10 that should trigger and 8-10 that shouldn't.
Should-trigger queries
These test whether the description captures the skill's scope. Vary them along several axes:
- Phrasing: some formal, some casual, some with typos or abbreviations.
- Explicitness: some name the skill's domain directly ("analyze this CSV"), others describe the need without naming it ("my boss wants a chart from this data file").
- Detail: mix terse prompts with context-heavy ones โ a short "analyze my sales CSV and make a chart" alongside a longer message with file paths, column names, and backstory.
- Complexity: vary the number of steps and decision points. Include single-step tasks alongside multi-step workflows to test whether the agent can discern the skill is relevant when the task it addresses is buried in a larger chain.
The most useful should-trigger queries are ones where the skill would help but the connection isn't obvious from the query alone. These are the cases where description wording makes the difference โ if the query already asks for exactly what the skill does, any reasonable description would trigger.
Should-not-trigger queries
The most valuable negative test cases are near-misses โ queries that share keywords or concepts with your skill but actually need something different. These test whether the description is precise, not just broad.
For a CSV analysis skill, weak negative examples would be:
"Write a fibonacci function"โ obviously irrelevant, tests nothing."What's the weather today?"โ no keyword overlap, too easy.
Strong negative examples:
"I need to update the formulas in my Excel budget spreadsheet"โ shares "spreadsheet" and "data" concepts, but needs Excel editing, not CSV analysis."can you write a python script that reads a csv and uploads each row to our postgres database"โ involves CSV, but the task is database ETL, not analysis.
Tips for realism
Real user prompts contain context that generic test queries lack. Include:
- File paths (
~/Downloads/report_final_v2.xlsx) - Personal context (
"my manager asked me to...") - Specific details (column names, company names, data values)
- Casual language, abbreviations, and occasional typos
Testing whether a description triggers
The basic approach: run each query through your agent with the skill installed and observe whether the agent invokes it. Make sure the skill is registered and discoverable by your agent โ how this works varies by client (e.g., a skills directory, a configuration file, or a CLI flag).
Most agent clients provide some form of observability โ execution logs, tool call histories, or verbose output โ that lets you see which skills were consulted during a run. Check your client's documentation for details. The skill triggered if the agent loaded your skill's SKILL.md; it didn't trigger if the agent proceeded without consulting it.
A query "passes" if:
should_triggeristrueand the skill was invoked, orshould_triggerisfalseand the skill was not invoked.
Running multiple times
Model behavior is nondeterministic โ the same query might trigger the skill on one run but not the next. Run each query multiple times (3 is a reasonable starting point) and compute a trigger rate: the fraction of runs where the skill was invoked.
A should-trigger query passes if its trigger rate is above a threshold (0.5 is a reasonable default). A should-not-trigger query passes if its trigger rate is below that threshold.
With 20 queries at 3 runs each, that's 60 invocations. You'll want to script this. Here's the general structure โ replace the claude invocation and detection logic in check_triggered with whatever your agent client provides:
#!/bin/bash
QUERIES_FILE="${1:?Usage: $0 <queries.json>}"
SKILL_NAME="my-skill"
RUNS=3
# This example uses Claude Code's JSON output to check for Skill tool calls.
# Replace this function with detection logic for your agent client.
# Should return 0 (success) if the skill was invoked, 1 otherwise.
check_triggered() {
local query="$1"
claude -p "$query" --output-format json 2>/dev/null \
| jq -e --arg skill "$SKILL_NAME" \
'any(.messages[].content[]; .type == "tool_use" and .name == "Skill" and .input.skill == $skill)' \
> /dev/null 2>&1
}
count=$(jq length "$QUERIES_FILE")
for i in $(seq 0 $((count - 1))); do
query=$(jq -r ".[$i].query" "$QUERIES_FILE")
should_trigger=$(jq -r ".[$i].should_trigger" "$QUERIES_FILE")
triggers=0
for run in $(seq 1 $RUNS); do
check_triggered "$query" && triggers=$((triggers + 1))
done
jq -n \
--arg query "$query" \
--argjson should_trigger "$should_trigger" \
--argjson triggers "$triggers" \
--argjson runs "$RUNS" \
'{query: $query, should_trigger: $should_trigger, triggers: $triggers, runs: $runs, trigger_rate: ($triggers / $runs)}'
done | jq -s '.'Avoiding overfitting with train/validation splits
If you optimize the description against all your queries, you risk overfitting โ crafting a description that works for these specific phrasings but fails on new ones.
The solution is to split your query set:
- Train set (~60%): the queries you use to identify failures and guide improvements.
- Validation set (~40%): queries you set aside and only use to check whether improvements generalize.
Make sure both sets contain a proportional mix of should-trigger and should-not-trigger queries โ don't accidentally put all the positives in one set. Shuffle randomly and keep the split fixed across iterations so you're comparing apples to apples.
If you're using a script like the one above, you can split your queries into two files โ train_queries.json and validation_queries.json โ and run the script against each one separately.
The optimization loop
- Evaluate the current description on both train and validation sets. The train results guide your changes; the validation results tell you whether those changes are generalizing.
- Identify failures in the train set: which should-trigger queries didn't trigger? Which should-not-trigger queries did?
- Only use train set failures to guide your changes โ whether you're revising the description yourself or prompting an LLM, keep validation set results out of the process.
- Revise the description. Focus on generalizing:
- If should-trigger queries are failing, the description may be too narrow. Broaden the scope or add context about when the skill is useful.
- If should-not-trigger queries are false-triggering, the description may be too broad. Add specificity about what the skill does not do, or clarify the boundary between this skill and adjacent capabilities.
- Avoid adding specific keywords from failed queries โ that's overfitting. Instead, find the general category or concept those queries represent and address that.
- If you're stuck after several iterations, try a structurally different approach to the description rather than incremental tweaks. A different framing or sentence structure may break through where refinement can't.
- Check that the description stays under the 1024-character limit โ descriptions tend to grow during optimization.
- Repeat steps 1-3 until all train set queries pass or you stop seeing meaningful improvement.
- Select the best iteration by its validation pass rate โ the fraction of queries in the validation set that passed. Note that the best description may not be the last one you produced; an earlier iteration might have a higher validation pass rate than later ones that overfit to the train set.
Five iterations is usually enough. If performance isn't improving, the issue may be with the queries (too easy, too hard, or poorly labeled) rather than the description.
Applying the result
Once you've selected the best description:
- Update the
descriptionfield in yourSKILL.mdfrontmatter. - Verify the description is under the 1024-character limit.
- Verify the description triggers as expected. Try a few prompts manually as a quick sanity check. For a more rigorous test, write 5-10 fresh queries (a mix of should-trigger and should-not-trigger) and run them through the eval script โ since these queries were never part of the optimization process, they give you an honest check on whether the description generalizes.
Before and after:
# Before
# After
Analyze CSV and tabular data files โ compute summary statistics,
add derived columns, generate charts, and clean messy data. Use this
skill when the user has a CSV, TSV, or Excel file and wants to
explore, transform, or visualize the data, even if they don't
explicitly mention "CSV" or "analysis."The improved description is more specific about what the skill does (summary stats, derived columns, charts, cleaning) and broader about when it applies (CSV, TSV, Excel; even without explicit keywords).
Next steps
Once your skill triggers reliably, you'll want to evaluate whether it produces good outputs. See Evaluating skill output quality for how to set up test cases, grade results, and iterate.
File: docs/skill-creation/quickstart.mdx
title: "Quickstart"
In this tutorial, you'll create a skill that gives an agent the capability to roll dice using a random number generator.
Prerequisites
- VS Code with GitHub Copilot
Create the skill
A skill is a folder containing a SKILL.md file. VS Code looks for skills in .agents/skills/ by default. Create .agents/skills/roll-dice/SKILL.md in your project:
---
name: roll-dice
---
To roll a die, use the following command that generates a random number from 1
to the given number of sides:
```bash
echo $((RANDOM % <sides> + 1))
```
```powershell
Get-Random -Minimum 1 -Maximum (<sides> + 1)
```
Replace `<sides>` with the number of sides on the die (e.g., 6 for a standard
die, 20 for a d20).That's it โ one file, under 20 lines. Here's what each part does:
nameโ A short identifier for the skill. Must match the folder name.descriptionโ Tells the agent when to use this skill. This is how the agent decides whether to activate it.- The body โ Instructions the agent follows when the skill activates. Here, the agent is instructed to generate a random number using a terminal command, substituting the number of sides from the user's request.
Try it out
- Open your project in VS Code.
- Open the Copilot Chat panel.
- Select Agent mode from the mode dropdown at the bottom of the chat panel.
- Type
/skillsto confirm thatroll-diceappears in the list. If it doesn't, check that the file is at.agents/skills/roll-dice/SKILL.mdrelative to your project root. - Ask: "Roll a d20"
The agent should activate the roll-dice skill. It may ask for permission to run a terminal command โ allow it. It will run the command and return a random number between 1 and 20.
How it works
Here's what happened behind the scenes:
Discovery โ When the chat session started, the agent scanned default skill directories and found your skill. It read only the
nameanddescription, just enough to know when the skill might be relevant.Activation โ When you asked about rolling dice, the agent matched your question to the skill's description and loaded the full
SKILL.mdbody into context.Execution โ The agent followed the instructions in the body, adapting the terminal command to the number of sides in your request.
This process uses progressive disclosure to let the agent access many skills without loading all their instructions up front.
Next steps
You've created a working Agent Skill. From here:
- Best practices โ How to write skills that are well-scoped and effective.
- Optimizing skill descriptions โ Test and improve your skill's description so it activates on the right prompts.
- Specification โ The complete format reference for
SKILL.mdfiles. - Example skills โ Browse real-world skills on GitHub.
File: docs/clients.mdx
title: "Client Showcase"
import { clients } from '/snippets/clients.jsx';
import { ClientShowcase } from '/snippets/ClientShowcase.jsx';
File: docs/home.mdx
title: "Agent Skills Overview" sidebarTitle: "Overview"
import { clients } from '/snippets/clients.jsx';
import { LogoCarousel } from '/snippets/LogoCarousel.jsx';
What are Agent Skills?
Agent Skills are a lightweight, open format for extending AI agent capabilities with specialized knowledge and workflows.
At its core, a skill is a folder containing a SKILL.md file. This file includes metadata (name and description, at minimum) and instructions that tell an agent how to perform a specific task. Skills can also bundle scripts, reference materials, templates, and other resources.
my-skill/
โโโ SKILL.md # Required: metadata + instructions
โโโ scripts/ # Optional: executable code
โโโ references/ # Optional: documentation
โโโ assets/ # Optional: templates, resources
โโโ ... # Any additional files or directoriesWhy Agent Skills?
Agents are increasingly capable, but often don't have the context they need to do real work reliably. Skills solve this by packaging procedural knowledge and company-, team-, and user-specific context into portable, version-controlled folders that agents load on demand. This gives agents:
- Domain expertise: Capture specialized knowledge โ from legal review processes to data analysis pipelines to presentation formatting โ as reusable instructions and resources.
- Repeatable workflows: Turn multi-step tasks into consistent, auditable procedures.
- Cross-product reuse: Build a skill once and use it across any skills-compatible agent.
How do Agent Skills work?
Agents load skills through progressive disclosure, in three stages:
Discovery: At startup, agents load only the name and description of each available skill, just enough to know when it might be relevant.
Activation: When a task matches a skill's description, the agent reads the full
SKILL.mdinstructions into context.Execution: The agent follows the instructions, optionally executing bundled code or loading referenced files as needed.
Full instructions load only when a task calls for them, so agents can keep many skills on hand with only a small context footprint.
Where can I use Agent Skills?
Agent Skills are supported by a large number of AI tools and agentic clients โ see the Client Showcase to explore some of them!
Open development
The Agent Skills format was originally developed by Anthropic, released as an open standard, and has been adopted by a growing number of agent products. The standard is open to contributions from the broader ecosystem.
Come join the discussion on GitHub or Discord!