ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Claude Code Skill 设计实战:从50个踩坑到结构化SKILL.md

Claude Code Skill 设计实战:从50个踩坑到结构化SKILL.md 1. 从 50 个 Skill 里踩出来的血泪教训我在过去几个月里陆陆续续写了超过 50 个 Claude Code Skill从最简单的代码格式化到复杂的多步骤工作流编排几乎把能踩的坑都踩了一遍。最扎心的发现是前 30 个基本等于白写。不是功能跑不通而是设计思路从根上就偏了——我把 Skill 当成了提示词模板来写结果越写越臃肿越写越难维护复用率低得可怜。如果你正在用 Claude Code或者刚接触 SKILL.md 这套机制这篇文章就是写给你的。我会把 50 个 Skill 迭代过程中真正有价值的经验拆开讲清楚Skill 到底该怎么设计、SKILL.md 的结构怎么组织、和 MCP 的边界在哪里、为什么很多人写的 Skill 看起来能用但实际上很脆弱。不管你是刚装完 Claude Code 想试试水还是已经写了十几个 Skill 但感觉不对劲都能从这里找到可以直接抄的改进方案。先说结论Skill 的本质不是给 AI 写提示词而是给 AI 定义能力边界和操作规范。这个认知转变是我写到第 31 个 Skill 时才真正想明白的。2. Skill 设计的核心逻辑为什么前 30 个都白写了2.1 把 Skill 当提示词模板是最大的误区我最初写 Skill 的思路很直接把一段好用的提示词存成文件需要的时候调用一下。比如写一个代码审查 Skill就是把请你审查以下代码关注命名规范、边界条件、异常处理……这段话存进 SKILL.md。前 10 个 Skill 基本都是这个套路写起来很快用起来也还行。问题出在规模上。当 Skill 数量涨到 20 个以上我发现几个致命问题第一提示词之间大量重复每个 Skill 都在重复描述项目背景、代码风格、输出格式第二Skill 之间无法组合A Skill 的输出没法直接喂给 B Skill第三同一个 Skill 在不同场景下表现差异巨大因为提示词里没有明确的能力边界AI 自由发挥的空间太大。提示判断一个 Skill 是不是提示词模板看它有没有明确的输入输出契约。如果没有那它大概率只是个提示词。真正的转折点是我开始把 Skill 当成函数来设计。每个 Skill 有明确的输入参数、输出格式、前置条件和后置效果。这个思路一变SKILL.md 的结构也跟着变了。2.2 Skill 和 MCP 的边界到底在哪很多人搞不清楚 Skill 和 MCP 的分工。我一开始也混着用结果两边都写得很乱。后来理清楚了MCP 负责连接外部能力Skill 负责编排内部流程。MCP 解决的是AI 怎么访问外部资源的问题——比如连接数据库、调用第三方 API、读取本地文件系统。它是一层协议适配把外部能力标准化成 AI 能理解的工具接口。而 Skill 解决的是AI 怎么按特定规范完成一类任务的问题——它不关心底层用什么工具只关心流程怎么走、输出长什么样。举个例子你要做一个自动生成周报的功能。MCP 负责连接你的项目管理工具比如 Jira、GitLab把原始数据拉出来。Skill 负责定义周报应该包含哪些板块、每个板块的数据怎么组织、语气和格式是什么样。两者配合但职责完全不重叠。我踩过的坑是早期把数据获取逻辑也写进了 Skill导致 Skill 里塞了一堆 API 调用细节换个数据源就得重写整个 Skill。后来把数据获取全部下沉到 MCPSkill 只保留编排逻辑复用率立刻上来了。2.3 一个 Skill 只做一件事这是我从第 31 个 Skill 开始严格执行的原则。前 30 个里有一半是多功能 Skill——一个 Skill 既做代码审查又做重构建议还做测试生成。看起来很强大实际上每个功能都做不精而且调用时 AI 经常搞混该走哪条路径。拆成单一职责后效果立竿见影。比如把代码质量 Skill拆成三个code-review只做审查输出问题列表、code-refactor只做重构输出修改后的代码、test-generator只做测试生成输出测试文件。 each 各司其职可以单独调用也可以串起来用。拆分的判断标准很简单如果 Skill 的描述里出现了并且、同时、还可以那它大概率需要拆。一个 Skill 的 SKILL.md 如果超过 200 行也要考虑拆。3. SKILL.md 的结构化写法从能用到好用3.1 标准 SKILL.md 的骨架长什么样经过 50 次迭代我现在的 SKILL.md 模板固定成这几个部分--- name: skill-name description: 一句话说明这个 Skill 做什么什么场景下用 version: 1.0.0 --- ## 能力边界 明确说明这个 Skill 能做什么、不能做什么。 ## 输入契约 - 参数名: 类型说明是否必填 - 示例输入 ## 输出契约 - 输出格式说明 - 示例输出 ## 执行流程 1. 第一步做什么 2. 第二步做什么 3. ... ## 约束条件 - 必须遵守的规则 - 禁止的操作 ## 示例 完整的输入输出示例这个结构看起来简单但每一部分都有讲究。能力边界是防止 AI 过度发挥的关键输入输出契约是保证 Skill 可组合的基础执行流程是让 AI 有章可循的路线图。我早期写的 SKILL.md 只有description和一段提示词AI 每次执行的结果都不一样根本没法用在正式流程里。加上契约和流程后输出稳定性提升了非常多。3.2 description 怎么写才能被正确触发description是 Skill 的入口它决定了 AI 在什么情况下会调用这个 Skill。我见过太多人把 description 写成这是一个用于处理代码的 Skill——这种描述等于没写AI 根本不知道什么时候该用它。好的 description 要包含三个要素动作、对象、场景。比如差的写法代码审查工具好的写法当用户提交代码片段并希望获得审查意见时对代码进行静态分析输出问题列表和改进建议再比如差的写法周报生成好的写法当用户提供本周的 Git 提交记录和任务列表时按固定模板生成结构化周报包含完成事项、进行中事项、风险和下周计划场景描述越具体触发越准确。我实测下来description 里包含当……时这种触发条件的写法误触发率能降低一半以上。3.3 输入输出契约让 Skill 可组合的关键这是前 30 个 Skill 完全缺失的部分。没有契约Skill 就是孤岛没法串起来用。输入契约要明确每个参数的类型、是否必填、默认值。比如一个code-reviewSkill 的输入契约参数名类型必填说明codestring是待审查的代码内容languagestring否编程语言默认自动识别focusarray否关注点如 [naming, error-handling]severitystring否最低报告级别默认 info输出契约要明确格式。我一般用 JSON 或 Markdown 表格因为这两种格式最容易解析和传递。比如code-review的输出{ summary: 共发现 5 个问题, issues: [ { severity: warning, line: 12, message: 变量命名不符合驼峰规范, suggestion: 将 user_name 改为 userName } ] }有了明确的输出格式下一个 Skill 就能直接消费这个结果。比如code-refactor可以接收code-review的输出自动修复其中的问题。这种组合能力是 Skill 体系真正强大的地方。4. 实操从零写一个高质量的 Skill4.1 环境准备与 Skill 目录结构Claude Code 的 Skill 存放位置有约定。我一般在项目根目录下建.claude/skills/目录每个 Skill 一个子目录里面放SKILL.md和可选的辅助文件。.claude/ └── skills/ ├── code-review/ │ └── SKILL.md ├── test-generator/ │ ├── SKILL.md │ └── templates/ │ └── test-template.py └── weekly-report/ └── SKILL.md辅助文件这个设计很实用。比如test-generator里放一个测试模板文件Skill 执行时直接读取模板填充比在 SKILL.md 里硬编码模板要灵活得多。注意Skill 目录名和 SKILL.md 里的name字段保持一致避免调用时出现歧义。4.2 完整实操写一个接口文档生成Skill我拿一个实际用过的 Skill 来演示。需求是给定一个 Spring Boot 的 Controller 类自动生成符合 OpenAPI 规范的接口文档。第一步确定能力边界。这个 Skill 只做从 Controller 代码生成接口文档不做代码修改不做接口测试不做文档部署。第二步写输入输出契约。输入是 Java 代码字符串输出是 YAML 格式的 OpenAPI 文档。第三步定义执行流程解析 Controller 类提取类级别的RequestMapping路径遍历每个方法提取 HTTP 方法、路径、参数、返回值根据参数类型推断 OpenAPI schema按 OpenAPI 3.0 规范组织 YAML 输出第四步写 SKILL.md--- name: api-doc-generator description: 当用户提供 Spring Boot Controller 类代码并希望生成接口文档时解析代码结构输出符合 OpenAPI 3.0 规范的 YAML 文档 version: 1.0.0 --- ## 能力边界 - 能做从 Spring Boot Controller 代码生成 OpenAPI 3.0 YAML 文档 - 不能做修改代码、生成测试用例、部署文档 ## 输入契约 - code: string必填Spring Boot Controller 类的完整代码 - basePath: string选填API 基础路径默认从类注解提取 ## 输出契约 - 格式YAML - 结构符合 OpenAPI 3.0 规范 - 必须包含openapi、info、paths 三个顶层字段 ## 执行流程 1. 识别类级别的 RestController 和 RequestMapping 注解 2. 遍历所有 public 方法识别 GetMapping、PostMapping 等注解 3. 提取方法参数识别 PathVariable、RequestParam、RequestBody 4. 根据参数类型生成对应的 schema 定义 5. 按 OpenAPI 3.0 规范组织输出 ## 约束条件 - 不修改原始代码 - 路径拼接要处理斜杠重复的情况 - 泛型返回值要展开为具体类型 - 遇到无法识别的注解时在输出中标注 TODO ## 示例 输入一个包含 3 个接口的 UserController 输出包含 3 个 path 的 OpenAPI YAML 文档这个 Skill 写完后我拿它处理了项目里 20 多个 Controller生成的文档直接导入 Swagger UI 就能用。关键是输出格式稳定每次生成的结构都一样可以直接进版本控制。4.3 参数选择与流程设计的取舍写 Skill 时经常面临取舍流程写多细参数给多少我的经验是流程写到AI 不会做错的程度就够了再细就是过度设计。比如上面那个文档生成 Skill我没有写如何解析注解的具体步骤因为这是 AI 的基础能力写多了反而限制它。但我写了路径拼接要处理斜杠重复因为这是实际会出错的点。参数设计也是同理。必填参数越少越好可选参数要有合理默认值。我见过一个 Skill 定义了 15 个参数结果每次调用都要填半天实际常用的就 3 个。后来砍到 4 个参数2 必填 2 选填使用频率立刻上来了。5. 常见问题与排查技巧实录5.1 Skill 不触发或误触发怎么办这是最高频的问题。排查思路按这个顺序走现象可能原因解决方法完全不触发description 太模糊加入当……时的触发条件偶尔触发description 和其他 Skill 重叠明确区分各 Skill 的适用场景频繁误触发description 过于宽泛收窄场景描述加入排除条件触发后行为不对执行流程不清晰补充流程步骤和约束条件我遇到过一个典型案例code-review和code-refactor两个 Skill 经常互相误触发。原因是两者的 description 都写了处理代码问题。后来把code-review改成当用户希望获得代码问题列表时code-refactor改成当用户希望获得修改后的代码时误触发就消失了。5.2 输出格式不稳定的排查方法输出格式飘忽是另一个高频问题。根本原因通常是输出契约不够明确。我的排查清单输出契约里有没有给出完整的示例输出有没有明确说明必须包含哪些字段有没有说明禁止输出哪些内容复杂输出有没有用 JSON Schema 或表格明确定义结构实测下来只要输出契约里给了一个完整的示例格式稳定性就能提升 80% 以上。AI 是模仿能力极强的给它一个标准答案它就会照着来。5.3 Skill 组合时的数据传递问题Skill 组合是进阶用法但数据传递容易出问题。核心原则是上游 Skill 的输出格式必须严格匹配下游 Skill 的输入契约。我一般会在两个 Skill 之间加一个适配层——如果上游输出是 Markdown 表格下游需要 JSON就写一个简单的转换 Skill 夹在中间。虽然多了一步但比让下游 Skill 去兼容多种输入格式要清晰得多。提示Skill 组合链路不要超过 4 个。超过 4 个后调试成本急剧上升出错时很难定位是哪一环的问题。5.4 我踩过的三个典型坑坑一在 Skill 里硬编码项目路径。早期写的 Skill 里直接写了/Users/xxx/project/换台机器就废了。后来全部改成相对路径或参数传入。坑二Skill 之间共享状态。我试过让两个 Skill 通过临时文件传递状态结果并发调用时互相覆盖。后来改成每个 Skill 完全无状态所有上下文通过参数传递。坑三忽略 Skill 的版本管理。改了 SKILL.md 后没有记录版本导致同一个 Skill 在不同时间的行为不一致排查问题时完全懵。现在每个 Skill 都有version字段改动时同步更新。6. 进阶让 Skill 真正融入工作流6.1 Skill 与 MCP 的协同模式前面说了 Skill 和 MCP 的边界这里讲具体怎么协同。我现在的架构是MCP 负责所有外部交互Skill 负责所有流程编排。比如一个自动修复 CI 失败的工作流MCP 连接 CI 系统拉取失败的构建日志Skilllog-analyzer解析日志定位失败原因Skillfix-generator根据原因生成修复方案MCP 连接代码仓库提交修复MCP 触发新的构建整个流程里MCP 出现了三次Skill 出现了两次各司其职。这种架构的好处是换 CI 系统只需要改 MCP 配置Skill 完全不用动。6.2 把 Skill 当成团队资产来管理一个人用的 Skill 和团队用的 Skill要求完全不同。团队用的 Skill 必须做到任何人看了 SKILL.md 就知道怎么用、输出格式所有人一致、修改有记录可追溯。我的做法是给每个 Skill 建一个简单的 README记录谁写的、什么时候写的、解决什么问题、有哪些已知限制。SKILL.md 本身保持简洁README 承载背景信息。这样新同事上手时先看 README 了解背景再看 SKILL.md 了解用法效率高很多。6.3 持续迭代从 50 个到 100 个的规划写到 50 个之后我的迭代节奏变了。不再追求数量而是追求每个 Skill 的被调用次数和组合深度。一个被高频调用、能和其他 Skill 组合的 Skill价值远高于十个孤立的 Skill。接下来的规划是把现有 50 个 Skill 里低频的合并或删除把高频的做深做透重点建设 5-8 个核心 Skill 组成的工作流套件。比如代码质量套件包含 review、refactor、test 三个 Skill文档套件包含 api-doc、readme、changelog 三个 Skill。套件内部 Skill 之间契约严格对齐套件之间通过标准格式交互。我在实际使用中发现Skill 的价值不在于数量而在于它能不能稳定地解决一类问题。前 30 个白写就是因为它们只是能跑而不是稳定可靠。从第 31 个开始每个 Skill 都按契约、流程、约束三件套来写虽然单个 Skill 的编写时间翻倍了但后续的维护成本和调试时间降了不止一半。这个投入产出比值得每一个认真用 Claude Code 的人去算一算。
返回列表