如何实现一个 Claude Code Skill:从底层原理到生产实践

0 阅读23分钟

导读:这篇文章不只是教你写一个 SKILL.md 文件——而是带你深入 Claude Code Skill 系统的内核,搞清楚 Skill 是怎么被发现的、怎么被触发的、上下文是怎么传递的、执行引擎又是怎么调度工具链的。读完之后,你将具备从零设计、开发、测试、优化到发布一个生产级 Skill 的完整能力。


一、Skill 到底是什么?

Claude Code Skill 不是传统意义上的"插件"或"扩展"。它本质上是一组结构化的 Prompt 指令,配合脚本、模板、参考文档等辅助资源,通过特定的协议注入到 Claude 的对话上下文中,让 Claude 在处理特定领域任务时拥有专家级的行为模式

换句话说,Skill 是一种给 LLM 注入领域知识和行为规范的标准化机制

这与传统插件系统有本质区别:

维度传统插件Claude Code Skill
执行主体插件代码Claude LLM
行为定义编程语言自然语言指令
扩展方式API/HookPrompt 注入
灵活性编译时确定运行时推理
边界处理需要硬编码LLM 自适应

这个设计哲学决定了 Skill 开发的核心思路:你不是在写代码,而是在写一份足够精确的工作说明书


二、整体架构剖析

在深入细节之前,先建立全局视角。Skill 系统的架构分为四个层次:

图1:Skill 整体架构图 用户交互层处理两种输入——显式的 /skill-name 命令和隐式的自然语言触发。核心引擎层是整个系统的中枢,包含注册表(Registry)、触发匹配器(Trigger Matcher)、上下文构建器(Context Builder)、执行引擎(Executor)等核心组件。资源层管理 Skill 的文件资产,包括 SKILL.md、脚本、参考文档等。基础设施层提供文件系统、Shell 环境、LLM API 等底层支撑。

这四层之间的交互遵循一个核心原则:渐进式加载(Progressive Disclosure)。不是所有 Skill 的全部内容都会加载到上下文中,而是按需逐层展开——这是 Skill 性能优化的关键所在。


三、加载机制:Skill 是如何被发现的?

Claude Code 启动时,会执行一套完整的 Skill 发现和注册流程。理解这个流程,对排查"Skill 没有被加载"的问题至关重要。

图2:Skill 加载机制流程图

3.1 目录扫描

Claude Code 在启动时扫描 ~/.claude/skills/ 目录。这个目录下的每一个子目录(或符号链接)都被视为一个潜在的 Skill。

~/.claude/skills/
├── draw-io/              # 直接目录
├── my-custom-skill/      # 直接目录
├── jira -> /path/to/jira-skill/   # 符号链接
└── sentry -> ~/.agents/skills/sentry/  # 符号链接

符号链接机制是 Skill 管理的关键能力。它允许 Skill 的源码放在任意位置(项目仓库、共享目录、插件市场),通过 symlink 注册到 Claude Code。这带来了几个好处:

  • 同一个 Skill 可以被多个项目复用
  • Skill 源码可以用 Git 管理,独立版本控制
  • 团队成员可以快速共享 Skill

3.2 Frontmatter 解析

对于每个目录,Claude Code 检查是否存在 SKILL.md 文件。如果存在,解析其 YAML Frontmatter 提取元数据:

---
name: my-awesome-skill
description: >
  自动化数据库迁移脚本生成器。当用户提到"生成迁移脚本"、
  "数据库变更"、"DDL 生成"、"schema migration"时使用。
  支持 MySQL、PostgreSQL、SQLite。
allowed-tools: Read, Write, Bash, Glob, Grep
---

三个核心字段:

  • name:Skill 的唯一标识符,建议使用小写字母和连字符
  • description:触发匹配的核心依据(后面详细讲)
  • allowed-tools:Skill 执行时可以调用的工具白名单

3.3 渐进式加载模型

这里要重点理解 Skill 的三层加载模型:

层级内容加载时机Token 消耗
L1name + description始终在上下文中~100 words
L2SKILL.md 完整内容Skill 被触发时可变(建议 < 500 行)
L3references/ scripts/按需 Read 加载无上限

L1 是常驻的——所有已注册 Skill 的 name 和 description 会被注入到 system-reminder 中,以列表形式呈现给 Claude。这就是为什么 description 的质量如此重要:它是 Claude 判断是否需要调用某个 Skill 的唯一信号源。

L2 在 Skill 被触发后加载。SKILL.md 的 Markdown Body 部分会被完整注入到对话上下文。

L3 的内容永远不会自动加载——Skill 的指令可以指导 Claude 在需要时通过 Read 工具读取 references/ 下的文件,但读取行为由 Claude 的推理过程驱动。

踩坑提醒:如果你把所有内容都塞进 SKILL.md,会导致每次触发时消耗大量 Token。正确做法是核心指令放 SKILL.md,详细参考放 references/,确定性计算放 scripts/。


四、触发匹配:Skill 是如何被激活的?

触发匹配是 Skill 系统中最微妙的部分。它涉及两条路径——显式调用和隐式触发。

图3:触发匹配逻辑流程图

4.1 显式调用

用户直接输入 /skill-name/skill-name args 时,走的是显式路径:

/draw-io create a flowchart for user registration
/jira PROJ-123
/unit-test-service-layer

显式调用会直接在 Registry 中查找对应 name 的 Skill。如果找到,加载其 SKILL.md 内容并执行;如果未找到,返回错误提示。

4.2 隐式触发(核心机制)

更常见的场景是隐式触发——用户用自然语言描述需求,Claude 自动判断是否需要调用某个 Skill。

这个过程发生在 Claude 的推理阶段。Claude 会看到 system-reminder 中注入的 available_skills 列表:

The following skills are available for use with the Skill tool:
- draw-io: draw.io diagram creation, editing, and review...
- jira: 查询公司 Jira 问题和项目...
- unit-test-service-layer: Provides patterns for unit testing...

Claude 基于以下信号做匹配决策:

  1. 关键词精确匹配:用户输入中是否包含 description 里提到的触发词
  2. 语义相似度:用户意图与 Skill 描述的语义相关性
  3. 场景上下文推断:当前对话上下文是否暗示需要某个 Skill
  4. 任务复杂度评估:任务是否复杂到需要专业 Skill 支持

4.3 Description 的艺术

description 的质量直接决定触发准确率。根据大量实践,以下是经过验证的写法规范:

好的 description:

description: >
  Generate Excalidraw diagrams from natural language descriptions.
  Use when asked to "create a diagram", "make a flowchart",
  "visualize a process", "draw a system architecture",
  "create a mind map", or "generate an Excalidraw file".
  Supports flowcharts, relationship diagrams, mind maps,
  and system architecture diagrams.

差的 description:

description: A tool for creating diagrams.

关键差异在于:好的 description 穷举了用户可能的表述方式,并且使用了 "Use when..." 这样的祈使句,明确告诉 Claude 在什么场景下应该触发。

图13:Skill 触发器决策树 Description 优化清单:

  • 包含中英文触发词(如果你的用户群体是双语的)
  • 列出所有同义表述("创建图表" / "画流程图" / "生成架构图")
  • 使用 "Make sure to use this skill whenever..." 强化触发信号
  • 明确标注 NOT 场景,避免误触发
  • 描述长度控制在 50-150 words

五、执行生命周期

Skill 被触发后,会经历完整的四阶段生命周期。

图4:执行生命周期流程图

5.1 初始化阶段

当 Claude 决定调用 Skill 时,它会通过内部的 Skill Tool 发起调用:

Skill Tool 调用 → 从 Registry 获取元数据 → 读取 SKILL.md 全文 → 生成执行提示

5.2 上下文构建阶段

这是最关键的一步——系统需要组装一个完整的执行上下文,注入到 Claude 的对话中:

注入内容包括:
1. Base directory for this skill: /path/to/skill/
2. SKILL.md 完整 Markdown 内容
3. ARGUMENTS: 用户传入的参数
4. 当前对话历史(保持连贯性)
5. allowed-tools 权限边界

这里有个容易忽略的细节:Skill 的执行发生在同一个对话流中,而不是一个独立的沙盒。这意味着 Skill 可以访问之前对话中的所有上下文——文件路径、变量值、用户偏好等。

5.3 执行阶段

Claude 解析 SKILL.md 的指令后,按照指令步骤执行。执行过程中可以调用 allowed-tools 中声明的工具:

  • Read:读取文件内容
  • Write:创建新文件
  • Edit:修改现有文件
  • Bash:执行 Shell 命令
  • Glob:文件模式匹配
  • Grep:内容搜索
  • Skill:调用其他 Skill(Skill 可以组合!)
  • Task:启动子代理处理并行任务
  • AskUserQuestion:向用户提问
  • TodoWrite:管理任务列表

5.4 收尾阶段

Skill 执行完成后,输出结果返回给用户。Skill 的上下文(包括其产出的文件、状态等)在对话中持久保留,后续消息可以继续引用。


六、上下文传递机制

上下文是 Skill 系统的血液。理解上下文如何在各组件间流转,是写好 Skill 的前提。

图5:上下文传递机制时序图 完整的上下文传递链路:

  1. 用户消息 → Claude Code 终端 UI
  2. Claude 分析意图,发现匹配 Skill
  3. 调用 Skill Tool(传入 skill name + args)
  4. Skill Engine 读取 SKILL.md 文件内容
  5. 组装完整上下文(Base dir + SKILL.md body + ARGUMENTS + 对话历史 + tools 权限)
  6. 发送到 Claude LLM API
  7. Claude LLM 返回工具调用指令
  8. 工具执行器执行工具(Read/Write/Bash...),可能需要权限确认
  9. 多轮工具调用循环,直到 Skill 指令执行完毕
  10. 汇总结果,展示给用户

一个关键的设计约束:Skill 的上下文大小直接影响 Token 消耗和响应速度。每加载 1000 行 SKILL.md 内容,大约消耗 4000-8000 Token。在 Claude 的上下文窗口中,这些 Token 会挤占用于推理和输出的空间。

这就是为什么渐进式加载如此重要——把大部分内容放在 references/ 和 scripts/ 中,让 Claude 按需加载。


七、Skill 文件结构全解

现在来详细拆解 Skill 的文件组织方式。

图6:Skill 文件结构模块关系图

7.1 核心文件:SKILL.md

SKILL.md 是一个 Skill 的灵魂,采用 YAML Frontmatter + Markdown Body 的格式:

---
name: db-migration-generator
description: >
  数据库迁移脚本生成器。当用户提到"生成迁移脚本"、"DDL变更"、
  "schema migration"、"数据库迁移"时使用。
  支持 MySQL、PostgreSQL。
allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
---

# 数据库迁移脚本生成器

## 工作流程

1. 读取用户提供的表结构变更需求
2. 分析当前数据库 schema(通过 Bash 执行 SQL)
3. 生成迁移脚本(UP + DOWN)
4. 验证脚本语法正确性
5. 输出到指定目录

## 约束规则

- **必须**生成 UP  DOWN 两个脚本
- **禁止**使用 DROP TABLE 语句(除非用户明确要求)
- **始终**在 UP 脚本中添加事务包裹
- 文件命名格式:`V{timestamp}__description.sql`

## 输出格式

```sql
-- UP Migration
BEGIN;
ALTER TABLE users ADD COLUMN age INT DEFAULT 0;
COMMIT;

参考

详细的 SQL 方言差异见 references/sql-dialects.md

**SKILL.md 写作的黄金法则:**- 使用祈使句("Do X",而不是 "You should do X")
-**必须/禁止/始终** 等强约束词明确边界
- 提供输出示例(减少 Claude 的猜测空间)
- 控制在 500 行以内(超出部分放 references/)
- 每个步骤足够具体,减少 LLM 自由发挥的空间
​
### 7.2 scripts/ 目录
​
scripts/ 存放可执行脚本,用于**确定性任务**——那些不需要 LLM 推理、只需要精确计算的工作。
scripts/ ├── convert-drawio-to-png.sh # 文件格式转换 
         ├── find_aws_icon.py # 图标查找 
         ├── validate-schema.py # Schema 校验 
         └── package_skill.py # Skill 打包
脚本的核心价值:**零 Token 消耗**。Claude 通过 Bash 工具执行脚本,只需要少量 Token 描述调用意图,脚本本身的执行不消耗任何 LLM Token。
​
SKILL.md 中这样引用脚本:
​
```markdown
## 图片转换
​
生成 .drawio 文件后,使用转换脚本生成 PNG:
```bash
bash ~/.claude/skills/draw-io/scripts/convert-drawio-to-png.sh path/to/file.drawio
### 7.3 references/ 目录
​
references/ 存放详细的参考文档,通过 Read 工具按需加载:
references/ 
          ├── api-guide.md # API 使用指南 
          ├── patterns.md # 常见模式参考 
          ├── layout-guidelines.md # 布局规范 
          └── aws-icons.md # AWS 图标索引
**最佳实践**:如果 reference 文件超过 300 行,在文件头部添加 Table of Contents,方便 Claude 快速定位需要的部分:
​
```markdown
# API Reference
​
## Table of Contents
- [Authentication](#authentication) - Line 15
- [Endpoints](#endpoints) - Line 50
- [Error Codes](#error-codes) - Line 120
- [Rate Limits](#rate-limits) - Line 180

7.4 templates/ 目录

templates/ 存放输出模板——预定义的文件结构,Claude 基于模板填充具体内容:

templates/
├── flowchart-template.json      # Excalidraw 流程图模板
├── migration-template.sql       # SQL 迁移模板
└── test-report-template.md      # 测试报告模板

模板的好处是一致性——无论 Claude 面对什么输入,输出的结构始终一致。

7.5 evals/ 目录

evals/ 存放自动化测试用例,用于评估 Skill 的质量:

{
  "skill_name": "db-migration-generator",
  "evals": [
    {
      "id": 1,
      "prompt": "帮我生成一个给 users 表添加 email 字段的迁移脚本",
      "expected_output": "包含 UP 和 DOWN 的 SQL 迁移脚本",
      "files": [],
      "expectations": [
        "生成了 UP 迁移脚本",
        "生成了 DOWN 迁移脚本",
        "UP 脚本包含 ALTER TABLE ... ADD COLUMN",
        "DOWN 脚本包含 ALTER TABLE ... DROP COLUMN",
        "文件名符合 V{timestamp}__description.sql 格式",
        "UP 脚本包含事务包裹 (BEGIN/COMMIT)"
      ]
    }
  ]
}

八、从零开始:实战开发一个 Skill

理论到此为止。接下来用一个真实的案例——开发一个 Git Commit Message 生成器 Skill——走完从创建到测试的全流程。

图7:Skill 开发调试流程图

8.1 Step 1:明确目标

  • 输入:当前 Git 仓库的暂存区变更
  • 输出:符合 Conventional Commits 规范的 commit message
  • 触发场景:用户说"帮我写 commit message" / "生成提交信息" / "commit msg"
  • 工具需求:Bash(执行 git 命令)、Read(读取文件)

8.2 Step 2:创建目录结构

mkdir -p ~/.claude/skills/commit-msg-generator
mkdir -p ~/.claude/skills/commit-msg-generator/references
mkdir -p ~/.claude/skills/commit-msg-generator/evals

8.3 Step 3:编写 SKILL.md

---
name: commit-msg-generator
description: >
  生成符合 Conventional Commits 规范的 Git commit message。
  当用户提到"commit message"、"提交信息"、"commit msg"、
  "帮我写提交"、"生成 commit"时使用。
  Make sure to use this skill whenever the user wants to
  create or improve git commit messages.
allowed-tools: Bash, Read, Glob, Grep
---

# Git Commit Message 生成器

## 工作流程

1. 执行 `git diff --cached --stat` 查看暂存区概况
2. 执行 `git diff --cached` 获取完整 diff
3. 执行 `git log --oneline -5` 查看最近 commit 风格
4. 分析变更内容,判断变更类型(feat/fix/refactor/docs/test/chore)
5. 生成 Conventional Commits 格式的 commit message
6. 输出给用户确认

## Conventional Commits 格式

type 类型

  • feat: 新功能
  • fix: 修复 bug
  • refactor: 重构(不是新功能,也不是修 bug)
  • docs: 文档变更
  • test: 测试相关
  • chore: 构建/工具/依赖变更
  • perf: 性能优化
  • style: 代码格式(不影响逻辑)
  • ci: CI/CD 配置变更

规则

  • description 使用英文,首字母小写,不加句号
  • body 可选,用于解释 "why"
  • scope 从变更文件路径推断
  • 如果有 breaking change,在 footer 中标注

约束

  • 禁止自动执行 git commit(只生成 message)
  • 必须匹配仓库已有的 commit 风格
  • 如果暂存区没有变更,提示用户先 git add

8.4 Step 4:编写测试用例

{
  "skill_name": "commit-msg-generator",
  "evals": [
    {
      "id": 1,
      "prompt": "帮我生成 commit message",
      "expected_output": "符合 Conventional Commits 格式的 commit message",
      "expectations": [
        "执行了 git diff --cached 查看变更",
        "生成的 message 包含 type(scope): description 格式",
        "type 是 feat/fix/refactor/docs/test/chore 之一",
        "没有自动执行 git commit"
      ]
    },
    {
      "id": 2,
      "prompt": "write a commit msg for my staged changes",
      "expected_output": "同上,验证英文触发也能工作",
      "expectations": [
        "Skill 被正确触发",
        "生成了英文的 commit message",
        "格式符合 Conventional Commits"
      ]
    }
  ]
}

8.5 Step 5:手动测试

在 Claude Code 中测试:

# 显式调用
/commit-msg-generator

# 隐式触发
帮我写个 commit message

如果触发失败,检查:

  • description 是否包含足够的触发词
  • SKILL.md 的 frontmatter 格式是否正确
  • ~/.claude/skills/ 下是否有对应目录

如果输出不符合预期,检查:

  • 指令是否足够具体
  • 约束是否明确(必须/禁止/始终)
  • 是否提供了输出示例

九、与 Claude Code 的交互细节

深入理解 Skill 与 Claude Code 之间的交互,对调试和优化至关重要。

图10:Skill 与 Claude Code 交互时序图 几个关键交互节点:

消息处理器是入口,负责将用户输入路由到正确的处理流程。如果输入以 / 开头,直接查找 Skill;否则发送到 LLM 进行意图分析。

权限控制是安全阀。Skill 调用工具时,如果该工具需要用户确认(比如执行 Bash 命令),会弹出确认提示。用户可以允许或拒绝。如果用户拒绝,Skill 需要能够优雅地处理这种情况——这就是为什么好的 SKILL.md 应该考虑工具调用被拒绝的场景。

多轮工具调用循环是执行的核心。Claude 不会一次性完成所有工作,而是通过多轮 "推理 → 调用工具 → 获取结果 → 继续推理" 的循环来完成复杂任务。每一轮都会消耗 Token。


十、错误处理机制

Skill 系统中的错误分为四个类别,每类有不同的处理策略。

图9:错误处理机制流程图

10.1 加载阶段错误

  • SKILL.md 不存在:该目录被静默跳过,不影响其他 Skill
  • Frontmatter 格式错误:Skill 不会被注册,建议在 name 和 description 后加冒号和空格
  • 符号链接断裂:Skill 不可用,需修复链接指向

这类错误通常不会有明显提示。如果你发现 Skill 没有出现在 available_skills 列表中,首先检查这三项。

10.2 触发阶段错误

这是最常见的问题——Skill 存在但没有被正确触发。

诊断方法

  1. 先用 /skill-name 显式调用,确认 Skill 可以工作
  2. 然后用自然语言触发,观察是否被调用
  3. 如果显式可以但隐式不行,说明 description 需要优化

常见原因

  • description 太简短,触发词覆盖不足
  • description 与其他 Skill 的描述重叠,导致竞争
  • 用户的表述方式 description 没有覆盖到

10.3 执行阶段错误

  • 工具权限不足:检查 allowed-tools 是否包含所需工具
  • 脚本执行失败:检查脚本路径、权限、依赖
  • 指令歧义:Claude 对模糊指令产生了非预期行为

防御性编程建议

## 错误处理

- 如果 git diff --cached 返回空结果,告知用户:
  "暂存区没有变更,请先使用 `git add` 添加文件"
- 如果执行脚本失败,显示错误信息并建议检查依赖
- 如果用户拒绝了工具调用权限,使用替代方案或告知限制

10.4 输出阶段错误

  • 输出格式不符预期:在 SKILL.md 中添加明确的输出示例
  • 文件写入路径错误:使用绝对路径或在指令中明确路径构建规则
  • Token 超限:使用渐进式加载,将大内容放在 references/

十一、性能优化策略

性能优化的核心目标是:减少 Token 消耗、加速执行速度、提高输出质量

图11:性能优化策略架构图

11.1 渐进式加载(Token 减少 50-80%)

这是最重要的优化策略。对比两种写法:

差的做法:全部塞进 SKILL.md

# My Skill(2000行)

## 完整的 API 参考(800行)
...全部内联...

## 所有模式的详细说明(600行)
...全部内联...

## 所有边界情况(400行)
...全部内联...

好的做法:分层加载

# My Skill(200行 - 核心指令)

## 参考文档

如需 API 细节,读取 `references/api-guide.md`。
如需模式参考,读取 `references/patterns.md`## 关键规则(只列最核心的5条)
1. ...
2. ...

11.2 脚本卸载(确定性任务零 Token)

把确定性计算从 LLM 推理中剥离出来:

## 不好的做法
"分析这个 JSON 文件,计算所有数值字段的总和"
→ Claude 用 Token 来做算术

## 好的做法
"执行 `python scripts/calculate_totals.py data.json` 获取计算结果"
→ 脚本执行,零 Token 消耗

11.3 指令精简(SKILL.md 体积减少 40%)

  • 使用祈使句:"Generate file" 而不是 "You should generate a file"
  • 删除冗余的解释性文字
  • 用 references/ 承载详细内容,SKILL.md 只保留执行流程

11.4 模板复用(输出一致性提升 60%)

为 Skill 提供输出模板,Claude 基于模板填充而不是从零生成:

## 输出

基于 `templates/migration-template.sql` 模板生成迁移脚本。
模板中的占位符说明:
- `{{TABLE_NAME}}`:表名
- `{{COLUMNS}}`:列定义
- `{{TIMESTAMP}}`:时间戳

11.5 并行工具调用(耗时减少 30-50%)

在 SKILL.md 中指导 Claude 并行执行独立任务:

## 步骤 3:信息收集

以下操作相互独立,并行执行:
- 读取 schema.sql 获取当前表结构
- 执行 git log 获取最近变更
- 读取 config.yaml 获取数据库配置

十二、配置加载优先级

当 Skill 指令与全局配置冲突时,遵循明确的优先级规则。

图14:Skill 配置加载优先级图 优先级从高到低:

  1. 用户显式参数/skill-name "specific args" — 最高优先
  2. Skill 指令硬编码:SKILL.md 中明确声明的行为
  3. allowed-tools 声明:Frontmatter 中的工具权限
  4. Claude Code 全局设置~/.claude/settings.json
  5. 项目级 CLAUDE.md:当前工作目录的配置
  6. Claude LLM 默认推断:最低优先

核心原则:显式 > 隐式,Skill 级 > 全局级,用户意图 > 默认行为


十三、版本管理

Skill 的版本管理涉及代码版本控制和迭代质量管理两个维度。

图12:版本管理流程图

13.1 语义化版本

建议采用 SemVer 规范:

  • MAJOR(主版本号):不兼容的变更。例如重命名 Skill name、删除核心功能
  • MINOR(次版本号):向后兼容的新功能。例如新增触发词、添加 reference 文件
  • PATCH(补丁号):向后兼容的修复。例如修正错别字、调整指令措辞

13.2 迭代工作流

每次迭代产出一组 benchmark 数据,用于量化改进效果:

iteration-1/
├── eval-1-basic-case/
│   ├── with_skill/        # 使用 Skill 的输出
│   ├── without_skill/     # 基准对比
│   ├── grading.json       # 通过率
│   └── timing.json        # Token 消耗
├── benchmark.json          # 聚合指标
└── feedback.json           # 用户评审反馈

iteration-2/                # 优化后的新一轮测试
├── ...(同样结构)

13.3 CHANGELOG

每次发布维护变更日志:

# Changelog

## [1.2.0] - 2026-03-15
### Added
- 新增中文触发词支持
- 添加 PostgreSQL 方言参考文档

### Fixed
- 修复事务包裹遗漏的边界情况

## [1.1.0] - 2026-03-01
### Added
- 新增 DOWN 迁移脚本生成

十四、发布上线

从开发到用户可用,完整的发布链路。

图8:Skill 发布上线流程图

14.1 分发方式

方式一:直接复制(最简单)

cp -r ./my-skill ~/.claude/skills/my-skill

方式二:符号链接(推荐用于开发)

ln -s /path/to/my-skill ~/.claude/skills/my-skill

方式三:Git 仓库 + Symlink(推荐用于团队)

git clone git@gitlab.example.com:team/shared-skills.git ~/shared-skills
ln -s ~/shared-skills/my-skill ~/.claude/skills/my-skill

方式四:插件系统(面向社区分发)

# 使用 skill-creator 的打包脚本
python -m scripts.package_skill ~/.claude/skills/my-skill
# 生成 my-skill.skill 文件,可通过 Marketplace 分发

14.2 团队共享最佳实践

将 Skills 放在团队共享的 Git 仓库中:

team-shared-skills/
├── README.md               # 使用说明
├── install.sh              # 一键安装脚本
├── commit-msg-generator/
│   ├── SKILL.md
│   ├── evals/
│   └── references/
├── code-reviewer/
│   ├── SKILL.md
│   └── references/
└── api-doc-generator/
    ├── SKILL.md
    ├── scripts/
    └── templates/

安装脚本:

#!/bin/bash
# install.sh - 一键安装团队 Skills
SKILLS_DIR="$HOME/.claude/skills"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

for skill_dir in "$SCRIPT_DIR"/*/; do
  skill_name=$(basename "$skill_dir")
  if [ -f "$skill_dir/SKILL.md" ]; then
    ln -sf "$skill_dir" "$SKILLS_DIR/$skill_name"
    echo "Installed: $skill_name"
  fi
done

十五、完整开发到上线链路

把前面所有内容串成一条完整的流水线。

图15:完整开发到上线链路图 六个阶段,每个阶段有明确的交付产物:

阶段关键活动交付产物
需求分析明确目标、触发场景、工具需求需求文档、触发词列表
编码开发创建目录、编写 SKILL.md 和辅助文件SKILL.md + scripts/ + references/
本地测试显式/隐式触发测试、边界情况验证测试通过记录
自动化评估编写 evals、运行 Benchmark、A/B 对比evals.json + benchmark.json
优化迭代Description 优化、指令精简、重新测试优化后的 SKILL.md + 提升数据
发布上线版本标记、Git 推送、Marketplace 发布.skill 包 / Git Tag

十六、常见踩坑清单

根据实践经验,以下是高频踩坑点和解决方案:

坑 1:Skill 没有被触发

症状:用自然语言描述需求,Claude 没有调用 Skill。

排查

# 1. 确认 Skill 已注册
ls -la ~/.claude/skills/my-skill/SKILL.md

# 2. 确认 frontmatter 格式正确
head -10 ~/.claude/skills/my-skill/SKILL.md

# 3. 显式调用测试
# 在 Claude Code 中输入: /my-skill test

解决:扩充 description 中的触发词,添加 "Make sure to use this skill whenever..." 语句。

坑 2:SKILL.md 太长导致输出质量下降

症状:Skill 被触发但输出不完整或质量差。

原因:SKILL.md 过长,挤占了 Claude 的推理空间。

解决:把详细内容移到 references/,SKILL.md 只保留核心流程和约束。

坑 3:脚本路径找不到

症状bash ~/.claude/skills/my-skill/scripts/xxx.sh 报错 "No such file"。

排查

# 检查实际路径(如果是 symlink)
readlink -f ~/.claude/skills/my-skill
ls -la ~/.claude/skills/my-skill/scripts/

解决:在 SKILL.md 中使用基于 Skill 基础目录的相对路径:

执行脚本:`bash <base_directory>/scripts/xxx.sh`

坑 4:多个 Skill 竞争触发

症状:想触发 Skill A,结果触发了 Skill B。

解决

  • 在两个 Skill 的 description 中明确区分适用场景
  • 使用否定句排除误触发:"Do NOT use this skill for..."
  • 让 description 更具体,避免泛化描述

坑 5:Skill 调用了不在 allowed-tools 中的工具

症状:Claude 尝试调用工具但被系统拒绝。

解决:检查 frontmatter 中的 allowed-tools 列表,添加缺失的工具。可用工具包括:Read, Write, Edit, Bash, Glob, Grep, Skill, Task, AskUserQuestion, TodoWrite。

坑 6:符号链接在 Git 中丢失

症状:克隆仓库后 symlink 变成了空文件。

解决:使用安装脚本(如上面的 install.sh)在 clone 后重建 symlink,而不是直接 commit symlink 到 Git。


十七、设计模式

经过大量 Skill 开发实践,沉淀出几种经典设计模式:

模式 1:Pipeline(流水线)

适用于有固定步骤的任务,每步的输出是下一步的输入:

## 流水线步骤

Step 1: 收集输入 → Step 2: 分析处理 → Step 3: 生成输出 → Step 4: 验证

模式 2:Branching(分支路由)

适用于根据输入类型走不同处理路径:

## 处理逻辑

判断输入类型:
- 如果是 SQL 文件 → 执行 SQL 方言检查 + 迁移生成
- 如果是 JSON Schema → 执行 Schema 转换 + DTO 生成
- 如果是自然语言描述 → 执行意图解析 + 代码生成

模式 3:Composition(组合调用)

一个 Skill 调用其他 Skill 完成子任务:

## 步骤 3: 生成图表

使用 draw-io skill 生成架构图:
调用 Skill 工具,skill: "draw-io", args: "create architecture diagram..."

模式 4:Interactive(交互式)

通过 AskUserQuestion 与用户多轮交互:

## 信息收集

使用 AskUserQuestion 工具询问用户:
1. "目标数据库类型?" 选项: MySQL / PostgreSQL / SQLite
2. "是否需要回滚脚本?" 选项: 是 / 否

十八、生产环境注意事项

安全性

  • 不要在 SKILL.md 中硬编码 API Key、密码等敏感信息
  • 使用环境变量或 ~/.claude/settings.json 中的 env 配置
  • 脚本执行时注意命令注入风险

稳定性

  • Skill 的行为应该是幂等的——多次执行同样的输入,产出应该一致
  • 考虑网络不可用、文件不存在等异常场景
  • 使用 TodoWrite 跟踪多步任务的进度,避免遗漏

可维护性

  • 每个 Skill 职责单一——不要做一个"万能 Skill"
  • 保持 SKILL.md 的可读性,让其他人能快速理解
  • 维护 CHANGELOG 和版本号

延伸思考

  1. Skill 的边界在哪里? 什么样的任务适合做成 Skill,什么样的任务用 CLAUDE.md 配置就够了?
  2. Skill 之间如何协作? 如果 Skill A 的输出是 Skill B 的输入,如何设计组合模式?
  3. 如何度量 Skill 的 ROI? 在什么指标下,一个 Skill 可以被认为是"值得维护"的?
  4. 随着 Claude 能力的增强,Skill 的角色会如何演变? 当 LLM 本身就够强时,Skill 还需要存在吗?

这些问题没有标准答案,但思考它们会帮助你在 Skill 开发中做出更好的设计决策。


参考资源