从踩坑到封装:手把手教你写一个 Claude Code Skill

4 阅读7分钟

最好的 Skill,从来不是「设计」出来的,而是从一个让你忍无可忍的重复劳动里长出来的。


先找到你的「忍无可忍」

在动笔之前,先问自己一个问题:

过去一个月里,有没有一件事,你让 AI 帮忙做了至少三次,而且每次都要把同样的话重新说一遍?

如果有,那就是一个 Skill 的种子。

它可能是:

  • 每周合并报表 PDF,每次都要告诉 AI 用哪个库、怎么处理页码
  • 每次写完代码让 AI review,都要重复「关注安全性和性能,别纠结格式」
  • 每次画图表都要说「用蓝色系,14 号标题,图例放右上角」

我的第一步建议是:先别写 Skill,先用 AI 裸做一次,边做边记录。

记什么?记三样东西:

  1. 你给了什么指令
  2. AI 犯了什么错
  3. 你纠正了什么

这些记录,就是你 Skill 里最有价值的原材料。


上手第一步:建一个最小的目录

Skill 的目录结构比你想的简单。最精简的版本,只需要一个文件:

my-skill/
└── SKILL.md    ← 唯一必需的文件,整个技能的入口

如果需要脚本支撑,再加一个 scripts/ 目录:

my-skill/
├── SKILL.md
├── scripts/
│   └── do_something.py
└── LICENSE.txt     ← 开源的话建议加,MIT 或 Apache 2.0

命名规范:文件夹名 = Skill 名,全小写,多单词用 - 连接。比如 weekly-report-generator 而不是 WeeklyReportGenerator

存放在哪?两个位置:

位置作用适用场景
项目根目录/.claude/skills/项目级,跟着 Git 走团队共享的领域规范
~/.claude/skills/用户级,跨项目生效个人通用的工作习惯

核心文件:SKILL.md 怎么写

SKILL.md 分两部分:前置元数据(YAML 头)和正文内容

前置元数据

---
name: my-skill                    # 技能名,和文件夹名一致
description: Use this skill when  # ← 最重要的字段!
  the user wants to [做什么事]
  involving [什么文件类型或场景].
  Triggers on: [触发关键词].
---

description 是 AI 判断是否激活这个 Skill 的唯一依据。 写得好,AI 自己就知道什么时候该用;写得模糊,你的 Skill 就永远不会被自动激活。

几个对比帮你感受一下好坏:

# ❌ 太模糊 —— AI 根本不知道什么时候该用
description: Helps with files.

# ❌ 范围过大 —— 所有数据处理都会触发
description: Use when the user wants to process data.

# ✅ 精准 —— AI 很清楚触发条件
description: Use this skill when the user wants to generate
  a weekly team report  collecting Git commits, Jira tickets,
  and meeting notes, then outputting a structured Markdown report.
  Triggers on: "weekly report", "周报", "standup report", "团队周报".

正文内容:一个拿来即用的模板

# [技能名称]

## Overview
一句话概括:这个技能做什么、适用于什么场景。
(这里可以包含更多关键词,辅助 AI 语义匹配)

## Quick Start
最小可运行示例。AI 读完这一段,就应该能上手处理最常见的场景。
(控制在 5 行代码以内)

## 常见任务

| 用户想做什么 | 用什么工具/方法 | 代码/命令 |
|------------|---------------|----------|
| ... | ... | ... |

## 常见陷阱 ⚠️
| 问题 | 原因 | 正确做法 |
|------|------|---------|
| 中文 PDF 提取乱码 | pypdf 对中文支持差 | 用 pdfplumber 替代 |
| ... | ... | ... |

## Quick Reference
| 任务 | 工具 | 示例命令 |
|------|------|---------|

## Next Steps
- 进阶用法见 reference.md
- 特定场景见 scenarios/xxx.md

这个模板的核心逻辑是:

Quick Start(让 AI 30 秒上手)
    ↓
常见任务(覆盖 80% 场景,按"用户意图"组织)
    ↓
常见陷阱(你踩过的坑,也是 Skill 最有价值的部分)
    ↓
速查表(快速索引)
    ↓
Next Steps(指向更深文档,渐进式加载)

关键设计:渐进式加载

如果你的 Skill 只有 100 行,全部都放 SKILL.md 没问题。

但如果它逐渐长大,到了一个 PDF Skill 那种体量,就需要渐进式加载

SKILL.md          ← 第一层:核心场景,自动加载(~100-200 行)
    │
    ├── reference.md    ← 第二层:进阶用法,按需加载
    ├── forms.md        ← 第三层:特定子场景,按需加载
    └── scripts/        ← 执行层:脚本工具,调用时不占上下文

为什么要这样设计? 因为每次加载 Skill 都会消耗 Token。你把 2000 行的 PDF 参考文档塞进 SKILL.md,AI 每次处理一个简单的合并请求都要先"读完一本书"——浪费且低效。

正确的做法是:SKILL.md 在末尾写 For advanced usage, see REFERENCE.md。AI 只在碰到复杂场景时,才去翻那本参考书。


最有价值的章节:常见陷阱

一个 Skill 里最宝贵的不是那些「正确的用法」——AI 本来就能从训练数据里找到这些。

最宝贵的是你踩过的、验证过的坑

因为这些坑:

  • 是你实际使用中发现的,不是 AI 训练数据里有的
  • 具有上下文特异性——在你的场景、你的工具版本下才会出现
  • 别人用你的 Skill 时一定会撞上,提前标注就能避免

举个例子,你帮团队写了一个「周报生成」的 Skill:

## 常见陷阱 ⚠️

- ⚠️ Jira API 返回的 issue 摘要可能包含 HTML 标签,
  需要用 `strip_tags()` 清理后再嵌入报告
- ⚠️ 如果某成员本周没有 commit,`git log --author` 会返回空,
  不要直接拼接,要检查后显示"本周无提交记录"
- ⚠️ 周一早上 9 点前运行,部分时区的 Git 记录可能还在上周,
  建议使用 `--since="last Monday 00:00:00"` 而非 `--since="7 days ago"`

这三条坑,每一条都是你在真实使用中流过的汗。当同事用同一个 Skill 时,这些坑已经被你填平了——这就是 Skills 的复利效应


什么时候需要 Scripts?什么时候不需要?

一个简单的判断标准:

场景需要 Scripts?原因
AI 直接能做的纯文本操作❌ 不需要指令就够了,AI 能自己写代码
涉及精确计算的流程✅ 需要确定性 > 概率性,脚本不会算错
涉及特定格式解析✅ 需要比如解析 PDF 表单结构,AI 容易漏字段
需要重复执行的标准化流程✅ 需要一次写好脚本,AI 只负责调用和解读结果

Scripts 的核心价值不是"让 AI 省事",而是"把不确定性变成确定性"。

写 Scripts 时注意:

  • 一个脚本只做一件事
  • 输入输出用 JSON 交接(AI 擅长读写 JSON)
  • 写上清晰的命令行用法,让 AI 能直接调用

写完后的第一次使用:观察、迭代

Skill 写完不是终点,而是起点。

第一次使用的时候,特别留意:

  1. AI 有没有自动激活? 如果没有,检查 description 是不是写得太模糊
  2. AI 有没有按照你预期的流程走? 如果跳过了某步,看看是不是 Quick Start 没覆盖
  3. 有没有发现新的坑? 立刻补进「常见陷阱」

一个好 Skill 是用出来的,不是写出来的。我建议维护一个简单的版本记录:

## Changelog
- v1.2: 新增"中文 PDF 提取乱码"陷阱
- v1.1: 补充 pdftotext 命令行工具对比
- v1.0: 初始版本,覆盖合并、拆分、OCR 三个场景

一个完整的案例:从脚本到 Skill

假设你经常需要把 Markdown 文件转成带公司样式的 PDF。你写了一个 Python 脚本 md2pdf.py 来处理这件事。

把它变成 Skill 的过程:

步骤 1:创建目录
    .claude/skills/md2pdf/
    ├── SKILL.md
    └── scripts/
        └── md2pdf.py

步骤 2:写 SKILL.md
    ---
    name: md2pdf
    description: Convert Markdown files to PDF with company
      branding. Triggers on: "生成 PDF", "导出 PDF", "转 PDF",
      "markdown to pdf".
    ---

    ## Quick Start
    使用 scripts/md2pdf.py:
    python scripts/md2pdf.py input.md output.pdf

    ## 常见陷阱
    - 图片路径必须是相对于 Markdown 文件的相对路径
    - 中文字体依赖系统安装的 Noto Sans CJK

步骤 3:试一次,迭代
    你:"帮我把周报转成 PDF"
    AI:(自动激活 md2pdf Skill,调用脚本)
    → 如果触发不了,优化 description
    → 如果遇到新坑,补充进陷阱列表

这篇文章的核心

  1. 找到痛点再写 Skill —— 不为写而写,先做一次,边做边记录
  2. description 是最关键的字段 —— AI 就靠它判断是否激活
  3. Quick Start + 常见任务 + 常见陷阱 + 速查表 —— 黄金四段结构
  4. 渐进式加载是省 Token 的关键 —— 入口轻,按需深入
  5. 把坑写进去 —— 这是你的 Skill 比官方文档更有价值的地方
  6. Skill 是用出来的,不是写出来的 —— 每次用完都迭代