Back to Writing
· 8 min read ai-agents skills markdown workflow

How I Make Agent Skills

How I Make Agent Skills

Last time I wrote about what a skill is: reusable guidance for a repeatable task, like a recipe. That post covered the idea. This one is about the part I actually get asked about.

How do you make one?

Short answer: I don’t really write them. I do the task once with an agent watching, and I have it take notes. The notes become the skill.

That’s most of it. The details are where it gets interesting.


Knowing When to Make One

Two things tip me off.

The first is repetition. It’s the fourth time I’ve explained “go to this website, check this inbox, give me a list,” and I can hear myself saying it again. If I’m explaining the same thing a fourth time, I’m burning time and tokens on something I already know.

The second one took me longer to notice: the task that isn’t common, but costs me something every time.

I report to stakeholders once a week. Once a week isn’t often. But every time, I have to go to a handful of different reports, collect the information, figure out what my team actually did, and run a calculation on it. It’s not hard. It’s just slow, and I rebuild the whole thing from memory every Monday.

That’s a good candidate. Not because it happens a lot, but because it hurts every time it happens.

So: things I repeat, and things that hurt.


I Don’t Write the Skill. I Do the Task Out Loud.

This is the part I’d skip if I were reading someone else’s post, so I’ll say it plainly. Starting with a blank file is the slow way. I’ve tried it. I sit there trying to remember all the steps and I get about half of them.

What works better for me is opening a session — usually Claude Code, that’s my preferred tool — and just doing the task. Out loud. With the agent taking notes as we go.

It sounds like this:

  • “Okay, go to this website.” → good, take notes on how to get there
  • “Now log in.” → right, you need login information. Let’s put that somewhere safe. Jot that down.
  • “Now pull these three numbers.” → note which reports they came from

By the time the task is done, the notes are done. Then I read back through and make sure we ended up with a decent piece of documentation. That’s the skill.

Here’s why I think this beats writing from scratch: you narrate the why without meaning to. You mention the gotcha in the moment, because the gotcha is sitting right in front of you. When I write a skill afterward from memory, that’s exactly the stuff I leave out. And it’s the stuff that mattered.

There are two ways I get here, and both work:

  • Intentional. I sit down knowing I’m building a skill. “Hey, let’s build out this skill.”
  • After the fact. I’ve done the thing a few times and I’m finally sick of it. “Hey, document what we’ve done so we can do it again next time.”

Same result either way. I don’t think it matters much which one you’re in.


The Steps Are the Cheap Part

Something surprised me when I went back and looked at my own skills.

I have one called git-deploy-report. It answers “what did we ship last week?” It’s got bash commands in it, a report format, the whole thing. And the bash is close to the least valuable content in the file.

The most valuable part is the section explaining why the skill exists at all:

Our CI/CD pipeline squash-merges feature branches into MR- commits authored as the merge-bot account. The real author is only visible on the original feature-branch commits. This skill digs past the squash to attribute work correctly.

That’s the payload. Without it, you run git log, you get a wall of commits that all look like a robot wrote them, and your report is wrong. Not broken. Wrong. Which is worse, because you’ll send it to stakeholders and never notice.

Anybody can look up the git commands. Nobody outside my team knows about our merge bot.

So the stuff I try to capture:

  • Why this exists. The context I learned the painful way.
  • Gotchas. Mine literally says “Christian commits under two email addresses, count both,” because I do, and it broke the report once.
  • Defaults, and permission to override them. Last 7 days, origin, master, me as the focus author, plus a note that the user can change any of it.
  • A real example of the output. Not a toy one. An actual report with actual names in it.

The instructions are the easy part. The context is the part only I have.


When It Needs a Script

Most of my skills are one markdown file. That’s it.

A skill earns a script when it needs a tool. Maybe there’s an API call that has to look a specific way, or something a few shell commands can’t reasonably do. Then I’ll drop a Python script next to the markdown and let the skill point at it.

One of mine queries a Notion board, so it has a query_board.py. The deploy report only needs git, so it’s bash in a markdown file. That’s the whole decision, honestly.

I try not to reach for code until the markdown can’t do the job.


It Will Do Something Dumb. Ask It Why.

You run the fresh skill and it does something dumb. Every time. That’s normal, and I’ve stopped being surprised by it.

Here’s the move I almost missed: I don’t go read the file. I ask the agent why.

“Why did we do that?” “Why did you make that decision?”

The answer shows me exactly where my instructions were unclear. The agent isn’t being stupid. It’s doing something reasonable with a sentence I thought was obvious and wasn’t. It’ll point right at the hole. That’s a lot faster than squinting at my own markdown trying to imagine how it could be misread.

Then I fix it in the session. “Okay, let’s update the skill.” Editing by hand works, but it’s slow, and I’m already sitting there with the agent that just told me what’s wrong.

I don’t start over. I’m iterating, not rewriting. It’s a playbook, same as any set of instructions you’d hand a person at work. You don’t throw out the playbook because one line was confusing.

Then I run it again. That’s how I know it’s fixed. Not by re-reading it. By using it.


Installing It, or Not

You can install a skill into a global namespace and the agent picks it up on its own. Or you can keep a folder of markdown files and point at one when you need it: “here’s this markdown file, do this.”

I mostly install them. But that’s convenience, not a rule. A markdown file you hand over works fine.

This part isn’t worth agonizing over.


How Does It Know When to Use It?

Two halves to this.

The first is the description — the one-line summary at the top of the skill. That’s what the agent reads to decide whether this thing is relevant. Mine tend to list the actual phrases I’d say out loud: what got deployed, what they shipped, weekly merge count, deploy history. I write it the way I’d ask for it, not the way I’d name it.

The second half is me. Knowing what I’ve got matters too. The description helps the agent choose, but having some awareness of my own inventory does real work. A skill I forgot I made isn’t helping anybody.

I’m still working on that part.


Is a Skill Ever Done?

Define done.

If it’s working and I’ve stopped iterating on it, sure. It’s done. If it stops working, I change it.

My deploy report is done until somebody reconfigures the pipeline, and then it isn’t. Same as any documentation. Same as any playbook. Nothing about this is special because it’s AI.


Conclusion

That’s the process. Or at least it’s my process right now.

I notice I’m repeating myself, or that some rare task hurts every time. I do the task with an agent and have it take notes. I keep the why and the gotchas, because the steps are the cheap part. I add a script only if it needs a tool. Then I run it, and when it does something dumb, I ask why.

I’m not writing software here. I’m writing down what I already know, once, so I don’t have to say it a fourth time.

The inventory problem I mentioned — knowing what I’ve built and actually remembering to reach for it — I haven’t solved that one. I made a skill for rewriting things in my own voice and then wrote a whole draft by hand before I remembered it existed. So, still learning.