Core principles
<objective> always defines what the skill does
- <quick_start> always provides immediate guidance
- <success_criteria> always defines completion
This consistency makes skills predictable and easier to maintain.
Markdown headings are just visual formatting. Claude must infer meaning from heading text, which is less reliable.
Markdown headings:
Total: ~20 tokens, no semantic meaning to ClaudeXML tags:
Total: ~15 tokens, semantic meaning built-inSavings compound across all skills in the ecosystem.
Pure XML structure is not just a style preference—it's a performance optimization.
<objective> - What the skill does and why it matters
- <quick_start> - Immediate, actionable guidance
- <success_criteria> or <when_successful> - How to know it worked
See use-xml-tags.md for conditional tags and intelligence rules.
Assume Claude is smart. Don't explain obvious concepts.
<quick_start>
Extract PDF text with pdfplumber:
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
**Verbose** (~150 tokens):
```xml
<quick_start>
PDF files are a common file format used for documents. To extract text from them, we'll use a Python library called pdfplumber. First, you'll need to import the library, then open the PDF file using the open method, and finally extract the text from each page. Here's how to do it:
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
This code opens the PDF and extracts text from the first page.
The concise version assumes Claude knows what PDFs are, understands Python imports, and can read code. All those assumptions are correct.
</concise_example>
<when_to_elaborate>
Add explanation when:
- Concept is domain-specific (not general programming knowledge)
- Pattern is non-obvious or counterintuitive
- Context affects behavior in subtle ways
- Trade-offs require judgment
Don't add explanation for:
- Common programming concepts (loops, functions, imports)
- Standard library usage (reading files, making HTTP requests)
- Well-known tools (git, npm, pip)
- Obvious next steps
</when_to_elaborate>
</conciseness_principle>
<degrees_of_freedom_principle>
<description>
Match the level of specificity to the task's fragility and variability. Give Claude more freedom for creative tasks, less freedom for fragile operations.
</description>
<high_freedom>
<when>
- Multiple approaches are valid
- Decisions depend on context
- Heuristics guide the approach
- Creative solutions welcome
</when>
<example>
```xml
<objective>
Review code for quality, bugs, and maintainability.
</objective>
<workflow>
1. Analyze the code structure and organization
2. Check for potential bugs or edge cases
3. Suggest improvements for readability and maintainability
4. Verify adherence to project conventions
</workflow>
<success_criteria>
- All major issues identified
- Suggestions are actionable and specific
- Review balances praise and criticism
</success_criteria>
Claude has freedom to adapt the review based on what the code needs.
<objective>
Generate reports with customizable format and sections.
</objective>
<report_template>
Use this template and customize as needed:
```python
def generate_report(data, format="markdown", include_charts=True):
# Process data
# Generate output in specified format
# Optionally include visualizations
Claude can customize the template based on requirements.
</example>
</medium_freedom>
<low_freedom>
<when>
- Operations are fragile and error-prone
- Consistency is critical
- A specific sequence must be followed
- Deviation causes failures
</when>
<example>
```xml
<objective>
Run database migration with exact sequence to prevent data loss.
</objective>
<workflow>
Run exactly this script:
```bash
python scripts/migrate.py --verify --backup
Do not modify the command or add additional flags.
Claude must follow the exact command with no variation.
</example>
</low_freedom>
<matching_specificity>
The key is matching specificity to fragility:
- **Fragile operations** (database migrations, payment processing, security): Low freedom, exact instructions
- **Standard operations** (API calls, file processing, data transformation): Medium freedom, preferred pattern with flexibility
- **Creative operations** (code review, content generation, analysis): High freedom, heuristics and principles
Mismatched specificity causes problems:
- Too much freedom on fragile tasks → errors and failures
- Too little freedom on creative tasks → rigid, suboptimal outputs
</matching_specificity>
</degrees_of_freedom_principle>
<model_testing_principle>
<description>
Skills act as additions to models, so effectiveness depends on the underlying model. What works for Opus might need more detail for Haiku.
</description>
<testing_across_models>
Test your skill with all models you plan to use:
<haiku_testing>
**Claude Haiku** (fast, economical)
Questions to ask:
- Does the skill provide enough guidance?
- Are examples clear and complete?
- Do implicit assumptions become explicit?
- Does Haiku need more structure?
Haiku benefits from:
- More explicit instructions
- Complete examples (no partial code)
- Clear success criteria
- Step-by-step workflows
</haiku_testing>
<sonnet_testing>
**Claude Sonnet** (balanced)
Questions to ask:
- Is the skill clear and efficient?
- Does it avoid over-explanation?
- Are workflows well-structured?
- Does progressive disclosure work?
Sonnet benefits from:
- Balanced detail level
- XML structure for clarity
- Progressive disclosure
- Concise but complete guidance
</sonnet_testing>
<opus_testing>
**Claude Opus** (powerful reasoning)
Questions to ask:
- Does the skill avoid over-explaining?
- Can Opus infer obvious steps?
- Are constraints clear?
- Is context minimal but sufficient?
Opus benefits from:
- Concise instructions
- Principles over procedures
- High degrees of freedom
- Trust in reasoning capabilities
</opus_testing>
</testing_across_models>
<balancing_across_models>
Aim for instructions that work well across all target models:
**Good balance**:
```xml
<quick_start>
Use pdfplumber for text extraction:
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
For scanned PDFs requiring OCR, use pdf2image with pytesseract instead.
This works for all models:
- Haiku gets complete working example
- Sonnet gets clear default with escape hatch
- Opus gets enough context without over-explanation
**Too minimal for Haiku**:
```xml
<quick_start>
Use pdfplumber for text extraction.
</quick_start>
Too verbose for Opus:
<quick_start>
PDF files are documents that contain text. To extract that text, we use a library called pdfplumber. First, import the library at the top of your Python file. Then, open the PDF file using the pdfplumber.open() method. This returns a PDF object. Access the pages attribute to get a list of pages. Each page has an extract_text() method that returns the text content...
</quick_start>
Don't optimize for one model. Find the balance that works across your target models.
- Simple task: Load SKILL.md only (~500 tokens)
- Medium task: Load SKILL.md + one reference (~1000 tokens)
- Complex task: Load SKILL.md + multiple references (~2000 tokens)
Without progressive disclosure, every task loads all content regardless of need.
See skill-structure.md for progressive disclosure patterns.
See workflows-and-validation.md for validation patterns.
- Stable first:
<objective>,<workflow>,<success_criteria>, reference links — content that never changes between turns - Dynamic last: Current date, session counters, user-specific state, computed values — content that may change each turn
The cache matches on exact prefix. If a dynamic value appears at byte 200 of the prompt, only the first 199 bytes get cached. If it appears at byte 5000, the first 4999 bytes get cached. Every stable byte moved before the first dynamic byte extends the cached prefix.
- Embedded timestamps:
Today is 2026-02-24in<objective>or early in the skill body - Non-deterministic ordering: Tool lists or option enumerations that change order between turns
- Mid-session tool changes: Adding or removing tools during a conversation
- Session-specific IDs: Request IDs, trace IDs, or counters placed before stable instructions
- Keep hook output minimal and stable where possible
- Document when a hook is expected to inject variable content
- Avoid designing hooks that prepend dynamic preambles to skill instructions
Cache-friendly — stable objective, dynamic content at end:
<objective>
Review code for security vulnerabilities.
</objective>
<workflow>
1. Read all modified files
2. Check OWASP Top 10
3. Report findings
</workflow>
<session_context>
Current date: 2026-02-24
Scan results last updated: 14:30:05 UTC
</session_context>