# Skills and Subagents

Course: [Markdown](https://www.devtutorials.ai/learn/markdown) · Section: AI-Native Markdown
Source: https://www.devtutorials.ai/learn/markdown/ai-native/skills-and-subagents

> Write a SKILL.md that gets picked for the right tasks. Fix a skill whose vague description never loads, follow the name rules, write a description with what, when and when not, keep the body small with progressive disclosure, and write a reviewer subagent file.

## The Skill That Never Loaded

Asha writes a skill to help an AI agent check refund requests against the policy. She puts the steps in a `SKILL.md` file. Then she asks the agent about a late refund. The agent does not use her skill at all.

```md runnable file="refund-check/SKILL.md" expect-lint="SKL004" probes="A customer wants a refund for order A-1042|Why is my refund late?|The parcel arrived damaged, can I get my money back?|Check if this refund request is inside the 30-day window|Customer asks for a refund on a damaged order|When will my order ship?|Track order A-1042|A customer asks when their order will be shipping|Write a unit test for the cart|Change the colour of the checkout button" title="A skill with a vague description" dialect="docs"
---
name: refund-check
description: Helps with refunds.
---

# Refund check

1. Find the order by its number or the customer's email.
2. Check the refund window: 30 days from delivery.
3. If the amount is over ₹5,000, ask for a manager's approval.
4. If the item is damaged, ask for a photo first.
```

The steps are fine. The problem is the second line. Open the **Agent view** tab. It lists ten prompts a person might type. The skill is picked for **none** of them, not even "Why is my refund late?".

At the start of a session, an AI tool reads only the **name** and **description** of each skill. It decides from those alone whether a skill fits the task. "Helps with refunds" is too short and too vague to win that choice.

In this lesson, you will learn how a `SKILL.md` file is built, how to write a description that gets picked for the right tasks and skipped for the wrong ones, and how to write a **subagent** file.

**In simple words:** a skill is a folder with a `SKILL.md` file. Its description is an advert. If the advert is vague, the skill is never used.

## TL;DR

- A **skill** is a reusable set of instructions for one kind of task. It is a folder with a `SKILL.md` file inside.
- `SKILL.md` starts with YAML **frontmatter**. `name` and `description` are required.
- The `name` is lowercase letters, numbers and hyphens, and must match the folder name.
- The **description** says **what the skill does** and **when to use it**, with the words people will actually type.
- Skills load in stages: name and description first, the body only when the task matches, extra files only when needed.
- A **subagent** file defines a separate helper agent: frontmatter for its name, description and tools, and a body that is its instructions.

## A Real-World Example

Think about the list of courses at a college.

You do not read every course's full textbook to choose one. You read the course list: a name and two lines about each course. Then you open the textbook for the one you picked.

AI tools choose skills the same way. The name and description are the course list. The body of `SKILL.md` is the textbook. A course called "Misc. Topics: helps with stuff" never gets chosen, however good its textbook is.

## What You Will Learn

In this lesson, you will learn:

1. What a skill is, and how it differs from `AGENTS.md`.
2. How a skill folder and its `SKILL.md` are laid out.
3. The rules for the `name` field.
4. How to write a description that matches the right prompts and skips the wrong ones.
5. How skills load in stages, and what that means for their size.
6. How to write a subagent file.

## Cheat Sheet

```md runnable clean file="refund-check/SKILL.md" probes="A customer wants a refund for order A-1042|Why is my refund late?|The parcel arrived damaged, can I get my money back?|Check if this refund request is inside the 30-day window|Customer asks for a refund on a damaged order|When will my order ship?|Track order A-1042|A customer asks when their order will be shipping|Write a unit test for the cart|Change the colour of the checkout button" title="A skill that gets picked" dialect="docs"
---
name: refund-check
description: "Checks a refund request against the refund policy: the 30-day window, the approval limit and damaged items. Use when a refund is requested or late, or when someone wants money back for a damaged parcel. Do not use for shipping, delivery dates or tracking."
---

# Refund check

## Steps

1. Find the order by its number or the customer's email.
2. Check the refund window: 30 days from delivery. After that, offer a voucher.
3. If the amount is over ₹5,000, ask for a manager's approval.
4. If the item is damaged, ask for a photo before you refund.

## Output

Reply with one line: **approve**, **voucher**, **needs approval** or **needs photo**, then the reason.

## More detail

The full policy, with edge cases, is in [the refund policy](references/refund-policy.md).
```

Open the **Agent view**. The skill is now picked for all five refund prompts, and for none of the five that are about something else. Open the **Checks** tab: nothing fires.

## What a Skill Is

### Always-On Versus On-Demand

In the last lesson, you met the **always-on test**: does a rule apply to almost every task? If yes, it goes in `AGENTS.md`. If not, it goes in a skill.

| | `AGENTS.md` | A skill |
|---|---|---|
| Loads | at the start of every session | only when a task matches its description |
| Holds | short facts for every task | steps for one kind of task |
| Cost | paid in every session | paid only when it is used |
| Example | "Run `npm run check` before you finish" | "How to check a refund request" |

A skill lets you write detailed steps for a task without making every other session pay for them.

### The Skill Folder

A skill is a **folder**. The folder's name is the skill's name. Inside, there must be a `SKILL.md` file. Other folders are optional.

```text title="A skill folder"
refund-check/
├── SKILL.md            required: frontmatter + instructions
├── references/         optional: longer docs, read only when needed
│   └── refund-policy.md
├── scripts/            optional: code the agent can run
└── assets/             optional: templates and data files
```

Where the folder lives depends on the tool:

| Tool | Skills folder |
|---|---|
| Claude Code | `.claude/skills/<name>/SKILL.md` |
| Codex | `.agents/skills/<name>/SKILL.md` |
| Cursor | `.cursor/skills/<name>/SKILL.md` (also reads `.agents/skills/`) |

The box below shows the path for the tool you picked at the start of the course:

The `SKILL.md` format is the same in every tool. It follows the open **Agent Skills** specification.

This lesson covers the **file**: its layout, its fields and its description. How to design a good skill — what to put in the steps, how to test it, how to make it safe — is the subject of the Agent Skills course.

## The Name Field

The `name` has strict rules, from the Agent Skills specification:

- 1 to 64 characters.
- Only lowercase letters `a-z`, numbers `0-9` and hyphens `-`.
- It must not start or end with a hyphen, or have two hyphens in a row.
- It must be the **same as the folder name**.

```md runnable file="refund-check/SKILL.md" expect-lint="SKL002,SKL003" title="A name that breaks the rules" dialect="docs"
---
name: Refund_Check
description: "Checks a refund request against the refund policy. Use when a refund is requested or late."
---

# Refund check
```

Open the Checks tab. **SKL002** fires because of the capital letters and the underscore. **SKL003** fires because `Refund_Check` is not the folder name, `refund-check`. Change the name to `refund-check` and both go away.

## The Description

### What It Does, and When to Use It

The **description** is the most important line in a skill. It is the only part the tool reads when it chooses which skill to use. The spec says it should describe **what the skill does and when to use it**, with **keywords** that help an agent spot the task. It can be up to 1,024 characters.

A good description has three parts:

1. **What it does:** "Checks a refund request against the refund policy: the 30-day window, the approval limit and damaged items."
2. **When to use it:** "Use when a refund is requested or late, or when someone wants money back for a damaged parcel."
3. **When not to use it:** "Do not use for shipping, delivery dates or tracking."

Each part uses the words a person would type: refund, late, money back, damaged, parcel.

The description above contains `: `, a colon and a space. As you learned in the frontmatter lesson, that breaks YAML unless the value is in quotes. A skill whose frontmatter does not parse is skipped without a word. Quote long descriptions.

### How the Agent View Decides

The tool's real choice is made by an AI model reading every skill's description. The **Agent view** in this course uses a simple, open **simulation** instead, so you can see the idea at work:

- Words in the prompt that also appear in the "use" part of the description count **for** the skill.
- Words that appear only in the "Do not use" part count **against** it.
- The skill is picked when enough words match.

A real model is smarter. It knows "money back" means a refund even if you never wrote "refund". But the lesson is the same: a description full of the right words gets picked, and a vague one does not.

### Why "Do Not Use" Helps

A description that is too broad gets picked for tasks it should not handle. A "Do not use" sentence draws the line.

```md runnable file="refund-check/SKILL.md" probes="A customer asks when their order will be shipping|A customer wants a refund for order A-1042" title="Too broad, then fenced in" dialect="docs"
---
name: refund-check
description: Checks refund requests and order questions. Use when a customer asks about an order or a refund.
---

# Refund check
```

Open the Agent view. The skill is picked for the shipping question, because "customer", "asks" and "order" all match. Now add this sentence to the end of the description: `Do not use for shipping or tracking.` Look again. The shipping question is no longer picked. The refund question still is.

## Skills Load in Stages

Skills are built to be cheap until they are needed. The spec calls this **progressive disclosure**: the tool reads more of a skill only as the task needs more.

| Stage | What loads | When | Size guide |
|---|---|---|---|
| 1. Metadata | `name` and `description` | at the start, for every skill | about 100 tokens |
| 2. Instructions | the body of `SKILL.md` | when the skill is picked | under 5,000 tokens |
| 3. Resources | files in `references/`, `scripts/`, `assets/` | only when the steps point to them | as needed |

So keep `SKILL.md` itself under 500 lines. Put long policies, tables and examples in `references/` files, and link to them from the steps, as the cheat sheet does with `references/refund-policy.md`. Keep those links one level deep from `SKILL.md`.

A skill with no "when" in its description usually fails stage 1. A skill with a 2,000-line body usually fails stage 2: it costs too much once picked. Fix the description first; then move bulk into references.

## Subagent Files

Subagents are mostly set up by developers. If you do not write code, you can skim this section: knowing that a subagent is a helper with its own instructions file is enough.

### One Agent per File

A **subagent** is a separate helper agent with its own instructions and its own tools. The main agent can hand a task to it, such as "review this change", and get back a result. It works in its own context, so its long work does not fill up the main conversation.

In Claude Code, a subagent is a Markdown file in `.claude/agents/`. The frontmatter is its settings. The body is its **system prompt**: the instructions it follows.

```md runnable clean file=".claude/agents/code-reviewer.md" title="A reviewer subagent" dialect="docs"
---
name: code-reviewer
description: Reviews a change for bugs, missing tests and broken project rules. Use after code is written and before it is committed.
tools: Read, Grep, Glob
model: sonnet
---

You review code changes in the order-support repo. You do not edit files.

## Scope

Only the files changed in this task.

## Checks

1. Money is handled as integer paise, never floating point.
2. Every new API route has a test in `test/api/`.
3. Nothing updates or deletes rows in `refund_log`.

## Output format

A list of findings. Each one: the file and line, the problem, and a suggested fix. If there are none, reply "No findings."
```

| Field | Required | What it does |
|---|---|---|
| `name` | yes | the subagent's id: lowercase letters and hyphens, no `:` |
| `description` | yes | when the main agent should hand work to it |
| `tools` | no | which tools it may use; if left out, it gets all of them |
| `model` | no | which model it runs on; if left out, it uses the main one |

The body says three things clearly: what it looks at (**scope**), what it checks (**checks**) and what it returns (**output format**). A reviewer with no output format returns something different every time.

### When a Subagent File Is Skipped

Claude Code skips a subagent file, **without any warning in the session**, if it has no `name`, has a `name` but no `description`, does not start with `---` on line 1, or has frontmatter that does not parse.

```md runnable file=".claude/agents/code-reviewer.md" expect-lint="SUB001" title="A subagent that is silently skipped" dialect="docs"
---
name: code-reviewer
tools: Read, Grep
---

You review code changes. You do not edit files.
```

Open the Checks tab: **SUB001** fires, because there is no `description`. Add one, and it passes.

### Other Tools

Other tools define subagents differently. Codex uses a **TOML** file in `.codex/agents/` instead of a Markdown file. TOML is a simple settings format: `key = "value"` lines. Codex needs three keys: `name`, `description` and `developer_instructions` (the instructions, like the body of a Claude Code subagent). Here is the same reviewer for Codex:

```toml
name = "code-reviewer"
description = "Reviews a change for bugs, missing tests and broken project rules. Use after code is written and before it is committed."
developer_instructions = """
You review code changes. You do not edit files.
Only review the files changed in this task.
Reply with a list of findings: file and line, the problem, and a fix.
"""
```

The idea is the same in every tool: a name, a description of when to use it, and instructions. Only the file format changes. Your tool's path:

Tools change often. These paths were checked against each tool's docs in October 2026; check again before you rely on them.

## Where This Is Used

- **Team workflows:** a skill per repeated task, such as checking a refund, writing release notes or fixing a flaky test.
- **Shared libraries of skills:** folders copied between repos, because the format is the same everywhere.
- **Reviews:** a reviewer subagent that checks every change against the team's rules.
- **Long tasks:** subagents that search or test in their own context, so the main conversation stays short.

## Common mistakes

| Symptom | Cause | Fix |
|---|---|---|
| The skill is never used | The description is vague or has no "when" | Say what it does, when to use it, with real keywords |
| The skill is used for the wrong tasks | The description is too broad | Make it specific and add "Do not use for …" |
| The skill does not show up at all | The frontmatter does not parse, often because of `: ` | Put the description in quotes |
| The tool rejects the skill | The name has capitals or underscores, or does not match the folder | Use lowercase and hyphens; match the folder |
| The skill is slow and costly when used | The body is very long | Move detail into `references/` files |
| A subagent never runs | No `description`, or the frontmatter is broken | Add a description; check the YAML |
| A reviewer's answers have a different shape every time | No output format in the body | Add an `## Output format` section |

## Quick Check

## Exercises

## What to Remember

- A skill is a folder with a `SKILL.md` file: frontmatter, then instructions for one kind of task.
- `name` and `description` are required. The name is lowercase with hyphens and matches the folder.
- The description says what the skill does and when to use it, in the words people type, plus "Do not use for …".
- Quote a description that contains `: `, or the frontmatter breaks and the skill disappears.
- Skills load in stages: metadata first, the body when picked, references only when needed. Keep `SKILL.md` under 500 lines.
- A subagent file has a name, a description, optional tools and model, and a body that is its instructions.
- Give a subagent a scope, its checks and an output format.

## Further Reading

- [Agent Skills specification](https://agentskills.io/specification): the `SKILL.md` format and its field rules.
- [Claude Code: subagents](https://code.claude.com/docs/en/sub-agents): subagent files, fields and locations.
- The **Agent Skills** course on this site: how to design, test and secure a skill.

Next: **Specs and Plans**, where you turn a vague ticket into a spec with goals, non-goals and acceptance criteria that an agent can build from.
