DEV Community

AI Frontier Post
AI Frontier Post

Posted on Originally published at aifrontierpost.com AI-assisted

Teach Claude your workflow: build an Agent Skill with SKILL.md

Originally published at AI Frontier Post.


Every regular Claude user eventually hits the same wall: a workflow they repeat every week — the way they want release notes written, code reviewed, or research briefs formatted — that they have to re-explain in every single session. Paste the checklist again. Correct the format again. Watch the agent improvise the steps you already decided. The knowledge exists, but it lives nowhere the agent can reliably find it.

Agent Skills are the industry's answer, and they are having a moment: Anthropic launched them as a Claude feature in October 2025, published the format as an open standard on December 18, 2025 at agentskills.io, and by mid-2026 roughly forty products read the same files — Claude Code, OpenAI's Codex, Cursor, GitHub Copilot, Google's Gemini CLI among them. The whole standard is almost absurdly small: a folder containing a single Markdown file, SKILL.md, with a few lines of YAML metadata on top and instructions below.

This tutorial builds one from scratch, end to end. You will pick a workflow worth teaching, write the frontmatter and instructions, validate the result with a real script, and install it so it triggers automatically in your own sessions. No API keys, no servers, no cost — and the skill you build works in every agent that speaks the open standard, not just Claude.

What you'll need

  • A coding agent that supports the open standard — Claude Code is the reference implementation, but the skill you build also loads in OpenAI Codex, Cursor, GitHub Copilot, Gemini CLI, and the rest. claude.ai supports skills too once enabled in settings.
  • A text editor and Python 3 (for the validation script; pip install pyyaml if you don't have it).
  • One repeatable workflow of your own — something you have done at least three times and will do again. We will build a changelog writer as the worked example; substitute your own at Step 1.
  • About 20–30 minutes. No accounts, no API keys, no cost.

What a skill actually is

Strip away the announcements and a skill is a directory with one required file:

changelog-writer/
└── SKILL.md        # YAML frontmatter + Markdown instructions
Enter fullscreen mode Exit fullscreen mode

The frontmatter — just name and description are required — tells the agent what the skill does and when to use it. The body tells it how: the workflow, the rules, the output contract, the edge cases. Optionally, the folder grows three sub-directories: scripts/ for executable code, references/ for docs loaded on demand, and assets/ for templates and static files.

The clever part is progressive disclosure — how the agent loads the skill in three stages instead of all at once:

Diagram of progressive disclosure: a tiny metadata chip at the top, a larger instruction document in the middle, and a toolbox of on-demand resources at the bottom

AI-generated illustration: progressive disclosure — metadata always loaded, instructions on trigger, resources on demand.

  1. Metadata (~100 tokens), always loaded. At startup the agent reads only every skill's name and description into context. You can have fifty skills installed and barely feel it.
  2. Instructions (<5,000 tokens recommended), loaded on trigger. When the model decides your task matches a skill's description, it reads the full SKILL.md body.
  3. Resources, loaded on demand. Scripts and reference files enter context only when the instructions point at them. A script's code never enters context at all — only its output does.

This is why skills scale where giant system prompts don't. Your changelog conventions cost you ~100 tokens every session; the full procedure costs nothing until someone actually asks for a changelog.

Step 1: Pick one job worth teaching

The most common failure in skill authoring is teaching the agent something that shouldn't be a skill. Use this filter — a job earns a skill when all three are true:

  • Repeated. You do it at least three times, across sessions or projects. Weekly release notes: yes. A one-off data migration: no.
  • Multi-step with conventions. There are steps, an order, and choices you'd make the same way every time — formats, checklists, review criteria.
  • Consistency matters. You care that it comes out the same way each time, because someone else reads it or a pipeline consumes it.

Good candidates: a changelog writer (our worked example), a code reviewer that enforces your team's conventions, a research briefer that always cites sources the same way, a release checklist runner. Bad candidates: single shell commands (make them aliases), pure reference facts (make them docs), anything you've only done once.

One skill, one job. If your "skill" needs a table of contents, it's two skills.

Step 2: Scaffold the folder

Create the directory where your agent looks for personal skills — ~/.claude/skills/ for Claude Code — and the one file that makes it a skill:

mkdir -p ~/.claude/skills/changelog-writer
touch ~/.claude/skills/changelog-writer/SKILL.md
Enter fullscreen mode Exit fullscreen mode

The directory name must match the skill's name in the frontmatter, and the spec is strict about that name:

  • 1–64 characters, lowercase letters, numbers, and hyphens only
  • Must not start or end with a hyphen, and no double hyphens
  • Must match the parent directory name exactly

Prefer the gerund form for names — writing-changelogs rather than changelog-writer is the spec's own recommendation, though noun forms like ours are widespread in the ecosystem. Either is valid; pick one convention and keep it.

Step 3: Write the frontmatter — the five lines that matter most

Everything above the skill's usefulness flows through the description. It is the only thing the agent sees before deciding to load your skill — so it must say what the skill does and when to use it, with the concrete keywords a user would actually type. Compare:

# Weak — the agent can't tell when this applies
description: "Helps with changelogs."

# Strong — what it does, when to trigger, user's own vocabulary
description: "Writes and updates project changelogs in Keep-a-Changelog format."
  Use when the user asks to draft a changelog, add release notes, or summarize
  recent commits for a release. Also use proactively before a version tag is created.
Enter fullscreen mode Exit fullscreen mode

The spec caps descriptions at 1,024 characters and, notably, agents tend to under-trigger skills — so be explicit about trigger contexts rather than subtle. Name the situations: "when the user asks to…", "before a version tag is created". Write in the third person, pack in the keywords.

Here is the complete frontmatter for our worked example:

---
name: changelog-writer
description: Writes and updates project changelogs in Keep-a-Changelog format.
  Use when the user asks to draft a changelog, add release notes, or summarize
  recent commits for a release. Also use proactively before a version tag is created.
license: MIT
---
Enter fullscreen mode Exit fullscreen mode

Four more fields are defined by the open spec, all optional:

Field What it's for Constraint
license License name, or a reference to a bundled license file Keep it short
compatibility Environment requirements — intended product, system packages, network access Max 500 chars; omit if you don't need it
metadata Arbitrary key-value map for anything the spec doesn't define (author, version, tags) Use unique-ish key names to avoid collisions
allowed-tools Space-separated pre-approved tools, e.g. Bash(git:*) Read — least privilege at the skill level Experimental; support varies by client

Claude Code adds its own non-portable extensions on top — disable-model-inviction: true (only the user may invoke it; use for anything with side effects like /deploy) and user-invocable: false (only the agent may invoke it; use for background knowledge). If you want the skill to travel to other agents unchanged, stick to the spec fields.

Step 4: Write the body — instructions, not essays

The body has no format restrictions — write whatever helps the agent perform the task — but the shape that works follows a consistent skeleton: Purpose, Workflow, Output Contract, Operating Rules. Tell the model what to do next, not the history of the domain. Keep the file under 500 lines; the spec recommends under 5,000 tokens for the instructions level.

Here is the complete worked example — the exact file I validated in Step 6:

# Changelog Writer

## Purpose
Produce a CHANGELOG.md entry or full file that follows the Keep-a-Changelog
format (Added / Changed / Deprecated / Removed / Fixed / Security), written
from git history or from user-supplied notes.

## Workflow
1. If no date or version is given, ask — never invent the release date.
2. Inspect recent history: `git log --oneline -20`.
3. Draft the entry under an `## [Unreleased]` heading (or the given version).
4. Sort entries: Added, Changed, Deprecated, Removed, Fixed, Security.
5. Write facts only. Do not embellish commit messages into features that
   were not shipped.

## Output Contract
- Output Markdown only, no commentary around it.
- Never claim a bug is fixed unless a commit touching it exists.
- Keep entries one line each, present tense, no trailing period.
Enter fullscreen mode Exit fullscreen mode

Notice what this does and doesn't contain. It names the format and the category order. It gives the exact command to inspect history. It pins down the failure modes that matter — inventing dates, embellishing commits, wrapping output in chatty commentary. It does not explain what a changelog is, what git log does, or the philosophy of release notes. The agent already knows those things; the skill supplies your decisions.

Two more authoring rules that separate working skills from dead ones:

  • Examples and edge cases earn their lines. A single before/after example of a well-formed entry teaches more than a paragraph of prose. If there's a case that always trips the agent up, write it down explicitly ("never invent the release date").
  • Split, don't bloat. When the body starts accumulating reference material — long API tables, full schemas, exhaustive examples — move it to references/ and point at it. The skill's instructions stay lean; the detail loads only when needed.

Step 5: Scripts, references, assets — only when they earn their place

Most first skills need nothing beyond SKILL.md, and that's fine — the spec's three optional directories exist for when instructions alone aren't the right tool:

Diagram of a skill folder: the required SKILL.md document on top, branching into scripts, references, and assets sub-folders

AI-generated illustration: the full skill layout — SKILL.md plus the three optional directories.

  • scripts/ — executable code, for anything deterministic. Sorting, parsing, form validation, math: when the agent would otherwise regenerate code by hand every time, check in a script. The code never enters context — only its output does — so a 200-line script costs you nothing until it runs. Scripts should be self-contained, document their dependencies, and fail with helpful error messages.
  • references/ — documentation loaded on demand. Detailed technical references (REFERENCE.md), form templates (FORMS.md), domain files (finance.md, legal.md). Keep each file focused and small — agents load them individually.
  • assets/ — static resources. Document templates, images, lookup tables, schemas — things the skill reads or produces, not instructions.

The judgment call: flexibility goes in instructions, reliability goes in scripts, factual lookup goes in references. A changelog checker that verifies every entry ends without a period? That's deterministic — a script. The Keep-a-Changelog category definitions? A reference file. File references use paths relative to the skill root, and the spec asks you to keep reference chains one level deep — SKILL.md points at a reference file, not at a file that points at another file.

Step 6: Install, trigger, and validate

Where you put the folder decides who gets the skill:

  • ~/.claude/skills/ — personal. Available in every project, on this machine only.
  • .claude/skills/ — project. Commit it with the repo and the whole team inherits the workflow.

After installing, start a new session (or run the client's skill-reload command). Triggering happens two ways: automatically, when your request matches the description — "draft the changelog for the 2.4 release" should now wake the skill on its own; or manually as a slash command — /changelog-writer in Claude Code. Test the automatic path with the exact phrasing from your description; if it doesn't trigger, your description needs more of the user's vocabulary, not less.

Now validate. Anthropic publishes a reference validation library (skills-ref), but the spec's naming rules are simple enough to check directly. This script enforces the constraints from the spec — name format, description length, directory match, the 500-line limit — and I ran it against the skill from Step 4:

import re, yaml
from pathlib import Path

def validate_skill(skill_dir):
    root = Path(skill_dir)
    errors = []
    text = (root / "SKILL.md").read_text()
    _, front, body = text.split("---", 2)
    fm = yaml.safe_load(front)          # pip install pyyaml
    name, desc = fm.get("name", ""), str(fm.get("description", ""))
    if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", name):
        errors.append("name violates naming rules (lowercase, hyphens only)")
    if name != root.name:
        errors.append(f"name '{name}' does not match directory '{root.name}'")
    if not (1 <= len(desc) <= 1024):
        errors.append("description length out of range (1-1024 chars)")
    if len(body.splitlines()) > 500:
        errors.append("SKILL.md exceeds 500 lines")
    allowed = {"name", "description", "license", "compatibility",
               "metadata", "allowed-tools"}
    if unknown := set(fm) - allowed:
        errors.append(f"unknown frontmatter fields: {unknown}")
    return errors

print(validate_skill("~/.claude/skills/changelog-writer".replace("~", str(Path.home()))))
Enter fullscreen mode Exit fullscreen mode

Against our changelog-writer: [] — valid. Against a deliberately broken skill (missing name, 1,100-character description), it reported exactly the two violations: name is required; description length out of range (1-1024). Validation is not a substitute for testing the behavior — ask the agent to use the skill on a real task and read what comes out — but it catches the structural mistakes that silently prevent loading.

One safety note before you go further: a skill is instructions plus, optionally, code that runs with your agent's permissions. Install skills only from sources you trust, and read SKILL.md before installing — the same review you'd give any script before running it. Community marketplaces now list thousands of skills; treat an unknown skill the way you'd treat an unknown npm package.

Which approach should you use?

Skills overlap with half a dozen other mechanisms. Here's the map, in plain terms:

  • System prompts / custom instructions: one-off guidance for a conversation. Use a skill when the knowledge should survive the session and follow you across projects.
  • Projects (static background knowledge): always-loaded context about a repo or domain. Skills are procedural and load dynamically — how to do the thing, not facts about the thing.
  • MCP servers: they give the agent access — databases, APIs, external services. Skills give it method — how to use those tools well. They compose: a Sentry skill wraps workflow around Sentry's MCP server.
  • Slash commands: in Claude Code, commands have effectively merged into skills — a skill at .claude/skills/deploy/SKILL.md creates /deploy, and adds auto-triggering on top.
  • Subagents: runtime isolation — a forked context for a task. The skill says what to do; the subagent provides the room to do it in. Use them together for long, messy jobs.

Mental model: MCP is the nervous system, skills are the handbook, projects are the memory, subagents are the work crew.

The takeaway

A skill is the smallest unit of reusable agent expertise: a folder, a SKILL.md, a name and description that cost ~100 tokens per session. Pick one repeated workflow, write the frontmatter as the trigger contract it is, keep the body to decisions and failure modes, split detail into references, validate the structure, and install it where the team can inherit it. Do that three or four times and your agent stops being a brilliant stranger every morning — it starts being the colleague who already knows how you work.

Top comments (0)