1. 从50个Skill里爬出来的血泪账先交个底。我在过去大半年里前前后后写了差不多50个Claude Code Skill从最开始照着文档瞎摸到后来能稳定产出可复用的技能包中间踩的坑能填满一个中型项目的issue区。最扎心的一个结论是前30个基本等于白写。不是它们跑不起来而是它们解决的都是“伪需求”或者用了一种极其别扭的方式去解决真需求导致维护成本高到不如手敲。这篇文章不打算给你灌“Skill有多强大”的鸡汤。我想干的事很具体把我在写这50个Skill过程中关于SKILL.md结构、frontmatter设计、MCP协同、触发词编排、测试与去AI味这几个核心环节的真实经验摊开讲。如果你刚开始接触Claude Code或者已经写了几个Skill但总觉得“哪里不对”这篇内容应该能帮你省下至少两三个周末的无效折腾。先对齐一下基础认知。Claude Code Skill本质上是一个可被模型按需加载的能力包核心载体是SKILL.md文件通过frontmatter里的元信息告诉Claude“我是谁、我什么时候该被调用、我依赖什么工具”。它和MCP的关系不是替代而是互补MCP负责把外部能力数据库、设计工具、调试器接口等接进来Skill负责把“怎么用这些能力解决某类具体问题”的流程固化下来。一个管“手”一个管“脑”。适合读这篇的人已经装好Claude Code、跑通过至少一个Skill、但产出质量不稳定的开发者或者正准备从零开始写Skill、想少走弯路的同学。纯小白也能看但建议先把官方文档里关于Skill目录结构和frontmatter字段的部分过一遍不然有些细节会跟不上。2. 前30个Skill为什么白写了三个致命误区2.1 误区一把Skill当成“提示词收藏夹”我最早写的十几个Skill现在回头看本质上就是把一段常用提示词塞进SKILL.md的正文里frontmatter随便填个name和description就完事。比如我写过一个“代码审查Skill”正文就是“请仔细审查以下代码关注性能、安全和可读性”。这东西能用吗能用。但它有价值吗几乎没有。原因很简单Claude本身已经具备代码审查能力你写不写这个Skill它都能干这件事。Skill的真正价值在于注入模型默认不知道的上下文——你们团队的代码规范、特定框架的坑、某个内部工具的调用约定。如果Skill的内容是“通用常识”那它就是在浪费加载开销。我后来给自己定了一条硬标准如果一个Skill的正文删掉之后Claude靠默认能力也能完成80%的任务那这个Skill就不该存在。这条标准直接砍掉了我早期一半的产出。2.2 误区二frontmatter写得像填空题frontmatter是Skill的“身份证”但很多人包括早期的我把它当填空题name随便起description写一句“用于处理XX任务”就交了。这是灾难性的。Claude决定是否加载一个Skill几乎完全依赖description的语义匹配。你写“用于处理数据处理任务”模型根本不知道什么时候该用它你写“当用户需要对CSV文件做列式聚合、且数据量超过10万行时使用内部封装了分块读取和内存控制逻辑”模型就能精准命中。我做过一个粗糙的对比测试同一个Skilldescription分别用“模糊版”和“场景化版”在20次随机任务里模糊版的触发准确率大概只有三成场景化版能到八成以上。这个差距直接决定了Skill是“资产”还是“噪音”。2.3 误区三忽视MCP与Skill的边界这是最隐蔽的一个坑。我早期写过一个“数据库查询Skill”正文里详细描述了怎么拼SQL、怎么处理连接。问题是Claude Code本身没法直接连数据库它需要MCP提供数据库访问能力。我的Skill写得再详细没有对应的MCP工具它就是一张废纸。正确的做法是MCP负责“能不能做”Skill负责“怎么做才对”。比如你有一个数据库MCP那Skill应该写的是“查询前必须先检查表的分区键避免全表扫描”“涉及金额字段时统一用DECIMAL而不是FLOAT”这类业务规则而不是重复MCP已经提供的能力说明。把这三个误区理清楚之后我后面20个Skill的产出效率和质量明显上了一个台阶。下面我把这套方法论拆成可操作的步骤。3. SKILL.md的骨架设计从frontmatter到正文的完整规范3.1 frontmatter字段的取舍与写法一个典型的frontmatter长这样--- name: csv-large-aggregation description: 当用户需要对超过10万行的CSV文件做分组聚合、且关注内存占用时使用。封装了分块读取、类型推断和流式聚合逻辑。 version: 1.2.0 ---字段不多但每个都有讲究。name建议用小写连字符语义上体现“领域动作”方便自己在几十个Skill里快速定位。description是重中之重我总结了一个“三段式”写法触发条件什么场景下该用“当用户需要……”能力边界这个Skill覆盖什么、不覆盖什么关键约束有没有特殊前提数据量、依赖工具、性能要求version字段很多人不写但我强烈建议加上。Skill是会迭代的尤其是当你的团队规范变化时没有版本号你根本不知道线上跑的是哪一版逻辑。注意description不要写成“这是一个用于XX的Skill”这种自指式描述对模型匹配毫无帮助。要站在“模型看到这句话能不能判断当前任务该不该加载我”的角度去写。3.2 正文结构为什么“步骤化”比“说明化”更有效我早期正文喜欢写成说明文大段描述“本Skill的作用是……”。后来发现模型对有序步骤的执行准确率明显高于对描述性文本的理解。现在我的正文基本遵循这个结构前置检查执行前必须确认的条件文件存在、依赖工具可用等执行步骤编号列表每步一个明确动作输出规范结果应该长什么样格式、字段、单位异常处理常见失败情况怎么应对举个真实例子。我写过一个“日志分析Skill”早期版本正文是一段话描述分析逻辑模型经常漏掉时间戳解析。改成步骤化之后## 执行步骤 1. 读取日志文件按行分割 2. 用正则提取时间戳字段格式为 YYYY-MM-DD HH:mm:ss 3. 按小时聚合统计每个小时的ERROR级别条目数 4. 输出为Markdown表格列为小时、错误数、占比同样的模型同样的任务准确率从六成提到了九成以上。步骤化本质上是在替模型做任务分解减少了它自由发挥的空间也就减少了出错的可能。3.3 触发词编排让Skill在该出现的时候出现触发词不是越多越好。我试过在一个Skill里塞二十几个触发词结果它在很多不相关场景下被误加载反而干扰了正常任务。后来我改用“核心触发词场景限定”的策略核心触发词控制在3到5个必须是任务描述里高频出现的词场景限定写在description里而不是堆在触发词列表里比如一个“GIS空间分析Skill”核心触发词是“空间分析”“缓冲区”“叠加分析”但description里明确写“仅当用户处理的是矢量数据且需要做几何运算时使用”。这样既保证了命中率又避免了在纯属性查询场景下被误触发。4. 实操从零写一个能打的Skill4.1 需求筛选先问三个问题在动手写之前我会先问自己三个问题这个任务Claude默认能做吗能且做得不错就不写。这个任务有明确的“正确做法”吗如果做法因人而异、没有标准Skill的价值就有限。这个任务会重复出现吗一次性任务不值得固化成Skill。三个问题都过了才进入下一步。这个筛选过程帮我砍掉了大量“看起来有用、实际鸡肋”的想法。4.2 目录结构与文件组织一个规范的Skill目录大概是这样skills/ csv-large-aggregation/ SKILL.md examples/ sample-input.csv expected-output.md scripts/ validate.pySKILL.md是必须的examples和scripts是可选的。但我强烈建议至少放一个examples目录里面放输入样例和期望输出。这不仅是给模型看的更是给你自己测试用的。没有样例你根本没法验证Skill是否按预期工作。scripts目录用于放辅助脚本。比如我那个CSV聚合Skill里面放了一个validate.py用来检查输入文件的行数和编码Skill正文里会引用它。这样把“确定性逻辑”交给脚本把“判断性逻辑”留给模型分工明确。4.3 正文编写一个完整的示例下面是我现在常用的正文模板以“CSV大文件聚合”为例## 前置检查 - 确认输入文件存在且为 .csv 格式 - 调用 scripts/validate.py 检查文件行数和编码 - 若行数超过50万提示用户确认是否继续 ## 执行步骤 1. 使用分块读取方式加载文件块大小设为10000行 2. 对每块数据做类型推断数值列转为对应类型 3. 按用户指定的分组键做流式聚合 4. 合并各块的聚合结果 5. 按聚合值降序排列取前20条 ## 输出规范 - 输出为Markdown表格 - 数值列保留两位小数 - 若存在空值单独标注空值数量 ## 异常处理 - 编码错误尝试 utf-8 和 gbk 两种编码 - 内存不足将块大小降至5000行并重试 - 分组键不存在列出所有可用列名供用户选择这个模板我用了大概十几次每次只需要替换具体步骤结构不用动。模板化的好处是降低认知负担让你把精力集中在“这个任务的核心逻辑是什么”上而不是“正文该怎么组织”。4.4 测试怎么判断一个Skill“能打”写完不等于能用。我的测试流程分三层单元测试用examples里的样例跑一遍看输出是否符合expected-output边界测试故意给空文件、超大文件、格式错误的文件看异常处理是否生效干扰测试在一个不相关的任务里看Skill会不会被误触发第三层最容易被忽略但恰恰最重要。我有个Skill因为触发词写得太宽泛在写文档的任务里被反复加载导致输出里莫名其妙多了一堆数据分析的步骤。后来把触发词收窄才解决。5. MCP协同Skill和外部工具的配合方式5.1 什么时候该用MCP什么时候该用Skill这个边界我前面提过这里展开说。判断标准很简单需要访问外部系统数据库、API、设计工具、调试器的用MCP需要固化业务流程和规范的用Skill。举个例子。你要做一个“Figma设计稿转代码”的能力。Figma的访问需要MCP因为要调Figma的API但“转成什么风格的代码、用什么组件库、命名规范是什么”这些属于Skill。两者配合的方式是MCP提供原始设计数据Skill定义转换规则。我见过有人试图用Skill去“模拟”MCP的能力比如在Skill正文里写“假设你可以访问数据库”然后让模型编造查询结果。这种做法在演示里能跑通在真实场景里毫无价值。5.2 MCP工具流的Skill封装技巧当你有一个MCP提供了一堆工具时直接让模型自由调用容易乱。我的做法是写一个Skill来约束调用顺序和参数规范。比如一个数据库MCP提供了query、list_tables、describe_table三个工具我会写一个Skill规定先调list_tables确认表存在再调describe_table确认字段最后才调query且query语句必须带LIMIT这样既利用了MCP的能力又通过Skill注入了“安全查询”的规范。实测下来模型乱查表、查错字段的情况明显减少。5.3 流式输出到文件的处理有个场景我踩过坑用MCP工具流式输出内容到文件时Skill如果没规定好写入方式容易出现内容截断或重复写入。后来我在Skill里明确写了## 流式写入规范 - 使用追加模式写入避免覆盖已有内容 - 每写入1000字符做一次flush - 写入完成后校验文件大小是否与预期一致这些细节看起来琐碎但正是它们决定了Skill在真实项目里能不能稳定跑。6. 常见问题与排查速查6.1 Skill不触发怎么办这是最高频的问题。排查顺序排查项检查方法常见原因description读一遍问自己“模型能判断吗”描述太模糊触发词看是否与任务描述用词一致用词偏差文件位置确认在skills目录下路径错误frontmatter检查YAML语法缩进或冒号问题我遇到最多的情况是description写得太“官方”比如“用于优化代码性能”模型根本不知道什么时候该用。改成“当用户反馈某个函数执行超过1秒、且需要定位性能瓶颈时使用”之后触发率立刻上来了。6.2 Skill触发了但输出不对通常是正文的步骤不够明确。我的经验是凡是模型做错的地方都是你写得不够具体的地方。比如你写“处理数据”模型可能按自己的理解处理你写“按第二列分组、对第三列求和、结果保留两位小数”模型就很难出错。另一个原因是缺少前置检查。如果Skill假设输入是干净的但实际输入有脏数据输出必然出问题。加上前置检查步骤能挡掉大部分异常。6.3 多个Skill冲突当你有几十个Skill时冲突是必然的。表现是一个任务触发了多个Skill输出里混了不同Skill的逻辑。解决办法有两个一是收窄description让每个Skill的适用场景更明确二是设置优先级在frontmatter里加一个priority字段冲突时高优先级的生效。我现在的做法是按领域分目录比如skills/data/、skills/code/、skills/doc/不同领域的Skill几乎不会冲突同领域内的再靠description区分。6.4 去AI味的Skill怎么写这是个有意思的需求。所谓“去AI味”本质是让输出更像人写的。我写过一个这样的Skill核心逻辑是禁止使用“首先、其次、最后”这类结构化连接词禁止使用“综上所述”“总而言之”这类总结套话句子长度要有变化避免全是中长句允许口语化表达和适度的不完美把这些规则写进Skill正文模型输出确实会自然很多。但要注意去AI味不等于降低质量该有的信息密度不能丢。7. 我现在的Skill工作流走到第50个Skill我现在的流程已经比较固定了。有新需求时先花五分钟判断值不值得写Skill值得写的话先写description和触发词用几个测试任务验证触发准确性触发没问题了再补正文步骤正文写完后用examples跑一遍再做边界和干扰测试。整个过程大概半小时到一个小时比早期快了很多。有个小技巧我一直在用给每个Skill写一个“废弃条件”。比如“当Claude默认能力能覆盖此任务时废弃此Skill”。这逼着我定期回顾把过时的Skill清理掉。毕竟Skill不是越多越好维护成本是实打实的。最后分享一个我踩过的坑不要试图用一个Skill解决所有问题。我早期写过一个“万能代码助手Skill”想覆盖审查、重构、测试、文档所有场景结果每个场景都做得不深触发还特别乱。后来拆成四个独立Skill每个都专注一件事整体效果反而好了很多。Skill的粒度宁小勿大。
阅读完成 · 觉得有帮助?