Agent Skills Authoring Best Practices
Source: https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices
This document covers practical authoring guidance for writing effective skills that agents can discover and use successfully.
Contents
- Core principles
- Skill structure
- Workflows and feedback loops
- Content guidelines
- Common patterns
- Evaluation and iteration
- Advanced: executable code
- Checklist for effective skills
Core Principles
Concise Is Key
The context window is a public good. Include only what the agent doesn't already know. Prefer short examples over long explanations.
Apply these heuristics when drafting content:
- Include only skill-specific information — omit general concepts the agent already knows
- Each paragraph should justify its token cost with actionable guidance
- When in doubt, use a compact example instead of prose
Good (~50 tokens):
## Extract PDF text
Use pdfplumber for text extraction:
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
```
Bad (~150 tokens):
## Extract PDF text
PDF (Portable Document Format) files are a common file format that contains
text, images, and other content. To extract text from a PDF, you'll need to
use a library. There are many libraries available...
Set Appropriate Degrees of Freedom
Match specificity to the task's fragility:
High freedom (text-based instructions) — Multiple approaches valid, decisions depend on context:
## Code review process
1. Analyze the code structure and organization
2. Check for potential bugs or edge cases
3. Suggest improvements for readability
4. Verify adherence to project conventions
Medium freedom (pseudocode/scripts with parameters) — Preferred pattern exists, some variation acceptable:
def generate_report(data, format="markdown", include_charts=True):
# Process data
# Generate output in specified format
Low freedom (specific scripts, few parameters) — Operations fragile, consistency critical:
## Database migration
Run exactly this script:
```bash
python scripts/migrate.py --verify --backup
```
Do not modify the command or add additional flags.
Analogy: Narrow bridge with cliffs = low freedom (exact instructions). Open field = high freedom (general direction).
Test with All Target Models
- Haiku (fast): Does the skill provide enough guidance?
- Sonnet (balanced): Is the skill clear and efficient?
- Opus (powerful): Does the skill avoid over-explaining?
Skill Structure
Writing Effective Descriptions
The description field enables skill discovery. Include both what the skill does and when to use it.
Write in third person. The description is injected into the system prompt.
- Prefer: "Processes Excel files and generates reports"
- Prefer: "Extract text from PDFs. Use when the user mentions PDFs or document extraction"
- Instead of first/second person: use "Processes…" rather than "I can help you…" or "You can use this to…"
Examples:
# PDF Processing
description: Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction.
# Excel Analysis
description: Analyze Excel spreadsheets, create pivot tables, generate charts. Use when analyzing Excel files, spreadsheets, tabular data, or .xlsx files.
# Git Commit Helper
description: Generate descriptive commit messages by analyzing git diffs. Use when the user asks for help writing commit messages or reviewing staged changes.
Progressive Disclosure Patterns
Keep SKILL.md body under 500 lines. Split content into separate files when approaching this limit.
Pattern 1 — High-level guide with references:
# PDF Processing
## Quick start
[core example]
## Advanced features
- **Form filling**: See [FORMS.md](FORMS.md)
- **API reference**: See [REFERENCE.md](REFERENCE.md)
Pattern 2 — Domain-specific organization:
bigquery-skill/
├── SKILL.md (overview + navigation)
└── reference/
├── finance.md
├── sales.md
└── product.md
Pattern 3 — Conditional details:
For simple edits, modify XML directly.
**For tracked changes**: See [REDLINING.md](REDLINING.md)
Keep References One Level Deep
Link each reference file directly from SKILL.md so the agent can discover content without following long chains.
Prefer (one level):
SKILL.md → advanced.md
SKILL.md → reference.md
SKILL.md → examples.md
Instead of (too deep):
SKILL.md → advanced.md → details.md → actual info
Structure Longer Reference Files
For files >100 lines, include a table of contents at the top so the agent can see the full scope when previewing.
Workflows and Feedback Loops
Use Workflows for Complex Tasks
Break complex operations into clear, sequential steps. Provide a checklist the agent can track:
## PDF form filling workflow
Task Progress:
- [ ] Step 1: Analyze the form (run analyze_form.py)
- [ ] Step 2: Create field mapping (edit fields.json)
- [ ] Step 3: Validate mapping (run validate_fields.py)
- [ ] Step 4: Fill the form (run fill_form.py)
- [ ] Step 5: Verify output (run verify_output.py)
Implement Feedback Loops
Common pattern: Run validator, fix errors, repeat.
## Document editing process
1. Make edits to `word/document.xml`
2. **Validate immediately**: `python scripts/validate.py unpacked_dir/`
3. If validation fails:
- Review the error message
- Fix the issues
- Run validation again
4. **Only proceed when validation passes**
5. Rebuild: `python scripts/pack.py unpacked_dir/ output.docx`
Content Guidelines
Use Current Patterns; Preserve Legacy in Labeled Sections
Use current methods as the default. When documenting deprecated approaches, keep them in a clearly labeled legacy section so agents know not to prefer them:
## Current method
Use the v2 API endpoint: `api.example.com/v2/messages`
## Old patterns
<details>
<summary>Legacy v1 API (deprecated 2025-08)</summary>
The v1 API used: `api.example.com/v1/messages`
</details>
Use Consistent Terminology
Choose one term and use it throughout:
- Good: Always "API endpoint", always "field", always "extract"
- Bad: Mix "API endpoint" / "URL" / "API route" / "path"
Common Patterns
Template Pattern
Strict requirements:
## Report structure
ALWAYS use this exact template:
# [Analysis Title]
## Executive summary
[One-paragraph overview]
## Key findings
- Finding 1 with data
## Recommendations
1. Specific recommendation
Flexible guidance:
## Report structure
Sensible default format — adapt as needed:
# [Analysis Title]
## Executive summary
[Overview]
## Key findings
[Adapt sections based on discovery]
Examples Pattern
Provide input/output pairs:
## Commit message format
**Example 1:**
Input: Added user authentication with JWT tokens
Output:
feat(auth): implement JWT-based authentication
Add login endpoint and token validation middleware
**Example 2:**
Input: Fixed bug where dates displayed incorrectly
Output:
fix(reports): correct date formatting in timezone conversion
Use UTC timestamps consistently
Conditional Workflow Pattern
## Document modification
1. Determine type:
**Creating new?** → Follow "Creation workflow"
**Editing existing?** → Follow "Editing workflow"
2. Creation workflow:
- Use docx-js library
- Build from scratch
- Export to .docx
3. Editing workflow:
- Unpack existing document
- Modify XML directly
- Validate after each change
- Repack when complete
Evaluation and Iteration
Build Evaluations First
Create evaluations BEFORE writing extensive documentation:
- Identify gaps: Run agent on tasks without a skill. Document failures.
- Create evaluations: Build three scenarios testing those gaps.
- Establish baseline: Measure performance without the skill.
- Write minimal instructions: Just enough to address gaps and pass evaluations.
- Iterate: Execute evaluations, compare against baseline, refine.
Evaluation structure:
{
"skills": ["pdf-processing"],
"query": "Extract all text from this PDF file and save it to output.txt",
"files": ["test-files/document.pdf"],
"expected_behavior": [
"Successfully reads the PDF file",
"Extracts text from all pages",
"Saves extracted text to output.txt"
]
}
Iterative Development with Two Instances
- Work through a task with Claude A (the skill author)
- Identify reusable patterns from the session
- Ask Claude A to create a skill capturing those patterns
- Test with Claude B (fresh instance with skill loaded)
- Observe Claude B's behavior — note struggles or missed context
- Return to Claude A with specifics to refine
- Repeat the observe-refine-test cycle
Advanced: Executable Code
Solve, Don't Punt
Handle errors explicitly in scripts:
def process_file(path):
try:
with open(path) as f:
return f.read()
except FileNotFoundError:
print(f"File {path} not found, creating default")
with open(path, "w") as f:
f.write("")
return ""
Document Constants
# HTTP requests typically complete within 30 seconds
REQUEST_TIMEOUT = 30
# Three retries balances reliability vs speed
MAX_RETRIES = 3
Provide Utility Scripts
Pre-made scripts are more reliable, save tokens, save time, and ensure consistency. Make execution intent clear:
- "Run
analyze_form.pyto extract fields" (execute) - "See
analyze_form.pyfor the algorithm" (read as reference)
Create Verifiable Intermediate Outputs
For complex tasks, use plan-validate-execute:
- Analyze input
- Create plan file (e.g.,
changes.json) - Validate plan with a script
- Execute only if validation passes
- Verify output
Package Dependencies
List required packages in SKILL.md. Verify availability in the target environment.
MCP Tool References
Use fully qualified names: ServerName:tool_name
Use the BigQuery:bigquery_schema tool to retrieve table schemas.
Checklist for Effective Skills
Core Quality
- Description is specific and includes key terms
- Description includes both what the skill does and when to use it
- Description written in third person
- SKILL.md body under 500 lines
- Additional details in separate files (if needed)
- Current patterns as default; legacy in clearly labeled section
- Consistent terminology throughout
- Examples are concrete, not abstract
- File references one level deep
- Progressive disclosure used appropriately
- Workflows have clear steps
Code and Scripts
- Scripts solve problems rather than punt to agent
- Error handling is explicit and helpful
- No magic constants (all values justified)
- Required packages listed and verified
- Forward slashes for paths (e.g.,
scripts/helper.py) - Validation/verification steps for critical operations
- Feedback loops for quality-critical tasks
Testing
- At least three evaluations created
- Tested with Haiku, Sonnet, and Opus
- Tested with real usage scenarios
- Team feedback incorporated (if applicable)
Preferred Alternatives
| Instead of | Use |
|---|---|
Windows-style paths (scripts\helper.py) |
Forward slashes: scripts/helper.py (portable) |
| Too many options without a default | One preferred approach with optional alternatives |
| Assuming tools are installed | List required packages in SKILL.md; verify availability |
| Vague descriptions ("Helps with documents") | Specific descriptions with triggers: "Extracts text from PDFs. Use when…" |
| Deeply nested references (SKILL → A → B → C) | Flat structure: SKILL links directly to each reference |
| Conditional logic on dates/versions | Current method as default; legacy in labeled section |
| Mixed terminology | One term per concept throughout |