Skip to content

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.

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-pr and 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.

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.

When you are about to package something, ask in this order:

  1. 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.
  2. 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).
  3. 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:

Four things you keep teaching the agent, all currently crammed into the rules file. Each needs a home: the rules file (loaded every session), a skill (a 25-token menu line every session, full body only when invoked), or the prompt (said when it comes up). Re-home them and watch the ledger.

  • cents, not floatsfact · matters most sessions · ~22 tok

    Money is integer cents - amountCents: number, never floats.

    right home

    Twenty-two tokens a session and the float bug is extinct. A fact the agent must hold while writing any code has to be in view before it starts - that’s the rules file.

  • release checklistprocedure · runs ~2×/week · ~1.2k tok

    The release ritual: bump the version, regenerate the changelog, tag, build, smoke-test - fifteen steps in a fixed order.

    idle rent

    Fifteen steps loaded into every session to be used twice a week. The other eight sessions pay 1.2k tokens for a procedure that never runs - bulk that competes with your real rules for attention.

  • migration recipeprocedure · runs ~2×/month · ~900 tok

    Schema migrations follow expand → backfill → contract, with a fixture check and a written rollback plan.

    idle rent

    Twenty sessions pay 900 tokens each for every one that migrates. The rarer the procedure, the worse a rules file suits it.

  • today’s flakeone-off · this week only · ~25 tok

    Today’s job: chase the flaky auth test in login.spec.ts.

    rent for a one-off

    True this week, noise forever after. Next month the agent still “knows” about a flake that’s long fixed.

window cost21.5k tok/weekyou re-teach0×/weekmisplaced3 of 4

The procedures are paying rent in every session for the few that use them. Move them behind a skill stub: the knowledge stays one invocation away, and the window cost collapses.

Numbers are illustrative - the ratios are the point. Over 10 sessions a week: a rule pays full size every session, a skill pays a ~25-token stub plus its body only when it fires, a prompt pays only when said - but you’re the one saying it.

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.