news 2026/10/8 12:16:06

Claude Code Skill 实战:从50个踩坑到20个高效封装

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Claude Code Skill 实战:从50个踩坑到20个高效封装

1. 从 50 个 Skill 里踩出来的血泪教训

我在过去几个月里陆续写了 50 个 Claude Code Skill,从最开始照着文档瞎写,到后来慢慢摸出一些门道,中间踩的坑实在太多了。最扎心的一个发现是:前 30 个基本等于白写。不是完全没用,而是投入产出比极低,维护成本高得离谱,真正高频调用的没几个。后来我复盘了一下,发现问题的根源不在于 Skill 本身难写,而在于我对“什么样的任务值得封装成 Skill”这件事判断错了。

这篇文章就是把这 50 个 Skill 的实战经验摊开来讲。我会说清楚 Skill 到底是什么、SKILL.md 应该怎么写、哪些场景适合封装、哪些场景纯属给自己找麻烦,以及怎么和 MCP、Spring Boot 这类后端服务配合使用。如果你刚开始接触 Claude Code Skill,或者已经写了一堆但感觉效果一般,这篇内容应该能帮你少走不少弯路。

先给不太熟悉的朋友快速对齐一下概念。Claude Code 是 Anthropic 推出的命令行 AI 编程工具,它可以在终端里直接读写文件、执行命令、调用工具。而 Skill 是 Claude Code 的一个扩展机制,你可以把它理解成“给 AI 写的一份操作手册”——通过一个叫 SKILL.md 的 Markdown 文件,告诉 Claude 在特定场景下应该怎么做、按什么步骤做、注意哪些事项。当用户的请求匹配到 Skill 的描述时,Claude 会自动加载这份手册,按照你定义的流程来执行任务。

听起来很简单对吧?但问题恰恰出在“看起来简单”这四个字上。我前 30 个 Skill 就是被这种错觉害的。

2. 前 30 个 Skill 为什么白写了

2.1 最常见的三个致命错误

回头看我最早写的那批 Skill,问题集中在三个地方。

第一个错误是把 Skill 当文档写。我一开始觉得 Skill 就是写一份说明文档,于是把某个框架的使用方法从头到尾写了一遍,什么安装步骤、API 说明、注意事项,洋洋洒洒几千字。结果 Claude 加载之后确实“知道”了这些信息,但它并不知道在当前项目里应该怎么用。Skill 不是知识库,它更像是一份 SOP(标准作业流程),核心价值在于“指导行动”而不是“传递知识”。

第二个错误是粒度太细。我给每一个小功能都写了一个 Skill,比如“创建 Spring Boot Controller”“添加 MyBatis Mapper”“写单元测试”各一个。听起来很模块化很优雅,但实际使用的时候,Claude 经常不知道该调哪个,或者调了一个之后不知道下一步该调另一个。Skill 之间没有编排关系,导致体验非常割裂。后来我改成按“任务场景”来划分,比如“新增一个完整的 CRUD 接口”作为一个 Skill,里面涵盖 Controller、Service、Mapper、测试的完整流程,效果好了很多。

第三个错误是触发描述写得太模糊。SKILL.md 里有一个关键字段是 description,它决定了 Claude 在什么情况下会加载这个 Skill。我早期写的描述都是“帮助用户完成数据库操作”“辅助代码审查”这种大而空的话,结果要么永远不触发,要么在不该触发的时候乱触发。后来我学乖了,description 必须包含具体的触发关键词和使用场景,比如“当用户需要新增数据库表对应的增删改查接口时使用,关键词:CRUD、Mapper、Controller、Service”。

2.2 什么样的任务根本不值得封装

这是我最想分享的一条经验:不是所有重复性工作都值得做成 Skill。

我总结了一个简单的判断标准,满足以下条件越多的任务,越值得封装:

判断维度值得封装不值得封装
执行频率每天多次每周不到一次
步骤确定性流程固定,步骤明确每次情况不同
上下文依赖依赖项目结构但不依赖具体业务高度依赖具体业务逻辑
出错成本出错后修复成本高出错了大不了重来
团队共享多人需要统一规范只有自己用

举个例子,“生成 Spring Boot 项目的基础分层结构”非常值得封装,因为步骤固定、频率高、团队新人都需要。“根据业务需求设计数据库表结构”就不太值得,因为每次的业务需求都不一样,Skill 能提供的帮助有限,不如直接对话。

我前 30 个 Skill 里,至少有 15 个属于“不值得封装”的类别。它们不是不能用,而是维护成本超过了收益。每次项目结构变了、依赖升级了,我都得回去改这些 Skill,改完还不一定对。后来我狠心删掉了这些,只保留了真正高频且流程固定的那些,整体效率反而提升了。

2.3 一个反直觉的发现:少即是多

删掉 20 个 Skill 之后,我剩下 30 个。但我继续用了一段时间,又发现其中 10 个左右虽然值得封装,但写得不够好。于是我又重写了一轮,最终稳定在 20 个左右的核心 Skill 上。

这 20 个 Skill 覆盖了我日常开发中 80% 以上的重复性场景,包括:

  • Spring Boot 项目初始化与分层
  • MyBatis 映射文件生成
  • RESTful 接口的标准化实现
  • 单元测试模板生成
  • 代码审查清单
  • 日志与异常处理规范
  • 数据库迁移脚本生成
  • API 文档自动生成
  • 配置文件管理
  • 多环境部署脚本

每一个都是经过反复打磨的,description 精确、步骤清晰、边界明确。这比 50 个半成品强太多了。

3. SKILL.md 到底该怎么写

3.1 文件结构与核心字段

一个标准的 Skill 就是一个目录,里面至少包含一个 SKILL.md 文件。目录结构通常长这样:

.claude/skills/ my-skill-name/ SKILL.md templates/ template1.java scripts/ helper.sh

SKILL.md 的头部是 YAML frontmatter,用来定义元信息:

--- name: spring-boot-crud description: 当用户需要为数据库表生成完整的增删改查接口时使用。触发关键词:CRUD、增删改查、Mapper、Controller、Service、RESTful ---

这里有两个关键点。name要简短且唯一,用英文小写加连字符。description是最重要的字段,它直接决定了 Skill 的触发准确率。我的经验是 description 要包含三部分:什么场景下使用、解决什么问题、触发关键词有哪些。

正文部分就是 Markdown 格式的操作指南。我一般会按这个结构来写:

## 前置检查 - 确认项目使用 Spring Boot 2.3.x 或 2.6.x - 确认已配置 MyBatis 或 MyBatis-Plus - 确认数据库连接可用 ## 执行步骤 1. 读取目标表结构 2. 生成 Entity 类 3. 生成 Mapper 接口和 XML 4. 生成 Service 和 ServiceImpl 5. 生成 Controller 6. 生成单元测试 ## 代码模板 (引用 templates 目录下的模板文件) ## 注意事项 - 字段命名遵循驼峰转换规则 - 主键策略默认为自增 - 分页查询统一使用 PageHelper

3.2 触发描述的三个层次

description 的写法我摸索了很久,最终总结出一个“三层描述法”:

第一层:场景定位。用一句话说清楚这个 Skill 是干什么的。比如“为 Spring Boot 项目生成标准化的 CRUD 接口”。

第二层:触发条件。列出用户可能说什么话、用什么关键词时会触发。比如“当用户提到新增接口、创建 CRUD、生成 Mapper 时”。

第三层:排除条件。说明什么情况下不应该触发。比如“不适用于非 Spring Boot 项目,不适用于 GraphQL 接口”。

完整的 description 示例:

为 Spring Boot + MyBatis 项目生成标准化的增删改查接口,包括 Entity、Mapper、Service、Controller 和单元测试。当用户需要新增 CRUD 接口、生成 Mapper 映射、创建 RESTful 端点时使用。触发关键词:CRUD、增删改查、Mapper、Controller、Service、RESTful、接口生成。不适用于非 Spring Boot 项目或 GraphQL 接口。

这样写之后,触发准确率从原来的大概 60% 提升到了 90% 以上。

3.3 步骤设计的原则

Skill 正文的步骤设计,我遵循几个原则。

原则一:每一步都要可执行。不要写“分析代码结构”这种模糊的话,要写“读取 src/main/java 目录下的所有 .java 文件,提取类名和包路径”。Claude 需要的是明确的动作指令,不是思考方向。

原则二:步骤之间要有依赖关系。好的 Skill 步骤是链式的,前一步的输出是后一步的输入。比如先生成 Entity,再根据 Entity 生成 Mapper,再根据 Mapper 生成 Service。这样 Claude 执行起来有明确的推进感。

原则三:关键决策点要给出判断规则。比如“如果表中存在 created_at 和 updated_at 字段,则在 Entity 中添加对应的自动填充注解;否则跳过”。这种条件分支能让 Skill 适应更多情况。

原则四:留出人工确认的节点。不是所有步骤都让 Claude 自动执行,有些关键节点应该暂停让用户确认。比如“生成完 Entity 后,展示给用户确认字段映射是否正确,确认后再继续生成 Mapper”。

4. Skill 与 MCP、Spring Boot 的配合实战

4.1 MCP 是什么,和 Skill 什么关系

MCP 全称 Model Context Protocol,是一个让 AI 模型与外部工具、数据源交互的协议。你可以把它理解成“AI 的 USB 接口”——通过统一的协议,AI 可以连接数据库、调用 API、操作文件系统等等。

Skill 和 MCP 的关系是互补的。Skill 定义的是“怎么做”的流程,MCP 提供的是“能做什么”的能力。举个例子,你要让 Claude 帮你操作数据库,MCP 负责提供数据库连接和查询能力,Skill 负责定义“先查表结构、再生成代码、再执行迁移”这个流程。

我实际使用中,最常见的组合是:用 MCP 连接数据库和代码仓库,用 Skill 定义开发流程。比如我有一个“数据库迁移”的 Skill,它会通过 MCP 读取当前数据库结构,对比目标结构,生成迁移脚本,然后通过 MCP 执行脚本。

4.2 一个完整的 Spring Boot CRUD Skill 实战

让我用一个具体例子来展示 Skill 怎么写、怎么用。假设我们要为一张user表生成完整的 CRUD 接口。

首先,Skill 的目录结构:

.claude/skills/spring-boot-crud/ SKILL.md templates/ entity.java.tpl mapper.java.tpl mapper.xml.tpl service.java.tpl serviceImpl.java.tpl controller.java.tpl test.java.tpl

SKILL.md 的内容:

--- name: spring-boot-crud description: 为 Spring Boot + MyBatis 项目生成标准化的增删改查接口。当用户需要新增 CRUD 接口、生成 Mapper 映射、创建 RESTful 端点时使用。触发关键词:CRUD、增删改查、Mapper、Controller、Service、RESTful、接口生成。不适用于非 Spring Boot 项目或 GraphQL 接口。 --- ## 前置检查 在执行任何生成操作之前,先确认以下条件: 1. 项目根目录存在 pom.xml 或 build.gradle,且包含 spring-boot-starter-web 依赖 2. 项目中存在 MyBatis 或 MyBatis-Plus 依赖 3. 用户已提供目标表名或表结构 如果任一条件不满足,停止执行并告知用户缺少什么。 ## 执行步骤 ### 第一步:获取表结构 通过 MCP 数据库工具查询目标表的 DDL,或者让用户提供建表语句。 需要提取的信息: - 表名 - 所有字段名、类型、是否可空、默认值 - 主键字段 - 索引信息 ### 第二步:生成 Entity 类 根据表结构生成 Entity 类,放在 `src/main/java/{basePackage}/entity/` 目录下。 命名规则: - 类名 = 表名转为大驼峰(如 user_role -> UserRole) - 字段名 = 列名转为小驼峰(如 created_at -> createdAt) - 类型映射:VARCHAR -> String, INT -> Integer, BIGINT -> Long, DATETIME -> LocalDateTime, DECIMAL -> BigDecimal 如果表中存在 created_at 和 updated_at 字段,添加 @TableField(fill = FieldFill.INSERT) 和 @TableField(fill = FieldFill.INSERT_UPDATE) 注解。 生成后展示给用户确认,确认后再继续。 ### 第三步:生成 Mapper 接口和 XML Mapper 接口放在 `src/main/java/{basePackage}/mapper/` 目录下,继承 BaseMapper<Entity>。 Mapper XML 放在 `src/main/resources/mapper/` 目录下,包含: - resultMap 定义 - 基础 CRUD 语句 - 分页查询语句(使用 PageHelper) ### 第四步:生成 Service 和 ServiceImpl Service 接口放在 `src/main/java/{basePackage}/service/` 目录下,继承 IService<Entity>。 ServiceImpl 放在 `src/main/java/{basePackage}/service/impl/` 目录下,继承 ServiceImpl<Mapper, Entity> 并实现 Service 接口。 ### 第五步:生成 Controller Controller 放在 `src/main/java/{basePackage}/controller/` 目录下。 包含以下端点: - GET /api/{resource} - 分页查询 - GET /api/{resource}/{id} - 根据 ID 查询 - POST /api/{resource} - 新增 - PUT /api/{resource}/{id} - 更新 - DELETE /api/{resource}/{id} - 删除 统一返回 Result<T> 包装类。 ### 第六步:生成单元测试 测试类放在 `src/test/java/{basePackage}/` 目录下,使用 JUnit 5 + Mockito。 覆盖以下场景: - 正常查询 - 分页查询 - 新增成功 - 更新成功 - 删除成功 - 参数校验失败 ## 注意事项 - 所有生成的代码必须符合项目的代码风格(检查是否有 checkstyle 或 spotless 配置) - 如果项目使用了 Lombok,Entity 使用 @Data 注解;否则手动生成 getter/setter - Controller 的参数校验使用 @Valid 注解 - 异常处理统一使用全局异常处理器 - 生成完成后,运行 `mvn compile` 验证编译通过

这个 Skill 写完之后,我每次新增一张表的 CRUD 接口,只需要说一句“帮我为 order 表生成 CRUD 接口”,Claude 就会自动走完整个流程。原来手动写这些代码大概需要 30 到 40 分钟,现在 3 到 5 分钟就能搞定,而且风格统一,不会出现这个接口用驼峰那个接口用下划线的情况。

4.3 和 MCP 配合的进阶玩法

上面这个例子已经用到了 MCP 的数据库查询能力。但 MCP 能做的事情远不止这些。我目前常用的 MCP 工具包括:

  • 数据库 MCP:查询表结构、执行 SQL、生成迁移脚本
  • 文件系统 MCP:批量读写文件、搜索代码
  • Git MCP:查看提交历史、创建分支、生成 commit message
  • API 测试 MCP:发送 HTTP 请求、验证接口返回

把这些 MCP 工具和 Skill 结合起来,能实现很多有意思的自动化流程。比如我有一个“接口联调”的 Skill,它会:

  1. 通过文件系统 MCP 读取 Controller 定义
  2. 通过数据库 MCP 准备测试数据
  3. 通过 API 测试 MCP 发送请求
  4. 验证返回结果是否符合预期
  5. 如果失败,通过 Git MCP 查看最近的变更,定位问题

这个 Skill 帮我省了大量的联调时间,尤其是接口多的时候,手动一个个测太痛苦了。

5. 常见问题与排查技巧实录

5.1 Skill 不触发怎么办

这是最常见的问题。你写了一个 Skill,但 Claude 就是不用它。排查思路如下:

第一步:检查 description 是否包含用户可能说的关键词。如果用户说“帮我建个接口”,而你的 description 里只有“CRUD”,那大概率不会触发。解决办法是把常见说法都列进去。

第二步:检查 Skill 目录位置是否正确。Claude Code 默认从.claude/skills/目录加载 Skill,如果你放在别的地方,需要额外配置。

第三步:检查 SKILL.md 的 frontmatter 格式。YAML 对缩进和冒号很敏感,一个多余的空格都可能导致解析失败。建议用 YAML 校验工具检查一下。

第四步:用claude --debug模式启动,查看 Skill 加载日志。如果 Skill 被加载了但没触发,日志里会有匹配过程的记录。

5.2 Skill 触发了但执行结果不对

这种情况通常是步骤描述不够明确导致的。Claude 在执行 Skill 时,会尽量按照你写的步骤来,但如果某一步描述有歧义,它就会按自己的理解来。

解决办法是把模糊的描述改成明确的指令。比如:

  • 模糊:“生成合适的 Entity 类”
  • 明确:“生成 Entity 类,类名使用大驼峰命名,字段使用小驼峰命名,类型映射关系如下表所示”

另外,可以在 Skill 里加入验证步骤。比如生成完代码后,让 Claude 自己检查一遍:“确认所有字段都已映射,确认没有遗漏主键注解,确认 import 语句完整”。这样能提前发现大部分问题。

5.3 多个 Skill 冲突怎么办

当你有很多 Skill 时,可能会出现两个 Skill 都觉得自己应该触发的情况。比如你有一个“生成 CRUD”的 Skill 和一个“生成 API 文档”的 Skill,用户说“帮我生成用户模块的接口和文档”,两个 Skill 都可能被触发。

解决办法有两个。一是在 description 里明确排除条件,比如 CRUD Skill 里写“不适用于仅生成文档的场景”。二是设计 Skill 的层级关系,让一个 Skill 可以调用另一个 Skill。比如“生成用户模块”这个 Skill 里,明确写了“先生成 CRUD 接口,再生成 API 文档”,这样就不会冲突了。

5.4 常见问题速查表

问题现象可能原因解决办法
Skill 完全不触发description 关键词不匹配补充常见说法和同义词
Skill 触发但报错SKILL.md 格式错误检查 YAML frontmatter 缩进
执行结果不符合预期步骤描述有歧义改成明确的动作指令
多个 Skill 同时触发description 边界不清添加排除条件或设计层级
Skill 执行到一半停了缺少必要的前置条件在开头添加前置检查步骤
生成的代码风格不统一没有引用项目规范在 Skill 里加入代码风格检查
Skill 加载很慢Skill 文件太大拆分 Skill,把模板放到单独文件
修改 Skill 后不生效缓存问题重启 Claude Code 或清除缓存

5.5 几个我踩过的坑

坑一:在 Skill 里写死绝对路径。我早期写的 Skill 里用了/Users/myname/project/这样的绝对路径,结果换台电脑就废了。后来全部改成相对路径,或者用环境变量。

坑二:Skill 里包含敏感信息。有一次我把数据库密码写在了 Skill 的示例代码里,差点提交到仓库。现在我的原则是 Skill 里绝对不出现任何密钥、密码、token,需要的话通过环境变量或配置文件读取。

坑三:过度依赖 Skill 的自动化。有些步骤其实让用户确认一下更好,但我为了“全自动”跳过了确认环节,结果生成了一堆错误代码还得手动改。现在我一般在关键节点都会加一个“展示给用户确认”的步骤。

坑四:忘了更新 Skill。项目升级了 Spring Boot 版本,但 Skill 里的模板还是老版本的写法,生成出来的代码编译不过。现在我养成了习惯,每次项目大版本升级后,都检查一遍相关 Skill 是否需要更新。

6. 我目前稳定在用的 Skill 清单

经过反复筛选和打磨,我目前稳定在用的 Skill 大概有 20 个。这里列一下最核心的 10 个,供参考:

Skill 名称用途触发频率
spring-boot-init初始化 Spring Boot 项目结构每周 1-2 次
spring-boot-crud生成完整 CRUD 接口每天多次
mybatis-mapper生成 MyBatis 映射文件每天多次
unit-test-gen生成单元测试每天多次
code-review代码审查清单每天 1-2 次
api-doc生成 API 文档每周 2-3 次
db-migration数据库迁移脚本每周 1-2 次
log-exception日志与异常处理规范每周 2-3 次
config-manage配置文件管理每周 1-2 次
deploy-script多环境部署脚本每周 1 次

这 10 个 Skill 覆盖了我日常开发中绝大部分重复性工作。每个都是经过至少 10 次以上实际使用和迭代的,description 精确、步骤清晰、边界明确。

写 Skill 这件事,我的核心体会就是:质量远比数量重要。与其写 50 个半成品,不如精心打磨 10 个真正好用的。判断一个 Skill 是否值得保留,就看它能不能让你在每次使用时都感到“省事了”。如果用了之后还得花时间检查和修正,那这个 Skill 就是负资产。

另外,Skill 不是一成不变的。项目在变、团队在变、工具在变,Skill 也需要跟着迭代。我现在的习惯是每个月花半个小时回顾一下所有 Skill,看看哪些需要更新、哪些可以合并、哪些该删了。保持 Skill 库的精简和新鲜,比一味地增加新 Skill 重要得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 12:14:26

写代码用 Wrangler,日常运维进自建面板:我是怎么用爽 Cloudflare 的

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/8 12:14:17

用Prompt Engineering生成可玩HTML游戏:从复制提示词到独立设计

在外面翻了一圈prompt收藏夹&#xff0c;你是不是也干过这种事&#xff1a;看到别人晒的“神级prompt”&#xff0c;赶紧复制进备忘录&#xff0c;真到让AI生成一个想玩的游戏时&#xff0c;要么生成出来是个空壳&#xff0c;要么直接被系统提示invalid prompt。我前三个月就是…

作者头像 李华