YAML Agent Format
Overview
Why YAML for Agents?
YAML provides an alternative format for defining Claude Code agents with several advantages:
Benefits:
- •Machine-parseable: Easy to validate, transform, and generate programmatically
- •Less verbose: No markdown headers, cleaner structure
- •Schema validation: Strong typing with JSON Schema or Zod
- •Tooling support: Better IDE autocomplete, linting, formatting
- •Data-first: Natural for configuration management
Trade-offs:
- •Less readable: Markdown is better for long-form documentation
- •Indentation-sensitive: YAML whitespace can be error-prone
- •No rich formatting: Can't use markdown tables, code blocks in descriptions
When to Use YAML vs Markdown
Use YAML when:
- •Generating agents programmatically
- •Agent definitions are data-heavy (many examples, tools, rules)
- •You need strong schema validation
- •Agent is simple and concise
- •Working in automation/CI pipelines
Use Markdown when:
- •Agent has extensive documentation needs
- •You want rich formatting (tables, diagrams, code examples)
- •Agent is tutorial-like with explanations
- •Human readability is priority
- •Agent includes narrative instructions
Compatibility with Claude Code
YAML agents are fully compatible with Claude Code:
- •Placed in
agents/directory with.agent.yamlextension - •Registered in
plugin.jsonidentically to markdown agents - •Loaded and executed the same way
- •Can mix YAML and markdown agents in same plugin
YAML Agent Schema
Complete Schema Definition
# Required fields
name: string # Agent name (kebab-case)
description: string # Brief description (1-2 sentences)
version: string # Semver version (e.g., "1.0.0")
# Optional but recommended
role:
identity: string # Agent's role/identity
expertise: string[] # List of expertise areas
mission: string # Primary mission statement
tools: string[] # Available tools (Read, Write, Edit, Bash, etc.)
instructions:
constraints: string[] # Critical constraints/rules
workflow: # Step-by-step workflow
- phase: string # Phase name
objective: string # Phase objective
steps: string[] # List of steps
knowledge: # Knowledge base entries
- topic: string # Knowledge topic
content: string # Knowledge content
examples: # Usage examples
- name: string # Example name
user: string # User message
assistant: string # Assistant response
formatting:
style: string # Communication style
templates: # Output templates
success: string
error: string
Field Details
Required Fields:
- •
name: Agent identifier (must match filename without extension) - •
description: Shown in agent list, used for agent selection - •
version: Semver for tracking changes
Role Section:
- •
identity: Who the agent is (e.g., "React Component Builder") - •
expertise: Array of skills (e.g., ["React 19", "TypeScript", "Testing"]) - •
mission: What the agent does (e.g., "Build production-ready React components")
Tools Array: Standard Claude Code tools:
tools: - Read - Write - Edit - Bash - Glob - Grep
Workflow Structure:
instructions:
workflow:
- phase: "Phase 1: Discovery"
objective: "Find relevant files"
steps:
- "Use Glob to find components"
- "Use Grep to search for patterns"
- "Read existing implementations"
YAML vs Markdown Comparison
Simple Agent: Side-by-Side
Markdown (simple-agent.md):
--- name: simple-agent description: A simple example agent version: 1.0.0 --- <role> <identity>Code Formatter</identity> <mission>Format code files according to standards</mission> </role> <instructions> 1. Read the file 2. Format using appropriate tool 3. Write back to file </instructions>
YAML (simple-agent.agent.yaml):
name: simple-agent
description: A simple example agent
version: 1.0.0
role:
identity: Code Formatter
mission: Format code files according to standards
instructions:
workflow:
- phase: Format
steps:
- Read the file
- Format using appropriate tool
- Write back to file
Complex Agent: Side-by-Side
Markdown (react-builder.md):
---
name: react-builder
description: Build React components with tests
version: 2.1.0
---
<role>
<identity>React Component Builder</identity>
<expertise>
- React 19 with TypeScript
- React Testing Library
- Component patterns
</expertise>
</role>
<instructions>
<workflow>
<phase number="1" name="Create Component">
<steps>
<step>Create component file with TypeScript types</step>
<step>Implement component logic</step>
</steps>
</phase>
</workflow>
</instructions>
<examples>
<example name="Button Component">
<user>Create a button component</user>
<assistant>I'll create Button.tsx with props...</assistant>
</example>
</examples>
YAML (react-builder.agent.yaml):
name: react-builder
description: Build React components with tests
version: 2.1.0
role:
identity: React Component Builder
expertise:
- React 19 with TypeScript
- React Testing Library
- Component patterns
instructions:
workflow:
- phase: "Phase 1: Create Component"
steps:
- Create component file with TypeScript types
- Implement component logic
examples:
- name: Button Component
user: Create a button component
assistant: I'll create Button.tsx with props...
Key Difference: YAML is ~30% shorter for structured data.
Conversion Patterns
Markdown to YAML Conversion
Conversion Rules:
- •Extract frontmatter YAML as base
- •Parse XML-style tags to nested objects
- •Convert numbered lists to arrays
- •Flatten markdown formatting to plain strings
Example Conversion:
Input (Markdown):
---
name: test-agent
version: 1.0.0
---
<role>
<identity>Tester</identity>
<expertise>
- Unit testing
- Integration testing
</expertise>
</role>
<instructions>
<constraints>
- Always write tests first
- Use TypeScript
</constraints>
</instructions>
Output (YAML):
name: test-agent
version: 1.0.0
role:
identity: Tester
expertise:
- Unit testing
- Integration testing
instructions:
constraints:
- Always write tests first
- Use TypeScript
YAML to Markdown Conversion
Conversion Rules:
- •Create frontmatter from top-level fields
- •Convert nested objects to XML-style tags
- •Convert arrays to markdown lists
- •Wrap in appropriate markdown structure
Example Conversion:
Input (YAML):
name: docs-agent version: 1.0.0 role: identity: Documentation Writer mission: Create comprehensive docs
Output (Markdown):
--- name: docs-agent version: 1.0.0 --- <role> <identity>Documentation Writer</identity> <mission>Create comprehensive docs</mission> </role>
Automated Conversion Tools
TypeScript Conversion Function:
import yaml from 'yaml';
import { z } from 'zod';
// Convert markdown agent to YAML
function markdownToYaml(markdownPath: string): string {
const content = fs.readFileSync(markdownPath, 'utf-8');
// Extract frontmatter
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
const frontmatter = yaml.parse(frontmatterMatch?.[1] || '');
// Parse XML-like tags
const role = extractRoleSection(content);
const instructions = extractInstructionsSection(content);
const agent = {
...frontmatter,
role,
instructions
};
return yaml.stringify(agent);
}
// Convert YAML agent to markdown
function yamlToMarkdown(yamlPath: string): string {
const content = fs.readFileSync(yamlPath, 'utf-8');
const agent = yaml.parse(content);
const { name, description, version, role, instructions, ...rest } = agent;
let md = `---\n${yaml.stringify({ name, description, version })}---\n\n`;
if (role) {
md += `<role>\n${objectToXml(role)}</role>\n\n`;
}
if (instructions) {
md += `<instructions>\n${objectToXml(instructions)}</instructions>\n\n`;
}
return md;
}
Validation
Schema Validation with Zod
Define Zod Schema:
import { z } from 'zod';
const AgentSchema = z.object({
name: z.string().regex(/^[a-z0-9-]+$/),
description: z.string().min(10).max(200),
version: z.string().regex(/^\d+\.\d+\.\d+$/),
role: z.object({
identity: z.string(),
expertise: z.array(z.string()).optional(),
mission: z.string()
}).optional(),
tools: z.array(z.enum([
'Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep'
])).optional(),
instructions: z.object({
constraints: z.array(z.string()).optional(),
workflow: z.array(z.object({
phase: z.string(),
objective: z.string().optional(),
steps: z.array(z.string())
})).optional()
}).optional(),
examples: z.array(z.object({
name: z.string(),
user: z.string(),
assistant: z.string()
})).optional()
});
// Validate YAML agent
function validateAgent(yamlPath: string): boolean {
const content = fs.readFileSync(yamlPath, 'utf-8');
const agent = yaml.parse(content);
try {
AgentSchema.parse(agent);
return true;
} catch (error) {
console.error('Validation failed:', error);
return false;
}
}
Common Validation Errors
1. Invalid Name Format:
# BAD name: "My Agent" # Spaces not allowed # GOOD name: my-agent
2. Missing Required Fields:
# BAD - missing version name: test-agent description: Test agent # GOOD name: test-agent description: Test agent version: 1.0.0
3. Invalid Semver:
# BAD version: "1.0" # Not semver # GOOD version: "1.0.0"
4. Invalid Tool Names:
# BAD tools: - ReadFile # Wrong name # GOOD tools: - Read - Write
5. Incorrect Array Format:
# BAD expertise: Unit testing, Integration testing # GOOD expertise: - Unit testing - Integration testing
Validation Tools
CLI Validator:
# Create validation script
cat > validate-agent.ts <<'EOF'
#!/usr/bin/env bun
import { AgentSchema } from './agent-schema';
import yaml from 'yaml';
const file = process.argv[2];
const content = await Bun.file(file).text();
const agent = yaml.parse(content);
const result = AgentSchema.safeParse(agent);
if (result.success) {
console.log('✓ Valid agent definition');
} else {
console.error('✗ Validation errors:');
result.error.issues.forEach(issue => {
console.error(` - ${issue.path.join('.')}: ${issue.message}`);
});
process.exit(1);
}
EOF
chmod +x validate-agent.ts
# Usage
./validate-agent.ts agents/my-agent.agent.yaml
File Naming
YAML Agent Naming Convention
Format: {agent-name}.agent.yaml
Examples:
- •
code-reviewer.agent.yaml - •
react-builder.agent.yaml - •
test-generator.agent.yaml
Rules:
- •Use
.agent.yamlextension (not.yamlor.yml) - •Name must match the
namefield in YAML - •Use kebab-case for names
- •Place in
agents/directory
Directory Structure
plugin-name/ ├── agents/ │ ├── builder.agent.yaml # YAML agent │ ├── reviewer.md # Markdown agent │ └── tester.agent.yaml # YAML agent ├── plugin.json └── README.md
Plugin.json Registration
Register YAML agents identically to markdown agents:
{
"name": "my-plugin",
"version": "1.0.0",
"agents": [
{
"name": "builder",
"file": "agents/builder.agent.yaml",
"description": "Build components"
},
{
"name": "reviewer",
"file": "agents/reviewer.md",
"description": "Review code"
}
]
}
Note: Claude Code detects format from file extension.
Best Practices
Do
- •Use YAML for data-heavy agents with many examples
- •Validate YAML syntax before committing
- •Keep descriptions concise (YAML has no rich formatting)
- •Use consistent indentation (2 spaces recommended)
- •Add comments for complex sections
- •Version agents with semver
- •Test agent loading after creation
Don't
- •Don't mix tabs and spaces in YAML
- •Don't use YAML for agents with extensive documentation
- •Don't forget required fields (name, description, version)
- •Don't use complex YAML features (anchors, aliases) - keep it simple
- •Don't embed long code examples (use markdown for that)
- •Don't use special characters in names without quoting
When YAML is Better
YAML excels for:
- •Agents with many structured examples
- •Programmatic agent generation
- •Configuration-heavy agents
- •Agents used in automation
- •Simple, data-focused agents
- •Agents needing strong validation
Example use case:
# API endpoint agent with 20+ examples
name: api-endpoint-generator
examples:
- name: GET endpoint
user: Create GET /users
assistant: "..."
- name: POST endpoint
user: Create POST /users
assistant: "..."
# 18 more examples...
When Markdown is Better
Markdown excels for:
- •Agents with extensive tutorials
- •Agents with rich formatting needs
- •Agents requiring code examples with syntax highlighting
- •Agents with diagrams or tables
- •Human-focused documentation
- •Narrative instructions
Example use case:
## Complex Workflow Explanation This agent follows a sophisticated workflow... | Phase | Duration | Tools | |-------|----------|-------| | Discovery | 5 min | Grep, Glob | ```typescript // Example implementation const component = buildComponent();
---
## Examples
### Example 1: Simple Code Formatter
**File:** `agents/formatter.agent.yaml`
```yaml
name: formatter
description: Format code files according to project standards
version: 1.0.0
role:
identity: Code Formatter
mission: Ensure consistent code formatting across the project
tools:
- Read
- Write
- Bash
instructions:
constraints:
- Always backup files before formatting
- Use project-specific formatter configuration
- Preserve file permissions
workflow:
- phase: Read and Analyze
objective: Understand file and detect language
steps:
- Read the target file
- Detect programming language from extension
- Check for project formatter config
- phase: Format
objective: Apply formatting
steps:
- Run appropriate formatter (prettier, black, gofmt)
- Capture formatted output
- phase: Write
objective: Save formatted file
steps:
- Write formatted content back to file
- Report formatting changes
formatting:
style: Concise and direct
templates:
success: "Formatted {file} ({changes} changes)"
error: "Failed to format {file}: {reason}"
Example 2: Complex React Component Builder
File: agents/react-builder.agent.yaml
name: react-builder
description: Build production-ready React components with TypeScript and tests
version: 2.1.0
role:
identity: React Component Architect
expertise:
- React 19 with TypeScript
- React Testing Library
- Component composition patterns
- Accessibility (a11y)
- Performance optimization
mission: Create maintainable, tested, accessible React components
tools:
- Read
- Write
- Edit
- Bash
- Glob
- Grep
instructions:
constraints:
- Always use TypeScript strict mode
- Export component as named export
- Include JSDoc comments for props
- Follow project naming conventions
- Add accessibility attributes
workflow:
- phase: "Phase 1: Discovery"
objective: Understand existing patterns
steps:
- Use Glob to find similar components
- Use Grep to search for patterns
- Read component examples
- phase: "Phase 2: Create Component"
objective: Write component file
steps:
- Define TypeScript props interface
- Implement component with hooks
- Add error boundaries if needed
- Include accessibility attributes
- phase: "Phase 3: Create Tests"
objective: Write comprehensive tests
steps:
- Create test file with RTL
- Test rendering
- Test user interactions
- Test accessibility
- phase: "Phase 4: Validate"
objective: Run quality checks
steps:
- Run TypeScript compiler
- Run tests
- Check formatting
examples:
- name: Button Component
user: Create a button component with loading state
assistant: |
I'll create a Button component with TypeScript props and loading state.
Creating Button.tsx with type-safe props and Button.test.tsx with RTL tests.
- name: Form Input
user: Build a form input with validation
assistant: |
Creating FormInput component with validation, error display, and accessibility.
Including tests for validation logic and error states.
formatting:
style: Professional and detailed
templates:
success: |
Component created successfully:
- {component}.tsx ({lines} lines)
- {component}.test.tsx ({tests} tests)
All quality checks passed.
Example 3: Conversion from Markdown
Before (Markdown):
--- name: test-generator description: Generate tests for existing code version: 1.0.0 --- <role> <identity>Test Generator</identity> </role> <instructions> 1. Read source file 2. Generate test cases 3. Write test file </instructions>
After (YAML):
name: test-generator
description: Generate tests for existing code
version: 1.0.0
role:
identity: Test Generator
instructions:
workflow:
- phase: Generate Tests
steps:
- Read source file
- Generate test cases
- Write test file
Summary
YAML agents provide a cleaner, more structured alternative to markdown for agent definitions:
Key Benefits:
- •Machine-parseable with schema validation
- •Less verbose for structured data
- •Better tooling support (autocomplete, linting)
- •Ideal for programmatic generation
Use YAML when:
- •Agent is data-heavy (many examples, rules)
- •You need strong validation
- •Agent is simple and concise
- •Working in automation pipelines
Use Markdown when:
- •Agent has extensive documentation
- •You need rich formatting
- •Human readability is priority
Both formats are fully compatible with Claude Code and can be mixed within the same plugin.