A walkthrough of the Claude Academy course Introduction to agent skills (Learn the products track, 6 lessons, about 1 hour). Each lesson is summarised with my own tables and examples; take the course for the full lessons. All the courses are listed in the Claude Academy course index.
Note: My own summary of the course, not the course itself; verify details against the lessons and current docs.
Lessons: What are skills? · Creating your first skill · Configuration and multi-file skills · Skills vs. other Claude Code features · Sharing skills · Troubleshooting skills
Prerequisites / Audience
- Claude Code users who keep re-explaining the same standards, formats, or procedures.
- Comfortable with Markdown/YAML, Git, and the terminal.
Learning objectives
- Explain what skills are, where they live, and how Claude Code matches them to requests.
- Create a skill with valid
SKILL.md frontmatter and verify that it loads.
- Write effective descriptions and pre-approve tools with
allowed-tools.
- Organize larger skills with progressive disclosure, reference files, and scripts.
- Choose between skills, CLAUDE.md, subagents, hooks, and MCP servers.
- Share skills via repos, plugins, enterprise managed settings, and custom subagents.
- Diagnose triggering, loading, priority, and runtime issues with the validator and
claude --debug.
Lesson 1 — What are skills?
- A skill is a folder of instructions and resources that Claude Code discovers and applies automatically. Its core is a
SKILL.md file with name and description in the frontmatter, followed by instructions.
- Matching: Claude compares your request against all skill descriptions and activates the ones that match.
- Rule of thumb: if you keep explaining the same thing to Claude, that’s a skill waiting to be written.
---
name: pr-review
description: Reviews pull requests for code quality. Use when reviewing PRs or checking code changes.
---
Where skills live
| Type |
Location |
Shared with |
| Personal |
~/.claude/skills/ (Windows: C:/Users/<you>/.claude/skills) |
You, across all projects |
| Project |
.claude/skills/ at the repo root |
Everyone who clones the repo (version-controlled) |
Skills vs. CLAUDE.md vs. slash commands
| Feature |
When it loads |
| CLAUDE.md |
Every conversation, always (e.g. “use TS strict mode”) |
| Skills |
On demand when the request matches. Only name and description sit in context until then |
| Slash commands |
Only when you explicitly type them |
- Good candidates: code-review standards, commit-message formats, brand guidelines, doc templates, framework debugging checklists.
Lesson 2 — Creating your first skill
mkdir -p ~/.claude/skills/pr-description # directory name = skill name
---
name: pr-description
description: Writes pull request descriptions. Use when creating a PR, writing a PR, or when the user asks to summarize changes for a pull request.
---
When writing a PR description:
1. Run `git diff main...HEAD` to see all changes on this branch
2. Write a description following this format:
## What
One sentence explaining what this PR does.
## Why
Brief context on why this change is needed
## Changes
- Bullet points of specific changes made
- Group related changes together
- Mention any files deleted or renamed
- Testing: Claude Code watches the skills directories, so new skills appear in the current session without a restart. If
~/.claude/skills didn’t exist at session start, run /reload-skills (and run it again after each change). Ask “what skills are available?” and then “write a PR description for my changes”.
- How matching works:
- At startup, Claude scans the skill locations and loads only names and descriptions.
- Each request is compared to the descriptions using semantic matching (intent overlap, not exact keywords).
- On a match, Claude reads the full
SKILL.md and follows it. A plain skill loads without asking. A skill that pre-approves tools or adds hooks may prompt for approval, depending on the permission mode.
Priority on name conflicts
| Rank |
Source |
| 1 (highest) |
Enterprise (managed settings) |
| 2 |
Personal (~/.claude/skills) |
| 3 |
Project (.claude/skills) |
| outside the order |
Plugin skills, namespaced /plugin-name:skill-name. They load alongside skills with the same name |
- Use distinctive names (
frontend-review, not review).
- Update a skill by editing
SKILL.md. Remove it by deleting its directory. Changes are picked up live.
Lesson 3 — Configuration and multi-file skills
Frontmatter fields
In Claude Code all fields are optional and only description is recommended. The agent skills open standard defines the core fields, and Claude Code adds more.
| Field |
Notes |
name |
Defaults to the directory name. On Claude.ai/API it’s required: lowercase, digits, hyphens, ≤64 chars |
description |
Most important (used for matching). On Claude.ai/API it’s required, ≤1,024 chars |
allowed-tools |
Pre-approves the listed tools while the skill is active. It does not restrict Claude to them |
model |
Model to use for the skill |
disallowed-tools |
Claude Code field that removes the listed tools while the skill is active |
- A good description answers two questions: What does it do? and When should Claude use it? If the skill doesn’t trigger, add keywords that match how you actually phrase requests.
---
name: codebase-onboarding
description: Helps new developers understand how the system works. Use when someone asks how the codebase is structured or where things live.
allowed-tools: Read, Grep, Glob, Bash
model: sonnet
---
- The
allowed-tools grant lasts for the rest of the turn that invoked the skill and clears when you send your next message. Other tools still go through normal permissions.
- ⚠️ Bare
Bash pre-approves shell commands in general. Narrow it, e.g. Bash(git status *).
Progressive disclosure
- Skills share the context window with your conversation. Keep
SKILL.md under 500 lines and link to supporting files that Claude reads only when needed.
my-skill/
├── SKILL.md # essential instructions + "read X when Y"
├── scripts/ # executable code
├── references/ # extra docs (e.g. architecture-guide.md)
└── assets/ # templates, images, data
For system-design questions, read references/architecture-guide.md.
To validate the environment, run scripts/check_env.sh (do not read it).
- Scripts run without loading their source into context. Only their output costs tokens. Tell Claude to run the script, not read it. Good uses: environment validation, consistent data transforms, and any operation that’s more reliable as tested code than as generated code.
Lesson 4 — Skills vs. other Claude Code features
| Feature |
Trigger / nature |
Use for |
| CLAUDE.md |
Always loaded |
Project-wide standards, constraints (“never modify the DB schema”), framework and style preferences |
| Skills |
Request-driven, on demand |
Task-specific expertise, knowledge that’s only sometimes relevant, detailed procedures |
| Subagents |
Separate, isolated context |
Delegated work, different tool access, isolation from the main context |
| Hooks |
Event-driven (tool calls, file saves) |
Run a linter on every save, validate before tool calls, automated side effects |
| MCP servers |
External tools and integrations |
Connecting to outside systems (a different category entirely) |
- Skills add knowledge to the current conversation. Subagents run tasks elsewhere and return results.
- Combine features rather than forcing everything into skills.
Lesson 5 — Sharing skills
| Method |
How |
Best for |
| Repository |
Commit to .claude/skills/. Teammates get updates on git pull |
Team standards, project workflows, codebase-specific skills |
| Plugins |
A skills/ dir at the plugin root (one folder + SKILL.md per skill), distributed via a marketplace |
Skills useful beyond one project or team |
| Enterprise managed settings |
.claude/skills/ inside the managed-settings dir (e.g. /etc/claude-code/.claude/skills/ on Linux). Highest priority |
Mandatory standards, security, compliance (the keyword is must) |
- Managed settings can also restrict plugin sources:
"strictKnownMarketplaces": [
{ "source": "github", "repo": "acme-corp/approved-plugins" },
{ "source": "url", "url": "https://plugins.example.com/marketplace.json" }
]
Skills and subagents (a common gotcha)
- A subagent doesn’t see skills you already invoked, because it starts with a fresh context (unless it’s a fork, which copies the conversation). It can still find and invoke skills if it has the
Skill tool.
- Built-in agents (Explore, Plan) don’t preload skills.
- Custom subagents can preload skills via a
skills: field. Preloaded skills load in full at startup, not on demand. If you set tools, keep Skill in the list.
---
name: frontend-security-accessibility-reviewer
description: "Use this agent when you need to review frontend code for accessibility..."
tools: Bash, Glob, Grep, Read, WebFetch, WebSearch, Skill
model: sonnet
color: blue
skills: accessibility-audit, performance-check
---
- Restart Claude Code if
.claude/agents/ didn’t exist at session start.
Lesson 6 — Troubleshooting skills
- Start with the validator:
claude plugin validate ~/.claude/skills or claude plugin validate .claude/skills (Claude Code ≥ v2.1.233). It catches frontmatter that doesn’t parse.
| Symptom |
Cause / Fix |
| Doesn’t trigger |
Almost always the description. Add the trigger phrases users actually say, and test variations (“why is this slow?”, “make this faster”) |
| Doesn’t load |
SKILL.md must be inside a named directory (not at the skills root), and the filename must be exactly SKILL.md. Run claude --debug and look for your skill name |
| Wrong skill used |
Descriptions are too similar, so make them distinct |
| Shadowed |
A higher-priority skill has the same name (enterprise > personal > project). Rename yours or talk to your admin |
| Plugin skills missing |
Check /plugin: is it listed and enabled, and what’s in the Errors tab? Run /reload-plugins. Skills must be in skills/ at the plugin root, not inside .claude-plugin/ |
| Runtime errors |
Missing dependencies (mention them in the description), scripts not executable (chmod +x), path separators (use forward slashes everywhere, even on Windows) |
Quick-Review Flashcards
- Q: What does Claude load from each skill at startup? → A: Only the name and description. The full
SKILL.md loads on a match.
- Q: Where do personal and project skills live? → A:
~/.claude/skills/ and .claude/skills/.
- Q: What are the two questions a good description answers? → A: What does it do? When should Claude use it?
- Q: Does
allowed-tools restrict Claude to those tools? → A: No. It pre-approves them, and other tools still go through normal permissions. Use disallowed-tools to remove tools.
- Q: What’s the recommended maximum length for
SKILL.md? → A: Under 500 lines. Move the rest to references/scripts/assets.
- Q: Why are scripts context-efficient? → A: They execute without loading their source, so only the output consumes tokens.
- Q: What’s the priority order on name conflicts? → A: Enterprise > Personal > Project. Plugin skills are namespaced and load alongside.
- Q: Skills vs. hooks? → A: Skills are request-driven knowledge. Hooks are event-driven automation.
- Q: Do subagents inherit invoked skills? → A: No. Custom subagents can preload skills via
skills:, or invoke them with the Skill tool.
- Q: What’s the first troubleshooting step? → A:
claude plugin validate <skills dir>, then claude --debug for loading errors.
- Q: A skill was created but
~/.claude/skills is new this session. What do you do? → A: Run /reload-skills.
- Q: Most common cause of a skill not triggering? → A: A description that doesn’t overlap with how users phrase requests.
Practice Ideas
- Build the personal
pr-description skill, then verify it with “what skills are available?” and a real branch diff.
- Create a project
commit-message skill and test 5 phrasings. Add keywords until all of them trigger it.
- Refactor a long skill into
SKILL.md + references/ + scripts/ (e.g. an env-check script that Claude runs but doesn’t read).
- Audit your CLAUDE.md and move task-specific sections into skills.
- Create a custom reviewer subagent with
skills: accessibility-audit and confirm it applies the skill.
- Deliberately break a skill (wrong filename, bad YAML, file at the root) and diagnose each with
claude plugin validate and claude --debug.