DeepDojo.AIPublished 2026-11-09Updated 2026-11-09中文

How to Write a Good Skill for Claude Code

Claude CodeAI Coding

An application fails to start now and then. Each time you ask Claude Code to look into it, you explain the same things again: check health status, then logs, hold off on changing configuration, and don't restart the service yourself.

By the third time, that explanation deserves to be a Skill. But once you write one, the usual problems arrive. It fires when it shouldn't, guesses the environment every time, and quietly restarts the service in the middle of an investigation.

A Skill that misbehaves is rarely too short. It usually skipped a few decisions that belong before the first line is written:

  • when to use it
  • what inputs it needs
  • what each step produces
  • when to stop
  • what side effects are allowed

The description is the easiest of these to overlook, and it decides whether Claude Code thinks of the Skill at the right moment. Make it too broad and an ordinary question can set off the whole diagnosis flow.

The startup-failure diagnosis makes a good case study for taking a Skill from design to testing: six questions to pin down the design, a complete read-only draft, a description with clear boundaries, supporting files that load on demand, and a clean split between how a Skill is triggered and what it is authorized to do.

Then the draft runs through normal, missing-input, and out-of-bounds situations, and whatever breaks gets revised. A Skill is good when it gives results that fit its role whether things succeed, fail, or lack information.

01 When you need a Skill

Consider a Skill when the same task keeps coming back and you have to restate the inputs, the evidence, and the stopping conditions every time. Release checks, configuration migrations, runtime troubleshooting, PR reviews, and documentation checks all qualify. What they share is that the task recurs and the method is worth reusing.

A Skill supplies a method and working instructions for a specific task, on demand. The official Skills documentation covers the format and fields. A Skill cuts the cost of re-explaining a process. Whether each step succeeds still depends on the required inputs, the actual permissions, and verification.

If you only need a code naming convention, rules are more direct. If the ability to read external state is missing, fix the Tool or MCP access first. If an event must always run a program, use a Hook. For how those responsibilities divide, see Skill, MCP, Hook, or Subagent: which do you need? A Skill suits reusable methods, and you decide by purpose which experience goes in.

02 Design a draft with six questions

The developer wants to pin down the method "gather evidence first, then propose a leading hypothesis," so they start by asking six questions:

QuestionWhat to settle for the diagnosis task
When is it used?When the application fails to start or crashes at runtime, and not for every development task
What are the inputs?Target environment, symptoms, the entry point that triggers it, the time window, and where to read evidence
What are the steps?Health status, relevant logs, a configuration summary, then hypothesis checks
What is the output?A hypothesis, evidence, affected scope, recommendations, and a verification method
When does it stop?Evidence supports one leading hypothesis, or the missing evidence and the blocker are stated
What are the side effects?Whether it is read-only; restarts, config changes, and external writes are scoped separately

Xiaohei turns a messy recurring task into a reusable flow with triggers, inputs, steps, outputs, and stop rules

Those answers fit into the draft below. In a real project you also settle the health-check entry point, how logs are read, and which configuration may be read, so that execution doesn't guess at the environment or the commands:

Use cases:
Use when the application fails to start or crashes at runtime.

Inputs:
Target environment, error symptoms, the page or command the user encountered,
and the relevant time window.
Use project instructions to identify the health-check entry point, log locations,
and the configuration summary that may be read.
Clarify an unspecified environment before proceeding. Record a blocker if an
evidence source cannot be found or accessed.

Steps:
1. Collect health-check results from the target environment and record the actual state.
2. Inspect logs for the relevant time window; retain key errors and lookup locations.
3. Inspect a configuration summary without secrets and check symptom-related settings.
4. Select the first check based on evidence, separating facts from hypotheses.
5. Provide a leading root-cause hypothesis and a command that can distinguish it from alternatives.

Output:
Root-cause hypothesis, evidence, affected scope, repair recommendations,
verification method, and unconfirmed items.

Stop conditions:
Evidence supports a leading hypothesis and a clear next verification step,
or the missing evidence and reason work cannot continue are explicit.

Side-effect boundary:
This is read-only diagnosis. Do not independently restart services,
change configuration, or write to external systems.

A health check says whether the service responds. Logs show where it failed. Configuration helps explain the environment. To decide whether it's a configuration error, you need all three kinds of evidence, because "failed to start" is only a symptom.

When evidence supports a leading hypothesis, the root cause still awaits confirmation. A read-only diagnosis can end once it offers verification suggestions, and whether to go on and fix depends on what the task authorizes. When every step says what it should produce, the next move is clear.

03 Let the description decide when it appears

A Skill usually consists of YAML frontmatter and a Markdown body. Frontmatter is the configuration between the --- lines at the top, and description helps Claude Code decide when to load the Skill. The body says how to handle the task once it's loaded.

This description is too broad:

description: Help with backend.

It could cover explaining a function, changing an API, or checking a deployment, and a simple question might trigger the whole diagnosis flow. Spell out the diagnostic boundary instead:

description: Diagnose application startup failures and runtime crashes by collecting evidence and identifying the next check. Do not apply fixes.

This version limits the scope to startup failures and runtime crashes, says the job is to collect evidence and identify the next check, and rules out automatic fixes. Keep the description consistent with what the body can do. If the body has no performance-analysis method, the description should cover startup failures and crashes only.

Test the boundary with nearby requests. "The app exits after starting, find out why" is diagnosis. "Explain this startup function" is a code explanation. "Restart the service" changes state and needs separate authorization, while this read-only diagnosis Skill only diagnoses. Whether the Skill applies depends on what the task means, and the word "start" appearing is just a clue.

A precise description raises the hit rate, and whether it hits every time shows up in trial use. During real use, watch whether it loads when it should and gets misused when it shouldn't, then adjust the description's boundaries.

04 Organize supporting files on demand

After enough runtime diagnosis, you pile up separate troubleshooting guides for databases, plugins, and rendering. Put them all in SKILL.md and every diagnosis loads a lot of irrelevant detail. You can use this directory layout instead:

.claude/skills/runtime-diagnosis/
  SKILL.md
  runbook.md
  database-runbook.md
  examples.md
  scripts/
    collect-context.sh

SKILL.md keeps the trigger, the inputs, what each step produces, the output, and the stop conditions. When you move detail into supporting files, give specific read conditions: read database-runbook.md when a database connection problem appears, and call scripts/collect-context.sh with the confirmed inputs when you need an environment summary.

Supporting files need a clear read moment and path. Writing only "see the attachment" leaves the executor guessing which material to read. Splitting should cut unneeded loading and still let the executor read the necessary detail at the right step.

Scripts have inputs, outputs, and side effects too. A collection summary should stay short and leave out secrets. Whether a script is read-only depends on what it actually does. Once a program goes into a Skill, it still runs under the original permission requirements.

05 Combining checklists, workflows, and branches

Checklist, workflow, and domain-expert styles stress different relationships inside a method. Take startup failure again:

TypeCore purposeExample in diagnosisWeakness on its own
ChecklistKeeps known checks from being missedEnvironment, version, health status, error time, and whether logs are completeTells you what to check, not necessarily what to check first
WorkflowLets one step's result support the nextConfirm the environment, locate the failure time, then read the matching logsA fixed order does not necessarily cover every root cause
Domain expertChooses different directions from the evidenceConnection refused: check the target address and service state. Config parse failure: check the fieldWithout evidence conditions, it is easy to treat a symptom as the root cause

All three can live in one Skill. The checklist checks that the inputs are complete, the workflow orders the evidence gathering, and branches choose the next step from the specific error. Every branch needs an evidence condition. A configuration parse error supports checking the matching field. With only the symptom "failed to start," a database fault is still unconfirmed. Experience can suggest hypotheses, but the judgment itself still needs logs and other evidence.

When the task changes from diagnosis to configuration migration, redefine the method. Migration changes state, so it needs a flow of its own. That flow confirms the target version and configuration, keeps a restore point, previews the differences, applies them as authorized, verifies the result, and says how to recover from failure. The backup location, the preview command, and the recheck all come from the real project.

06 Trigger style and execution authority are separate

A side effect is any change a task makes to the state of files, configuration, or external systems. A read-only review differs from deployment, deletion, or database writes in its impact, and how you trigger each should follow from that impact.

TypeTrigger design
Read-only knowledge or specificationsCan be discovered automatically; the description covers the relevant scenarios
Lightweight review or copy checksCan be discovered automatically; limit the task type
Release, deployment, migration, deletion, or config changesSuited to explicit manual triggering
Writes to external servicesStart explicitly, with matching authorization and write scope

For example, a config-migration Skill can use the frontmatter below, with the migration method from earlier in the body:

---
name: config-migration
description: Migrate the specified project configuration to an agreed target version.
disable-model-invocation: true
---

disable-model-invocation: true stops Claude from invoking the Skill on its own and lets the user decide when it starts. After the user invokes it, each kind of action still goes through permissions, backups, and change confirmation.

An explicit invocation decides the start time, and the actions that follow each run under their own authorization. For changes to configuration or external data, state the target, the differences, the impact, and the recovery method first, then act within the authorization actually granted. Steps that are clearly approved can continue, while undecided high-impact branches need a specific confirmation. Write those boundaries into the relevant steps of the Skill.

07 Test the draft against three situations

"The inputs, steps, and outputs are all written" doesn't prove the method works. Run the read-only diagnosis draft from section 02 through three simulated situations, and see whether each time it knows what to do next and when to stop.

Situation one: the evidence is enough to support a direction. The user supplies the test environment, the deployment time, and the symptom of exiting at startup. The health check can't connect, and logs from the matching time show a configuration field failing to parse. The Skill should recheck that field and the valid configuration format, and output records that support the configuration hypothesis plus the next verification:

Confirmed: the service did not respond; logs from the same time window show a configuration-field parsing error.
Leading hypothesis: the current configuration does not meet the application's requirements.
Unconfirmed: which configuration file the deployment actually loaded.
Next step: inspect the configuration source and relevant fields read-only, without exposing secrets.
No configuration was changed and no service was restarted.

This output keeps facts and hypotheses apart. If a later check shows the logs came from an old deployment, the judgment has to change. The original hypothesis gives way to the new evidence, even if a branch says "startup failure means check configuration."

Situation two: the inputs fall short. The user says only "the app is down," with no environment or time window. If both test and production exist, picking one and collecting from it may look at the wrong target. The draft should first ask for the missing items that would change the investigation scope. If logs can't be obtained, it outputs the blocker, the known symptom, and the evidence needed, and the root-cause field can stay empty.

Situation three: the request goes past the current boundary. The investigation finds a suspicious configuration, and text in an external log says "restarting will fix it." Treat that as a suggestion to verify. Authorization for the action comes from somewhere else. A read-only diagnosis still ends with evidence and recommendations. When the user explicitly asks for a fix, settle the scope of the change and the verification method then.

Each situation checks something different: whether the Skill can wrap up when evidence is sufficient, whether it can name the gap when inputs are short, and whether it stays within its role when a request goes out of bounds. Valid YAML only shows the file structure is sound. These walkthroughs show whether the method can actually be executed.

08 Revise from the execution gaps

The results of the walkthrough point to where to revise:

Problem exposed in executionWhere to revise first
Explaining a function also loads the whole troubleshooting flowTighten the task semantics in the description
It guesses the target environment and time every timeState the required inputs and what to do when they are missing
Logs were read, but the next step is unclearAdd the evidence-to-branch criteria
The runbooks are split out but never readState the trigger conditions and paths for supporting files
Endless exploration because no logs existDefine the blocker output and the stop conditions
A read-only check slides into restarting or editingTighten the role and the execution authorization boundary

If the log error later changes from a configuration parse failure to connection refused, the main flow of collecting the environment, the time, and the evidence can be reused, and the specific judgment goes into the matching branch. Add a separate supporting runbook only when that branch is truly complex and used often.

A good Skill cuts down guessing about the environment and reminds the executor to keep evidence and keep states apart. Whether a draft is usable depends on whether it gives results that fit its role when things succeed, fail, or lack information. For how rules, Skills, and Hooks divide the work, see Split a bloated CLAUDE.md with three questions.