Agent Skills: How to Create a Skill for an AI Agent — Structure, Rules, and Tests
Table of Contents
- How a skill is structured
-
Six rules for developing skills
- 1. Start with a solved task, then create the skill
- 2. Test every line for whether it prevents an error
- 3. The description field is the trigger
- 4. SKILL.md should not become documentation
- 5. Be precise where errors are costly, and allow flexibility where choice is needed
- 6. The Gotchas section is the most valuable part
- Testing a skill: evals/evals.json
- Skill collections: benefits and risks
- Ready-to-use prompt: package a session as a skill
- Skills in a working project
Agent Skills is an open format for giving an AI agent a ready-made procedure: how to deploy a website, perform an audit, or compile a report. You describe a skill once as a folder containing an SKILL.md file, and it works without modification in Claude Code, OpenAI Codex, Cursor, GitHub Copilot, VS Code, Gemini CLI, and other agents.
The format was created by Anthropic, which transferred it to the Agentic AI Foundation—a foundation under the Linux Foundation—on October 22, 2026. The MCP protocol was previously transferred there as well. They serve different purposes: MCP connects AI to external data and APIs, while Agent Skills stores portable procedural knowledge—what companies call standard operating procedures (SOPs). The SKILL.md format itself did not change during the transfer.
Below is a guide to designing, packaging, and validating skills according to the official agentskills.io specification.
How a skill is structured
Agent Skills is built around progressive disclosure. A model’s context window is limited, and an excess of instructions reduces accuracy: the model has a harder time retaining information located in the middle of a long text. Therefore, a skill is loaded in three stages:
- Metadata—always in context. At the start of a session, the agent reads only the
nameanddescriptionfields from theSKILL.mdYAML front matter of each installed skill. This is about 100 tokens per skill. Based on these fields, the model understands which skills are available. - Instructions—upon activation. The body of
SKILL.mdenters the context only when the skill is needed. It contains the workflow, constraints, links to additional files, and a list of common errors. - Resources—on demand. Files in
references/,scripts/, andassets/are not read automatically. The agent opens them when it reaches the relevant step.
Folder structure
deploy-static-astro/
├── SKILL.md # required file: YAML front matter and instructions
├── references/ # documentation the agent reads as needed
│ ├── nginx-vhost.conf
│ └── cache-headers.md
├── scripts/ # executable scripts for precise operations
│ └── validate-build.sh
├── assets/ # templates and other static files
└── evals/ # test scenarios (not part of the specification, see below)
└── evals.json
What the specification requires
| Field or file | Requirement |
|---|---|
name |
Required. From 1 to 64 characters: lowercase Latin letters, digits, and hyphens. Must not start or end with a hyphen or contain consecutive hyphens. Must match the folder name |
description |
Required. From 1 to 1024 characters: what the skill does and when to use it |
license, compatibility, metadata, allowed-tools |
Optional. compatibility—up to 500 characters; allowed-tools is currently experimental |
SKILL.md |
Recommendation: up to 500 lines and 5000 tokens. Move details to separate files |
| File references | No deeper than one level from SKILL.md |
The only hard restrictions here apply to the front matter fields. The 500-line and 5000-token limits are recommendations: a longer skill will still work, but it will consume more context than necessary.
Six rules for developing skills
1. Start with a solved task, then create the skill
Do not ask a model to write a skill “from scratch.” If you commission a deployment or parsing skill from zero, it will fill it with generic advice such as “check the logs when errors occur” or “make sure the configuration is secure.” The agentskills.io guide calls this the main mistake: a skill built solely on the model’s general knowledge adds nothing to it.
The practical workflow is:
- Complete a real task with the agent in a regular session.
- Correct it where it made mistakes: selected the wrong utility flag or violated the output format.
- Record the commands that worked, file paths, and edge cases.
- After successfully completing the task, package the session as a skill.
A second source of material is what has already accumulated in the project: internal procedures, incident postmortems, and the Git change history.
2. Test every line for whether it prevents an error
Once the SKILL.md draft is ready, check every line using the question from the guide: Will the agent make a mistake if this instruction is removed?
- If not—the model already knows Git syntax and HTTP status codes—delete the line.
- Keep what changes the model’s behavior to meet your requirements: non-standard infrastructure, internal conventions, and business logic.
A short step-by-step instruction with one working example usually performs better than exhaustive documentation.
3. The description field is the trigger
A skill is activated automatically based only on the description field: at the beginning of a session, the agent sees nothing except the description and the name. If the description is vague, the agent will not associate it with the task and will start solving the task from scratch.
- Limit—1024 characters. This is a hard specification limit.
- Imperative form. Start with “Use this skill when…” rather than “This skill does…”.
- User intent, not implementation. Describe the task the user will bring to the agent, not how the skill is structured internally.
- Implicit requests. List situations where the subject area is not stated explicitly. A skill for auditing Core Web Vitals should trigger not only for “check CWV,” but also for “why does the page load slowly?” and “optimize LCP and CLS.”
Example front matter:
---
name: nginx-php-fpm-hardening
description: Use this skill when you need to configure, optimize, or audit an Nginx + PHP-FPM stack on a Linux server (Debian/Ubuntu). Trigger it for requests involving virtual host configuration, resolving 502 Bad Gateway and 504 Gateway Timeout errors, tuning pm.max_children pools, configuring FastCGI caching, rate limiting, or restricting access to service directories.
---
The trigger should be tested. The guide recommends compiling around 20 prompts: half should activate the skill and half should not. “Almost relevant” negative examples are especially useful. Run each prompt several times and track how often the skill triggers.
4. SKILL.md should not become documentation
Keep the main file within 500 lines and 5000 tokens. Configuration templates, long SQL queries, API references, and error tables belong in references/. SKILL.md should contain routing with a precise condition: “Before generating the configuration, read references/nginx-vhost.conf and use it as a template.” Without such a condition, the agent may either fail to open the file or read everything indiscriminately.
5. Be precise where errors are costly, and allow flexibility where choice is needed
The specificity of an instruction should match the fragility of the operation.
- If an operation is fragile, provide an exact command or script. Instead of “back up the database before the migration,” write:
mysqldump --single-transaction --routines --triggers "$DB_NAME" | gzip > "/var/backups/${DB_NAME}_$(date +%F_%H%M).sql.gz". It is even safer to move the logic toscripts/and explicitly prohibit modifying the command or adding flags. - If multiple options are possible, set one as the default. Do not list three equally valid approaches. Name the primary one and briefly explain when to switch to the fallback.
6. The Gotchas section is the most valuable part
The “Common Errors” (Gotchas) section stores what the model cannot know: where it confuses syntax versions, forgets a flag, or chooses a path that is not obviously wrong. The guide calls this list the most valuable content in many skills.
A skill is a living document. When the agent makes a mistake and you have to correct it, do not limit yourself to fixing it in the chat: add the rule to Gotchas.
Testing a skill: evals/evals.json
The evals/ folder is not part of the specification—it is a technique from the agentskills.io guide for evaluating quality. The evals/evals.json file contains test prompts and a description of the expected result. It shows whether the skill broke after an instruction change or a model switch.
{
"skill_name": "nginx-php-fpm-hardening",
"evals": [
{
"id": 1,
"prompt": "On a server with 4 GB of RAM and 2 vCPUs, Nginx returns 502 Bad Gateway errors during peak traffic. The logs show upstream prematurely closed connection. Calculate the PHP-FPM pool settings and update the configuration.",
"expected_output": "Updated PHP-FPM pool configuration with a calculation of pm.max_children and justification for the selected pm mode.",
"files": ["evals/files/www.conf"],
"assertions": [
"Average memory consumption per php-fpm process was measured",
"pm.max_children was calculated with RAM reserved for the OS and Nginx",
"php-fpm -t and nginx -t were run before restarting"
]
},
{
"id": 2,
"prompt": "Set up a virtual host for example.com in /var/www/example/dist with long-term static asset caching and a redirect from www.",
"expected_output": "Nginx virtual host configuration based on the template from references/.",
"assertions": [
"The references/nginx-vhost.conf template was used",
"A 301 redirect from www.example.com to example.com was configured",
"Cache-Control: public, max-age=31536000, immutable was set for assets"
]
}
]
}
How testing works:
- Two runs per scenario. One with the skill and one without it or with the previous version. Without a comparison, it is impossible to tell whether the skill helps at all.
- Clean context. Each run starts from scratch; otherwise, the previous conversation affects the result. In Claude Code, subagents are convenient for this.
- Assertion-based evaluation. Each
assertionsitem receives a “passed” or “failed” result with evidence. Where possible, validation should be performed by code rather than by the model. - Summary. Compare the share of passed assertions, execution time, and token usage with and without the skill.
Do not look only at the final result; examine the execution process as well. It shows which instruction the agent skipped or misunderstood.
Skill collections: benefits and risks
There are already a great many skills. According to a Vercel report dated September 25, 2026, one million skills have been published in the skills.sh registry, with nearly 280 million installations. At the same time, almost half of all skills were installed only once, while 62% of installations are accounted for by 0.04% of skills. Most of the registry is ballast.
Thematic collections are also appearing on GitHub. For example, gamedev-skills/awesome-gamedev-agent-skills contains 79 skills and a skill router for 12 game engines, including Godot, Unity, Unreal Engine, Roblox, three.js, and Phaser. It can be useful for those who make a game solo with AI agents. When working with such collections, keep three limitations in mind.
Do not install the entire collection. Each skill adds about 100 tokens of metadata to the context. A collection of 79 skills consumes approximately 8000 tokens even before the first request and creates a risk of trigger conflicts: a rendering optimization skill for Unity may start triggering in a Godot project. Choose only the skills that match the project stack.
Filter out skills without real-world experience behind them. Many collection skills violate the first rule: they are generic advice that has not been tested on a real task. Open SKILL.md. If it contains no specific commands, paths, versions, or Gotchas section, the skill will only consume context.
Review the contents before installation. The scripts/ directory contains executable code, while the agent treats the text in SKILL.md as instructions. A third-party skill may exfiltrate environment variables containing API and SSH keys or make the agent execute unrelated commands. This is the same class of threat as MCP servers. A Snyk audit in February 2026 found malicious code in 76 of the 3984 skills reviewed. Read SKILL.md and all nested files before installation.
Ready-to-use prompt: package a session as a skill
When you and an agent have solved a nontrivial or recurring task together, send this prompt in the same session. It was written for Claude Code but will work with any agent that has file access.
Following the specification at https://agentskills.io/specification and the guide at https://agentskills.io/skill-creation/best-practices, package the task we have just completed into a portable Agent Skill.
Requirements:
1. Data sources: use only the commands, steps, data formats, and solutions that actually worked in this session, my corrections, and task-relevant rules from CLAUDE.md, AGENTS.md, and this repository’s Git history. Do not fill gaps with general knowledge or generic advice.
2. Name: come up with a short skill name (lowercase Latin letters, digits, and hyphens, up to 64 characters). Create a folder with this name in the project’s skills directory.
3. Trigger: write the description field in the form “Use this skill when…”. Include both direct activation scenarios and implicit problem statements where the skill should be triggered. No more than 1024 characters.
4. Scope: SKILL.md must be no more than 500 lines and 5,000 tokens. Remove every line that would not prevent you from making a mistake. Move long templates, configs, schemas, and reference materials to references/ and specify the exact condition for reading each file in SKILL.md. Put complex commands and checks into scripts/.
5. Accuracy: provide exact commands for critical operations; where alternatives are possible, specify one default and the conditions for switching to a fallback.
6. Common errors: create a Gotchas section and move all errors and corrections from this session into it.
7. Verification: create evals/evals.json with 2–3 realistic scenarios (fields: prompt, expected_output, assertions). Run each scenario with and without the skill in a clean context, show the results for each assertion, and briefly describe the files created.
Skills in a working project
- Keep skills in the repository. Project skills live alongside the code under Git: in
.claude/skills/for Claude Code or.agents/skills/for other agents. Check your agent’s documentation for the exact path. - Update the skill alongside the code. If the infrastructure or stack changes, update the skill in the same commit. An outdated skill is worse than no skill: the agent will confidently follow the wrong procedure.
- Add to Gotchas. Every agent error that required manual correction is a new line in the section.
- Recheck after changing the model. Run
evals/evals.json: an instruction that was necessary for the previous model may hinder the new one.