本教程带你从零开发一个 Claude Code 自定义 Skill——"schema-designer"。它接收一句自然语言需求(如"做一个多租户博客系统"),自动产出符合范式的建表 DDL、索引、外键和种子数据 SQL。学完后你将掌握 Skill 的目录结构、frontmatter 配置、渐进式加载、动态上下文注入、参数替换与 evals 评估闭环,具备独立设计任意 Skill 的能力。适合已装好 Claude Code、想把自己的重复工作流沉淀为可复用工具的开发者。
${CLAUDE_PROJECT_DIR} 等新特性)很多教程一上来就让你写文件,但理解机制比照抄更重要。Claude Code 的 Skill 本质是一个文件夹,里面至少有一个 SKILL.md。它和你塞进 CLAUDE.md 的内容有本质区别:
| 维度 | CLAUDE.md | Skill |
|---|---|---|
| 加载时机 | 每轮对话全量常驻 | 仅描述常驻,正文用时才加载 |
| Token 成本 | 持续消耗 | 不用几乎为零 |
| 触发方式 | 永远在 | 描述命中或 /skill-name |
| 适合放什么 | 事实、规矩、偏好 | 多步骤流程、清单、可复用套路 |
这就是官方反复强调的渐进式加载(progressive disclosure):Claude 只把每个 Skill 的 description(连同 when_to_use,合计上限 1536 字符)塞进技能清单里。真正那份几百行的正文,只有 Claude 判断"这次用得上"或你手动 /schema-designer 时才整体读入。所以你可以放心地写一个详尽的参考文档,平时一点也不浪费。
记住这条铁律:当你发现自己反复粘贴同一段指令、同一个清单、同一套步骤时,就该把它抽成 Skill。
写代码前先回答四个问题,能避免 90% 的返工:
/ 调用?建表这种需要人工拍板的场景,建议设 disable-model-invocation: false 允许自动,但保留手动入口。本例最终目录结构:
~/.claude/skills/schema-designer/
├── SKILL.md # 入口:总览 + 流程 + 导航
├── conventions.md # 命名与范式规范(按需加载)
└── templates/
└── ddl.template.sql # DDL 骨架模板
Skill 存放位置决定作用域,务必先选对:
~/.claude/skills/<name>/SKILL.md——你所有项目可用.claude/skills/<name>/SKILL.md——仅当前项目.claude/skills/,编辑该子目录文件时按需加载(适合 monorepo)我们选个人级,让它在任何后端项目都能用:
mkdir -p ~/.claude/skills/schema-designer/templates
cd ~/.claude/skills/schema-designer
接着新建 SKILL.md。每个 Skill 由两段构成:--- 之间的 YAML frontmatter(告诉 Claude 何时用),和后面的 Markdown 正文(告诉 Claude 怎么做)。目录名决定命令名,所以你在 / 菜单里输入的会是 /schema-designer。
---
name: schema-designer
description: 把自然语言需求转成规范的建表 DDL(含索引、外键、种子数据)。用于用户描述业务、要设计数据库表结构、要生成 CREATE TABLE 语句时。
when_to_use: |
触发词:设计表、建表、数据库 schema、数据建模、CREATE TABLE、
多对多怎么建表、要不要加索引、生成建表 SQL。
argument-hint: [需求描述] [数据库方言]
arguments: [requirement, dialect]
allowed-tools: Read Write Glob Bash
---
# Schema Designer
你是一位资深数据架构师。根据用户的需求产出可直接执行的建表脚本。
## 输入
- 需求:$requirement
- 方言:$dialect(缺省为 mysql,可选 postgres)
## 工作流程
1. 读取已有 schema 作为约束
当前项目若已有迁移文件,先扫描:
!`find ${CLAUDE_PROJECT_DIR} -type d \( -name migrations -o -name db \) 2>/dev/null | head`
2. 拆解实体:从需求中识别名词,列出候选实体与关系。
3. 规范化:遵循 conventions.md 中的命名与范式规则(需要时读取)。
4. 产出 DDL:按 templates/ddl.template.sql 的结构生成,包含:
- 表注释(中文说明该表用途)
- 字段(统一 id/timestamps 软删除约定)
- 主键、唯一键、外键、业务索引
- 种子数据 INSERT(至少 3 行示例)
5. 自检清单(逐条核对再交付):
- [ ] 所有外键都有索引
- [ ] 字符串长度合理(VARCHAR vs TEXT)
- [ ] 金额用 DECIMAL 不用 FLOAT
- [ ] 时间列带默认值
- [ ] 多对多已建中间表
## 输出格式
用 ```sql 代码块输出完整脚本,最后附一句中文设计说明。
要点拆解:
description 写法:把核心用例放最前面,因为清单里只保留前 1536 字符。"做什么 + 何时用"挤进前一两句最稳。arguments + $requirement:声明命名参数,正文里用 $requirement 引用。若正文没出现 $ARGUMENTS,Claude 会把参数以 ARGUMENTS: <值> 追加。!命令动态注入**:反引号包裹的 `!`find ... 在 Claude 读到正文前先执行**,输出直接替换该行。这里用来扫描现有迁移目录,让产出与现有库对齐。allowed-tools:列出本 Skill 激活期间可免确认使用的工具,免去逐条授权打断。把长参考拆出去,正文才够精简。新建 conventions.md:
# 建表规范
## 命名
- 表名:小写蛇形复数,如 `users`、`order_items`
- 主键统一 `id BIGINT UNSIGNED AUTO_INCREMENT`(postgres 用 `BIGSERIAL`)
- 外键列 `<表名单数>_id`,如 `user_id`
- 时间列 `created_at`、`updated_at`,软删除 `deleted_at`
## 范式
- 默认满足第三范式,冗余字段需在表注释写明理由
- 多对多必须建中间表,命名 `<a>_<b>` 按字母序
## 索引
- 所有外键自动加普通索引
- 高频查询条件(如 status、tenant_id)加索引
- 软删除字段 deleted_at 不索引
## 类型
- 金额一律 DECIMAL(18,2)
- 布尔用 TINYINT(1)(mysql)或 BOOLEAN(postgres)
- 长文本 TEXT,短文本 VARCHAR 带长度
再建 templates/ddl.template.sql:
-- 表:{table_name} | 用途:{purpose}
CREATE TABLE {table_name} (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
-- 业务字段在此
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_{table_name}_{unique_col} ({unique_col}),
KEY idx_{table_name}_{fk_col} ({fk_col})
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{purpose}';
-- 种子数据
INSERT INTO {table_name} (...) VALUES (...);
正文里用一句话引导 Claude "需要时读取 conventions.md / templates",它就会在该用的时候才加载——这正是 500 行正文红线的实践方式。
新建/修改 Skill 后无需重启——Claude Code 监听 Skill 目录,会话内即时生效(前提是启动时该目录已存在)。开一个 git 项目,claude 进入会话。
路径 A:自动触发。输入一段贴合 description 的话:
帮我给一个多租户的内容管理平台设计数据库,要有文章、作者、栏目,作者属于某个租户
预期:Claude 自动加载 schema-designer,先扫描现有迁移(动态注入行展开为真实路径),再输出含三张表、租户外键索引、中间表(文章-栏目多对多)、种子数据的完整 DDL。
路径 B:手动调用 + 参数:
/schema-designer "电商订单 含商品 SKU 优惠券" postgres
预期:$requirement 展开为需求串,$dialect 展开为 postgres,输出改用 BIGSERIAL、BOOLEAN 等 PG 语法。
常见问题速查:
| 现象 | 原因 | 解决 |
|---|---|---|
输入 /schema 没有补全 |
启动时目录不存在 | 重启 Claude Code 让它开始监听新目录 |
| 自动不触发、手动能跑 | description 没覆盖该说法 | 在 when_to_use 补触发词 |
| 触发太频繁误伤 | description 过宽 | 加约束,如"仅当明确要建表时" |
| description 在清单里被截断 | 超 1536 字符 | 精简,把细节挪到 when_to_use 之外的正文 |
Skill 不是写完就完。官方提供 skill-creator 内置能力,能跑 evals、做方差分析、优化 description 的触发准确率。
在会话里直接说:
帮我评估 schema-designer 这个 skill 的触发准确率,跑 10 条用例,
对一半是建表需求、一半是无关需求,看它会不会误触发
它会自动生成正负样本、统计触发命中、给出 description 改写建议。拿到结果后微调 description/when_to_use,再跑一轮,直到误触发率收敛。这一步是把"能用"提升到"好用"的分水岭。
~/.claude/skills/.claude/skills/schema-designer/ 并提交到 git(注意别提交敏感内容).claude-plugin/plugin.json,变成可安装插件,命名空间 your-plugin:schema-designer,避免与他人同名冲突把上面所有步骤串起来。需求:给现有博客加评论,支持楼中楼。
直接对 Claude 说:
给博客加评论功能,要支持二级回复
Claude 加载 schema-designer 后产出(节选):
-- 表:comments | 用途:文章评论,支持二级嵌套回复
CREATE TABLE comments (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
article_id BIGINT UNSIGNED NOT NULL COMMENT '所属文章',
parent_id BIGINT UNSIGNED NULL COMMENT '父评论id,NULL为一级评论',
author_id BIGINT UNSIGNED NOT NULL COMMENT '评论者',
content TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL,
PRIMARY KEY (id),
KEY idx_comments_article_id (article_id),
KEY idx_comments_parent_id (parent_id),
KEY idx_comments_author_id (author_id),
CONSTRAINT fk_comments_article FOREIGN KEY (article_id) REFERENCES articles(id),
CONSTRAINT fk_comments_author FOREIGN KEY (author_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论表';
INSERT INTO comments (article_id, parent_id, author_id, content) VALUES
(1, NULL, 10, '好文章!'),
(1, 1, 20, '同意,二级回复'),
(1, NULL, 30, '学到了');
它自动给三个外键列都建了索引、用 parent_id 表达二级回复、附了种子数据——这正是规范文件 + 模板 + 自检清单合力产出的结果。下次任何建表需求,一句话即可。
flowchart TD
A[识别重复流程] --> B[设计:触发/输入/输出/支撑文件]
B --> C[创建目录 ~/.claude/skills/name]
C --> D[写 SKILL.md frontmatter+正文]
D --> E[拆分长参考到支撑文件]
E --> F[动态注入 !cmd + 参数 $N]
F --> G{测试}
G -->|自动触发| H[匹配 description]
G -->|手动 /name| I[展开参数]
H --> J[skill-creator evals]
I --> J
J -->|误触发/漏触发| K[调 description/when_to_use]
K --> G
J -->|通过| L[分发:个人/项目/插件]
$ARGUMENTS、${CLAUDE_SKILL_DIR}、${CLAUDE_PROJECT_DIR}/doctor、/code-review、/batch、/debug、/loop、/run、/verify,可作为 SKILL.md 写法范本[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
