# Write a skill: the description is the trigger, the body is the instructions (/docs/agent/write-a-skill)

---
type: Procedure
title: "Write a skill: the description is the trigger, the body is the instructions"
description: "How to write a skill a coding agent will actually reach for, from The AI Agent Factory and OpenAI's skill guidance: progressive disclosure and what it costs, the description formula and the delete-the-keyword test, an imperative body with real examples and edge cases, what belongs in a script instead of a sentence, one skill or several, where skills live, how to test the trigger, and why a skill has no scope of its own."
status: stable
order: 18
generated: { by: "process:claude-code", at: 2026-09-09T07:30:00Z }
verified:
  - { by: "human:rrizwan98", at: 2026-09-09T07:47:26Z }
sources:
  - id: af-fte
    title: "Building a Digital FTE: A Crash Course. The AI Agent Factory, Panaversity, 2026"
    resource: https://agentfactory.panaversity.org/docs/digital-fte-crash-course
  - id: af-skills
    title: "Skills & Connectors: A Crash Course. The AI Agent Factory, Panaversity, 2026"
    resource: https://agentfactory.panaversity.org/docs/skills-connectors-crash-course
  - id: openai-build-skills
    title: "Build skills. OpenAI developer documentation, retrieved 2026-09-09"
    resource: https://developers.openai.com/codex/skills
ksor:
  audience: [public]
  owner: human:rrizwan98
  approval: { by: "human:rrizwan98", at: 2026-09-09T07:47:26Z }
trust_tier: human-reviewed
build_id: sha256:4d4bff09bd0a1dcff0a0a50f20f7ef514fc471e2b1f9e81e0e7b6150b93c0793
dirty: true
---

A chat message tells an AI what to do this once. A skill teaches it how to do
something every time. A connector gives it hands to reach real apps and data.
[^af-skills] This room ships one skill, the one that runs the room, and every
worker built here may need skills of its own. This page is the rule for
writing one that fires when it should, stays quiet when it should not, and
does the same thing for whoever runs it.

## What a skill is, and what it costs

A skill is a folder with a `SKILL.md` file, plus optional `scripts/`,
`references/` and `assets/`. `SKILL.md` is the entry point: frontmatter with a
name and a description, then the instructions. The smallest skill is one file
with those three things and nothing else. Because it is a file on disk it
versions, travels and gets reviewed like any text. [^af-fte]

A skill loads in three stages, each firing only when the last said it was
relevant: [^af-fte]

1. **Discovery.** At startup the agent loads the name and description of every
   skill, roughly 100 tokens each. Fifty skills cost about 5,000 tokens per
   turn: the price of knowing what is in the library.
2. **Activation.** When the model matches a task to a description, it loads
   that skill's full body. Keep it under about 5,000 tokens; most sit at 500
   to 2,000. Paid only on turns that use the skill.
3. **Execution.** Files the body references load only when the agent reaches
   for them.

Two things follow and drive everything below: the description is what fires
at discovery, so it decides everything; and long bodies cost you on every
matching turn, so keep `SKILL.md` tight and push depth into references.
[^af-fte] OpenAI's guidance adds the host's budget: hosts may shorten
descriptions when many skills are installed, so front-load the key use case
and trigger words. [^openai-build-skills]

## The description is the trigger

Only two frontmatter fields are required: `name`, lowercase with hyphens and
matching the folder, and `description`, the trigger surface the agent reads at
discovery. [^af-fte] The description decides whether the skill ever fires; the
model does not read the instructions to decide relevance. The formula: **what
it does, when to use it, and the exact phrases a person would actually say.**
[^af-skills]

The scaffold gets it wrong by writing a circular one: "summarises a ticket
into five sections; use when the user wants to summarise a ticket." That fires
on "summarise this ticket" and misses how people actually talk: "write a
handoff note for #4471", "TL;DR this thread", "give my lead the rundown before
I escalate". A description that fires reliably names four things: [^af-fte]

- What it produces, the actual output.
- When to reach for it, the real situations: a handoff, an escalation, a
  briefing.
- Keywords people actually type, including the ones that never say the obvious
  word.
- A do-not line for the look-alikes that must stay quiet.

**The self-check that kills circular descriptions:** delete the obvious keyword
from your description. Does it still say when to fire? If not, it is too
narrow. [^af-fte] Once installed, the debugging trick is to ask the agent
"when would you use my X skill, and when would you not?" It paraphrases the
description back; if the answer is narrower or wider than you meant, you have
found exactly what to fix. Add a negative trigger when a skill fires too
eagerly: "do not use for one-off calculations or quick questions."
[^af-skills] OpenAI's guidance says the same in one line: explain exactly when
the skill should and should not trigger, and test prompts against the
description to verify. [^openai-build-skills]

| Weak description | Why it fails | Better |
| --- | --- | --- |
| "Helps with reports." | Fires for everything or nothing | "Prepares a monthly client financial summary. Use when the user asks for a client summary, monthly close, or month-end report." |
| "Handles patient documentation." | No trigger words a person would say | "Converts consultation notes into SOAP-format clinical notes. Use when asked for a SOAP note, a clinical note, or to write up a consultation." |

Two more rules that prevent upload errors: no XML-style tags in the name or
description, and do not put "claude" or "anthropic" in a skill's name; those
are reserved. [^af-skills]

## The body is the instructions

No format is required, but good bodies are imperative ("Read the full thread.
List what was tried."), carry one or two real examples, worth roughly five
times a description for steering, and name two or three edge cases that have
actually broken. [^af-fte] For every instruction line, ask one question:
would two colleagues who read it do the same thing? "Flag the big payments"
fails; "flag any single payment above the withholding threshold with a
WITHHOLDING note" passes. A line that fails shows no error; the output just
comes out different every run. [^af-skills]

Write instructions as steps with explicit inputs and outputs, and prefer
instructions over scripts unless you need deterministic behaviour or external
tooling. [^openai-build-skills] The book's timing rule says where the line is:
an exact step, a sum, a threshold check, belongs in a small script rather than
a sentence, because code is exact and a sentence gets read a little
differently each time. If the skill keeps guessing at data, that data should
arrive through a connector, not from memory. [^af-skills] This is the same
rule the room applies to workers: anything that must hold regardless of the
model lives in code, never only in prose.

Write instructions under the [prompting guide](../prompting/overview.md):
only what the model cannot work out on its own, neutrally framed, pruned by
the delete test. A skill body that restates what a capable model already knows
is resident cost with no steering.

Keep each skill focused on one job. [^openai-build-skills] The book's decision
between one big skill and several small ones: one skill is easy to discover
and one activation, but every step runs in one context, nothing is reusable
alone, and a mid-way failure leaves the model recovering with stale work.
Several small skills can each be tested, replaced and reused, a failure is
localised, and each step activates fresh. Write one skill when the steps are
tightly coupled and never reused alone; write several when a step might be
called on its own or when clean context matters. Separation usually wins past
two or three steps. Chain them through the filesystem, not the conversation:
skill A writes a file, skill B reads it, and the steps in between stay on disk
for the agent, the person and the audit trail. [^af-fte]

## Where it lives, and how it travels

The folder has one required file and three optional folders, each with one
job: `scripts/` for code the agent runs, `references/` for deep documents
loaded on demand, one topic per file, and `assets/` for templates, schemas and
lookup tables. Inside `SKILL.md`, point at them by relative path; they resolve
from the skill's own folder, not from wherever the agent is running.
[^af-fte]

Skills are an open standard, so a basic `SKILL.md` travels across compatible
tools; each product adds its own install path, invocation and permissions on
top, so the core is portable while the edges differ. [^af-skills] The book's
one rule for location: put skills in `.claude/skills/`, which Claude Code
reads, OpenCode falls back to, and an SDK worker can point at directly. When
a project-level skill and a user-level skill share a name, the project-level
one wins, the same way a project rules file overrides a global one. [^af-fte]
The exact folders each tool reads are on [the skill page](build-your-agent-skill.md),
which also carries this record's own install instructions.

## Test the trigger, then iterate

A skill is never done on the first draft. The loop: describe it and let the
agent generate the first version; read it and fix anything obviously wrong;
test triggering with the phrases that should activate it and with unrelated
requests that should not; test the output on a realistic input; test the hard
cases (an empty month, a value exactly on the threshold, a messy input); bring
the failures back and tighten. [^af-skills]

The book's stronger form is a trigger eval: give the skill-building tool your
fire and do-not-fire cases, let it turn them into trigger evals, run them, and
tighten the description until it fires on the handoff, the TL;DR and the
status phrasings and stays quiet on the near-misses. You read the pass and
fail table, not the raw description. [^af-fte] That table is the rigorous
version of the delete-the-keyword instinct, and it is the same discipline as
[evals before shipping](evals-before-shipping.md) applied to one field.

When a skill misbehaves, note when it went wrong before you change anything:
[^af-skills]

| When | Where the problem is | What to do |
| --- | --- | --- |
| Wrong from the first reply | The file itself: it never triggers (description too vague), triggers on the wrong things (too broad), or fires with output off (an instruction missing or loose) | Add the words people actually use, narrow or add a do-not line, write down the rule you assumed it knew |
| Right at first, worse as the chat grows | The chat, not the skill | Start a fresh chat and restate the task in two lines |
| The same mistake every run, even after tightening the wording | The step is in the wrong place | Move the exact step into a script; bring guessed data in through a connector |
| Used to work and now does not | Something around the skill changed: a threshold, a template, a file it reads, how the team does the task | Re-read the skill against how you work today; nothing warns you when a skill goes stale |

Those four rows are the four causes on
[diagnose misbehaviour](diagnose-misbehaviour.md), seen from inside one file.

Two notes for skills that a less disciplined model will run: put any required
order between skills into a short preamble in the system prompt and keep
skill bodies declarative; be explicit about what not to do, not only what to
do; and remember that trigger blindness gets worse, not better, on a weaker
model. Budget the strong model's effort into the skill and the weak model's
effort into the system prompt. [^af-fte]

## A skill has no scope of its own

A connector has scopes you grant and can narrow. A skill does not: it runs
with whatever access the session it runs in already has, so its reach is
everything that session can reach, not only what its stated task needs. That
is why reading a skill before enabling it is the control for skills, and
starting read-only is the control for connectors. [^af-skills] The full
procedure for deciding whether to enable one, five checks and three outcomes,
is on [govern it](govern-it.md). A skill from a stranger is a text file you
are about to let an AI follow: treat it like a contract you are about to sign.
[^af-skills]

Not every task deserves a skill. A task you do once is a good prompt; a skill
earns its place when it encodes your specific repeated way, the thing no app
does for you. [^af-skills]

The skill this room publishes was rewritten under this page: a description
that names the situations and the phrases, a body of judgement steps and
quality bars rather than a phase-by-phase file list, exact steps in a script,
and the record, not the skill, as the place the knowledge lives. Continue to
[the skill](build-your-agent-skill.md) to download it.

[^af-fte]: Building a Digital FTE: A Crash Course. The AI Agent Factory, Panaversity, 2026.
[^af-skills]: Skills & Connectors: A Crash Course. The AI Agent Factory, Panaversity, 2026.
[^openai-build-skills]: Build skills. OpenAI developer documentation, retrieved 2026-09-09.
