AI coding agents are only as good as the context they're given. Ask one to "review this pull request" and you'll get generic advice. Give it your team's review checklist and it reviews like a senior on your team.
Agent skills are how you package that context so it loads automatically, only when it's relevant. They're plain Markdown files, they work across GitHub Copilot, Claude Code and a growing list of other agents, and you can commit them to your repository so the whole team benefits.
I've published eleven of them for free. This tutorial covers what I learned writing them: why most skills don't change anything, and how to write ones that do.
What a skill actually is
A skill is a folder containing a SKILL.md file:
.github/skills/
release-notes/
SKILL.md
The file has a short YAML header followed by instructions in Markdown:
---
name: release-notes
description: Write user-facing release notes from merged pull requests. Use when asked to draft a changelog, release notes or a "what's new" summary.
---
# Release notes
Instructions the agent follows when this skill is loaded...
That's the whole format. There's no build step, no SDK and no API key.
Where skills live
Each agent looks in its own folder, inside your project or your home directory:
- GitHub Copilot (VS Code):
.github/skills/in the project - Claude Code:
.claude/skills/in the project, or~/.claude/skills/for every project - Other agents:
.agents/skills/is becoming the shared convention
Project folders are the ones to use for team conventions, because they're versioned with the code they describe.
How agents decide to load a skill
This is the most important concept in the tutorial, and the one most skill authors miss.
Agents don't read every skill on every request. That would waste their context window. Instead they use progressive disclosure:
- At the start of a session, the agent reads only the
nameanddescriptionof every installed skill. - When your request seems to match a description, the agent loads that skill's full
SKILL.md. - If the skill points to other files (scripts, references, templates), the agent reads those only when the instructions tell it to.
Which means:
The description is the only part of your skill that's guaranteed to be read. If it doesn't clearly say when to use the skill, the rest never gets loaded.
Skills vs instructions files
You may already use copilot-instructions.md, CLAUDE.md or AGENTS.md. Those are always loaded, on every request. Skills are loaded on demand.
A simple rule:
- Instructions files: short facts that apply to everything. "We use pnpm." "Tests live next to source files."
- Skills: focused workflows that apply sometimes. "How we write migrations." "How we review accessibility."
Putting a 300-line accessibility checklist in an always-on instructions file wastes context on every request that has nothing to do with accessibility. As a skill, it costs nothing until it's needed.
Why most skills don't help
Most skills I see fail in one of three ways:
- They describe instead of decide. "Consider performance and accessibility" changes nothing. The model already "considers" those things.
- Their description is vague. "Helps with React" never triggers reliably, because almost everything in a React project is "React".
- They restate what the model already knows. If a skill reads like the first page of the official docs, it adds tokens without adding judgement.
A good skill contains what the model can't know: your conventions, your trade-offs, your definition of done, and the mistakes your team has already made once.
What's next
In the full tutorial we'll fix all three problems:
- writing descriptions that trigger reliably
- turning advice into decision rules
- bundling scripts and reference files without bloating context
- building a complete skill from scratch
- testing skills with eval prompts so you know they work
Checking access…