# Teaching Your Agent New Skills by [kirupa](https://www.kirupa.com/me/index.htm) | filed under [AI Fundamentals](https://www.kirupa.com/ai_fundamentals/index.htm) A couple of weeks ago, I asked an agent to draw a full set of pixel-art icons for this site, nearly two thousand of them. Each one had to fit on a 16×16 grid, which is just 256 pixels, and look at home next to the sprites from old Nintendo games. My verdict on the first results was ***"The designs look comically bad."*** About a week and a lot of critiques later, the agent was drawing icons I was happy to ship. Nothing about the model had changed. What changed is what it knew, because I taught it, and then I had it write all of that down in a folder any agent can read when it needs to draw. That folder is called a **skill**, and mine is called [pixelperfect](https://github.com/kirupa/pixelperfect). In the following sections, we'll look at how I taught the agent, what a skill actually is, and how to share one across agents. Onwards! ## What the Agent Couldn't Do Out of the box, an agent doesn't know that a 16×16 icon needs one crisp black outline, that a coffee cup reads better from the side than from above, or that every pixel has to earn its spot. So it took the obvious shortcut. It took each icon's artwork from Twemoji (the open-source emoji designs Twitter released), shrank it onto the grid, and let a resizing algorithm pick the pixels. This site's version history still has those drawings. Here are four of them from October 30, 2026, next to the same subjects drawn the way the skill teaches today: ![Four 16 by 16 icons, a hot beverage, paw prints, a microphone, and a smiley, drawn twice. The before row, from October 30, 2026, was made by shrinking Twemoji artwork onto the grid: no outlines, a muddy cup seen from above, paw prints that read as smudges, and a wobbly microphone. The after row, drawn the way the skill teaches, has one black outline, a side-view cup, clear paw pads, a straight microphone handle, and a clean smiley.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_before_after.png) The top row is what averaging gets us. There are no outlines, so the icons melt into whatever is behind them. The cup is seen from above, and at 16 pixels its rim turns into a brown smear. The paw prints are blobs, and the microphone's handle wobbles like a bendy straw. My critiques from those days weren't gentle. I told the agent I couldn't even tell the paw prints were paw prints, and that the coffee cup looked really bad. The bottom row has one black outline, a cup turned to its side, toe pads we can count, and a ruler-straight handle. How does a language model, which only writes text, draw anything at all? It doesn't paint. It types. In pixelperfect, each drawing is a small text file called a `.sprite` file, and its grid is 16 rows of 16 characters, where each character stands for one pixel: ![On the left, the 16 rows of 16 characters from the grid of the approved tangerine's .sprite file. On the right, the same tangerine rendered, with every character turned into one pixel: the hash marks become the black outline, dots stay clear, and each letter is a color from the file's palette.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_sprite_text.png) The file also starts with a few lines of planning, written before any pixels go down. Here's the top of the approved tangerine's file: ```text name: tangerine size: 16 essence: a round orange fruit with a leafy twig keep: a full round body lit from the upper left, the twig, one leaf drop: peel dimples, the navel, a second leaf view: front, the twig and leaf above the body ``` ## Teaching One Critique at a Time I didn't sit down and write a style guide. Honestly, I couldn't have, because I didn't know which rules mattered until I saw them broken. Instead, I treated the agent like a junior artist who just joined the team. It drew something. I looked at the drawing at its real size and said exactly what was wrong. Then (and this is the important part) the agent wrote my critique down as a rule, with tiny pictures of the right and wrong way to do it, and drew again. Here is that loop: ![Four steps in a loop. 1, the agent tries, drawing the icon as a .sprite file. 2, I critique it at real size, the way I'd coach a junior artist. 3, the critique becomes a rule in the skill, with right-and-wrong grids and an approved example. 4, a check in sprite_tool.py lints every new drawing for that mistake. Then the agent tries again.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_loop.png) The tangerine's planning lines came from one lap of this loop. I told the agent to ask itself what the essence of each icon was, the one thing it had to show, and that became a rule: before the first pixel, write the essence in one line, then list what to keep and what to drop. The microphone took another lap. My critique was short: ***"the microphone doesn't look good. It looks curved."*** As a rule, it covers every icon with a straight edge, and the skill's construction guide shows it with small right-and-wrong grids: ![My critique, the microphone doesn't look good, it looks curved, becomes a rule in the skill: straight edges are straight runs, and the steps of a diagonal touch only at their corners. Below it, two square pixel grids. Wrong: L-joins, where each step of the diagonal is filled in, so the line looks thick and jagged. Right: a 1 to 1 diagonal whose steps touch only at their corners.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_critique_to_rule.png) A diagonal line on a pixel grid is a staircase. When the steps are even and touch only at their corners, our eyes see a straight line. When each step gets filled in (an ***L-join***), or the steps are uneven, the line looks thick and bent, which is what my microphone was doing. The rule also says that long, thin things like microphones and pencils should lie along the 45° diagonal, because that's the longest straight line a square grid can draw. Here's the microphone before and after: ![Three microphones. Before, a 16 by 16 microphone shrunk from Twemoji, with a wobbly handle, a blue squiggle, and no outline. After, a 16 by 16 microphone with a straight, tapered handle on the 45 degree diagonal under a dotted ball. And a 24 by 24 microphone drawn natively on its own grid, not resized from the 16.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_microphone.png) The 24×24 version isn't the 16×16 blown up. The skill says each size is drawn on its own grid, because each one has to read clearly at its own real size. I also learned that one critique is really a bug report for a whole group of icons. At one point I had to remind the agent that my lessons weren't just for the smileys, and after that the rule became that a mistake flagged on one icon gets fixed on every icon that has it. After about a week, the skill's `lessons.md` file held my critiques word for word, typos included, grouped into 22 principles, each with the rule it produced. ## Turning Rules Into Checks Some rules need an artist's eye, and some can be checked by a program. One of my critiques was that simple designs beat blotchy black lines that muddle the picture. The rule it became is that black inside an icon has to earn its place, for things like holes, deep creases, and face features. That's easy to measure, so the skill's script, `sprite_tool.py`, measures it. It runs a **lint** check (a small program that scans a file for known mistakes, kind of like a spell checker) on every drawing. Here's the start of what it says about a smiley whose mouth is one big black slab: ```text $ python3 scripts/sprite_tool.py check examples/lint-failures/blotch-16.sprite examples/lint-failures/blotch-16.sprite (16px): ERRORS inner 34% colours 6 span 15x15 mirror x+x'=16 (1 off) ERROR 34% of the drawing is black inside the silhouette: blotchy. Separate parts with tones and keep inner ink for holes, crevices, face features, overlaps of similar values and line-art symbols ``` Here's that smiley next to the approved one, which passes with 7% black inside: ![Two 16 by 16 smileys checked by sprite_tool.py. On the left, a smiley whose mouth is a solid black slab fails with errors: 34 percent of the drawing is black inside the outline. On the right, the approved smiley passes as ok, with 7 percent black inside.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_lint.png) Why use code when the agent can read the rules? Because reading a rule and following it every single time are different things. A model can talk itself into thinking a drawing is fine, while the script gives the same answer every time and costs almost nothing to run. [Anthropic's engineering post on skills](https://www.anthropic.com/research/equipping-agents-for-the-real-world-with-agent-skills) makes the same point: when a job has to come out the same way every time, a script beats asking the model nicely. The lint can't tell that a tangerine looks squished, though, so the skill also has a review loop and a grading rubric. My rule there was simple. If a drawing doesn't earn an A+, the agent draws it again. ## What's Inside a Skill So far, I've been saying "the skill" as if it were magic. It's really just a folder. The format is called **Agent Skills**. Anthropic introduced it in October 2025 and [published it as an open standard](https://agentskills.io/) on December 18, 2025, and [the specification](https://agentskills.io/specification) says a skill is a folder with, at minimum, a `SKILL.md` file. Here's what's in pixelperfect's folder: ![The pixelperfect folder. SKILL.md holds the name, the description, and the 14 steps. references holds five deeper guides, read when a step points to them. assets/reference holds about 250 approved drawings at both sizes. scripts holds sprite_tool.py, which lints drawings and makes review boards. templates holds starting points for faces, and examples holds a portrait and lint failures.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_folder.png) `SKILL.md` starts with a short header (a few `name: value` lines between dashes, called YAML frontmatter) with a name and a description. After the header come plain instructions in Markdown. Here's pixelperfect's header, with its long description trimmed: ```text --- name: pixelperfect description: How to hand-draw proper 16x16 and 24x24 pixel-art emoji for any subject (...) Use it to draw, redraw, fix, review, grade or critique pixel emoji, icons or sprites at 16px or 24px, and to turn a photo of someone into a pixel emoji of their face. (...) license: MIT (LICENSE.txt); bundled artwork is under assets/LICENSE.md --- ``` The name can use only lowercase letters, numbers, and hyphens, up to 64 characters. The description can run up to 1,024 characters, and it's the most important text in the skill, because it's how the agent decides whether to use the skill at all. That's why mine lists the words people type when they want pixel art, like ***draw***, ***redraw***, ***fix***, and ***review***. Below the header are the 14 steps the agent follows for every drawing, and the other folders hold the depth. Anthropic's post describes a skill with a comparison I really like: > Building a skill for an agent is like putting together an onboarding guide for a new hire. > > [Anthropic, Equipping agents for the real world with Agent Skills](https://www.anthropic.com/research/equipping-agents-for-the-real-world-with-agent-skills) That's exactly what this folder is, except I had to discover what went in it one mistake at a time. ## Loaded Only When Needed Here's a reasonable worry. pixelperfect's reference guides add up to about 85,000 tokens, which are the chunks of text a model reads (we met them in [Tokens and Your Bill](https://www.kirupa.com/ai_fundamentals/tokens_and_your_bill.htm)). If the agent carried all of that around, it would crowd the [context window](https://www.kirupa.com/ai_fundamentals/context_window_limits.htm) on every task, even ones that have nothing to do with pixel art. It doesn't, thanks to something the specification calls **progressive disclosure**. The agent loads a skill in levels, and each level arrives only when it's needed. Here's what that looks like for pixelperfect, with token counts from OpenAI's o200k tokenizer: ![Three snapshots of the agent's context window. 1, at startup, it holds the system prompt, every skill's name and description (pixelperfect's is 215 tokens), and the conversation. 2, after asking for pixel art, SKILL.md is added, about 11,000 tokens. 3, when a step needs more, one reference such as construction.md is added, about 7,700 tokens. The other references and the approved drawings stay on disk until a step needs them.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_disclosure.png) At startup, the agent reads only each skill's name and description, and [Anthropic's post](https://www.anthropic.com/research/equipping-agents-for-the-real-world-with-agent-skills) explains that those go right into the agent's system prompt (the standing instructions from [System Prompts vs. User Prompts](https://www.kirupa.com/ai_fundamentals/system_prompts_vs_user_prompts.htm)). For pixelperfect, that's 215 tokens. When I ask for a 16×16 doughnut, the description matches, and the agent reads `SKILL.md`, which is about 11,000 tokens. A reference like the construction guide comes in only when a step points to it. The faces guide alone is about 42,000 tokens, and it gets read only when there's a face to draw. Scripts are even cheaper, because the agent can run `sprite_tool.py` and read what it prints without loading the script's code at all. One honest confession: the specification recommends keeping `SKILL.md` under 500 lines and under 5,000 tokens. Mine squeaks in at 473 lines, but it runs to about 11,000 tokens. Pixel art has a lot of rules! ## Teaching Isn't Fine-Tuning It's tempting to call all of this training, but not a single one of the model's parameters changed. In [Prompting vs. Fine-Tuning](https://www.kirupa.com/ai_fundamentals/prompting_vs_fine_tuning.htm), we saw that prompting changes what the model reads, while fine-tuning changes the model itself. A skill sits firmly on the prompting side: ![Two rows. In the skill row, the pixelperfect folder is added to what the agent reads, and the model's dials stay untouched. In the fine-tuning row, a stack of examples goes into training, and two of the model's dials are turned and highlighted.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_vs_fine_tuning.png) The agent learns from a skill the same way it learns from anything else in its prompt. This is called **in-context learning**: when a model reads instructions and examples in the text it's given, it follows them, with no extra training. If we delete the folder, all of that know-how is gone. That sounds like a weakness, but it's what makes a skill easy to live with. When I spotted a new mistake, I edited a Markdown file, and the fix applied to the very next drawing. Fine-tuning would have meant training a new model every time I changed my mind, and I had a lot of opinions about eyes. ## Sharing a Skill Across Agents Because a skill is a folder in an open format, it isn't tied to one agent. I published pixelperfect as a GitHub repository, with the skill in its `skills/pixelperfect` folder. Installing it copies that one folder to wherever each agent looks for skills: ![The kirupa/pixelperfect repository on GitHub holds the skill in skills/pixelperfect. The installers, gh skill install and npx skills add, copy that one folder to where each agent looks for skills: ~/.copilot/skills for GitHub Copilot, ~/.claude/skills for Claude Code, ~/.agents/skills for Codex, ~/.cursor/skills for Cursor, and ~/.gemini/skills for Gemini CLI.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_sharing.png) The GitHub CLI added a `gh skill` command, in public preview, with [version 2.90.0 on April 16, 2026](https://github.blog/changelog/2026-04-16-manage-agent-skills-with-github-cli/), and Vercel Labs' [skills](https://github.com/vercel-labs/skills) package does the same job through `npx`: ```text gh skill install kirupa/pixelperfect pixelperfect npx skills add kirupa/pixelperfect --skill pixelperfect ``` At the time of writing, GitHub's changelog lists GitHub Copilot, Claude Code, Cursor, Codex, Gemini CLI, and Antigravity as agents that `gh skill` installs into, and the [Agent Skills site](https://agentskills.io/clients) keeps a longer list. My favorite proof that the teaching travels came from a test. An agent that had never seen any of my critiques drew my face from two photos, using nothing but the skill, and its 11th round of the 16×16 portrait became the skill's worked portrait example. One word of caution: a skill is instructions plus scripts, and both run with whatever permissions our agent has. GitHub's changelog points out that GitHub doesn't check the skills we install, and that a skill could hide sneaky instructions or a harmful script. So read a skill before installing it (`gh skill preview` shows what's inside). This is the same worry we covered in [Prompt Injection Defense](https://www.kirupa.com/ai_fundamentals/prompt_injection_defense.htm). ## When to Write a Skill A skill isn't the only way to change what an agent does. Here are four options side by side: ![Four cards. Project instructions: short rules for every task, loaded on every request, like run tests with npm test. A skill: know-how for one kind of task, loaded only when needed, like draw a 16 by 16 icon. An MCP server: a live connection to systems and data outside the agent, like look up today's orders. Fine-tuning: behavior trained into the model itself, like one house style at huge volume.](https://www.kirupa.com/ai_fundamentals/images/teaching_your_agent_new_skills_which_tool.png) Project instructions, like the `CLAUDE.md` and `AGENTS.md` files from [How an Agent Like Claude Code Works](https://www.kirupa.com/ai_fundamentals/how_an_agent_works.htm), are for short rules that apply to every task, because they're read on every trip around the agent's loop. A skill is for know-how that's needed only some of the time, especially when it's big, comes with examples, or needs a script. If our project instructions keep growing a section about one kind of task, that section probably wants to be a skill. Fine-tuning is for behavior that has to be baked in at a scale a prompt can't handle, which is rarer than people expect. An MCP server is for reaching things outside the agent, like a database or a live order system, and it's the topic of the next article. The two work well together. As Anthropic's Mahesh Murag [put it to VentureBeat](https://venturebeat.com/technology/anthropic-launches-enterprise-agent-skills-and-opens-the-standard), MCP gives an agent the connection to outside software and data, and a skill gives it the know-how for using those tools well. If you do write a skill, here's what made pixelperfect work: - The description is specific. It names the task and the words people use to ask for it. - It shows good and bad work, like the approved drawings and the lint failures. - It has checks the agent can run, because a rule with a script behind it gets followed far more reliably. - The gotchas are written down. Every mistake I caught became a named failure with its fix. [Anthropic's advice](https://www.anthropic.com/research/equipping-agents-for-the-real-world-with-agent-skills) for building a skill is to start by running the agent on real tasks and watching where it struggles, before writing anything. That's the loop from earlier. pixelperfect grew one critique at a time, and I suspect most good skills do. ## Conclusion We started with an agent that couldn't draw a coffee cup. It wasn't missing intelligence. It was missing knowledge that lived in my head: what makes pixel art readable at 16 pixels, which shortcuts look terrible, and how to check its own work. A skill is how we hand that knowledge over. It's a folder with a `SKILL.md` whose description the agent reads up front, instructions it reads when a task matches, and references, examples, and scripts it reaches for only when a step needs them. Teaching it is a loop of letting the agent try, critiquing what it makes, and turning each critique into a rule, an example, or a check. Because the format is open, the same folder works in GitHub Copilot, Claude Code, Codex, Cursor, Gemini CLI, and more. If you want to poke around a finished one, pixelperfect is [on GitHub](https://github.com/kirupa/pixelperfect), and it has its own page at [kirupa.com/pixelperfect](https://www.kirupa.com/pixelperfect.htm). Next, we'll look at the other half of extending an agent, the [Model Context Protocol](https://www.kirupa.com/ai_fundamentals/model_context_protocol.htm), which connects an agent to tools and data that live outside it.