Course · Claude Code · Skills
Choose between a skill, a slash command, and a subagent
Package some work and reuse it describes three different tools in Claude Code, and reaching for the wrong one is a common way to fight the grain. A skill is a folder with a SKILL.md that the agent invokes itself when your request matches its description. A slash command is a procedure you trigger by typing /name. A subagent is a separate worker with its own context window. This lesson is the decision: which container a given piece of work actually wants, and when the answer is rules or neither.
The worked case is a branch wrap-up in a small TypeScript payments service (the example this course returns to). It lives at .claude/skills/finish-pr/SKILL.md, its description names the moment a change is done or a PR is ready, and its body runs four steps and stops on the first failure: npm test, a check that any bug fix names its regression test, npm run lint, npm run build. The create lesson shows the full file.
One file, two ways to fire
Section titled “One file, two ways to fire”Start with the confusion the interface itself creates: custom slash commands and skills are the same underlying thing now. Custom commands were merged into skills - a file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and work the same way, and the skills page documents the merge. So the distinction is not two formats; it is two ways the same file can fire:
- As a skill - the agent reads the
description, recognizes the situation, and invokes it itself. You say this is ready and the wrap-up runs. - As a command - you type
/finish-prand it runs because you said so. The agent never decides.
By default both are available: you can invoke any skill as /name, and Claude can load it when the conversation matches. Two frontmatter flags carve that up, and they are not mirror images.
disable-model-invocation: true makes the skill yours alone - it leaves the listing, the skill menu the agent browses each session, cannot fire on recognition, and runs only when you type the command. user-invocable: false goes the other way: the skill disappears from the / menu and /name will not run it, while Claude can still load it when a task matches. That one is for background knowledge never meant to be an action.
The working rule is about mistiming. Let the agent invoke a skill when running it at the wrong moment is harmless - checks, summaries, lookups, regeneration. Make it command-only when a mistimed run is expensive or irreversible: deploys, pushes, messages, spending.
finish-pr sits near the line: its lint step makes edits, but edits a diff can carry. The day you append the shipping act - git push, opening the PR - splitting beats flipping. disable-model-invocation: true on finish-pr itself would silence the checks along with the ship. Keep finish-pr model-invoked, and move the irreversible act to a command-only companion - ship-pr with the flag set - so the checks fire on recognition while the ship waits for /ship-pr.
When the job wants its own window
Section titled “When the job wants its own window”The third tool answers a different question. A skill or command is a procedure - a fixed set of steps you want run. A subagent is a context - a separate window where open-ended work happens without filling yours, defined by a markdown file in .claude/agents/ that names its tools and instructions. The tell is the shape of the work:
- Known routine -> skill or command. The four wrap-up steps never change. You are not asking the agent to figure anything out; you are handing it a script.
- Open investigation -> subagent. Trace every place a charge amount is computed and report the disagreements has no fixed steps, generates a pile of intermediate reading you do not want in your window, and ends in a summary. That is delegation, and the subagents chapter covers it in full.
The two compose rather than compete. A skill can set context: fork in its frontmatter to run in a forked subagent context, so a heavy procedure does its noisy work in isolation and returns only its result - a skill borrowing the subagent’s window, with the mechanics on the skills page. The point is not to memorize the overlap; it is to start from the right question.
The three-way test
Section titled “The three-way test”When you are about to package something, ask in this order:
- Is it a fixed procedure, or open-ended work? Open-ended, context-heavy, ends in a report -> subagent. A fixed set of steps -> skill, and read on.
- Should it fire on recognition, or only when I say so? Harmless if mistimed -> model-invoked skill. Expensive or irreversible -> command-only (
disable-model-invocation: true). - Is it a fact rather than an action? Money is integer cents, errors come back in this shape - that is not a procedure the agent runs, it is knowledge it must already hold while writing any code. Facts belong in rules.
The third is the quiet mistake: a standing fact crammed into a skill body, where it loads only in the sessions where the skill fires. Rules are what the agent knows; skills are what it does; subagents are where the noisy doing happens. Keep those three straight and the packaging question mostly answers itself.
Under the test sits one economy, and you can run it yourself. A rule is loaded in full into every session. A skill pays a menu line every session and loads its body only when invoked. A plain prompt costs nothing until the moment you need it - and then again every time after that - which is why a one-off’s answer is neither: just say it. Four pieces of knowledge, three possible homes; see what the wrong one costs:
The edge of what a skill can reach
Section titled “The edge of what a skill can reach”Skills close a gap: the agent owns the procedures you used to narrate, and fires them when the situation calls. But a skill only orchestrates what the agent can already reach - your files, your shell, the commands on your machine. finish-pr runs npm test and npm run build because you can. The moment the ritual must file a ticket, query the production database, or post the summary - or must fire deterministically, whatever any model decides - you have reached the edge of what a skill can do.
That edge is where the extending chapter lives, in three moves. Reach: MCP servers connect the agent to external systems. Gates: hooks put a deterministic check on the agent’s own tool calls. Ship: plugins bundle a whole setup into one installable unit. One fact to carry with you, straight from the plugin reference: a plugin bundles skills, agents, hooks, and MCP servers - not rules. A CLAUDE.md at a plugin’s root is not loaded as project context; persistent instructions ship as skills, and the create lesson walks one end to end.