Skip to content
Stop 4 of 7

Practical skill development methodology

Building Production-Ready AI Tools with Claude Skills

Building Production-Ready AI Tools with Claude Skills

"Production-ready" means something specific. It means the skill works reliably across different contexts. It means failure modes are handled. It means someone else could use it without reading your mind.

Most AI skills never get there. They stay in the demo phase - impressive for one-off tasks, brittle when conditions change. The gap between "this works when I'm watching it" and "this works when I'm not" is where most skills die.

This is how you cross that gap.

What "Production-Ready" Actually Means

Let me be concrete about the standard we're aiming for:

Reliable: The skill produces consistent output quality across its intended use cases. Not perfect every time - that's impossible - but reliably good enough that you trust it without constant supervision.

Documented: Someone who didn't create the skill can understand what it does, when to use it, and how to invoke it. This includes you, six months from now, when you've forgotten the context.

Testable: You can verify the skill works. There's some way - automated or manual - to check that it produces acceptable output for representative inputs.

Maintainable: When Claude's capabilities change or your needs evolve, you can update the skill without starting from scratch. The structure supports iteration.

Composable: The skill plays nicely with other skills. It can be referenced, extended, or orchestrated as part of larger workflows.

This isn't perfection. It's engineering maturity - the difference between a prototype and something you'd deploy.

The Factory Metaphor

I think about skill development as a factory with stages.

Not because I love manufacturing analogies, but because the metaphor captures something important: there's a process, and each stage has different concerns.

Stage 1: Discovery - Noticing that you're doing something repeatedly that could be captured as a skill.

Stage 2: Specification - Defining what the skill should do, including edge cases and failure modes.

Stage 3: Implementation - Writing the skill file with clear instructions and examples.

Stage 4: Testing - Verifying the skill works across representative inputs.

Stage 5: Refinement - Iterating based on real-world usage.

Stage 6: Integration - Connecting the skill to your broader skill ecosystem.

Most people jump straight from noticing a pattern (Stage 1) to writing a skill file (Stage 3). They skip specification and testing. That's why most skills stay demos.

The factory process doesn't add much time. It adds structure that makes the result actually work.

Stage 1: Discovery - Recognizing Skill Opportunities

The best skills come from patterns you're already executing manually. You're not inventing new capabilities - you're capturing existing ones.

Signs that something should be a skill:

Repetition with variation. You do the same type of task repeatedly, but the specific content changes. Code review. Documentation generation. Test writing. Email drafting. The pattern is stable; the inputs vary.

Context switching cost. You find yourself repeatedly setting up the same context. Explaining your coding standards. Describing your documentation style. Every time you do this, you're paying a tax that a skill could eliminate.

Quality inconsistency. Some sessions produce better results than others for the same type of task, and you suspect the difference is in how well you set up the context. A skill standardizes the good setup.

Explanation overhead. You could explain how to do this task to someone else. The explanation is clear enough that you could write it down. If it's too fuzzy to articulate, it's not ready to be a skill.

The discovery question: "What am I doing repeatedly that I could teach Claude to do well?"

Stage 2: Specification - Defining the Skill

This is where most skill development fails. Not because specification is hard, but because people skip it.

A skill specification answers four questions:

What does the skill do?

Not vaguely. Specifically. "Code review" isn't a specification. "Review TypeScript code for our team's conventions, focusing on error handling, type safety, and test coverage" is a specification.

What inputs does it need?

What information must the user provide? What context does the skill assume? If the skill reviews code, does it need the code, the PR description, both? If it generates documentation, does it need the codebase context, the intended audience, the documentation format?

What output does it produce?

What form does the result take? A list of issues? A revised version of the input? A report with sections? Being explicit about output format helps both the skill implementation and the user's expectations.

What are the edge cases?

What inputs should the skill refuse to process? What failure modes need handling? What happens when the input is too large, too small, ambiguous, or outside the skill's domain?

Here's a specification example:

markdown
## Skill: TypeScript Code Review **Purpose:** Review TypeScript code for adherence to team conventions and common issues **Inputs required:** - Code to review (required) - PR description or context (optional, improves review quality) - Specific areas of focus (optional) **Output format:** - Summary of overall code quality - List of issues, each with: - Severity: critical / warning / suggestion - Location: file and line reference - Issue: what's wrong - Suggestion: how to fix - List of things done well (positive reinforcement) **Edge cases:** - Code too long (>1000 lines): split into sections, review each - Non-TypeScript code: refuse with explanation - No clear issues found: provide "looks good" summary with any minor suggestions

You don't need this level of detail for every skill. But you need enough clarity that you could explain the skill to someone else.

Stage 3: Implementation - Writing the Skill File

Now you write the SKILL.md file. This is the artifact that teaches Claude the capability.

The structure I use:

markdown
--- name: skill-name description: One-line description of what the skill does --- # Skill Name ## What This Skill Does [2-3 sentences describing the skill's purpose and output] ## When To Use This [Situations where this skill applies] ## How To Apply This Skill [Detailed instructions for executing the skill] ### Step 1: [First Step] [Instructions with examples] ### Step 2: [Second Step] [Instructions with examples] ## Examples ### Example 1: [Case Name] **Input:** [Representative input] **Output:** [Expected output showing desired quality] ### Example 2: [Different Case] [Another example showing skill versatility] ## What NOT To Do [Anti-patterns and common mistakes] ## Related Skills [Links to skills that work well with this one]

The key insight: a skill file isn't documentation. It's instructions. Write it the way you'd explain the task to a smart colleague who's never done it before.

Let me show a concrete implementation:

markdown
--- name: typescript-code-review description: Review TypeScript code for team conventions and common issues --- # TypeScript Code Review ## What This Skill Does Reviews TypeScript code against our team's conventions and best practices. Produces a structured review with issues categorized by severity, plus acknowledgment of things done well. ## When To Use This - Pull request reviews - Self-review before submitting code - Reviewing code from external sources before integration ## How To Apply This Skill ### Step 1: Understand the Context Before reviewing, understand what the code is trying to do. Read any PR description or comments. If the purpose is unclear, note that as a review finding - code should be self-explanatory or documented. ### Step 2: Check Type Safety Look for: - `any` types that could be more specific - Missing return types on functions - Type assertions (`as`) that bypass type checking - Implicit `any` from untyped dependencies Flag `any` as warning unless explicitly justified. Type assertions are warnings if the assertion could be wrong at runtime. ### Step 3: Review Error Handling Look for: - Unhandled promise rejections - Empty catch blocks - Errors swallowed without logging - Missing error boundaries in async operations Unhandled errors are critical. Empty catches are warnings. ### Step 4: Assess Test Coverage If tests are included or expected: - Are edge cases covered? - Are error paths tested? - Is the test code as clear as the production code? Missing tests for critical paths are warnings. Poor test quality is a suggestion. ### Step 5: Check Conventions Against our specific team conventions: - File naming: kebab-case - Function naming: camelCase - Constants: SCREAMING_SNAKE_CASE - Component files: PascalCase Convention violations are suggestions unless they cause confusion. ## Examples ### Example 1: Function with Type Issues **Input:** ```typescript async function fetchUser(id) { const response = await fetch(`/api/users/${id}`); return response.json(); }

Output:

  • Warning [line 1]: Function fetchUser missing parameter type for id
  • Warning [line 1]: Function fetchUser missing return type annotation
  • Warning [line 3]: response.json() returns any - consider typing the response
  • Suggestion: Add error handling for failed fetch

Example 2: Well-Written Code

Input:

typescript
interface User { id: string; name: string; email: string; } async function fetchUser(id: string): Promise<User | null> { try { const response = await fetch(`/api/users/${id}`); if (!response.ok) { console.error(`Failed to fetch user ${id}: ${response.status}`); return null; } return response.json() as User; } catch (error) { console.error(`Network error fetching user ${id}:`, error); return null; } }

Output: Summary: Code looks good overall. Proper typing, error handling, and clear structure.

  • Suggestion [line 15]: Consider using a typed fetch wrapper instead of type assertion

Things done well:

  • Explicit return type with null case
  • Error handling for both HTTP and network failures
  • Clear error messages with context
The examples section is crucial. It shows what "good" looks like. Without examples, the instructions are abstract. With examples, Claude has concrete patterns to match. ## Stage 4: Testing - Verifying the Skill Works Testing AI skills isn't like testing code. There's no assert statement that verifies output. But you can still be systematic. **Representative input testing:** Run the skill against 3-5 inputs that represent its intended use cases. Do the outputs meet your quality bar? Do they match the expected format? **Edge case testing:** What happens with unusual inputs? Empty input? Very large input? Input outside the skill's domain? The skill should fail gracefully, not unpredictably. **Regression testing:** If you change the skill, do previously-working cases still work? Keep a small set of "golden" input/output pairs. **Integration testing:** If the skill references other skills or is part of a workflow, test the combination. Skills that work in isolation sometimes conflict when composed. Here's a lightweight test checklist: ```markdown ## Skill Test Cases: typescript-code-review ### Basic Function - [ ] Input: Simple function with type issues - [ ] Expected: Identifies type issues, suggests fixes - [ ] Actual: ___ ### Complex Module - [ ] Input: 200-line module with mixed issues - [ ] Expected: Finds issues across categories, organized by severity - [ ] Actual: ___ ### Clean Code - [ ] Input: Well-written code with no obvious issues - [ ] Expected: "Looks good" summary with maybe minor suggestions - [ ] Actual: ___ ### Non-TypeScript - [ ] Input: Python code - [ ] Expected: Refuses politely, explains skill scope - [ ] Actual: ___ ### Empty Input - [ ] Input: No code provided - [ ] Expected: Requests code to review - [ ] Actual: ___

You don't need automated testing infrastructure. A document with test cases and a habit of running them is enough.

Stage 5: Refinement - Iterating Based on Usage

Your first implementation won't be perfect. That's fine - the factory process builds in iteration.

Track failure modes. When the skill produces bad output, note what went wrong. Was the input unusual? Was the instruction unclear? Was an edge case unhandled?

Improve instructions. Each failure mode suggests an instruction improvement. "The skill missed type issues in generic functions" becomes "Pay special attention to generic type parameters - they often hide type safety issues."

Add examples. When you find a case the skill handles well after refinement, add it to the examples section. The skill's example library should grow over time.

Simplify when possible. Sometimes instructions become too complex and the skill gets confused. If a skill isn't working despite detailed instructions, try simplifying. Remove edge cases. Focus on the core pattern. Build complexity back gradually.

Version your refinements. Keep a changelog in the skill file or a separate document. When you change instruction, note what changed and why. This helps when debugging regressions.

Refinement isn't a phase you complete. It's ongoing. Production skills evolve with use.

Stage 6: Integration - Connecting to Your Ecosystem

A skill in isolation has limited value. Connected to your ecosystem, it multiplies.

Reference other skills. Your code review skill might reference your team conventions skill. Your documentation skill might reference your writing style skill. Make these connections explicit.

markdown
## Related Skills This skill references: - `team-conventions`: Our coding standards and patterns - `typescript-patterns`: Common TypeScript idioms we use This skill is referenced by: - `pr-review-workflow`: Full PR review process - `code-quality-check`: Pre-commit verification

Create skill indices. Maintain a document that lists your skills, what they do, and when to use them. This becomes your skill menu.

Build workflows. Combine skills into sequences for complex tasks. A documentation workflow might chain: analyze-code -> generate-docs -> apply-writing-style -> format-for-publishing.

Share across projects. Skills that work well in one project often work in others. Your TypeScript review skill might apply to any TypeScript project. Keep these in a global location.

The ecosystem effect: each new skill makes existing skills more valuable, because composition creates capabilities none of them have alone.

The Complete Example: Building a Documentation Skill

Let me walk through the entire factory process for a real skill.

Discovery

I notice I'm generating documentation repeatedly. Each time, I explain our documentation standards, show examples of good docs, correct formatting issues. The pattern is clear: this should be a skill.

Specification

markdown
## Skill: API Documentation Generator **Purpose:** Generate API documentation from TypeScript interfaces and functions **Inputs:** - TypeScript code with exported interfaces/functions (required) - Module description (optional) - Target audience (optional, defaults to "developers") **Output:** - Markdown documentation with: - Module overview - Interface/type documentation with descriptions - Function documentation with parameters and return types - Usage examples **Edge cases:** - No exports: refuse, explain nothing to document - Complex generics: simplify explanation, link to type definitions - Internal implementation details: exclude unless specifically requested

Implementation

markdown
--- name: api-documentation description: Generate API documentation from TypeScript code --- # API Documentation Generator ## What This Skill Does Generates clear, consistent API documentation from TypeScript code. Produces Markdown output suitable for README files, documentation sites, or inline comments. ## How To Apply This Skill ### Step 1: Identify Public API Focus only on exported interfaces, types, and functions. Internal implementation details are out of scope unless specifically requested. ### Step 2: Document Each Element For interfaces and types: - State what the type represents - Document each property with type and description - Note optional vs required properties For functions: - State what the function does (one sentence) - Document parameters with types and descriptions - Document return type and what it represents - Note any side effects or thrown errors ### Step 3: Add Usage Examples For each major type or function, provide at least one usage example. Examples should be realistic and show correct usage patterns. ### Step 4: Format Consistently Use this structure: ```markdown ## TypeName Description of the type. | Property | Type | Required | Description | |----------|------|----------|-------------| | ... | ... | ... | ... | ### Usage \`\`\`typescript // Example code \`\`\`

Examples

[Include 2-3 examples of input code and expected documentation output]

### Testing Run the skill against: 1. Simple interface with 3-4 properties -> clean docs 2. Complex function with generics -> readable docs 3. Mixed module with types and functions -> organized output 4. Code with no exports -> appropriate refusal ### Refinement After first use, I notice the skill doesn't handle JSDoc comments. Add instruction: "If JSDoc comments exist on the code, incorporate them into documentation. Don't duplicate - use JSDoc as the source of truth for descriptions." ### Integration Link to `writing-style` skill for prose quality. Reference from `module-documentation-workflow` which chains: api-documentation -> example-generator -> formatting. ## What You Can Build From Here This factory process applies to any skill you want to create. The stages are the same whether you're building: - **Code generation skills** that produce code matching your patterns - **Review skills** that check work against your standards - **Analysis skills** that extract insights from data - **Communication skills** that draft messages in your voice - **Workflow skills** that orchestrate multi-step processes The investment in proper skill development pays off every time the skill is used. And skills compound - each one makes the next one easier to build and more powerful when composed. Start with one skill. Run it through the factory. Get it to production quality. Then build the next one. ## Related For the foundational thinking behind why artifacts and skills matter, see [Evaluating Claude Artifacts Strategy](/artifacts/claude-evaluating-claude-artifacts-strategy).