I spend a good chunk of my week watching AI coding agents do things wrong. Not dramatically wrong — just lazy wrong. They skip the spec, ship a feature without a test, and merge something that works locally but falls apart in review. The frustrating part is that the agent is smart enough to know better. It just has no reason to care.

That changed the day I stopped treating my agent like a chat window and started treating it like a junior developer who needs standard operating procedures. The tool for that is called an agent skill — a plain Markdown file that teaches your agent how to work the way your best engineer works. This guide walks through the anatomy of a good SKILL.md, based on the format behind Addy Osmani’s agent-skills repository, which has become the de facto reference for this pattern. I cloned the repo, installed skills into a live agent, wrote a sample skill from scratch, and validated it — so every command here is one I actually ran.
Why Agent Skills Exist
AI coding agents default to the shortest path. Given a task, they’ll usually produce code that works, skip the parts that feel like overhead, and call it done. That’s fine for a prototype and dangerous for production. Skills exist to fix that gap: they encode the workflows, quality gates, and best practices that senior engineers apply without thinking, in a format the agent can follow step by step. Even the big-repo agents like Meta’s Muse Code benefit from the same structure — the discipline layer is what separates them from a clever autocomplete.
Osmani’s pack ships 24 skills that map onto the whole development lifecycle — define, plan, build, test, review, ship. Each one is a structured workflow with verification gates. The philosophy is simple: agents are only as disciplined as the process you hand them, so hand them the process you actually want.
This is a bigger deal than it sounds. I covered how stacked PRs change the way agents submit work, and one of the things that caught my attention there was gh skill install — agents installing skills as first-class tooling. That’s the direction the whole ecosystem is moving, and the format matters more than any single tool.
The Anatomy of a SKILL.md
Every skill lives in its own directory under skills/, and the only required file is SKILL.md. The format has three layers:
skills/
skill-name/
SKILL.md # Required: the skill definition
scripts/ # Optional: runnable helpers
references/ # Optional: skill-specific docs
A SKILL.md starts with YAML frontmatter, then follows a recommended section flow. The frontmatter is the most important part because it’s the only part the agent sees at startup:
---
name: test-driven-development
description: Drives development with tests. Use when implementing any logic, fixing any bug, or changing any behavior. Use when you need to prove that code works.
---
Two rules on that frontmatter. First, the name must be lowercase, hyphen-separated, and match the directory name — I tested this with the test-driven-development skill straight from the repo and the match check passed. Second, the description has to tell the agent both what the skill does and when to activate it. The description is injected into the system prompt, so it’s your discovery contract. Keep it under 1,024 characters, and don’t summarize the workflow in it — if the description contains process steps, the agent may follow the summary instead of reading the full skill.
The Sections That Matter
After the frontmatter, well-written skills follow a consistent structure. Each section has a job, and skipping any of them weakens the whole thing.
Overview and When to Use
The overview is one or two sentences: what the skill does and why it matters. The “When to Use” section lists positive triggers and negative exclusions — use this skill when X, but NOT for Y. That exclusion is what stops an agent from dragging a code-review skill into a documentation edit.
Core Process
This is the heart of the skill: the numbered steps the agent follows. The rule here is specific over general. “Run npm test and verify all tests pass” beats “make sure the tests work.” Include code examples, exact commands, and ASCII flowcharts at decision points. I wrote a PHP SQL-injection audit skill as my test case, and the core process is a sequence of greps and a flagged-code example — nothing the agent has to interpret.
Common Rationalizations
This is the most distinctive feature of good skills, and the one most people skip. It’s a table of the excuses agents use to skip important steps, paired with the rebuttal:
| Rationalization | Reality |
|---|---|
| "This input is sanitized elsewhere" | Sanitization that happens elsewhere is invisible here. Prove it, or parameterize. |
| "It's an internal tool, no attacker can reach it" | Internal tools are one leaked credential from being external. |
Think of every time your agent said “I’ll add tests later” or “this is simple enough to skip the spec.” Those go in the table with a factual counter-argument. The rationalization table is what stops an agent from talking itself out of doing the work.
Red Flags and Verification
Red Flags are observable signs the skill is being violated — things to watch for during review. Verification is the exit criteria: a checklist where every item is provable with evidence, like test output or a grep result. If a checkbox can’t be verified, it shouldn’t be there.
Keep Skills Lean
Skills load on demand. At startup, the agent only sees each skill’s name and description — the full file loads only when the agent decides it’s relevant. That changes how you should write them. Keep SKILL.md under 500 lines, and push anything longer into supporting files. Use progressive disclosure: reference a file, and the agent reads it only when the workflow reaches that step.
Prefer scripts over inline code. A helper script executed by the agent consumes no context — only its output does — while inline code blocks are paid for on every load. When you do ship a script, use a #!/bin/bash shebang, set -e for fail-fast behavior, status messages to stderr, and machine-readable output to stdout.
One portability gotcha I hit while testing: the skills CLI per-skill install copies only the skills/<name>/ directory, not the repo-level references/ folder that shared checklists live in. The skill still works, but any link into that shared folder breaks. It’s a known issue in the project, and it means shared material should either live inside the skill or be copied alongside it.
Installing Skills in Your Agent
The fastest path works with more than 70 agents — Claude Code, Cursor, Codex, Copilot, Cline, and others — through the open skills CLI. I ran both of these live:
npx skills add addyosmani/agent-skills # install all 24 skills
npx skills add addyosmani/agent-skills --list # browse before installing
The --list flag cloned the repo and showed all 24 skills with their descriptions — that’s the exact discovery contract in action. To grab a single skill:
npx skills add addyosmani/agent-skills --skill code-review-and-quality
I verified that single-skill path end to end: it cloned the repo, copied code-review-and-quality/SKILL.md into .agents/skills/, and finished with a sensible warning that skills run with full agent permissions. That warning matters — I wrote up a whole audit on leaked n8n API tokens and the lesson carries over: anything an agent can run, a compromised agent can run against you, so treat skill sources with the same care you’d apply to vetting VS Code extensions. Each tool also has a native install — Claude Code uses /plugin marketplace add addyosmani/agent-skills, Codex CLI 0.122+ has codex plugin marketplace add, and Gemini CLI and Antigravity have their own commands. The README in the repo covers every setup path, including the skill-extensibility angle I explored in my Grok Build walkthrough.
Writing Your First Skill
You don’t need a whole pack. Start with one skill that targets your most expensive recurring mistake. Here’s the exact recipe I used:
- Pick the mistake. For me it was PHP files reaching the database with concatenated user input.
- Write the frontmatter with a precise “Use when.” Mine was: audit PHP code that builds database queries.
- Write the core process as numbered, runnable steps — greps that list files, then a trace of every variable into SQL.
- Add a rationalizations table with the three excuses I’d heard my agent make.
- Finish with a verification checklist that’s all evidence: zero concatenations after grep, tests pass, every flagged line documented.
The result was a 60-line file whose YAML frontmatter parses cleanly and whose name matches its directory. If you’re auditing AI coding tools anyway, the same discipline applies — I walked through a full data-privacy audit for AI coding tools a while back, and skills slot right into that workflow as the enforcement layer.
Where to Start
If you’ve never written a skill, don’t build a framework. Clone Osmani’s repo, read two or three SKILL.md files, and steal the structure. Then write one skill for the single thing your agent keeps getting wrong. Version it like code, review it with your team, and treat it as living documentation — because that’s exactly what it is.
The agent isn’t the problem. The missing process is. Give it a process worth following, and you’ll be surprised how fast “lazy but smart” becomes “disciplined and fast.” That’s a trade I’ll take every time — whether I’m reviewing someone else’s code or watching my own agent ship.