In the previous lesson, you learned how to use CLAUDE.md files to give your agent persistent knowledge and consistent behavior through natural language instructions. Your travel planner agent could follow guidelines, ask clarifying questions, and structure its responses according to your specifications. But what happens when you need Claude to perform tasks that require more than just instructions? What if you need executable code, specialized utilities, or domain-specific algorithms that go beyond what natural language prompts can provide? This is where Agent Skills come in — modular, task-specific packages that extend Claude's capabilities by combining structured instructions with executable code and supporting resources. In this lesson, you'll learn how to configure the SDK so Claude can discover and use Skills, and craft prompts that trigger them automatically.
Agent Skills are modular capabilities that extend Claude's functionality. Each Skill packages instructions, metadata, and optional resources (scripts, templates, reference materials) that Claude uses automatically when relevant to a user's request.
Skills are reusable, filesystem-based resources that provide Claude with domain-specific expertise: workflows, context, and best practices. Unlike CLAUDE.md files (which provide project-wide instructions that load at startup), Skills load on-demand and can be reused across multiple projects. What makes Skills powerful is their composability — Claude can identify when a Skill is relevant and invoke it automatically, combining multiple Skills if needed for complex workflows.
The Agent SDK supports custom Skills — Skills you create yourself and place in your project's .claude/skills/ directory. Each Skill can contain three types of content that load at different times:
- Instructions: Natural language guidance in
SKILL.md(and optional additional markdown files) that describe workflows and best practices - Code: Executable scripts that provide deterministic operations without consuming context tokens
- Resources: Reference materials like templates, documentation, schemas, or examples
This differs from CLAUDE.md files in two key ways: Skills include executable code and supporting resources beyond just instructions, and Skills use progressive disclosure (loading only when needed) rather than loading all content at startup.
Before we dive into the structure of Skills, it's helpful to know where to find examples. Anthropic maintains a public repository for Skills on GitHub with demonstrations ranging from creative applications to technical tasks to enterprise workflows.
The repository includes example Skills (many open source under Apache 2.0), the document creation Skills that power Claude's PowerPoint/Excel/Word/PDF capabilities (source-available as reference), a Skills specification, and a starter template.
The slack-gif-creator Skill we're using in this lesson follows patterns similar to those in the public repository. Now let's examine the filesystem structure that makes Skills work.
Skills live in a .claude/skills/ directory within your project, following a specific filesystem structure that the SDK recognizes automatically. Each Skill is its own subdirectory containing at minimum a SKILL.md file, with optional scripts and resource folders.
Let's examine the structure of the slack-gif-creator Skill:
The heart of every Skill is the SKILL.md file, which uses YAML frontmatter followed by Markdown content. The YAML frontmatter at the top defines metadata like the Skill's name and description, which helps Claude understand when to use this Skill. The Markdown content provides detailed instructions about technical requirements, available utilities, and best practices. The core/ directory contains Python modules that Claude can use to process images and build GIFs with precise control over frames, colors, and timing. This combination of instructions and executable code is what makes Skills more powerful than CLAUDE.md files alone.
Before we configure the SDK, let's look at what's inside a SKILL.md file to understand what Claude sees when it loads a Skill. Here's what the beginning of the slack-gif-creator SKILL.md looks like:
The name field identifies the Skill, while the description field tells Claude when to use it — notice how it includes example phrases like "make me a GIF of X doing Y for Slack" that help Claude recognize relevant requests. The Markdown content below the frontmatter provides detailed technical specifications that Claude will follow when generating GIFs, such as the exact dimensions for Slack emoji (128x128) and optimal parameters for file size and frame rates. This structured format allows Claude to understand both when to use the Skill and how to use it correctly.
Skills use a three-level loading model called progressive disclosure that ensures only relevant content occupies the context window at any given time. Understanding this model is crucial because it means having many Skills installed doesn't create a context penalty.
Level 1: Metadata (always loaded) — At startup, Claude loads only the YAML frontmatter from each SKILL.md file (the name and description fields). This lightweight metadata tells Claude what Skills exist and when to use them, consuming roughly 100 tokens per Skill. You can install dozens of Skills without significant context cost.
Level 2: Instructions (loaded when triggered) — When you make a request that matches a Skill's description, Claude reads the full SKILL.md file from the filesystem using bash commands. Only then does the Markdown content below the frontmatter enter the context window. This typically adds under 5,000 tokens.
Level 3: Resources and code (loaded as needed) — If the instructions reference additional files (like FORMS.md or Python scripts), Claude reads or executes those files via bash only when needed. Script code never enters the context window — only the script's output does, making executable code extremely efficient compared to generating equivalent code from scratch.
This architecture means Claude navigates your Skill like you'd reference specific sections of an onboarding guide, accessing exactly what each task requires without loading everything upfront.
To use Skills in the Agent SDK, you need to configure two things: where Skills are located, and which tools Claude can use to access them. Just like in the previous unit, it is highly recommended to use an explicit absolute path for the cwd parameter to ensure your code works reliably regardless of where it is executed.
The cwd parameter points to your project root where the .claude/ directory lives. When the SDK runs, it discovers Skills in the .claude/skills/ directory under cwd and loads their metadata (Level 1 loading). Using Path(__file__).parent.absolute() ensures that the SDK always looks for the .claude folder relative to your script's location, rather than the current working directory of the shell (.), which can be inconsistent.
The setting_sources=["project"] parameter tells the SDK to load configuration from the .claude/ directory, which includes discovering available Skills.
The most critical configuration is . You must include to enable Skill invocation. The other tools serve important purposes: allows Claude to read files from the filesystem and run Python scripts, lets Claude save generated files, and help Claude find and access existing resources. Without these tools, Claude cannot fully interact with Skills.
When a Skill is triggered, Claude doesn't simply "load" the Skill into memory. Instead, Claude uses bash commands to interact with the Skill's filesystem contents, just like you would navigate files on your computer.
Here's what happens when Claude uses a Skill:
- Discovery: Claude's system prompt includes the metadata from all Skills (Level 1), so it knows
slack-gif-creatorexists and when to use it - Triggering: When you request "create a GIF for Slack," Claude recognizes this matches the Skill's description
- Reading instructions: Claude executes a bash command to read
SKILL.md, bringing the full instructions into context (Level 2) - Accessing resources: If the instructions reference utilities like
gif_builder.py, Claude reads or executes those files via bash (Level 3) - Running scripts: When Claude runs
python core/gif_builder.py, only the script's output enters context, not the code itself
This filesystem-based architecture is why Skills can include comprehensive documentation, large datasets, or complex utilities without context penalties — files only consume tokens when Claude actually accesses them.
Once you've configured the SDK, the final piece is crafting prompts that guide Claude to use your Skills. The key is to be specific about what you want while mentioning the Skill by name or describing the task in a way that matches the Skill's description.
This prompt works well because it explicitly mentions the Skill name "slack-gif-creator," which helps Claude identify the right tool immediately. It describes the desired outcome clearly and references an existing image file "cosmo.png" that Claude will need to locate and process.
You don't always need to mention the Skill name explicitly — if you wrote "Create a spinning animated GIF for Slack from cosmo.png", Claude would still recognize that the slack-gif-creator Skill is relevant based on its description. However, being explicit helps ensure Claude uses the right Skill, especially if you have multiple Skills that could potentially handle similar tasks.
Now let's build the complete code that configures the SDK to use Skills from our project directory, enables the necessary tools, and crafts a prompt that triggers the Skill. We'll set up all the configuration options we've discussed and prepare to run the agent.
The configuration sets cwd=project_root to use the script's directory as the project root, ensuring the SDK correctly identifies the .claude/skills/ directory. The allowed_tools list includes Skill to enable Skill invocation, Bash to read SKILL.md files and run Python scripts, Write to save the generated GIF file, Read to access the source image, and to find files in the project. We also set to give Claude enough iterations to complete the multi-step process of triggering the Skill, reading instructions, locating the image file, writing code, and generating the GIF. Let's see what happens when we run this code.
Before we run the agent, let's look at the source image that Claude will be working with. The cosmo.png file is a static image of Cosmo the corgi character that we want to transform into a spinning animated GIF:

This is a simple static PNG file with transparent background. Claude will take this single image and use the slack-gif-creator Skill's utilities to generate multiple rotated frames, optimize the color palette, and create a smooth looping animation that meets Slack's technical requirements. Now let's see how Claude handles this transformation.
When we run the code, Claude immediately recognizes that it should use the slack-gif-creator Skill. Remember that at startup, Claude already knows the Skill exists from its metadata (Level 1 loading). Now Claude triggers the Skill by reading its full instructions.
When Claude invokes the Skill tool, it's executing a bash command to read the slack-gif-creator/SKILL.md file from the filesystem (Level 2 loading). This brings the full instructions into Claude's context window. After reading the instructions, Claude understands Slack's technical requirements for emoji GIFs, including the 128x128 dimension limit, optimal frame rates, and color palette constraints.
Before proceeding, Claude uses the Read and Glob tools to verify that the cosmo.png file exists in the project directory and can be accessed. This demonstrates how Claude combines multiple tools to complete a workflow — reading the Skill's instructions via bash, verifying resources, and preparing to execute code. Next, Claude will write the Python script to generate the spinning animation.
After verifying the source image exists and consulting the Skill's instructions, Claude writes Python code that leverages the Skill's utilities to create the spinning animation with precise control over frames and optimization.
Claude uses the Write tool to create a Python script that imports the Skill's utilities from the core/ directory, loads the cosmo.png image, generates rotation frames, and builds an optimized GIF file. The script applies the technical specifications from the Skill's instructions, ensuring the output meets Slack's requirements for emoji GIFs.
Claude then uses the Bash tool to execute the Python script with a command like python create_gif.py. This is Level 3 loading in action — Claude runs the script via bash, and only the script's output (success messages, file paths, errors) enters the context window. The script's code itself never consumes context tokens, making executable utilities far more efficient than having Claude generate equivalent code from scratch each time.
This demonstrates how Skills can include complex workflows that leverage Python's image processing capabilities with exact precision that would be difficult to achieve through natural language prompts alone. Now let's see the final results of what Claude created.
Finally, Claude presents the results with a detailed summary of what was created, showing how the Skill's knowledge was applied to meet Slack's exact specifications.
Notice how Claude provides detailed specifications that match Slack's requirements exactly. The 128x128 dimensions, ~17 FPS frame rate, and 48-color palette are all optimized based on the knowledge from the slack-gif-creator Skill's instructions that Claude read via bash. The file size of 47.3 KB is well under typical limits, and the animation duration of 0.7 seconds creates a short, snappy loop perfect for emoji use.
Claude also mentions that the Skill's GIFBuilder utility automatically optimized the animation by reducing the frame count from 24 to 12 frames, demonstrating how the Skill's executable code handles optimization decisions that would be tedious to implement manually. All of this precision came from the Skill's instructions and Python utilities accessed via bash, which would have been difficult to achieve through natural language prompts alone.
Here's the final spinning Cosmo emoji GIF that Claude created from the static PNG image:

The animation shows a smooth, continuous rotation that loops seamlessly. Comparing this to the original static cosmo.png image, you can see how the Skill's utilities handled the image processing, rotation frames, and color optimization to create a professional-looking result that's ready to upload to Slack as a custom emoji. The transformation from a single static image to a fully optimized animated GIF demonstrates the power of combining Claude's decision-making with executable Python code accessed through filesystem-based Skills.
Before you start using Skills from various sources, it's crucial to understand the security implications. Skills provide Claude with new capabilities through instructions and code, and while this makes them powerful, it also means Skills from untrusted sources can pose security risks.
Only use Skills from trusted sources — those you created yourself, obtained from teammates you trust, or received from reputable organizations. Just like you wouldn't install software from unknown sources on your computer, you should exercise extreme caution with Skills from unfamiliar origins.
Audit thoroughly before use: If you must use a Skill from an external source, review all files it contains: the SKILL.md instructions, any bundled scripts, and supporting resources. Look for unusual patterns like unexpected network calls, file access operations, or instructions that don't match the Skill's stated purpose. Skills that fetch data from external URLs pose particular risk, as fetched content may contain malicious instructions.
Understand the risks: Depending on what access Claude has when executing a Skill, malicious Skills could lead to data exfiltration, unauthorized system access, or misuse of tools like file operations and bash commands. Skills with access to sensitive data could be designed to leak information to external systems.
For this lesson's slack-gif-creator Skill, you would review the SKILL.md instructions, examine all Python scripts in the core/ directory, and verify that the code only performs image processing operations without making network calls or accessing unrelated files. Treat Skills like installing software — with appropriate caution and verification.
You've now learned how to extend Claude's capabilities using Agent Skills, which combine structured instructions with executable code and supporting resources. Skills live in the .claude/skills/ directory and are discovered automatically when you configure cwd and setting_sources appropriately. Skills use progressive disclosure — Claude loads only metadata at startup, reads full instructions when triggered via bash, and accesses resources only as needed.
The Skill tool must be enabled in allowed_tools for Claude to invoke Skills, along with Bash for reading SKILL.md files and running scripts, and file operation tools like Write, Read, and Glob. You should craft prompts that mention the Skill name or describe tasks that match the Skill's description. Claude accesses Skill content through the filesystem using bash commands, making scripts efficient since only their output (not code) enters context.
The Agent SDK supports custom Skills that you create and place in .claude/skills/, and you should only use Skills from trusted sources and audit any external Skills thoroughly. In the upcoming practice exercises, you'll work with different Skills and learn when to use Skills versus simpler configuration approaches like CLAUDE.md files.
