SSD Nodes Learn 🎉 VPS from $5.50/mo
How to do am Matt ConnorBy Matt Connor · Updated 2026-08-13

How to Write Your Own Agent Skill for Real Failures

Learn how to write an agent skill from one repeated failure, including SKILL.md structure, the description line wey makes am fire, and how to test am.

Write your own agent skill from one real failure

The best way to write your own agent skill na to distill am from one real failure. Find one task wey your coding agent get wrong twice, write down the correction wey you type both times, and save that correction as a SKILL.md file wey the agent fit load by itself. After that, na mechanics remain: the file layout, and the one line wey decide whether the skill go ever fire.

That order matter. Skill wey you write from imagination dey document problem wey never happen to you, and e still dey use context for every session. Skill wey you distill from failure wey you watch come with test already: ask the same question again, then check whether the agent get am right this time. If this format new to you, read wetin agent skills be and how agent dey load dem first, then come back and write one.

Start na task wey agent get wrong two times

One time fit be chance. Two times don turn pattern, and pattern deserve make you record am for file.

See one failure wey dey repeat for real servers. You ask agent make e add reverse proxy block to nginx. E edit /etc/nginx/conf.d/app.conf, then run sudo systemctl restart nginx. The edit get typo, so nginx refuse start, and site remain down until you fix am:

nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12
Job for nginx.service failed because the control process exited with error code.

You correct am for chat. Test the config with sudo nginx -t before you touch the service, then apply am with reload instead of restart. One week later, for another task, the same mistake happen again. That second time na the signal.

Write down two things while the failure still dey in front of you: the request wey you type, and the correction wey you give, using the exact words wey you use. Those two lines become the skill. The request tell you wetin the trigger must match. The correction na the complete content.

Anthropic own authoring guidance put this first. Run the agent on representative tasks without skill, record where e fail, then write only the minimum instructions wey fix those failures. The failures na the specification, so if you no fit trace a skill back to one failure, usually na skill wey nobody need.

For worked example of the same distillation, Ponytail turn one repeated failure, where agent rewrite far pass wetin you ask, into a skill wey you fit read from start to finish before you write your own.

Skill get wetin inside

Skill na directory wey get one required file inside.

.claude/skills/nginx-config-changes/
├── SKILL.md
├── reference/
│   └── proxy-headers.md
└── scripts/
    └── check-and-reload.sh

SKILL.md dey start with frontmatter block, wey be some settings wey dem write for YAML (na the same configuration format wey Docker Compose files dey use) between --- markers. After that, markdown instructions dey follow. Na the complete skill for the failure wey happen before.

---
name: nginx-config-changes
description: Tests and reloads nginx safely after a config edit. Use when editing files under /etc/nginx, adding a server block or a reverse proxy, or changing a TLS certificate path.
---

## Rules

Run `sudo nginx -t` after every edit under `/etc/nginx`. Do not touch the service until it prints `test is successful`.

Apply the change with `sudo systemctl reload nginx`. Never use `restart`. A reload keeps the running workers serving traffic until the new config parses, so a broken config leaves the site up. A restart stops nginx first, so a broken config takes the site down.

If `nginx -t` fails, fix the file and test again. Never reload a config that failed the test.

For the proxy header defaults this project expects, see [reference/proxy-headers.md](reference/proxy-headers.md).

That file no reach twenty lines, and e complete as one skill. Na these parts dey inside:

  • name: e fit get up to 64 characters, and na lowercase letters, digits, and hyphens only. E no fit contain the words claude or anthropic. For personal or project skill, na only display label e be. The command wey you type come from directory name, so this one answer to /nginx-config-changes.
  • description: wetin the skill dey do and when to use am, up to 1,024 characters. Na this line dey do the main work, and the next section na only about this.
  • The body: na instructions wey agent load only when the skill actually fire.
  • reference/: extra files wey agent read when e need dem. Link dem from SKILL.md, and make the links no pass one level, because file wey another referenced file link to fit only read partly.
  • scripts/: files wey agent execute instead of reading. Na only their output dey use context, so 300-line script no cost much.

Where you put the directory decide who fit use the skill.

  • .claude/skills/<name>/SKILL.md for the repository: na this project only, and e go travel reach everybody wey clone the repo.
  • ~/.claude/skills/<name>/SKILL.md: every project for your machine, and nobody else own.
  • <plugin>/skills/<name>/SKILL.md: e dey shipped inside plugin, and e dey available anywhere wey dem enable that plugin.

Create one with mkdir -p .claude/skills/nginx-config-changes and write the file. Claude Code dey watch these directories, so when you edit existing skill, e go take effect inside the session wey dey run. If you create top-level skills directory wey no dey exist when the session start, you need restart, because nothing dey there to watch when the session begin.

Description field na the line wey get the biggest effect for the file

When agent start, e loads name and description of every skill wey dey available into e context. E no load the bodies. When your request enter, na that one line be the complete basis for deciding whether the skill relate to the request. So, even if body perfect, vague description mean say e never get read.

Write the description for third person. "Tests and reloads nginx safely" dey work. "I can help you with nginx" no dey work, because system prompt go inject the text there, and first person go sound like na model dey talk about itself.

Put two things inside am: wetin the skill dey do, and the condition wey make am apply. Put the important use case first, because Claude Code dey truncate the listing entry at 1,536 characters. Optional when_to_use field dey available for extra trigger phrases and example requests, and e dey append to the description under that same cap.

Then use the words wey you go actually type. description: Helps with nginx no match anything, because nobody dey type "helps with". The version above name /etc/nginx, server block, reverse proxy and TLS (transport layer security) certificate path, and that one roughly match the vocabulary of any request wey suppose trigger am.

This na the test for description. Give that single line to person wey never see the body, together with the request wey you wan type, then ask whether the skill apply. If dem no fit tell, the model no fit tell either.

Keep the body small, because e dey stay for context

When agent invoke one skill, e rendered content enter conversation as one message and remain there for the rest of the session. Claude Code no dey read the file again for later turns. Every line wey you write na cost wey you go pay for the whole session, no be for only one answer.

Anthropic recommend make you keep SKILL.md below 500 lines and move extra detail go separate files. Compaction show why this number no be arbitrary. When conversation summary happen to free context, Claude Code attach the most recent invocation of each skill again, keep only the first 5,000 tokens of each one, then fill combined 25,000 token budget starting from the skill wey dem invoke last. If skill long, dem fit cut am midway. If several skills long, dem fit push each other comot completely.

So write only wetin model no already know. E know wetin nginx be and wetin reverse proxy dey do. E no know your house rule about reload over restart, and na only that rule make this file exist.

If skill tell agent make e run bundled script, name the path with ${CLAUDE_SKILL_DIR} so e go resolve anywhere dem install the skill, and pre-approve the same command so permission prompt no go stop the run.

---
name: nginx-config-changes
description: Tests and reloads nginx safely after a config edit. Use when editing files under /etc/nginx, adding a server block or a reverse proxy, or changing a TLS certificate path.
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/check-and-reload.sh *)
---

The grant cover the turn wey invoke the skill and e clear when you send your next message, so e no go quietly turn permanent permission.

How to prove say the skill dey fire

To watch skill load show say agent find am. E no show say answer don change. Check both, and check am for fresh session, because session wey you use write the skill already hold everything wey you talk while you dey write am. That leftover context fit hide gaps for the file.

  1. Start new session with claude for the project.
  2. Type the request the way you go type am for normal workday, with your own words, without mention the skill.
  3. Watch whether invocation happen. If the skill no fire, fix the description. Body no be the problem yet.
  4. Invoke am by hand with /nginx-config-changes as control. If behaviour correct when you invoke am by hand but wrong when request invoke am, that confirm say na trigger problem, no be instruction problem.
  5. Run the same request with the skill switched off, then compare both answers. For the /skills menu, highlight the skill, press Space to cycle the state reach off, then Enter to save. That one write skillOverrides entry inside .claude/settings.local.json, and when you press Space again, e go cycle am back to on after you finish.
  6. Write couple requests wey no suppose trigger the skill, and check say e remain quiet for those ones.

To automate that loop, install skill-creator plugin from the official marketplace.

/plugin marketplace add anthropics/claude-plugins-official
/plugin install skill-creator@claude-plugins-official

If install output talk say Run /reload-plugins to activate., run that command. Then ask Claude to evaluate your skill by name. The plugin store test cases for evals/evals.json inside the skill directory and run each case for separate subagent, so every run start with clean context. E then write comparison between with-skill and without-skill. Na that be the honest number: pass rate improvement measured against the tokens and time wey the skill dey cost.

Failure mode: skill no dey trigger

You type the request, agent still do the old wrong thing, and no skill line show. Go through these points in order.

  • Description talk wetin the skill dey do but e no ever talk when to use am, so nothing for your request match am.
  • Description no use the words wey you type. If you talk "nginx", description must talk nginx.
  • disable-model-invocation: true dey set for frontmatter. This one remove description completely from model context, and skill fit only be called by you with /name.
  • paths glob for frontmatter limit activation to files wey match am, and the file wey you dey work on no match.
  • Skill dey inside nested .claude/skills/ directory under your starting directory. Dem only load after agent read or edit file inside that subdirectory, so before then skill no dey available at all.

Failure mode: skill dey trigger all di time

Di opposite problem na description wey too broad, so skill dey fire for work wey no relate. "Use when working on the server" fit match almost any request for server repository. Body go then load for tasks wey e no fit help with, and e go remain for context for di rest of di session.

Narrow di description reach di condition wey really matter, and name di files or commands wey e cover. Add paths glob when di skill apply only to particular files. For anything wey get side effects, like deploy or commit, set disable-model-invocation: true and call am yourself with /name, so agent no go decide by itself say now na good time to deploy.

Failure mode: put the skill inside your rules file

Rules file like CLAUDE.md or AGENTS.md dey load for the beginning of every session, and dem apply to every task. Skill body dey load only when the skill run. Na how often the instruction apply dey determine the choice. Any fact wey apply to every task for the repository, like the package manager wey you dey use, belong inside rules file. Any procedure wey apply to small part of tasks, like the nginx rule above, belong inside skill. E no cost anything for days wey nobody edit nginx.

The real failure na to put the instruction for both places. The two copies go dey differ over time. When the agent do wrong thing, you no fit know which copy e follow. Choose one place for every instruction. the boundary between skills, MCP servers and rules files dey explain the difficult cases too, including when the correct answer na MCP (model context protocol) server wey give the agent new tool instead of new instruction.

Share am only after e don prove say e useful

Skill wey survive one week of real work deserve make you commit am. Dem dey review project skills for .claude/skills/ like code, and dem dey come with the repository. So teammate wey clone am go get your correction without any setup step. Moving skill between repositories without copy and paste na another problem. how to share agent skills across repos cover am.

One portability note. Claude Code accept plenty frontmatter fields, but Agent Skills standard allow only six: name, description, license, compatibility, metadata and allowed-tools. If you upload skill to claude.ai, or package am for Skills API, with any other thing inside the frontmatter, e go fail completely instead of ignoring the field:

Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name

Stay inside these six fields, and the same file go load for Claude Code and for anything else wey dey read the standard. Writing the instructions themselves so dem fit work after you move am to another model na separate task. writing skills that work with any model cover am.

FAQ

SKILL.md file suppose long reach how much?

Make e no pass 500 lines, and expect say most useful skills go shorter well well. The body enter the conversation when skill invoke am and remain there for the rest of the session, so every line na recurring cost, no be one-time cost. Move long reference material go separate files inside the skill directory and link dem from SKILL.md, one level deep, so the agent go read dem only when e need dem. Bundled scripts dey execute instead of read, so na only their output dey cost.

Why my skill no dey trigger at all?

Description na the usual cause, because na only that part of the skill dey context when the model dey decide. Make sure e talk when to use the skill, no be only wetin e dey do, and make sure e contain the words wey you dey actually type for your requests. If the description look correct, check the frontmatter for disable-model-invocation: true, wey dey hide the skill completely from the model, and for a paths glob wey limit am to files wey you no dey touch. Skill wey dey inside nested .claude/skills/ directory below your starting directory na another cause: e go load only after agent read or edit file for that subdirectory.

This one suppose be skill or line for my rules file?

Ask how many of your tasks e dey apply to. Rules file dey load for every session, so e suppose contain facts wey true for every task, like the package manager or branch naming convention. Skill dey load only when e fire, so na the correct place for procedure wey matter for small part of your tasks. No ever write the same instruction for both places, because the two copies fit change differently and you go lose the ability to know which one agent follow.

How I fit know say skill really help?

Compare am with a baseline. Gather some real requests, run each one for fresh session with the skill available, then run dem again with the skill switched off from /skills menu, and read both answers side by side. Fresh session matter because the conversation where you write the skill still contain your explanations, wey fit make incomplete file look complete. skill-creator plugin dey run this comparison for you and report the pass rate beside the token cost.

I fit use the same SKILL.md with another agent?

Yes, as long as you stay inside the fields wey Agent Skills standard define: name, description, license, compatibility, metadata and allowed-tools. Claude Code accept plenty more fields, and e also support body features like shell command injection wey other tools no dey run. If you upload skill with field outside the standard, e go fail with explicit error wey list the allowed properties, so decide early whether the skill suppose remain for Claude Code or travel.