Introduction
The single most useful mental model for writing a SKILL.md is this: you are writing a prompt that the agent will read when it activates the skill. Not a config file, not a manifest, not a README. A prompt. Every line is text the model will consume, weigh, and act on. Once you internalize that framing, the rest of the format follows.
Key Concepts
- YAML frontmatter: A block at the very top, fenced by
---, declaring metadata.nameanddescriptionare mandatory. - Markdown body: Everything below the frontmatter. Loaded into the agent's context when the skill activates.
- Convention sections: Headings the agent recognizes by convention:
## When to Use,## Procedure,## Pitfalls,## Verification. - Discoverability vs execution: Frontmatter drives discovery (Level 0). The body drives execution (Level 1).
Real World Context
A developer writes a git-commit-style skill. The frontmatter is two lines: name and description. The body has four headings: When to Use tells the agent the trigger (user asks to commit, push, or write a commit message). Procedure lists the four steps (run git diff --staged, parse the change set, format a conventional commit, run git commit). Pitfalls lists the gotchas (do not commit if pre-commit hooks would fail). Verification says final commit message is one line subject plus an optional body, no emoji. The whole file is fifty lines. The agent uses it the same way every time.
Deep Dive
Here is the canonical structure of SKILL.md:
markdown--- name: my-skill description: One sentence telling the agent when to use this skill. Phrased like the question a user would actually ask. version: 1.0.0 author: Your Name metadata: hermes: tags: [git, workflow] category: workflows --- # My Skill ## When to Use The trigger conditions. What does the user ask, what state is the repo in, what makes this skill relevant? ## Procedure 1. The first concrete step (with the tool you expect the agent to call). 2. The second step. 3. The third step. ## Pitfalls - Known failure modes and how to detect them. - Edge cases the agent should treat with extra care. ## Verification How the agent (and the user) can tell the workflow succeeded.
The frontmatter has two jobs:
- Required fields (
name,description) drive Level 0 discovery. The agent never reads the body when picking a skill; it only sees the description. Sharp descriptions are the single highest-leverage thing you can write. - Optional fields declare contracts: version, author, tags, category, platforms, required environment variables, toolset dependencies, fallback rules, config settings. They mostly shape when the skill is visible and what it needs to run.
The body has one job: tell the agent what to do once activated. The sectioning is convention, not enforcement. The agent does not parse ## Procedure differently from any other heading. What matters is that the headings communicate intent clearly to a model reading top to bottom.
The most common section pattern is the one above (When to Use, Procedure, Pitfalls, Verification), but any structure that makes the procedure clear is fine. Some skills add ## Examples, ## References, or ## Output Format. The model adapts to whatever you write as long as it is coherent.
A few prompt-craft principles apply:
- Write for a careful reader, not a careless one. The agent will read every line. Vague phrasing produces vague behavior.
- State the tool the agent should use.
Run the terminal tool with: git diff --stagedis more reliable thanlook at the staged changes. - Use lists and headings. Models follow numbered procedures far more reliably than they follow prose.
- Keep the body bounded. A two-page
SKILL.mdis harder to follow than a 50-line one. If you need more, put it underreferences/and let the agent pull it on demand.
Common Pitfalls
- Writing the description as an internal note: Descriptions like
wrapper around the Tenor APIdescribe the implementation. The model wants the user-intent description:Find GIFs matching a topic. The description is read by the model, not by you. - Burying the trigger: If the agent has to read the whole body to figure out when to activate, it often will not. The
## When to Usesection should be the first heading, and it should be specific.
Best Practices
- Write the description last: Once you know what the skill actually does, distilling it to one sentence becomes easy. Writing the description first leads to vague placeholders.
- Make the procedure executable in your head: Read your
## Procedurefrom a cold start. Do you know which tool to call at each step? If you would not, the agent will not either.
Summary
SKILL.mdis a prompt: frontmatter on top, Markdown body below.- Required frontmatter is
nameanddescription. The description drives discovery. - The body is loaded into the agent's context on activation. Be deliberate about every line.
- Convention sections (
When to Use,Procedure,Pitfalls,Verification) make procedures easy for the model to follow.
Code Examples
---
name: git-commit-style
description: Draft a conventional-commits-style commit message from staged changes, ready for the user to confirm before committing.
version: 1.0.0
author: Platform Team
metadata:
hermes:
tags: [git, workflow]
category: workflows
---
# Git Commit Style
## When to Use
User asks to commit, write a commit message, or stage and commit changes. The repo has staged changes (`git diff --staged` is non-empty).
## Procedure
1. Run `git diff --staged --stat` via the `terminal` tool to get the shape of the changes.
2. Run `git diff --staged` to read the actual changes.
3. Classify the change: feat / fix / chore / docs / refactor / test / perf.
4. Write a subject line: `<type>(<scope>): <short imperative summary>` (max 72 chars).
5. If the change is non-trivial, add a body explaining the why in 1 to 3 short paragraphs.
6. Show the message to the user and ask for confirmation before running `git commit`.
## Pitfalls
- Never bypass pre-commit hooks. If a hook fails, surface the failure and stop.
- Do not include literal file paths in the subject line; the diff already shows them.
## Verification
A commit message that follows the conventional-commits prefix, has a clean imperative subject, and an optional body that explains intent rather than restating the diff.