How to author skills correctly
A set of rules based on the Agent Skills specification + practice. Verified against real skills.
1. Frontmatter (required fields)
---
name: my-skill
description: Use when [triggers/symptoms/contexts]. [what it does + when to apply]
---
| Field |
Rule |
name |
REQUIRED. 1–64 characters, a-z0-9 + hyphens. Must match the skill's folder name |
description |
REQUIRED. 1–1024 characters. «What it does + when to use»; include the keywords the agent searches by. NOT a workflow summary |
license |
optional |
compatibility |
1–500 characters, only if there are environment requirements |
2. Directory structure
skill-name/
├── SKILL.md # required
├── scripts/ # optional: executable scripts
├── references/ # optional: details, «read when X»
├── assets/ # optional
└── any other files/folders — allowed
- From SKILL.md reference files with relative paths from the skill root.
- Progressive disclosure: SKILL.md < ~500 lines; details go into
references/ with a pointer «read this when X happens».
3. Script bundling (scripts/)
- First check for an existing tool:
npx, uvx, pipx, bunx — take an existing one, write your own only when none exists.
- If you bundle a script, it must be self-contained: document dependencies in SKILL.md or
compatibility.
- Agent-safe design:
- NO interactive prompts — the agent will hang on a TTY. Input only via arguments.
--help with usage; clear error messages.
- Structured output: result to stdout, diagnostics to stderr.
- Idempotency;
--dry-run for destructive operations.
- Predictable output size (agents truncate ~10–30K characters).
4. Best practices and antipatterns
Do:
- Small, composable, like a function: one coherent task.
- Description in the imperative: «Use when …», list the triggers. Agents under-trigger.
- Add what the agent does not know; drop what it already can do.
Gotchas sections — the most valuable content; checklists for multi-step processes; output templates.
- Defaults, not menus; procedures, not declarations; explain «why».
- Calibrate detail to fragility: for fragile operations — prescriptively.
Do not:
- Do not stuff code into SKILL.md — move it to
scripts/.
- Do not describe the workflow in
description.
- Do not give many equal options without a default.
- Do not generate generic content without subject knowledge.
5. New skill template
---
name: my-skill
description: Use when [symptoms/contexts]. [what it does + when to apply, 1–1024 chars.]
license: MIT # optional
compatibility: Requires X # optional
---
# What it does (1–2 sentences)
## When to use / when NOT to use
## Workflow (numbered, imperative)
## Gotchas
## Available scripts (relative paths from the skill root)
## References (pointers «read when X»)
6. Turning a session into a skill (the former /learn flow)
The raw material is what happened in this chat (or a named directory/procedure/URL) — not a skill-format question, and not a conclusion to remember (that is dev-wiki/findings).
- Isolate the repeatable procedure. What did you actually do that a fresh session would have to rediscover? Steps in order, with the "why" behind non-obvious decisions. One-off facts are NOT skills → memory instead; general knowledge the agent already has is NOT a skill (YAGNI).
- Trigger test before writing. In a fresh session, would the description fire for the natural phrase a user would say? No plausible trigger → stop, don't write it. The description is the only thing a future session sees.
- Draft SKILL.md by the rules above: numbered imperative procedure, defaults (not menus), gotchas — the most valuable section.
- Choose the location. Portable (any machine/project) → kit
skills/<slug>/, subject to English, file-size and review checks. Machine/user-specific → the harness's user skills dir (e.g. ~/.claude/skills/), which does not propagate. Creating a skill does not itself authorize a commit or deployment to installed harnesses; apply AGENTS.md action authorization.
- Verify and candidate state before broad promotion. Frontmatter delimiters,
name == folder, description within limits; trigger test against the natural phrase. A newly distilled procedure starts as a candidate:
- Promotion criteria: promotion to default or mandatory policy requires replaying the originating case, at least one nearby negative case (where the procedure must NOT fire or alter behavior), and at least one held-out case.
- Retirement criteria: skills are evaluated and retired by post-install opportunity/use and measurable contribution to correct outcomes, not raw read counts.
Gotchas: don't over-generalize — encode the procedure that exists, not the class of procedures; Russian belongs only in trigger words; scripts stay in
scripts/, never inline; a skill that was wrong once is fixed like code — edit + verify against the same case.
1---2name: skill-authoring3description: Use when creating or editing any skill: frontmatter rules (name/description), folder structure, script bundling, quality checklist — including converting the current session/procedure/URL into a new reusable skill ("learn", "/learn", "turn this session into a skill", "make a skill from this workflow", "сделай скилл из этой процедуры", "навык из"). Per the Agent Skills specification (Hermes-compatible).4license: MIT5---67# How to author skills correctly89A set of rules based on the Agent Skills specification + practice. Verified against real skills.1011## 1. Frontmatter (required fields)1213```markdown14---15name: my-skill16description: Use when [triggers/symptoms/contexts]. [what it does + when to apply]17---18```1920| Field | Rule |21|---|---|22| `name` | REQUIRED. 1–64 characters, `a-z0-9` + hyphens. **Must match the skill's folder name** |23| `description` | REQUIRED. 1–1024 characters. «What it does + when to use»; include the keywords the agent searches by. NOT a workflow summary |24| `license` | optional |25| `compatibility` | 1–500 characters, only if there are environment requirements |2627## 2. Directory structure2829```30skill-name/31├── SKILL.md # required32├── scripts/ # optional: executable scripts33├── references/ # optional: details, «read when X»34├── assets/ # optional35└── any other files/folders — allowed36```3738- From SKILL.md reference files with **relative paths from the skill root**.39- Progressive disclosure: SKILL.md < ~500 lines; details go into `references/` with a pointer «read this when X happens».4041## 3. Script bundling (scripts/)42431. **First check for an existing tool**: `npx`, `uvx`, `pipx`, `bunx` — take an existing one, write your own only when none exists.442. If you bundle a script, it must be **self-contained**: document dependencies in SKILL.md or `compatibility`.453. **Agent-safe design:**46 - NO interactive prompts — the agent will hang on a TTY. Input only via arguments.47 - `--help` with usage; clear error messages.48 - Structured output: result to stdout, diagnostics to stderr.49 - Idempotency; `--dry-run` for destructive operations.50 - Predictable output size (agents truncate ~10–30K characters).5152## 4. Best practices and antipatterns5354**Do:**55- Small, composable, like a function: one coherent task.56- Description in the imperative: «Use when …», list the triggers. Agents under-trigger.57- Add what the agent does not know; drop what it already can do.58- `Gotchas` sections — the most valuable content; checklists for multi-step processes; output templates.59- Defaults, not menus; procedures, not declarations; explain «why».60- Calibrate detail to fragility: for fragile operations — prescriptively.6162**Do not:**63- Do not stuff code into SKILL.md — move it to `scripts/`.64- Do not describe the workflow in `description`.65- Do not give many equal options without a default.66- Do not generate generic content without subject knowledge.6768## 5. New skill template6970```markdown71---72name: my-skill73description: Use when [symptoms/contexts]. [what it does + when to apply, 1–1024 chars.]74license: MIT # optional75compatibility: Requires X # optional76---77# What it does (1–2 sentences)7879## When to use / when NOT to use80## Workflow (numbered, imperative)81## Gotchas82## Available scripts (relative paths from the skill root)83## References (pointers «read when X»)84```8586## 6. Turning a session into a skill (the former /learn flow)8788The raw material is what happened in this chat (or a named directory/procedure/URL) — not a skill-format question, and not a conclusion to remember (that is dev-wiki/findings).89901. **Isolate the repeatable procedure.** What did you actually do that a fresh session would have to rediscover? Steps in order, with the "why" behind non-obvious decisions. One-off facts are NOT skills → memory instead; general knowledge the agent already has is NOT a skill (YAGNI).912. **Trigger test before writing.** In a fresh session, would the description fire for the natural phrase a user would say? No plausible trigger → stop, don't write it. The description is the only thing a future session sees.923. **Draft SKILL.md** by the rules above: numbered imperative procedure, defaults (not menus), gotchas — the most valuable section.934. **Choose the location.** Portable (any machine/project) → kit `skills/<slug>/`, subject to English, file-size and review checks. Machine/user-specific → the harness's user skills dir (e.g. `~/.claude/skills/`), which does not propagate. Creating a skill does not itself authorize a commit or deployment to installed harnesses; apply AGENTS.md action authorization.945. **Verify and candidate state before broad promotion.** Frontmatter delimiters, `name` == folder, description within limits; trigger test against the natural phrase. A newly distilled procedure starts as a candidate:95 - **Promotion criteria:** promotion to default or mandatory policy requires replaying the originating case, at least one nearby negative case (where the procedure must NOT fire or alter behavior), and at least one held-out case.96 - **Retirement criteria:** skills are evaluated and retired by post-install opportunity/use and measurable contribution to correct outcomes, not raw read counts.97Gotchas: don't over-generalize — encode the procedure that exists, not the class of procedures; Russian belongs only in trigger words; scripts stay in `scripts/`, never inline; a skill that was wrong once is fixed like code — edit + verify against the same case.