☰
Claude Code Skill 设计实战:从50个失败案例到高效触发与MCP配合
2026/10/8 15:58:35 网站建设 项目流程

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

我在过去几个月里陆续写了 50 个 Claude Code Skill,从最开始照着文档瞎摸索,到后来慢慢摸出一些门道,中间踩的坑实在太多了。最扎心的一个感受就是:前 30 个基本白写了。不是功能跑不通,而是写完之后发现根本没人用,包括我自己——因为触发时机不对、描述写得含糊、结构设计得太复杂,导致 Claude 压根不知道什么时候该调用它。

这篇文章不是官方文档的复述,也不是什么“保姆级教程”。我想做的是把“为什么前 30 个白写了”这件事拆开,讲清楚 Skill 到底该怎么设计、SKILL.md 该怎么写、触发条件怎么设、和 MCP 怎么配合、以及那些只有真正写过几十个 Skill 之后才会明白的细节。如果你正在用 Claude Code,或者准备给自己的项目加 Skill,又或者你只是好奇“Skill 和 MCP 到底有什么区别”,那这篇内容应该能帮你少走不少弯路。

先给一个最直观的结论:Skill 的核心不是“写代码”,而是“写触发条件”和“写上下文约束”。很多人(包括前 30 个的我)把 Skill 当成一个函数来写,觉得只要逻辑对就行。但 Claude Code 的 Skill 本质上是一个“给模型看的说明书”,它需要让模型在正确的时机、用正确的方式、拿正确的上下文去执行一件事。逻辑只是其中一部分,甚至不是最重要的那部分。

下面我会从整体设计思路开始拆,然后逐层深入到 SKILL.md 的结构、触发条件的写法、和 MCP 的配合方式、常见报错和排查技巧,最后再聊几个我实际在用的 Skill 案例。内容会比较长,但如果你真的想写出“能被用起来”的 Skill,这些细节都值得过一遍。

2. Skill 到底是什么,和 MCP 有什么区别

2.1 用一句话说清楚 Skill 的定位

Claude Code 的 Skill 可以理解成“给 Claude 预设的一套操作手册”。你写一个 SKILL.md,里面描述这个 Skill 是干什么的、什么时候该用、用了之后按什么步骤执行、需要哪些参数、输出什么格式。Claude 在对话过程中会根据你的描述来判断是否触发这个 Skill。

它和 MCP 最大的区别在于:MCP 是“能力扩展”,Skill 是“行为约束”。MCP 解决的是“Claude 能不能访问某个外部系统”的问题,比如能不能读数据库、能不能调某个 API、能不能操作某个工具。Skill 解决的是“Claude 在某个场景下应该怎么做”的问题,比如“当用户要求生成周报时,按固定格式整理本周 commit 记录并输出”。

打个比方:MCP 像是给 Claude 装了一双手,让它能去够到外面的东西;Skill 像是给 Claude 一本操作手册,告诉它“够到东西之后该怎么处理”。两者不是替代关系,而是配合关系。我见过不少人一上来就想用 Skill 去实现 MCP 的功能,结果写出来的东西又臃肿又难维护。

2.2 为什么前 30 个 Skill 会白写

回头看我最早写的那些 Skill,问题基本集中在三个地方:

第一,描述写得太抽象。比如我写过一个“代码审查 Skill”,描述是“用于审查代码质量”。这个描述对 Claude 来说几乎没有信息量,因为“审查代码质量”这件事在任何编程对话里都可能发生,Claude 根本不知道什么时候该触发它。后来我改成“当用户提交了一个 Pull Request 链接,或者明确说‘帮我看看这段代码有没有问题’时,按以下清单逐项检查”,触发率立刻上来了。

第二,步骤写得太细但缺少判断逻辑。我早期喜欢把每一步都写死,比如“第一步读取文件,第二步提取函数名,第三步检查命名规范”。但实际场景里,用户给的东西千奇百怪,写死的步骤很容易在第二步就卡住。后来我学会在关键节点加“如果……则……否则……”的分支判断,让 Skill 有一定的弹性。

第三,没有考虑上下文长度。有些 Skill 我塞了大量示例和规则进去,结果 SKILL.md 本身就有好几千字。Claude 在触发这个 Skill 的时候,光读描述就消耗了大量上下文,真正执行的时候反而没空间了。后来我学会把非核心内容拆到单独的参考文件里,SKILL.md 只保留最关键的触发条件和执行框架。

这三个问题加起来,导致我前 30 个 Skill 里有不少是“写完了但从来没被触发过”,或者“触发了但执行到一半就偏了”。真正好用的 Skill,往往不是功能最复杂的,而是触发条件最清晰、执行路径最短的那些。

2.3 一个 Skill 的最小可用结构

一个能跑起来的 Skill,最少需要包含这几个部分:

  • 名称:简短、唯一、能一眼看出用途。
  • 触发描述:什么情况下该用这个 Skill。这是最重要的部分。
  • 执行步骤:触发之后按什么顺序做什么事。
  • 输入输出约定:需要用户提供什么,最终产出什么格式。
  • 边界条件:什么情况下不该用这个 Skill,或者需要额外确认。

这五个部分里,触发描述和执行步骤是核心,输入输出和边界条件是加分项。我后来写 Skill 的时候,会先花一半时间想触发描述,剩下时间才去写具体步骤。因为触发描述写不好,后面写得再漂亮也没用。

3. SKILL.md 的结构设计与触发条件写法

3.1 SKILL.md 的推荐结构

我现在写 SKILL.md 基本遵循一个固定骨架,虽然不同场景会微调,但整体结构比较稳定:

# Skill 名称 ## 何时使用 (描述触发条件,越具体越好) ## 前置条件 (需要哪些环境、文件、权限) ## 执行步骤 (分步骤描述,关键节点加判断) ## 输出格式 (最终产出什么,用什么格式) ## 注意事项 (容易出错的地方、边界情况)

这个结构看起来简单,但每个部分都有讲究。比如“何时使用”这一节,我一般会写三到五条具体的触发场景,而不是一句抽象的描述。“前置条件”是为了让 Claude 在触发之前先确认环境是否满足,避免执行到一半发现缺东西。“执行步骤”里我会刻意留一些“如果……则……”的分支,让 Skill 有应对变化的能力。

3.2 触发条件到底该怎么写

触发条件是 Skill 的灵魂。我总结了一个原则:用“用户会说的话”来写触发条件,而不是用“技术术语”来写。

举个例子,我写过一个“生成接口文档”的 Skill。最早的触发描述是“当需要生成 API 文档时使用”。这个描述的问题在于,用户很少会说“我需要生成 API 文档”,他们更可能说“帮我把这几个接口整理一下”、“这个 Controller 能不能输出成文档”、“我要给前端写接口说明”。后来我把触发描述改成:

  • 当用户提到“整理接口”、“输出接口说明”、“生成 API 文档”时触发。
  • 当用户提供了一个 Controller 文件或一组接口定义,并要求“说明每个接口的用途”时触发。
  • 当用户说“给前端写一份接口对接说明”时触发。

改完之后,这个 Skill 的触发率明显提升。原因很简单:Claude 在判断是否触发时,是在匹配用户的实际表达,而不是在匹配你脑子里的技术分类。

还有一个技巧是在触发描述里加入“反例”。比如“当用户只是询问某个接口的参数含义时,不要触发这个 Skill,直接回答即可”。这样能避免 Skill 在不该触发的时候被触发,减少干扰。

3.3 执行步骤的粒度控制

执行步骤写多细?我的经验是:写到“一个刚入行的开发者能照着做”的程度就够了,不要写到“每一步的每个按键”。

太粗了 Claude 会自由发挥,太细了又容易卡死。我一般会把一个 Skill 拆成 5 到 8 个步骤,每个步骤用一句话描述目标,必要时加一个判断分支。比如:

  1. 读取用户指定的文件或目录,确认文件类型和数量。
  2. 如果文件数量超过 10 个,先输出文件清单让用户确认,再继续。
  3. 逐个提取关键信息,按统一格式整理。
  4. 如果遇到无法解析的内容,记录到“待确认”列表,不要中断流程。
  5. 汇总输出,并在末尾附上“待确认”列表。

这种写法既给了 Claude 明确的路径,又留了处理异常的余地。实测下来,比那种“第一步做什么、第二步做什么、第三步做什么”的机械写法要稳得多。

3.4 一个实际案例:Spring Boot 接口整理 Skill

我拿一个实际在用的 Skill 来举例。这个 Skill 的作用是:当用户给出一个 Spring Boot 项目的 Controller 目录时,自动整理出所有对外接口的清单,包括路径、方法、参数、返回值说明。

触发描述我写的是:

  • 当用户提供 Spring Boot 项目的 Controller 文件或目录,并要求“整理接口”、“输出接口清单”、“生成接口文档”时触发。
  • 当用户说“帮我看看这个项目有哪些对外接口”时触发。
  • 当用户要求“给第三方写接口说明”时触发。

执行步骤大致是:

  1. 扫描用户指定的目录,找出所有带@RestController或@Controller注解的类。
  2. 对每个类,提取类级别的@RequestMapping路径。
  3. 对每个方法,提取@GetMapping、@PostMapping等注解,拼接完整路径。
  4. 提取方法参数和返回值类型,如果参数是自定义对象,尝试读取该对象的字段定义。
  5. 按“路径 | 方法 | 参数 | 返回值 | 说明”的格式输出表格。
  6. 如果某个接口的说明不明确,标注“待补充”,不要自行编造。

这个 Skill 我用了大概两个月,触发率很高,输出也比较稳定。关键就在于触发描述里用了“整理接口”、“输出接口清单”这些用户实际会说的词,而不是“生成 API 文档”这种技术术语。

4. Skill 和 MCP 的配合方式

4.1 什么时候该用 Skill,什么时候该用 MCP

这个问题我被问过很多次。我的判断标准很简单:如果这件事需要访问 Claude 本身访问不到的外部系统,用 MCP;如果这件事只是对已有信息做处理,用 Skill。

比如,你要让 Claude 读取本地数据库里的数据,这需要 MCP,因为 Claude 本身没有数据库连接能力。但你要让 Claude 把读取到的数据按某个格式整理成报告,这用 Skill 就够了。

再比如,你要让 Claude 调用某个内部 API 获取用户信息,这需要 MCP。但你要让 Claude 根据用户信息生成一封通知邮件,这用 Skill 就行。

实际场景里,两者经常是配合使用的。MCP 负责“拿到数据”,Skill 负责“处理数据”。我现在的做法是:先用 MCP 把外部能力接进来,然后针对常见的数据处理场景写对应的 Skill。这样 Claude 在拿到数据之后,能自动按预设的方式处理,不需要用户每次都重复描述。

4.2 MCP 工具流式输出到文件的 Skill 设计

有一个场景我印象比较深:用 MCP 工具获取数据后,需要把结果流式写入文件。这个场景如果只靠 MCP,每次都要用户手动指定输出路径和格式;如果只靠 Skill,又拿不到数据。所以我把两者结合起来。

Skill 的触发描述写的是:

  • 当用户要求“把 MCP 工具的输出保存到文件”时触发。
  • 当用户说“把刚才查到的内容写到某个文件里”时触发。

执行步骤是:

  1. 确认用户指定的输出文件路径和格式。
  2. 调用对应的 MCP 工具获取数据。
  3. 如果数据是流式的,按块读取并追加写入文件。
  4. 写入完成后,输出文件路径和总行数/总大小。
  5. 如果写入过程中出现错误,保留已写入部分,并输出错误信息。

这个 Skill 的关键在于“流式写入”的处理。如果一次性把数据全部读进内存再写入,遇到大数据量时容易出问题。所以我在步骤里明确写了“按块读取并追加写入”,让 Claude 知道要用流式方式处理。

4.3 MCP 协议在 Skill 里的角色

MCP 协议本身对 Skill 来说是透明的。Skill 不需要知道 MCP 底层是怎么通信的,它只需要知道“调用哪个工具、传什么参数、拿什么结果”。所以我在写 Skill 的时候,会把 MCP 工具当成一个普通的函数来引用,不会去描述协议细节。

但有一个点需要注意:MCP 工具的返回格式可能不稳定。有些工具返回 JSON,有些返回纯文本,有些返回结构化对象。如果 Skill 里写死了“假设返回 JSON”,遇到纯文本返回时就会出错。所以我现在会在 Skill 里加一步“先判断返回格式,再决定怎么解析”。

5. 实操:从零写一个能用的 Skill

5.1 准备工作:明确场景和边界

在动手写之前,先问自己三个问题:

  1. 这个 Skill 解决的是什么场景下的什么问题?
  2. 用户在这个场景下通常会说什么话?
  3. 这个 Skill 不该在什么情况下被触发?

这三个问题的答案,基本就构成了 SKILL.md 的触发描述和边界条件。我早期跳过这一步,直接开始写步骤,结果就是写出来的 Skill 触发条件模糊,经常在不该触发的时候被触发。

5.2 编写 SKILL.md 的完整流程

我现在的流程大概是:

  1. 先写“何时使用”,列出三到五条具体触发场景,再加一到两条反例。
  2. 再写“前置条件”,确认需要哪些环境、文件、权限。
  3. 然后写“执行步骤”,控制在 5 到 8 步,关键节点加判断。
  4. 接着写“输出格式”,明确最终产出是什么。
  5. 最后写“注意事项”,把容易出错的地方列出来。

写完之后,我会自己模拟几个用户输入,看看触发描述是否能覆盖这些输入。如果某个输入无法被触发描述覆盖,就补充进去;如果某个输入不该触发但被覆盖了,就加反例。

5.3 参数计算与选择过程

有些 Skill 涉及参数计算,比如“根据文件数量决定是否分批处理”。这种时候我会在 Skill 里写清楚计算逻辑,而不是让 Claude 自己猜。

比如我写过一个“批量处理文件”的 Skill,里面有一段:

  • 如果文件数量小于等于 5,一次性处理。
  • 如果文件数量在 6 到 20 之间,分两批处理,每批不超过 10 个。
  • 如果文件数量超过 20,先输出文件清单让用户确认,再决定分批策略。

这种明确的阈值设定,比“根据文件数量决定”这种模糊描述要可靠得多。Claude 不需要自己判断“多少算多”,它只需要按你给的阈值执行就行。

5.4 实操现场记录:一个 Skill 的调试过程

我拿最近写的一个“代码变更摘要”Skill 来举例。这个 Skill 的作用是:当用户提供一组 git commit 记录时,自动生成一份变更摘要,按模块分类,并标注影响范围。

第一版触发描述写的是“当用户提供 commit 记录时触发”。测试的时候发现,用户只是贴了一行 commit message 问“这是什么意思”,也会触发这个 Skill,明显过度触发了。

第二版改成“当用户提供三条以上 commit 记录,并要求‘总结’、‘整理’、‘生成摘要’时触发”。这次触发准确多了,但遇到用户说“帮我看看这些改动”时又没触发。

第三版改成“当用户提供多条 commit 记录,并要求‘总结’、‘整理’、‘生成摘要’、‘看看这些改动’时触发”。同时加了一条反例:“当用户只提供一条 commit 记录时,不要触发”。

这一版跑了两周,触发准确率明显提升。整个过程让我意识到,触发描述不是一次写好的,而是需要根据实际使用情况不断调整。

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

6.1 Skill 不触发怎么办

这是最常见的问题。排查思路按顺序来:

第一,检查触发描述是否用了用户实际会说的词。如果你写的是“生成 API 文档”,但用户说的是“整理接口”,那大概率不会触发。解决办法是把用户可能的表达方式都列进去。

第二,检查是否有反例写得太宽。比如你写了“当用户只是询问参数含义时不要触发”,但用户的实际输入可能被判定为“询问参数含义”,导致该触发的时候没触发。解决办法是把反例写得更具体。

第三,检查 SKILL.md 是否太长。如果描述部分超过一定长度,Claude 可能在读取阶段就消耗了太多上下文,导致触发判断变弱。解决办法是把非核心内容拆到单独文件里。

6.2 Skill 触发了但执行偏了怎么办

执行偏了通常是因为步骤描述不够明确,或者缺少判断分支。排查思路:

第一,检查步骤里是否有“如果……则……”的分支。如果没有,Claude 遇到异常情况时容易自由发挥。

第二,检查是否有“不要自行编造”这类约束。有些 Skill 需要严格按输入处理,不允许 Claude 补充不存在的信息。这种约束要写清楚。

第三,检查输出格式是否明确。如果只写“输出一份报告”,Claude 可能会用各种格式。如果写“输出 Markdown 表格,列为路径、方法、参数、返回值”,就会稳定很多。

6.3 常见问题速查表

问题现象可能原因解决办法
Skill 完全不触发触发描述用了技术术语而非用户表达改用用户实际会说的词
Skill 过度触发触发描述太宽泛,缺少反例加具体反例,缩小触发范围
执行到一半卡住步骤缺少异常处理分支在关键节点加“如果……则……”
输出格式不稳定输出格式描述不明确明确指定格式和字段
上下文不够用SKILL.md 太长拆分非核心内容到单独文件
MCP 返回解析失败假设了固定返回格式先判断格式再解析

6.4 几个容易忽略的细节

第一个细节:Skill 名称不要用缩写。我早期写过一个叫“CR Skill”的,本意是 Code Review,但 Claude 在判断时经常把它和“Create”、“Convert”混淆。后来改成“代码审查与问题清单”,触发准确率立刻上来了。

第二个细节:前置条件要写清楚。比如“需要用户提供文件路径”、“需要项目使用 Maven 构建”。如果前置条件不满足,Skill 应该先提示用户,而不是直接开始执行。

第三个细节:输出里加一个“待确认”列表。有些信息在输入里不明确,Claude 不应该自行编造,而应该记录到“待确认”列表里,让用户后续补充。这个习惯能大幅减少输出错误。

7. 几个我实际在用的 Skill 案例

7.1 Spring Boot 接口清单整理

这个前面提过,是我用得最频繁的 Skill 之一。触发描述里包含了“整理接口”、“输出接口清单”、“生成接口文档”、“给第三方写接口说明”等表达。执行步骤里加了“如果参数是自定义对象,尝试读取字段定义”和“如果说明不明确,标注待补充”。

实测下来,这个 Skill 在处理中等规模项目(10 到 30 个接口)时表现最好。接口太多的时候,输出会很长,需要分批处理。

7.2 代码变更摘要生成

这个 Skill 用于把一组 commit 记录整理成变更摘要。触发描述里写了“提供多条 commit 记录”和“要求总结、整理、生成摘要”。执行步骤里按模块分类,并标注影响范围。

有一个细节我特意加进去了:如果 commit message 里包含“fix”或“修复”,归到“问题修复”类别;如果包含“feat”或“新增”,归到“功能新增”类别。这样分类更稳定。

7.3 配置文件对比与差异说明

这个 Skill 用于对比两个配置文件,输出差异说明。触发描述里写了“对比配置文件”、“找出配置差异”、“说明改了什么”。执行步骤里先解析两个文件,再逐项对比,最后按“新增、删除、修改”三类输出。

这个 Skill 的关键在于处理嵌套结构。如果配置文件是 YAML 或 JSON,需要递归对比。我在步骤里写了“如果遇到嵌套结构,递归对比,并在输出里用缩进表示层级”。

7.4 项目依赖检查与版本对齐

这个 Skill 用于检查项目依赖,找出版本不一致的地方。触发描述里写了“检查依赖版本”、“对齐依赖”、“看看有没有版本冲突”。执行步骤里先读取依赖文件,再提取版本号,最后输出不一致的项。

这个 Skill 我一般配合 MCP 使用,先用 MCP 读取依赖文件,再用 Skill 做对比分析。

8. 写 Skill 这件事,我踩过的坑和总结的经验

写到现在,我最大的感受是:Skill 的质量不取决于你写了多少行,而取决于触发描述有多准、执行路径有多短、异常处理有多全。前 30 个 Skill 白写,本质上是因为我把精力花在了“功能实现”上,而忽略了“触发时机”和“上下文约束”。

如果让我给刚开始写 Skill 的人一条建议,我会说:先花时间想清楚“用户会在什么情况下说哪些话”,然后再动手写步骤。触发描述写好了,Skill 就成功了一半。

另外,不要追求一次写完美。我现在的习惯是,先写一个最小可用的版本,跑一周,根据实际触发情况调整触发描述和步骤。大部分 Skill 都是在第二版或第三版才真正好用的。

最后分享一个小技巧:在 SKILL.md 里加一段“如果用户输入不明确,先提问确认,不要直接执行”。这一句话能避免很多因为输入模糊导致的执行偏差。我后来写的每个 Skill 里都有这句话,实测下来非常有用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询