# Skill Authoring

> Write an agent skill - a SKILL.md with YAML frontmatter - so that it is actually loaded at the right moment. Use this when authoring or editing a SKILL.md, when a skill you wrote is never picked up, when rewriting a skill's description or name so it routes, when deciding what belongs in written instructions versus a deterministic tool, and when a SKILL.md has grown long enough to split into a body plus references. Covers YAML frontmatter, progressive disclosure, why the description is the routing mechanism, and how to test that a skill triggers. This is about writing skills - it is NOT for a Langflow Agent component that will not call a connected tool.

- Skill: `x1linwang/skill-authoring` (Agent Skill)
- Install (CLI): `npx skillmds@latest add x1linwang/skill-authoring`
- Raw SKILL.md: https://api.skillmd.com/api/skills/x1linwang/skill-authoring/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: x1linwang (https://skillmd.com/u/x1linwang)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/x1linwang/skill-authoring

---


# Writing a skill that gets used

A skill is a folder with a `SKILL.md` in it:

```
my-skill/
  SKILL.md            <- required: YAML frontmatter + markdown body
  references/          optional: longer material, loaded only when needed
  scripts/             optional: code the skill tells the agent to run
```

```markdown
---
name: weekly-equity-review
description: >
  Produce a weekly equity review memo for one ticker ...
---

# Weekly equity review

...instructions...
```

## 1. The description is the routing mechanism

This is the whole game, and it is the thing people get wrong.

**Before a skill opens, the agent sees only its `name` and `description`.** Not
the body. Not the references. So the description is not a summary for a human —
it is the only evidence the agent has when deciding whether this skill is
relevant to what the user just asked. A perfect skill with a vague description is
a skill that never runs.

Write the description around **triggers**, not around topic:

```yaml
# too vague - never fires
description: Helps with financial analysis.

# topic, not trigger - fires unpredictably
description: Information about equity research memos and valuation.

# triggers - fires when it should
description: >
  Produce a weekly equity review memo for one ticker: price action, a valuation
  section, and a risk note. Use this whenever asked for a weekly review, an
  equity memo, a "what happened to X this week" summary, or to update an existing
  memo with new prices. Also use it to check whether a draft memo has the
  required sections.
```

Concretely, a good description:

- names the **artifact or action** ("produce a weekly equity review memo"),
- lists the **phrasings a user would actually type**, including partial ones,
- says what it also covers, so near-miss requests still route correctly, and
- says what it is *not* for, when a sibling skill would be a plausible wrong pick.

Test the description by covering up the body and asking: given only this, would
I know to open it? If you have two skills whose descriptions could both plausibly
match one request, one of them needs an explicit boundary sentence.

## 2. Progressive disclosure

Skills are structured this way because context is finite and paid per turn.

| Layer | When it enters context | Keep it |
|---|---|---|
| `name` + `description` | always, for every skill installed | a few lines |
| `SKILL.md` body | when the skill is opened | short enough to read in full |
| `references/*.md` | only when the body sends the agent there | as long as needed |
| `scripts/*` | only when run | any size |

So: put the decision-making and the sharp edges in the body, and push
exhaustive tables, long examples and reference data into `references/`. A
1,500-line `SKILL.md` defeats the mechanism — the agent pays for all of it the
moment the skill opens, even if only one section was relevant.

Link forward explicitly from the body, so the agent knows the material exists:
*"the full option-symbol format is in `references/symbols.md`"*.

## 3. Skill, tool, or neither

A common mistake is writing a skill for something that should be code.

- **A skill is instructions.** Use it for judgement, sequencing, conventions,
  and knowing which of several approaches applies. It changes *how* the agent
  works.
- **A tool is a capability.** Use it when the task needs a deterministic
  computation, a network call, or a guaranteed-correct number. It changes *what*
  the agent can do.
- **Neither** is right when the instruction applies to every request in a
  project. That belongs in a project-level instructions file, not a skill, because
  a skill that must always be open is just permanently-loaded context with extra
  steps.

The distinction matters most where they look interchangeable. "Compute
annualised volatility from daily returns" written as skill instructions gets you
a model doing arithmetic, with the error rate that implies. The same thing as a
tool gets you the right number every time. Conversely, "decide whether this memo
needs a liquidity caveat" cannot be a tool, because the criterion is judgement.

**Instructions are not capabilities.** If a skill tells the agent to do something
it has no way to actually do, the agent will produce something that looks like
the output and is invented. When you write a step, check that the agent has the
means to carry it out.

## 4. The body

Write for an agent that has just opened the file mid-task and will act on it
immediately.

- **Lead with the decision.** If there are three cases, open with how to tell
  them apart, then handle each.
- **Give exact commands and exact paths.** `python3 tests/verify_components.py
  custom_components/mytools` is actionable; "run the component tests" is not.
- **State failure modes, not just the happy path.** The highest-value sentences
  in a skill are of the form "if you see X, the cause is Y" — especially where
  the failure is silent, since the agent has no other way to know.
- **Say why, once, where the why changes behaviour.** A rule with no reason gets
  dropped the first time it is inconvenient.
- **Do not pad.** No "Introduction", no restating the description, no summary at
  the end.

## 5. Naming

`name` should be lowercase, hyphenated, and match the folder name. Prefer a
verb-or-artifact name over a topic name: `weekly-equity-review` beats
`equity-stuff`, `langflow-component-build` beats `langflow-notes`. The name is
also part of the routing signal, so it should read as the thing it does.

## 6. Testing that it actually triggers

A skill you have never seen fire is not finished. Test it deliberately:

1. Start a **fresh session** — descriptions are read at session start, so an
   edited description does not take effect in the session where you edited it.
2. Ask the question in the words a real user would use, not in the words of your
   description. Reusing your own phrasing tests nothing.
3. Try three or four different phrasings, including an oblique one.
4. Try a **near miss** that should *not* open the skill, and confirm it does not.
   A description broad enough to fire on everything is as broken as one that
   never fires; it just fails more expensively.

If it does not fire, the description is the thing to change — not the body.

## 7. Checklist before you call it done

- Frontmatter parses; `name` matches the folder; `description` is present.
- The description names triggers and phrasings, not just a topic.
- The body would let someone who has never seen the task do it correctly.
- Every step is something the agent can actually carry out.
- Long reference material is in `references/`, not inlined.
- You have watched it fire on a phrasing you did not write, in a fresh session.

