--- name: yaml-agent-format description: YAML format for Claude Code agent definitions as alternative to markdown. Use when creating agents with YAML, converting markdown agents to YAML, or validating YAML agent schemas. Trigger keywords - "YAML agent", "agent YAML", "YAML format", "agent schema", "YAML definition", "convert to YAML". version: 0.1.0 tags: [agentdev, yaml, agent, format, schema, definition] keywords: [yaml, agent, format, schema, definition, conversion, validation, frontmatter] plugin: agentdev updated: 2026-01-28 --- # 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.yaml` extension - Registered in `plugin.json` identically to markdown agents - Loaded and executed the same way - Can mix YAML and markdown agents in same plugin --- ## YAML Agent Schema ### Complete Schema Definition ```yaml # 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: ```yaml tools: - Read - Write - Edit - Bash - Glob - Grep ``` **Workflow Structure:** ```yaml 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`):** ```markdown --- name: simple-agent description: A simple example agent version: 1.0.0 --- Code Formatter Format code files according to standards 1. Read the file 2. Format using appropriate tool 3. Write back to file ``` **YAML (`simple-agent.agent.yaml`):** ```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`):** ```markdown --- name: react-builder description: Build React components with tests version: 2.1.0 --- React Component Builder - React 19 with TypeScript - React Testing Library - Component patterns Create component file with TypeScript types Implement component logic Create a button component I'll create Button.tsx with props... ``` **YAML (`react-builder.agent.yaml`):** ```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:** 1. Extract frontmatter YAML as base 2. Parse XML-style tags to nested objects 3. Convert numbered lists to arrays 4. Flatten markdown formatting to plain strings **Example Conversion:** **Input (Markdown):** ```markdown --- name: test-agent version: 1.0.0 --- Tester - Unit testing - Integration testing - Always write tests first - Use TypeScript ``` **Output (YAML):** ```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:** 1. Create frontmatter from top-level fields 2. Convert nested objects to XML-style tags 3. Convert arrays to markdown lists 4. Wrap in appropriate markdown structure **Example Conversion:** **Input (YAML):** ```yaml name: docs-agent version: 1.0.0 role: identity: Documentation Writer mission: Create comprehensive docs ``` **Output (Markdown):** ```markdown --- name: docs-agent version: 1.0.0 --- Documentation Writer Create comprehensive docs ``` ### Automated Conversion Tools **TypeScript Conversion Function:** ```typescript 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 += `\n${objectToXml(role)}\n\n`; } if (instructions) { md += `\n${objectToXml(instructions)}\n\n`; } return md; } ``` --- ## Validation ### Schema Validation with Zod **Define Zod Schema:** ```typescript 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:** ```yaml # BAD name: "My Agent" # Spaces not allowed # GOOD name: my-agent ``` **2. Missing Required Fields:** ```yaml # BAD - missing version name: test-agent description: Test agent # GOOD name: test-agent description: Test agent version: 1.0.0 ``` **3. Invalid Semver:** ```yaml # BAD version: "1.0" # Not semver # GOOD version: "1.0.0" ``` **4. Invalid Tool Names:** ```yaml # BAD tools: - ReadFile # Wrong name # GOOD tools: - Read - Write ``` **5. Incorrect Array Format:** ```yaml # BAD expertise: Unit testing, Integration testing # GOOD expertise: - Unit testing - Integration testing ``` ### Validation Tools **CLI Validator:** ```bash # 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.yaml` extension (not `.yaml` or `.yml`) - Name must match the `name` field 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:** ```json { "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:** ```yaml # 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:** ```markdown ## 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` ```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):** ```markdown --- name: test-generator description: Generate tests for existing code version: 1.0.0 --- Test Generator 1. Read source file 2. Generate test cases 3. Write test file ``` **After (YAML):** ```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.