How to Write Great Skills for AI Coding Agents — The Missing Manual
A four-dimension checklist — trigger, structure, steering, pruning — for evaluating whether an AI agent skill actually steers behavior or just burns context-window tokens.
Why This Matters
You download a skill that promises to turn your agent into a planning machine. You wire it up, feed it a task, and watch. The agent skips half the steps, ignores the template, and produces something you could have written yourself in ten minutes.
The skill was not broken. You just could not tell a good skill from a bad one. And that problem — what Matt Pocock calls skill hell — is only getting worse. GitHub now hosts tens of thousands of freely available agent skills. Some are genuinely useful. Most are noise that burns context-window tokens without changing agent behavior. Developers try everything at once, get none of the promised results, and conclude the entire approach is broken.
In a talk prepared for the AI Engineer World's Fair, Pocock laid out what amounts to the first shared rubric for evaluating skills. It is not a library or a tool. It is a checklist — four dimensions you can walk through with any skill, whether you are downloading one or writing your own, to determine whether it actually steers the agent or just occupies space in the context window.
Prerequisites
What you should already know
- Familiarity with AI coding agents — tools like Claude Code, OpenAI Codex, or Cursor that can read, write, and execute code from a terminal
- Basic understanding of what a skill is in this context: a markdown file (typically
SKILL.md) that an agent reads into its context window and uses to steer its behavior- Awareness that agents maintain a context window — a finite token budget that holds the conversation, tool outputs, and any loaded skills. Every word added to a skill costs tokens on every invocation
Core Idea
A great skill works across four dimensions, and you can evaluate any skill by walking through them in order.
Trigger is how the skill gets invoked — either by the user typing a slash command, or by the model deciding on its own that the skill applies. Each choice carries a different cost.
Structure is how the skill is laid out internally. Every skill is composed of two fundamental units: steps (the procedure) and reference (supporting information like templates and definitions). A well-structured skill keeps its main SKILL.md file as small as possible by hiding branch-specific reference material behind context pointers — links to separate files the agent only loads when it needs them.
Steering is how you get the agent to actually do what the skill says. The core technique is leading words: compact, semantically dense phrases that survive into the agent's reasoning traces and shape its behavior from the inside. If the agent is not doing enough work on a particular step, you split that step into its own skill so the agent only sees one phase at a time.
Pruning is the cleanup pass. Most skills accumulate sediment (contributions nobody felt brave enough to delete), no-ops (text that sounds important but does not actually change what the agent does), and duplication (the same information appearing in multiple places). A small skill is easier to maintain, cheaper to invoke, and less likely to confuse the agent.
What this framework gives you is the ability to look at any skill and diagnose why it is not working — instead of just downloading another one and hoping.
How It Actually Works
The Trigger: User-Invoked vs. Model-Invoked
Every skill sits on your filesystem. The agent can always read it if you tell it to — that is the default. But skills can also declare themselves model-invocable: they include a description that permanently lives in the agent's context window, and the model can decide on its own when to load the full skill.
This creates a fundamental trade-off.
Model-invoked skills increase what Pocock calls context load. Every model-invocable skill adds its description to the context window on every single request. With 100 model-invoked skills, that is 100 descriptions competing for the agent's attention — and 100 descriptions worth of tokens you pay for on every turn. But they reduce cognitive load on the user: you do not need to remember which skill to invoke. The model figures it out.
User-invoked skills flip the trade-off. They impose no context load — the skill sits silently on disk until you explicitly call it. But the more user-invoked skills you have, the more skills you need to keep in your head. You become the skill router.
This is the architectural difference between the two most popular skill collections on GitHub. Superpowers (by obra, 48K+ stars) is primarily model-invoked — it gives the agent capabilities it can reach for on its own. Matt Pocock's skills (100K+ stars) is primarily user-invoked — the user stays in full control and the context window stays clean.
Pocock's argument for preferring user-invoked skills is about predictability. Every time you add a model-invocable skill, you introduce the possibility that the model simply chooses not to invoke it — even when it is exactly right for the task. You then need to evaluate your skills to verify they fire at the right times, which is a difficult testing problem. User-invoked skills remove that entire class of failure by making invocation a human decision.
How to decide
If the skill is critical to your workflow and you always want to know when it is in play, make it user-invoked. If the skill handles a scenario that arises unpredictably and you do not want to monitor for it, make it model-invoked. The right choice depends on whether you would rather pay in tokens or attention.
Structure: Steps, Reference, and Branches
Once the skill is loaded, the agent reads its SKILL.md file — the main body of the skill. Structuring this file well is the difference between a skill that fits in one screen and a skill that scrolls for pages.
Pocock breaks every skill into two fundamental units:
Steps are the step-by-step procedure the skill walks through. They are the imperative backbone — "find the relevant context," "confirm the test seams with the user," "write the PRD." Each step is one discrete unit of work.
Reference is any supporting information the steps need: templates, definitions, examples, checklists. In his write-a-prd skill, the reference includes a definition of "test seam" and a full PRD template in markdown.
Some skills have no steps and are pure reference (a style guide, a glossary). Some have no reference and are pure steps (a short checklist). Most useful skills have both.
graph TD
A["SKILL.md loaded into context"] --> B["Steps: sequential procedure"]
A --> C["Reference: templates, definitions, examples"]
B --> D["Agent executes step 1"]
D --> E["Agent executes step 2"]
E --> F["Agent executes step N"]
C -.-> D
C -.-> E
C -.-> F
style A fill:#1a1a2e,stroke:#6366f1,color:#e0e0ff
style B fill:#1a1a2e,stroke:#22c55e,color:#e0e0ff
style C fill:#1a1a2e,stroke:#22c55e,color:#e0e0ff
style D fill:#1a1a2e,stroke:#f59e0b,color:#e0e0ff
style E fill:#1a1a2e,stroke:#f59e0b,color:#e0e0ff
style F fill:#1a1a2e,stroke:#f59e0b,color:#e0e0ff
The critical constraint is keeping SKILL.md as small as possible. A smaller skill is easier to maintain, easier to audit, and cheaper to invoke. Every word shaved is a token saved — and since the skill is loaded on every invocation, those savings compound.
The technique for shrinking SKILL.md is branching with context pointers. Some skills do multiple different things depending on context. Pocock's domain-modeling skill, for example, does two things: it updates a local glossary called CONTEXT.md, and it creates architectural decision records (ADRs). Sometimes it does one, sometimes the other, sometimes neither.
If both the glossary template and the ADR template lived inside SKILL.md, the agent would read both every time — even when it only needed one. The solution is to move branch-specific reference into separate files and replace each with a short context pointer:
If you need the ADR template, read `references/adr-template.md`.
If you need to update CONTEXT.md, read `references/context-template.md`.
These pointers cost a few tokens. The templates — which might be dozens of lines each — only enter the context window when the agent actually follows the pointer. Across many invocations, this saves a meaningful amount of context.
The branching rule
If reference material is used on every invocation, keep it in
SKILL.md. If it is only used on some invocations, move it behind a context pointer.
Steering: Leading Words and Leg Work
The most common complaint about agent skills is also the most frustrating: "I wrote clear instructions and the agent just did not follow them."
Pocock's diagnosis is that most skill authors are not using leading words. A leading word is a compact, semantically dense phrase that the agent repeats back to itself during its reasoning process — and repeating it changes its behavior.
The example he uses is vertical slice. When an agent is given a large chunk of work, its default behavior is to code layer by layer: all the database models, then all the API endpoints, then all the frontend components. This produces a program that does not work until the very end — no feedback loop, no way to course-correct.
You could write a paragraph telling the agent not to do this. Or you could use the leading word "vertical slice" — a well-known development term that packs the entire alternative approach into two words. The agent's training data contains countless explanations of what a vertical slice is. When you put "vertical slice" in the skill and the agent reads it, the term activates those priors. When the agent then writes "we will implement this as a thin vertical slice" in its own reasoning trace, it steers its own behavior toward building one complete feature at a time.
The technique is testable: if you see your leading word appear in the agent's thinking traces, it is working. If the word never appears, either the skill is not being read carefully or the word does not carry enough semantic weight. You can iterate: try a different leading word, or make the current one more prominent.
graph LR
A["Skill text contains<br/>'vertical slice'"] --> B["Agent reads skill<br/>into context"]
B --> C["Agent writes in reasoning:<br/>'I'll build this as a<br/>thin vertical slice'"]
C --> D["Agent behavior shifts:<br/>slice-by-slice<br/>instead of layer-by-layer"]
style A fill:#1a1a2e,stroke:#6366f1,color:#e0e0ff
style B fill:#1a1a2e,stroke:#f59e0b,color:#e0e0ff
style C fill:#1a1a2e,stroke:#22c55e,color:#e0e0ff
style D fill:#1a1a2e,stroke:#a855f7,color:#e0e0ff
The second steering technique addresses a different problem: the agent does not do enough work on a particular step. Pocock calls this the leg work problem.
His canonical example is plan mode. Nearly every implementation of plan mode has two steps: ask clarifying questions, then create a plan. In practice, the agent sees that its ultimate goal is to create a plan, so it asks one or two shallow questions and eagerly jumps to plan creation. The "ask clarifying questions" step gets shortchanged because the agent can see the finish line.
Pocock's solution was to split the two phases into separate skills: grill-with-docs handles the deep questioning phase as its own isolated skill, and write-a-prd handles the planning phase separately. The agent working through grill-with-docs has no idea that a planning phase follows — its entire world is asking thorough questions. Only after that skill completes does the planning skill begin.
When to split a skill
Split a skill into separate phases when a step consistently gets less effort than it needs. By hiding future steps from the agent, you force it to treat the current step as its entire job — not as a box to check on the way to something more interesting.
Pruning: Sediment, No-Ops, and Duplication
Once a skill works, the final pass is about removing everything that does not need to be there. Pocock identifies three failure modes that bloat skills over time.
Sediment is what happens when multiple people contribute to a shared markdown file over weeks or months. Each person adds their own section. Nobody feels brave enough to delete or modify what came before. The result is a skill that has grown to five times its necessary size, with sections that contradict each other and advice that applied to a workflow from two versions ago.
The fix for sediment is to go back to structure: identify the skill's branches, move branch-specific material behind context pointers, and delete anything that applies to a branch that no longer exists.
No-ops are the subtlest failure mode and the one most common in agent-written skills. A no-op is text that appears to instruct the agent but does not actually change what the agent would have done anyway. Pocock's litmus test: delete the paragraph. If the agent's behavior does not change, the paragraph was a no-op.
For example, a skill that says "write a long, detailed commit message" is probably a no-op. The agent was going to write a reasonable commit message regardless. The paragraph costs tokens on every invocation and produces no behavioral difference.
Duplication is the most straightforward failure: the same reference material or instruction appears in multiple places — in SKILL.md, in a reference file, and in a template. Every duplicated piece of information is a maintenance hazard. When something changes, you have to remember to update it everywhere, and you will miss at least one of them.
The principle is single source of truth: every fact, template, and instruction appears in exactly one place within the skill. Steps reference that source rather than duplicating its content.
Worked Example
Consider a skill that takes a feature request and produces a product requirements document. Here is how the four dimensions apply to it.
Trigger. This skill is a good candidate for user invocation. You want to decide when to create a PRD — not have the model decide mid-conversation that now is the time. Making it user-invoked keeps the context window cleaner and gives you control over entry.
Structure — before. The initial SKILL.md might contain: three steps (find context, confirm test seams, write PRD), a paragraph explaining what test seams are, the full PRD template (30+ lines of markdown), and some general advice about writing requirements.
graph TD
subgraph "Before: everything in SKILL.md"
SK1["SKILL.md (200+ lines)"]
SK1 --> S1["3 steps"]
SK1 --> R1["Test seam definition"]
SK1 --> R2["PRD template (30 lines)"]
SK1 --> R3["General writing advice"]
end
subgraph "After: branching with context pointers"
SK2["SKILL.md (~60 lines)"]
SK2 --> S2["3 steps"]
SK2 --> CP1["If needed: read<br/>references/prd-template.md"]
SK2 --> CP2["If needed: read<br/>references/test-seams.md"]
R2B["prd-template.md<br/>(30 lines — only loaded<br/>when writing PRD)"]
CP1 -.-> R2B
end
style SK1 fill:#1a1a2e,stroke:#ef4444,color:#e0e0ff
style SK2 fill:#1a1a2e,stroke:#22c55e,color:#e0e0ff
style R2B fill:#1a1a2e,stroke:#f59e0b,color:#e0e0ff
Structure — after. The test seam definition and general writing advice are used on every invocation — they stay in SKILL.md but are compressed to a few sentences each. The full PRD template is only needed during the "write PRD" step, so it moves to references/prd-template.md with a context pointer. The skill shrinks from 200+ lines to about 60.
Steering. The skill uses "test seam" as a leading word — the agent will repeat it when asking the user about testing boundaries, which reinforces the focus on defining testable interfaces rather than vague feature descriptions. If the clarification step keeps getting shortchanged, the skill can be split into two: grill-for-requirements (deep questioning with no visibility into the PRD phase) followed by write-prd (planning with the answers already collected).
Pruning. The "general writing advice" paragraph is tested: delete it and run the skill on a real feature. If the PRD quality does not drop, the paragraph was a no-op and stays deleted. The test seam definition appears in exactly one place — not duplicated across SKILL.md and the PRD template.
Result
The skill goes from 200+ lines that the agent reads on every invocation to ~60 lines, with the template loaded only when needed. Context cost drops by roughly two-thirds per invocation. If the skill runs 20 times a day, that is thousands of tokens saved — for a single skill.
Common Misconceptions
Common misconceptions
- "Model-invoked skills are strictly better because the model can figure out when to use them." They are more flexible, but every model-invocable skill adds its description to the context window permanently. At ~50 skills, you are paying for thousands of tokens of skill descriptions on every single request — whether those skills are relevant or not.
- "If the agent is not doing what I want, I need to add more detail to the skill." More often, the problem is that the existing text is not steering the agent effectively. Try a better leading word or check whether the current words are even appearing in the agent's reasoning traces. Adding text to a skill that already has no-ops just adds more no-ops.
- "Longer skills are more thorough and therefore more reliable." Length correlates more strongly with sediment and duplication than with thoroughness. A 60-line skill that the agent reads carefully is more effective than a 200-line skill that the agent skims. If every piece of reference is in the right branch and every instruction survives the deletion test, the skill will be short.
- "A skill should handle every possible variation of its task." A skill that tries to handle every edge case becomes a sediment magnet. Focus on the common path. Edge cases belong in separate, focused skills or in reference material behind context pointers.
Key Takeaways
- A great skill works across four dimensions: how it is triggered, how it is structured, how it steers the agent, and what can be pruned.
- User-invoked skills trade user attention for cleaner context windows and predictable invocation. Model-invoked skills trade context load for flexibility. Neither is universally better — the right choice depends on the skill.
- Every skill is built from steps (the procedure) and reference (supporting templates, definitions, and examples). Keep
SKILL.mdsmall by hiding branch-specific reference behind context pointers. - Leading words are compact phrases that survive into the agent's reasoning traces and steer behavior from the inside. If you do not see your leading words in the thinking traces, they are not working.
- Splitting a skill hides future phases from the agent, forcing it to put full effort into the current step. Use this when a step consistently gets less work than it needs.
- Three failure modes bloat skills: sediment (accumulated contributions nobody deletes), no-ops (text that sounds important but does not change behavior), and duplication (the same information in multiple places). The deletion test — remove it and see if behavior changes — catches all three.
Open Questions
Open questions
- Can leading words be formalized into a shared vocabulary? If the community settled on a standard set of leading words for common failure modes (layer-by-layer coding, shallow planning, premature optimization), skills would become more composable and easier to evaluate.
- How do you evaluate a model-invoked skill's trigger accuracy? Unlike user-invoked skills, where invocation is binary and predictable, model-invoked skills need to fire at the right time and not fire at the wrong time. Building an evaluation framework for this is an open problem.
- At what point does splitting a skill into phases become counterproductive? Two skills are clearly better than one bloated one. But ten micro-skills that must be invoked in sequence impose their own cognitive load on the user. The optimal granularity is not yet known.
References
- Pocock, M., "The Missing Manual: How to Write Great Skills," AI Engineer World's Fair, 2026. https://youtu.be/UNzCG3lw6O0
- Pocock, M., "Skills for Real Engineers — mattpocock/skills," GitHub. https://github.com/mattpocock/skills
- obra, "Superpowers," GitHub. https://github.com/obra/superpowers
- Pocock, M., "AI Hero — AI Skills for Real Engineers." https://www.aihero.dev/skills
Related
Agent Loops: Autonomous AI Coding Workflows
An agent loop is a system where an AI coding agent repeatedly works toward a specified goal without waiting for human approval between each step — you define the trigger and the stopping condition, and the agent runs autonomously.
Browser Use: Making Websites Accessible to AI Agents
Browser Use is a family of techniques and tools — led by the open-source Python library browser-use — that lets AI agents control a real web browser the way a human would, all described in natural language.
LLM Function Calling: Giving Language Models a Way to Act
Function calling (also called tool use) is a capability that lets an LLM output structured commands — like get_weather(location='Cairo') — which your own code then executes, bridging the gap between what the model says and what it can do.