AI Agents
Go past a single SKILL.md: supporting files, arguments, live context from shell commands, forked subagent skills and skills that build on each other.
Your first Claude Code skill is a small win: a deploy checklist or commit format you no longer repeat. By the tenth, three skills copy the same API conventions, a release skill needs the changelog skill's output, and an audit skill floods the conversation with 200 files. Better single skills will not fix that. Skills that compose will, and the SKILL.md frontmatter has the fields to build them.
There is no import or function-call syntax between skills. Composition works in four documented ways: skills share supporting files, a skill's instructions tell Claude to use another skill, users stack several skills in one command (up to 6), and context: fork runs a skill in an isolated subagent. Together these cover almost every multi-skill workflow.
The basics, name and description, are covered in the introduction to SKILL.md. These are the fields that control how skills combine; the Claude Code skills documentation lists the rest:
description and when_to_use: what Claude reads to decide whether to load a skill. Together they are capped at 1,536 characters in the listing.disable-model-invocation: true: only you can run the skill with its slash command. Its description is removed from Claude's context.user-invocable: false: hidden from the slash menu; only Claude can invoke it. Good for background knowledge.allowed-tools: tools Claude may use without a permission prompt during the turn the skill is invoked, such as Bash(gh issue view *).arguments and argument-hint: named positional arguments, substituted as $name in the skill body.context: fork, agent and background: run the skill in a subagent of a given type, in the background or not.paths: glob patterns that limit automatic loading to work on matching files.model and effort: override the model or effort level while the skill is active.A skill is a directory, and only SKILL.md is required. Supporting files load only when Claude opens them, so a long reference costs nothing until it is needed. Keep SKILL.md to a navigable overview, around 500 lines at most, and link out:
.claude/skills/
├── release/
│ ├── SKILL.md orchestrator, user-only
│ └── checklist.md read only when the skill says so
├── changelog/
│ ├── SKILL.md
│ └── scripts/collect-commits.sh
└── api-conventions/
└── SKILL.md background knowledge, Claude-only
When a script ships with a skill, reference it through ${CLAUDE_SKILL_DIR}, which expands to the skill's own directory regardless of the current working directory. ${CLAUDE_PROJECT_DIR} does the same for the project root.
A skill that starts by asking Claude to go and fetch context wastes a turn and some tokens. Dynamic context injection runs shell commands before the skill content reaches Claude, and replaces each command with its output. Combined with named arguments, a skill arrives already briefed:
---
name: fix-issue
description: Fix a GitHub issue end to end. Use when the user gives an issue number and asks to fix, resolve or implement it.
argument-hint: "[issue-number]"
arguments: [issue]
allowed-tools:
- Bash(gh issue view *)
- Bash(git log *)
- Bash(pnpm test *)
---
## Issue
!`gh issue view $issue --json title,body,labels`
## Recent commits
!`git log --oneline -15`
## Steps
1. Restate the bug in one sentence and name the files you expect to change.
2. Write a failing test first, following [testing.md](testing.md).
3. Fix it, run `pnpm test`, and summarise the change for the PR description.
Running /fix-issue 482 substitutes 482 for $issue, runs both commands, and hands Claude the issue text and the recent commits in the first message. Commands time out after 2 minutes, run with your normal permission rules, and fail the invocation on a non-zero exit, so append || true to anything that may legitimately exit non-zero.
Browse ready-made Claude Code subagents for testing, documentation, security and more, each downloadable as a Markdown file you can adapt.
Browse the agent libraryFor multi-step workflows, write one user-invoked orchestrator whose instructions name the component skills, and keep each component focused on one job. The orchestrator carries the side effects, so it is the one that should never run on its own initiative:
---
name: release
description: Prepare a release branch, changelog and version bump.
disable-model-invocation: true
---
Prepare release $ARGUMENTS. Work through these steps in order and stop at the first failure:
1. Use the changelog skill to draft release notes since the last tag.
2. Use the api-conventions skill to check every changed route in the diff.
3. Read [checklist.md](checklist.md), then bump the version in package.json
and commit with the message "release: $ARGUMENTS".
4. Show me the notes and a summary of the diff, and wait for confirmation before pushing.
The component skills must stay invocable by Claude, which is the most common mistake in this pattern: setting disable-model-invocation: true on the changelog skill blocks the orchestrator from ever using it. Pure knowledge skills such as api-conventions are better with user-invocable: false and a paths scope, so they load automatically when Claude works in src/api/ and never clutter your slash menu.
For ad hoc combinations you do not want to formalise, stacking does the same job from the prompt: /write-tests /fix-issue 482 loads both skills and passes 482 to each. Stacking stops at the first skill that cannot run inline, such as a forked one.
Some skills read far more than they report: a dependency audit, a security sweep, a migration inventory. Run them with context: fork and the reading happens in an isolated subagent; only the summary comes back to your conversation.
---
name: dependency-audit
description: Audit dependencies for unused, duplicated or outdated packages. Use when asked to clean up or audit dependencies.
context: fork
agent: Explore
background: false
effort: low
---
Audit the dependencies of this repository and report back. Do not modify any files.
1. List every dependency in each package.json, including workspaces.
2. Search the source for imports of each one. Flag packages with no imports.
3. Flag packages installed at more than one major version.
4. Return a table: package, finding, evidence (a file path or "no imports found"), suggested action.
Three things change when a skill forks. The subagent does not see your conversation, so the skill must contain a complete task, not guidelines. The agent type sets its tools: Explore is read-only, which suits an audit. And forked skills run in the background by default; background: false (Claude Code v2.1.218 and later) makes the current turn wait for the result. This is the same isolation model described in subagent isolation.
when_to_use is dropped, and with it the trigger phrases you put at the end. Lead with the use case./rewind does not undo them. Keep background forks read-only.disableSkillShellExecution in settings turns dynamic context off, and shell: bash needs Git Bash on Windows. Write skills that still make sense when a command produced no output.Skills are for procedures you need sometimes. Facts every session needs belong in CLAUDE.md, as explained in Claude Code memory. A specialist with its own tools, model and persistent role is a subagent, covered in the subagents guide. Anything that must happen every time, whatever the model decides, is a hook, as described in Claude Code hooks explained. Most mature setups use all four, each for what it does best. The pipeline that publishes this blog works that way: a pipeline definition sequences separate Claude Code subagents for writing, SEO review and deployment, each a markdown file with one job.
Not through any import or call syntax. A skill can instruct Claude to use another skill, which Claude then invokes like any other, and a user can stack several skills in one command, such as /write-tests /fix-issue 123. Shared reference files and forked subagent skills cover most other composition needs.
It runs the skill in an isolated subagent instead of the main conversation. The skill content becomes the subagent's task, the subagent does not see the conversation history, and the agent field picks its type, such as Explore. It keeps heavy reading out of your main context but needs an explicit, self-contained task.
The description and when_to_use fields share a cap of 1,536 characters in the skill listing; anything beyond that is cut. Put the main use case and trigger phrases first, because the description is what Claude reads when deciding whether to load the skill.
Set disable-model-invocation: true in the frontmatter. The skill then runs only when you type its slash command, and its description is left out of Claude's context. Use it for skills with side effects, such as deploys or releases. The opposite setting, user-invocable: false, hides a skill from the slash menu so only Claude can use it.