How to write an agent skill that actually gets used: what the evidence says
Skills can lift an agent's pass rate by double digits, or never fire at all. A meta-study of the official guides, the papers and the best-tested public skills, with every recommendation graded by how strong its evidence is.
Writing an agent skill takes ten minutes. You make a folder, add a SKILL.md file with two lines of YAML at the top, and write some instructions. Claude, Codex, Cursor, GitHub Copilot, Gemini CLI and more than 40 other agents will pick it up.
Whether it does anything is another matter. In Vercel’s own evals, a skill teaching new Next.js APIs did nothing at all: the pass rate was 53% with it and 53% without it, because “in 56% of eval cases, the skill was never invoked.” On the other hand, in the largest benchmark so far, SkillsBench, well-written skills raised average pass rates from 33.9% to 50.5% across 18 model and harness setups. In the first version of the same study, skills that models wrote for themselves “provide no benefit on average”.
So skills can work, and they often don’t. This piece collects what is known about telling the difference. It draws on the official authoring guides from Anthropic, OpenAI, Cursor and the open spec, the papers and published measurements, and the public skills with real evidence behind them. Each recommendation carries a grade: Measured (a published experiment with numbers), Vendor docs (official guidance, informed by mostly unpublished internal testing), Consensus (vendors and practitioners agree, nobody has measured it) or Opinion (one source, or sources that disagree).
What a skill is, and what it isn’t
A skill is a folder. It holds a SKILL.md file, made of YAML frontmatter plus Markdown instructions, and optionally scripts/, references/ and assets/ directories. That layout comes from the Agent Skills specification. Anthropic developed the format and released it as an open standard in December 2025. Only two fields are required:
---
name: processing-pdfs
description: Extracts text and tables from PDF files, fills forms, merges documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction.
---
# Processing PDFs
...
What makes a skill different from its neighbours is when it enters the model’s context:
| Mechanism | When it’s in context | Best for |
|---|---|---|
| System prompt | Always | The agent’s identity and global rules |
AGENTS.md, CLAUDE.md, Cursor rules |
Always, or on matching files | Short facts and conventions that apply to almost every task |
| Skill | Name and description always; body only when needed | Procedures, domain knowledge, scripts for specific tasks |
| MCP tool | Tool schema always; results when called | Access to external systems and data |
The vendors draw the same lines. Claude Code’s docs say to create a skill “when a section of CLAUDE.md has grown into a procedure rather than a fact”; GitHub and Cursor say much the same. On MCP, Anthropic puts it this way: “MCP connects Claude to data; Skills teach Claude what to do with that data.”
A skill is also a request, not a guarantee. For rules that must always hold, Claude Code’s docs say to “move the rule into a hook”.
How skills are loaded, and why it shapes everything
Every agent that supports skills uses the same three-stage loading, which Anthropic calls progressive disclosure (overview):
- Metadata, always. At startup, the name and description of every installed skill go into the system prompt. Anthropic estimates “~100 tokens per Skill”.
- The body, on trigger. When the model decides a skill is relevant, it reads
SKILL.md. Anthropic’s guidance is to keep it “under 5k tokens”; the spec says the same and adds “under 500 lines”. - Everything else, on demand. Reference files load only when the instructions send the model to them. Scripts run without their source entering context; only their output costs tokens. In Anthropic’s words, bundled content is “effectively unbounded”.
Three consequences follow, and most of the advice later in this piece comes from them.
The description is the only thing the model sees when it decides. The agentskills.io guide says the description “carries the entire burden of triggering”. If it doesn’t match how users phrase requests, the rest of the skill doesn’t matter.
Descriptions compete for a fixed budget. Claude Code gives the whole skill listing 1% of the model’s context window and truncates each entry at 1,536 characters. Codex’s listing uses at most 2% of the context window (or 8,000 characters) and “shortens skill descriptions first”. With dozens of skills installed, long descriptions get cut or dropped.
Simple tasks may not trigger anything. Anthropic’s own skill-creator warns that “simple, one-step queries like ‘read this PDF’ may not trigger a skill even if the description matches perfectly”, because the model consults skills mainly for tasks it can’t easily handle on its own.
The triggering problem is the biggest one
Before any advice on what to write, the most consistent finding: skills often don’t fire.
- Vercel (vendor, measured): in its Next.js 16 eval suite, the skill was never invoked in 56% of cases. The pass rate was 53% with no docs, 53% with the skill, 79% when the prompt also told the agent to use the skill, and 100% when a compressed 8KB docs index went into
AGENTS.mdinstead. Vercel didn’t name the agent or model, or publish the eval set. It noted that “the gap may close as models get better at tool use.” - A practitioner’s sandboxed test (measured, small): a developer ran the real Claude Code binary with Sonnet 4.5 on 22 prompts, twice (write-up). Skills activated in 55% and 50% of cases with no help. A “forced-eval” hook, which makes the agent explicitly consider each skill before answering, reached 100% in both runs. A hook that asked an LLM to pick skills also hit 100%, but recommended skills for 4 of 5 unrelated queries.
- Anthropic (vendor docs): its skill-creator says “Claude has a tendency to ‘undertrigger’ skills”. Its description optimiser “improved triggering on 5 out of 6 public skills”. Anthropic published no before or after rates.
Practitioners have three workarounds. You can write stronger descriptions (below). You can force activation with a hook or a standing instruction; Superpowers, a popular skill library, does the latter. Or, for knowledge the agent needs on nearly every task, you can skip skills and put a compact index in AGENTS.md, as Vercel did.
Be careful with the last one. A preprint from ETH Zurich and LogicStar that tested always-on context files found they “do not generally improve task success rates, while increasing inference cost by over 20% on average”. It also found that instructions in those files were well followed. Skills and AGENTS.md each have a cost, and neither is free.
The dos and don’ts, graded
1. Write the description as a trigger, not a summary
Grade: Vendor docs + Measured (small).
Every vendor says the description must say what the skill does and when to use it (spec, Anthropic, Codex). Anthropic’s Claude Code team goes further: “the description field is not a summary, it’s a description of when to trigger this skill.”
The Superpowers writing-skills skill documents a specific failure. A description that summarised a workflow (“dispatches subagent per task with code review between tasks”) caused an agent to do one review instead of the two the body required: the agent followed the description and skipped the skill. Its fix is to describe only the triggering conditions: “Use when executing implementation plans with independent tasks in the current session”. It’s one documented case, not a study, but it’s a failure you can test for.
The measured support comes from the description loops. Anthropic’s 5-of-6 result comes from rewriting descriptions alone. In one practitioner case study, a skill went from 66.7% to 100% across about 20 test cases, and “the description change alone fixed 5 of 7 failures.”
Sources disagree on voice. Anthropic’s docs say “Always write in third person” (“Processes Excel files…”). The agentskills.io guide says to use imperative phrasing, “Use this skill when…”. Anthropic’s own document skills open with “Use this skill…”, so the imperative form evidently works on Claude. What every source avoids is the first person: “I can help you…”.
2. Be specific, and a little pushy, about when to fire
Grade: Vendor docs.
Because of undertriggering, Anthropic’s skill-creator asks for descriptions that are “a little bit ‘pushy’”, and agentskills.io says to “err on the side of being pushy.” Codex says to “front-load the key use case and trigger words”, since descriptions get shortened from the end.
Anthropic’s production xlsx skill shows the pattern. It lists casual phrasings (“even casually (like ‘the xlsx in my downloads’)”) and ends with negative scope: “Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script…”. For overtriggering, Anthropic’s guide recommends exactly that: “Add negative triggers”. The best descriptions are pushy and bounded. Trail of Bits’ sharp-edges skill adds a literal keyword list (“Triggers: footgun, misuse-resistant, secure defaults…”).
3. Keep the body short, and only write what the model doesn’t know
Grade: Vendor docs + Measured (indirect).
Anthropic’s best-practices page starts from “Claude is already very smart” and asks of every paragraph, “Does this paragraph justify its token cost?” The agentskills.io version is sharper: “Would the agent get this wrong without this instruction?’ If the answer is no, cut it.” The Claude Code team puts it like this: “A skill that restates what Claude would do by default adds context without adding value.”
Anthropic’s docs, Claude Code and the spec all say under 500 lines, and the spec adds 5,000 tokens. Anthropic’s PDF guide says “under 5,000 words”, which doesn’t match. Superpowers is far stricter: under 200 words for frequently loaded skills and under 500 for others.
The indirect evidence agrees. SkillsBench found that “focused Skills with at most three modules outperform larger or exhaustive bundles”. The IFScale study found that even the best frontier models followed only 68% of instructions at a density of 500, with most failures being omissions. Neither measures skill length directly.
One caution: a factorial study of 1,650 Claude Code sessions found no detectable effect of instruction-file size or position on compliance with a deliberately trivial rule. The size limit may be more about context budget than obedience.
4. Put the gotchas in; leave the textbook out
Grade: Vendor docs + Consensus.
Anthropic’s Claude Code team: “The highest-signal content in any skill is the Gotchas section.” agentskills.io calls gotchas “the highest-value content in many skills”. Anthropic’s production skills are built this way. The docx skill introduces its list with “The model knows the API; these are the footguns:”, for example “use ShadingType.CLEAR, never SOLID (renders black)”. The pdf skill warns never to use Unicode subscripts in ReportLab, because they “render as solid black boxes”.
5. Match the level of freedom to how fragile the task is
Grade: Vendor docs.
Anthropic and OpenAI use the same image. Anthropic: a “narrow bridge with cliffs on both sides” needs exact steps; an “open field” needs only direction. OpenAI’s skill-creator says the same about Codex. For fragile operations (database migrations, file formats), give exact commands or a script. For judgement tasks (code review, design), give principles. OpenAI’s gh-fix-ci skill shows how to fence the edges: “Do not attempt Buildkite or other providers; keep the workflow lean.”
6. Give a default, not a menu
Grade: Vendor docs.
Anthropic says “Provide a default (with escape hatch)” rather than a list of options. agentskills.io says “Provide defaults, not menus.” A skill that lists five PDF libraries makes the agent choose; one that says “use pypdf; for scanned files use OCR” makes the choice for it.
7. Use scripts for anything that must be deterministic
Grade: Vendor docs + Measured (security).
Scripts are “more reliable than generated code” and their source never enters the context. Anthropic notes that sorting a list “via token generation is far more expensive than simply running a sorting algorithm.” Tell the model whether to run a script or read it. Anthropic’s webapp-testing skill says “Always run scripts with --help first … DO NOT read the source until you try running the script first”.
Sources disagree on the default. Codex says “Prefer instructions over scripts unless you need deterministic behavior or external tooling”, and its skill-creator defaults to instruction-only. Anthropic’s guides encourage bundling utility scripts. Both agree on when one is needed.
There’s a security cost too. A study of 31,132 public skills found that those with scripts were 2.12× more likely to contain a vulnerability.
8. Build in a verification loop
Grade: Vendor docs + Consensus.
Anthropic says the “run validator → fix errors → repeat” pattern “greatly improves output quality”, and the Claude Code team says “verification skills have had the most measurable impact on Claude’s output quality internally”. Anthropic hasn’t published those measurements. The xlsx skill shows how to do it well. It says “Never ship while recalc.py reports errors_found”. It also warns about the limits of its own check: “A green recalc proves your formulas evaluate, not that they are right”, and “errors_found exits 0, so never treat a clean exit as a clean workbook.”
But don’t overdo it. Grade: Measured. A study of skill-induced failures attributed 182 efficiency regressions to skills. The largest source was excessive verification, at 67 cases: “skills often turn validation checklists and construction recipes into mandatory work.” Verify what matters, and make heavyweight checks conditional.
9. Keep references one level deep
Grade: Vendor docs.
Link reference files directly from SKILL.md, not from other reference files. Anthropic explains that the model “might use commands like head -100 to preview content” of nested files and miss things. Add a table of contents to any reference file over 100 lines (Anthropic’s docs) or 300 lines (its skill-creator). Say when to read each file. The pdf skill does this in one line: “If you need to fill out a PDF form, read FORMS.md and follow its instructions.”
10. Explain why, and be careful with ALWAYS and NEVER
Grade: Opinion, and sources disagree.
Anthropic’s skill-creator says “If you find yourself writing ALWAYS or NEVER in all caps … that’s a yellow flag” and recommends explaining the reasoning instead. Yet Anthropic’s best-practices page gives “MUST filter” as an example of a fix, and its production skills use bold “Never” freely. A practitioner’s case study found the opposite to soft wording: “‘Always use interactions.create()’ works. ‘The Interactions API is the recommended approach’ doesn’t.”
Superpowers’ wording tests found that prohibitions (“don’t X”) produced more of the unwanted behaviour than a positive recipe for the desired output. Adding a nuance clause (“Don’t X unless it matters”) made a working instruction inconsistent. These are internal tests in a skill file, not a paper.
The reconciliation we’d suggest (our analysis): state the desired behaviour positively and directly, give the reason in one clause, and keep hard prohibitions for real hazards. Then test your wording, because this is where models differ most.
11. Test on every model you’ll use
Grade: Vendor docs + Measured.
Anthropic: “What works perfectly for Opus might need more detail for Haiku.” Hugging Face’s upskill experiment measured this. A skill written by a frontier model lifted a small open model from 40% to 85% on its task, but gave the frontier model itself no gain and cost it extra tokens. SkillsBench also found that “smaller models with Skills can match larger models without them”.
12. Don’t let the model write the skill unsupervised
Grade: Measured.
SkillsBench v1 is the clearest result in the field: self-generated skills “provide no benefit on average, showing that models cannot reliably author the procedural knowledge they benefit from consuming.” The fix is to put a loop around generation, not to ban it. Anthropic’s “Claude A / Claude B” method has one instance write the skill and fresh instances test it on real tasks. A later paper, CoEvoSkills, reports that self-evolved skills with a verification loop outperformed five baselines on SkillsBench. Use the model as a drafter and your evals as the editor.
13. Follow the format rules
Grade: Vendor docs.
Names are lowercase with hyphens, at most 64 characters, and match the folder; VS Code says a mismatched skill “is not loaded”. Descriptions stay under 1,024 characters (spec). For portability, use only the spec’s frontmatter fields: Claude Code ignores unknown ones, but claude.ai and the Skills API reject them “with a hard error”.
Before and after: rewriting a weak skill
Here’s a typical first draft. We wrote it to illustrate the advice; it isn’t from a real repository.
---
name: db-helper
description: I can help you with database migrations and other database tasks using our Postgres setup and best practices.
---
# Database Helper
This skill helps with databases. Postgres is a powerful open-source
relational database. Migrations are a way to change a schema over time.
You can use Prisma, Knex, raw SQL, or Flyway for migrations.
IMPORTANT: ALWAYS be careful with migrations!!! NEVER break production!
Follow best practices for indexes, naming and performance. See docs/db.md
which links to docs/conventions.md for more.
What’s wrong with it: a vague name (Anthropic lists helper among names to avoid); a first-person description with no trigger words and no boundary; a body explaining what Postgres is; four tools instead of one; shouting without saying what “careful” means; references nested two deep; and no verification step.
The rewrite:
---
name: writing-postgres-migrations
description: Use when creating, editing or reviewing a database migration in this repo, or when the user mentions schema changes, new columns, indexes, or files in db/migrations/. Not for ad-hoc queries or data analysis.
---
# Writing Postgres migrations
Use Prisma Migrate (`bunx prisma migrate dev --name <change>`). Don't hand-write
SQL migrations unless Prisma can't express the change (see references/raw-sql.md).
## Gotchas
- Production tables over 1M rows: create indexes with `CREATE INDEX CONCURRENTLY`
in a separate raw-SQL migration. A normal index locks writes for minutes.
- Adding a NOT NULL column: add it nullable, backfill, then add the constraint,
in three migrations. One-step adds fail on existing rows.
- Never edit a migration that is already on main; add a new one.
## Before you finish
1. Run `bun run db:check`. It applies all migrations to a scratch database
and fails on drift.
2. If it fails, fix the migration and run it again. Don't finish while it fails.
The description now says when to fire, with trigger words, a file path and a boundary. The body sets one default, spends its lines on gotchas with one-clause reasons, points to one reference file and says when to read it, and ends with a script-backed check. It’s longer, but every line does work.
Skills worth reading, and what backs them
Popularity isn’t evidence. Superpowers shows about 294,000 GitHub stars and Anthropic’s skills repository about 179,000 (as of 2 October 2026), but stars don’t tell you whether a skill works. The column that matters is the last one.
| Skill | Source | What it does | Evidence it works |
|---|---|---|---|
| skill-creator | Anthropic | Writes skills, runs with/without-skill evals, tunes descriptions | Ships its own grader, comparator and benchmark scripts. Anthropic reports better triggering on 5 of 6 public skills (vendor claim, no rates published) |
| xlsx, docx, pptx, pdf | Anthropic | Office and PDF file creation and editing | Anthropic says they’re “actively used in a production AI application”; updated several times through July 2026. No public evals |
| frontend-design | Anthropic | Pushes UI work away from generic defaults | Before/after examples in Anthropic’s post; qualitative only |
| webapp-testing | Anthropic | Tests local web apps with Playwright | Official maintenance only; no evals found |
| skill-creator (Codex) | OpenAI | Creates Codex skills, with a validator script | Ships with Codex by default; no evals. The openai/skills repo is now deprecated in favour of openai/plugins |
| gh-fix-ci | OpenAI | Debugs failing GitHub Actions checks, fixes only after approval | Curated by OpenAI; no evals |
| loop-on-ci | Cursor | Watches PR checks and fixes failures until green | Cursor describes the kit as “internal-style workflows”; no evals found |
| react-best-practices | Vercel | 70 React and Next.js performance rules, one file per rule | Vendor-maintained, about 31,800 stars; no evals for this skill. Vercel’s measured result is for a different skill (above) |
| azure-ai-projects-py | Microsoft | Azure AI Foundry Python SDK | The strongest eval evidence we found: the repo reports “129 skills with 1169 test scenarios”, with acceptance criteria per skill and an eval harness in CI. No pass rates published |
| differential-review | Trail of Bits | Security review of a diff, with blast-radius analysis | Repo-wide checks validate plugin metadata and skill interfaces; written to strict house rules. No per-skill evals |
| writing-skills | Superpowers (open source) | Test-driven method for writing skills | A tests/ directory per agent harness, documented wording experiments and frequent releases (v6.4.1 in September 2026). Results are described, not published as numbers |
| hf-cli | Hugging Face | Hugging Face Hub CLI | Generated from the CLI itself, so it can’t drift from it; no evals |
Two things stand out. Almost nobody publishes pass rates for their skills, Anthropic included; Microsoft and Superpowers publish test methods, not numbers. And the best skills share a shape: a trigger-focused description with negative scope, a short body of defaults and gotchas, references loaded on demand, and a check at the end.
Skills you didn’t write need caution. Snyk scanned 3,984 skills from public marketplaces and found that “13.4% of all skills, or 534 in total” had a critical-level issue, with 76 confirmed malicious payloads. An academic scan of 31,132 skills found 26.1% with at least one vulnerability. A later paper found most scanner verdicts collapse under closer analysis, with only 0.52% remaining suspicious once the surrounding repository was considered. So treat these rates as dependent on the scanning method. Anthropic’s advice holds either way: “Treat like installing software.” Read the scripts, and check what allowed-tools grants.
How to test a skill
All the vendors now agree on a method, even if the tools differ.
1. Start with a baseline. Run your test prompts without the skill first. Anthropic says to “create evaluations BEFORE writing extensive documentation”. Superpowers’ rule is “NO SKILL WITHOUT A FAILING TEST FIRST”. If the model already does the task well, you don’t need the skill.
2. Test triggering separately from output. Anthropic’s skill-creator uses about 20 queries: 8–10 that should trigger and 8–10 that shouldn’t. The most valuable negatives are “the near-misses”, which share keywords but need something else. It runs each query three times, splits the set 60/40 into train and test, and picks the description that scores best on the held-out set. OpenAI’s eval guide labels each prompt should_trigger and includes negative controls.
3. Check outcomes deterministically where you can. OpenAI’s method runs codex exec --json, captures the trace, and checks it with code: did it run npm install, did it create package.json? It then uses a model grader only for style. Its guide says “a small set of 10–20 prompts is enough” for a single skill. Track tokens and time too, so you catch the efficiency regressions the failure study found.
4. Run every case several times, with and without the skill. Claude Code’s claude plugin eval runs each case three times by default and reports the lift (Δ) over a no-plugin run. It also explains how to read the result: “If a case scores 1.0 both with and without the plugin, the plugin isn’t what made it pass.” Its docs say the most common first finding is a Δ near zero because the skill never fired. Superpowers asks for five or more reps per variant: “Single samples lie.”
5. Test under pressure, for discipline skills. If your skill enforces a process (write tests first, review before merging), polite test prompts will pass. Superpowers’ subagent testing guide builds scenarios with time pressure, sunk cost and authority (“It’s 6pm, dinner at 6:30pm…”), and records the rationalisations agents use to skip steps.
6. Re-run when models change. Anthropic points out that capability-uplift skills “may become less necessary as models improve. Evals tell you when that’s happened.” Pin model versions in CI so a model update isn’t mistaken for a regression.
What we couldn’t verify
- Anthropic’s claims that verification skills have the most impact, and that description tuning improved triggering, come with no published numbers.
- Vercel’s eval set and model aren’t public.
- The triggering measurements outside Vercel come from small practitioner tests on one or two Claude models. Rates will differ on other agents and on newer models.
- No study has compared description styles (third person vs imperative, pushy vs neutral) head to head across agents.
- No study has tested XML tags against Markdown in skills.
The checklist
Before you ship a skill:
- You ran the task without the skill and saw it fail, or do worse.
- The name is lowercase with hyphens, specific, and matches the folder.
- The description says when to use it, with words users actually type, plus what it’s not for. It doesn’t summarise the steps, and it’s not in the first person.
- The important trigger words come first, and the description is well under 1,024 characters.
- The body is under 500 lines, and you can’t cut a line without the agent getting something wrong.
- It gives one default per decision, not a menu.
- It has a gotchas section with the things the model can’t know.
- Fragile steps are scripts, and the skill says whether to run or read them.
- It ends with a verification step, sized to what can actually go wrong.
- Reference files are one level deep, with a line saying when to read each one.
- You have 10–20 trigger tests, including near-miss negatives, and a few outcome tests, run three or more times each.
- You tested on every model you’ll run it on.
- It uses only spec frontmatter fields if it has to work in more than one agent.
- For anything that must always happen, you used a hook, not a skill.
Skills are the cheapest way to give an agent knowledge it doesn’t have, and one of the easiest ways to fool yourself that you have. The evidence points to one habit: write the test before the skill, and keep the skill only if the test says it helps.
