
1. 从一次踩坑说起为什么我们需要认真聊聊SKILL去年年底我接手了一个内部知识库项目团队想把散落在各个文档里的操作流程、代码规范、排查手册统一收拢让AI助手能直接调用。一开始我的思路很朴素——把所有内容塞进一个巨大的提示词里按章节分好让模型自己去检索。结果第一次测试就翻车了上下文窗口被撑爆模型开始胡言乱语明明写在第三段的规范回答时却引用成了第七段的内容。更离谱的是同一个问题问两遍答案能差出十万八千里。后来我花了两周时间研究Anthropic官方放出的SKILL机制才意识到自己犯了一个根本性错误我把SKILL当成了“更长的提示词”而它本质上是一套按需加载、渐进披露的能力封装体系。这个认知转变直接决定了你写出来的SKILL是能用还是不能用。这篇文章就是把我这段时间踩过的坑、试过的方案、以及最终跑通的实践整理出来。不管你是刚接触SKILL这个概念还是已经写过几个但总觉得效果不稳定下面这些内容应该都能帮你少走弯路。我会从SKILL到底是什么讲起拆解它的核心机制然后手把手带你写一个真正优秀的SKILL最后把常见问题和排查技巧一次性说清楚。提示本文讨论的SKILL特指Anthropic在Claude生态中定义的技能封装机制不涉及其他平台的类似概念。如果你用的是其他AI助手的技能系统底层逻辑相通但具体文件格式和加载方式需要对照对应平台的文档。2. SKILL到底是什么别被名字骗了2.1 一句话说清楚SKILL的本质SKILL不是提示词模板不是知识库文件也不是简单的函数封装。用一句话概括SKILL是一份写给AI看的“操作说明书”它告诉模型在什么场景下、按照什么步骤、调用哪些资源来完成一件具体的事。这个定义里有三个关键词需要拆开理解。“什么场景下”指的是触发条件模型需要知道什么时候该用这个SKILL。“按照什么步骤”指的是执行流程这是SKILL的核心内容。“调用哪些资源”指的是SKILL可以引用外部文件、脚本、模板等辅助材料而不是把所有东西都塞进一个文件里。我见过太多人把SKILL写成了“百科全书”——恨不得把某个领域的所有知识都塞进去。结果就是模型加载时消耗大量token真正执行时反而抓不住重点。优秀的SKILL应该像一份精炼的SOP只写这个任务需要知道的东西其他内容通过引用外部文件的方式按需加载。2.2 SKILL和普通提示词的本质区别很多人第一次接触SKILL时会问这不就是写个提示词吗有什么区别我一开始也这么想直到实际用起来才发现差异巨大。普通提示词是“一次性”的。你写一段话模型读完执行结束。下次换个任务你得重新写一段。SKILL是“可复用”的。你写好一个SKILL文件放在指定目录模型在需要的时候自动加载执行完这个任务后这个SKILL的上下文可以被释放不会持续占用窗口。更关键的区别在于渐进式披露机制。普通提示词是你写多少模型读多少SKILL是分层的——第一层只有元数据名称和描述模型根据描述判断是否需要加载第二层是SKILL.md的主体内容包含核心步骤第三层是引用的外部文件只有在执行到特定步骤时才读取。这种分层设计让SKILL可以在不撑爆上下文的前提下承载远超普通提示词的信息量。我做过一个对比测试同样一个“代码审查”任务用普通提示词写大概能塞进去800字左右就开始出现注意力涣散用SKILL结构写主文件控制在500字以内引用三个外部文件分别存放检查清单、常见反模式、修复示例总信息量超过3000字模型执行准确率反而更高。2.3 SKILL的目录结构长什么样一个标准的SKILL在文件系统里是这样的my-skill/ ├── SKILL.md # 主文件必须存在 ├── references/ # 参考文档目录可选 │ ├── checklist.md │ └── examples.md ├── scripts/ # 可执行脚本目录可选 │ └── validate.py └── assets/ # 静态资源目录可选 └── template.jsonSKILL.md是入口文件必须存在。它的开头有一段YAML格式的元数据包含name和description两个字段。这两个字段决定了模型是否会在正确的时机加载这个SKILL。很多人写SKILL时把大量精力花在主体内容上却忽略了元数据的打磨结果就是SKILL写得再好模型该用的时候想不起来用。references目录存放参考文档比如检查清单、示例集合、背景说明等。这些文件不会在SKILL加载时全部读入而是当SKILL.md中明确指示“读取references/checklist.md”时才会被加载。scripts目录存放可执行脚本模型可以调用这些脚本来完成确定性计算或外部操作。assets目录存放模板、配置等静态资源。注意不同平台对SKILL目录结构的支持程度不同。有些平台只支持SKILL.md单文件有些平台支持完整的目录结构。写之前先确认你的运行环境支持哪些能力避免写了引用却加载不了。3. 渐进式披露SKILL最核心的设计哲学3.1 为什么不能把所有东西写在一个文件里上下文窗口是有限资源。即使现在很多模型支持超长上下文但“能塞进去”和“能有效利用”是两回事。我做过一个实验把一份两万字的操作手册直接塞进提示词然后问模型手册里第三部分第七条的细节。模型确实能回答但响应速度明显变慢而且当问题涉及跨章节关联时准确率大幅下降。渐进式披露解决的就是这个问题。它的核心思想是只在需要的时候加载需要的内容。SKILL.md只写“做什么”和“怎么做”的骨架具体细节放在外部文件里等执行到那一步再读取。这样模型在大部分时间里只需要处理几百字的上下文注意力高度集中执行准确率自然就上去了。我自己的经验是一个设计良好的SKILLSKILL.md主体控制在300到800字之间最合适。太短了说不清楚太长了模型注意力分散。超过800字的内容就应该考虑拆到references目录里。3.2 三层加载机制的实际运作方式第一层是元数据加载。当模型启动时它会扫描所有可用SKILL的元数据把name和description读进来。这一层的信息量极小通常每个SKILL只有几十个字。模型根据当前任务和这些描述做匹配决定是否加载某个SKILL。第二层是主体加载。当模型判断需要某个SKILL时它会把SKILL.md的完整内容读入上下文。这一层包含了执行这个任务的核心步骤、注意事项、以及对外部文件的引用指令。第三层是按需加载。当执行到某一步SKILL.md中写着“读取references/checklist.md并逐项检查”时模型才会去读取那个文件。读完执行完这个文件的内容就可以从上下文中释放为后续步骤腾出空间。这个机制的美妙之处在于你可以把一个复杂任务的完整知识体系拆成十几个文件但模型在执行时永远只加载当前需要的那一两个。我试过把一个包含二十多个检查项的质量审查SKILL拆成主文件加五个参考文件总信息量超过一万字但模型在整个执行过程中上下文峰值只有两千字左右执行效果比之前塞在一个文件里好得多。3.3 渐进式披露的常见误用最常见的误用是把所有内容都放在SKILL.md里然后安慰自己“反正模型上下文够大”。这种做法在简单任务上可能看不出问题一旦任务复杂起来模型就会开始丢三落四。另一个极端是过度拆分。我见过有人把一个简单的“生成周报”SKILL拆成主文件加七个参考文件每个文件只有一两句话。结果模型在执行时频繁跳转读取反而增加了出错概率。拆分的粒度应该以“一个完整的逻辑单元”为标准比如“检查清单”是一个单元“示例集合”是一个单元不要把一句话也单独拆出去。还有一个隐蔽的坑是引用路径写错。SKILL.md里写“读取references/checklist.md”但实际文件放在references/checklists/checklist.md模型找不到文件就会跳过这一步而且很多时候不会报错只是默默忽略。这种问题在测试时如果不仔细看执行日志很难发现。4. 动手写一个优秀的SKILL从零到跑通4.1 先想清楚三件事再动笔写SKILL之前先回答三个问题。第一个问题这个SKILL解决什么具体问题不要写“帮助处理文档”这种模糊描述要写“把Markdown格式的会议记录转换成包含行动项、决策记录、待跟进问题的结构化摘要”。越具体越好。第二个问题模型在执行这个任务时最容易在哪一步出错这个问题的答案决定了你需要在SKILL里重点强调什么。比如代码审查SKILL模型最容易漏掉的是边界条件检查那你就要在SKILL里明确写“必须检查空值、越界、并发冲突三类边界情况”。第三个问题哪些内容是每次执行都必须知道的哪些是偶尔才需要的必须知道的放SKILL.md主体偶尔需要的放references目录。这个判断直接决定了你的SKILL结构是否合理。我自己的习惯是先拿一张纸把整个任务的执行流程画出来然后在每个步骤旁边标注“这一步需要什么信息”。画完之后信息需求最密集的步骤就是SKILL.md要重点写的信息需求独立且量大的就拆到外部文件。4.2 元数据怎么写才能让模型正确触发元数据里的name和description是模型决定是否加载这个SKILL的唯一依据。很多人在这里写得太随意导致SKILL明明存在却从来不被触发。name要简洁明确用英文小写加连字符比如code-review、meeting-summary、>name: code-review description: 对代码变更进行系统性审查检查逻辑错误、边界条件、安全漏洞和性能问题。当用户提交代码片段或请求审查PR时使用。输出包含问题列表、严重程度评级和修复建议。这段描述里“对代码变更进行系统性审查”说明了做什么“当用户提交代码片段或请求审查PR时使用”说明了什么时候用“输出包含问题列表、严重程度评级和修复建议”说明了结果形式。模型读到这样的描述就能准确判断当前任务是否匹配。提示description的长度控制在100到200字之间比较合适。太短了信息不足太长了模型处理时也会稀释注意力。如果你发现description写不下说明这个SKILL可能承担了太多职责考虑拆成两个。4.3 SKILL.md主体的黄金结构主体内容我推荐用“目标-步骤-注意事项-输出格式”四段式结构。这个结构经过多次迭代验证在大多数任务类型上都能取得不错的效果。目标部分用一两句话重申这个SKILL要完成什么。虽然元数据里已经写了但主体里再写一遍有助于模型在加载后快速进入状态。步骤部分是核心按执行顺序列出每一步做什么。每一步的粒度要适中太粗了模型不知道怎么执行太细了又显得啰嗦。我的经验是一个步骤对应一个明确的动作比如“读取输入文件”、“提取关键信息”、“按照模板生成输出”。注意事项部分写那些容易出错的地方。比如“如果输入文件为空直接返回错误提示不要尝试生成内容”、“日期格式统一使用YYYY-MM-DD不要使用其他格式”。这些注意事项往往是从实际踩坑中总结出来的是SKILL价值的重要体现。输出格式部分明确告诉模型最终输出应该长什么样。可以给一个模板也可以给一个示例。有明确格式要求的任务这一步不能省。我试过不写输出格式结果模型每次生成的格式都不一样后续处理非常麻烦。4.4 一个完整SKILL示例会议记录结构化下面这个SKILL是我在实际项目中反复打磨过的用来把自由格式的会议记录转换成结构化摘要。你可以直接拿去用也可以根据自己的需求调整。--- name: meeting-summary description: 将自由格式的会议记录转换为结构化摘要提取行动项、决策记录和待跟进问题。当用户提供会议记录文本并请求整理时使用。输出为Markdown格式的结构化文档。 ---# 会议记录结构化 ## 目标 将非结构化的会议记录转换为包含行动项、决策记录、待跟进问题的标准格式摘要。 ## 执行步骤 1. 读取用户提供的会议记录全文。如果内容为空或明显不是会议记录返回提示信息并终止。 2. 识别会议基本信息日期、参会人员、会议主题。如果某项信息缺失标注为“未提及”。 3. 提取行动项。行动项的判断标准包含明确的动作动词如“完成”、“提交”、“确认”且有明确的负责人或截止时间。每条行动项记录为负责人 | 动作 | 截止时间 | 备注。 4. 提取决策记录。决策的判断标准包含“决定”、“确定”、“通过”等表示结论的词汇。每条决策记录为决策内容 | 决策依据 | 影响范围。 5. 提取待跟进问题。判断标准讨论中没有得出结论、需要后续确认、或明确标记为“待定”的事项。每条记录为问题描述 | 当前状态 | 建议下一步。 6. 按照输出格式生成最终文档。 ## 注意事项 - 行动项的负责人如果原文没有明确标注为“待分配”不要自行推断。 - 决策记录只记录已经明确结论的事项讨论过程中的观点不作为决策。 - 如果会议记录中同一事项在不同位置重复出现合并为一条取最完整的描述。 - 日期格式统一为YYYY-MM-DD。如果原文只有“下周三”这类相对时间保留原文并标注“需确认具体日期”。 ## 输出格式 markdown # 会议摘要[会议主题] **日期**[日期] **参会人员**[人员列表] ## 行动项 | 负责人 | 动作 | 截止时间 | 备注 | |--------|------|----------|------| | ... | ... | ... | ... | ## 决策记录 | 决策内容 | 决策依据 | 影响范围 | |----------|----------|----------| | ... | ... | ... | ## 待跟进问题 | 问题描述 | 当前状态 | 建议下一步 | |----------|----------|------------| | ... | ... | ... |这个SKILL的SKILL.md主体大约600字结构清晰每一步都有明确的判断标准。实际测试中模型执行这个SKILL的准确率比我之前写的“把所有要求混在一起”的版本高出很多。 ### 4.5 外部文件怎么组织才合理 当SKILL.md主体超过800字或者某些内容只在特定条件下才需要时就应该拆到外部文件。我常用的拆分策略是检查清单放一个文件示例集合放一个文件背景知识放一个文件。 检查清单文件适合存放那些“逐项核对”的内容。比如代码审查SKILL里可以把所有检查项列成一个清单文件SKILL.md里写“读取references/checklist.md逐项检查并记录结果”。这样模型在执行时会先读清单然后一项一项过不容易遗漏。 示例文件适合存放“输入输出对照”的内容。比如格式转换SKILL可以把几个典型的输入输出示例放在一个文件里SKILL.md里写“参考references/examples.md中的示例格式”。模型看到具体示例后生成的结果会更符合预期。 背景知识文件适合存放那些“解释为什么”的内容。比如某个业务规则SKILL可以把规则背后的业务逻辑放在一个文件里SKILL.md里写“如果遇到规则冲突读取references/background.md了解优先级判断依据”。这样模型在遇到边界情况时有据可依。 注意外部文件的引用路径要写相对路径从SKILL根目录开始。不要写绝对路径不要写“../”这种跳出SKILL目录的路径。不同平台对路径的处理方式可能不同相对路径是最稳妥的选择。 ## 5. 常见问题与排查技巧实录 ### 5.1 SKILL不被触发怎么办 这是最常见的问题。你写了一个SKILL测试时模型却完全不用它。排查思路按以下顺序进行。 先检查元数据。description是否准确描述了使用场景我见过有人写“处理数据”结果模型遇到数据相关任务时根本想不起来用这个SKILL。改成“当用户提供CSV文件并请求清洗和格式转换时使用”触发率立刻上去了。 再检查文件位置。SKILL是否放在了平台指定的目录下不同平台的目录约定不同有的放在项目根目录的.skills/下有的放在用户主目录的~/.claude/skills/下。放错位置模型扫描不到自然不会触发。 然后检查文件命名。SKILL.md必须大写不能写成skill.md或Skill.md。有些平台对文件名大小写敏感写错了就加载不了。 最后检查是否有冲突。如果你有多个SKILL的description描述的场景有重叠模型可能会犹豫不决。这时候需要把description写得更精确明确区分各自的适用场景。 ### 5.2 SKILL执行到一半中断或跳过步骤 这种情况通常是外部文件引用出了问题。模型读到“读取references/checklist.md”时如果文件不存在或路径不对它可能会跳过这一步继续执行也可能直接中断。排查方法是先确认文件确实存在然后确认路径拼写完全一致。 另一个可能的原因是步骤描述不够明确。比如写“检查代码质量”模型不知道具体检查什么可能就随便看看跳过了。改成“逐行检查代码确认每个函数都有错误处理、每个循环都有边界检查、每个外部调用都有超时设置”模型就知道具体要做什么了。 还有一种情况是步骤太多导致模型“疲劳”。我试过一个SKILL有十五个步骤执行到第十步左右模型就开始敷衍。后来拆成两个SKILL每个七八步执行质量明显提升。一个SKILL的步骤数控制在十步以内比较稳妥。 ### 5.3 输出格式不稳定怎么调 输出格式不稳定的根本原因通常是格式要求不够具体。只写“输出Markdown格式”是不够的模型对Markdown的理解可能和你不一致。要给出具体的模板或示例。 我习惯在SKILL.md里直接嵌入一个输出模板用代码块包起来。模型看到具体模板后生成的结果会高度一致。如果模板比较复杂可以放在references目录里SKILL.md里写“严格按照references/output-template.md的格式生成输出”。 还有一个技巧是在注意事项里加一条“输出中不要添加模板之外的任何额外内容”。有时候模型会自作主张加一些“总结”、“备注”之类的东西明确禁止后就能避免。 ### 5.4 常见问题速查表 | 问题现象 | 可能原因 | 排查方法 | 解决措施 | |----------|----------|----------|----------| | SKILL不被触发 | 元数据描述不准确 | 检查description是否包含场景关键词 | 重写description明确使用场景 | | SKILL不被触发 | 文件位置错误 | 确认SKILL目录是否在平台指定路径下 | 移动到正确目录 | | 执行中断 | 外部文件引用路径错误 | 检查SKILL.md中的引用路径 | 修正为正确的相对路径 | | 执行中断 | 外部文件不存在 | 确认references目录下文件是否存在 | 创建缺失的文件 | | 跳过步骤 | 步骤描述过于模糊 | 检查步骤是否有明确的动作和判断标准 | 细化步骤描述增加判断条件 | | 输出格式不稳定 | 格式要求不具体 | 检查是否提供了模板或示例 | 在SKILL.md中嵌入输出模板 | | 输出内容冗余 | 缺少禁止性约束 | 检查注意事项是否明确禁止额外内容 | 增加“不要添加模板之外内容”的约束 | | 执行质量下降 | 步骤过多导致注意力分散 | 统计SKILL.md中的步骤数量 | 拆分为多个SKILL每个不超过十步 | ### 5.5 几个我踩过的坑 第一个坑是过度依赖模型的理解能力。我一开始写SKILL时喜欢用“合理处理”、“适当调整”这类模糊表述觉得模型应该能理解。实际测试发现模型对“合理”的理解和我的预期经常不一致。后来我把所有模糊表述都改成了具体判断标准执行准确率大幅提升。 第二个坑是忽略了负面约束。我只写了“要做什么”没写“不要做什么”。结果模型在执行时经常添加一些我没要求的内容比如自动生成总结、自动补充示例。后来在注意事项里加了“不要生成模板之外的任何内容”、“不要自行推断缺失信息”输出就干净多了。 第三个坑是测试用例太少。我写完一个SKILL后只测了两三个用例就上线了结果遇到边界情况时各种出问题。后来我养成了习惯每个SKILL至少准备十个测试用例包括正常情况、边界情况、异常输入。测试用例多了问题暴露得就充分。 第四个坑是版本管理混乱。我改SKILL时经常直接覆盖原文件改坏了想回退都回不去。后来用Git管理SKILL目录每次修改都提交出问题随时回退。这个习惯强烈推荐。 ## 6. 让SKILL真正好用的几个进阶思路 ### 6.1 用脚本处理确定性计算 SKILL里有些步骤是确定性的比如日期格式转换、数据校验、文件解析。这些步骤如果让模型来做不仅慢还可能出错。更好的做法是写一个脚本放在scripts目录里SKILL.md里写“运行scripts/validate.py进行数据校验根据返回结果决定下一步”。 脚本的好处是结果确定、速度快、不消耗模型注意力。我有个数据处理SKILL原本让模型逐行检查数据格式一千行数据要跑好几分钟还经常漏检。后来写了个Python脚本做格式校验模型只需要读取脚本输出的错误列表处理时间降到几秒钟准确率也上去了。 脚本的编写要注意几点输入输出格式要明确错误处理要完善不要依赖外部环境。脚本最好用标准库避免依赖第三方包因为不同运行环境的包安装情况可能不同。 ### 6.2 用示例锚定输出风格 模型生成内容时风格往往不稳定。有时候很简洁有时候很啰嗦。解决方法是给示例。在SKILL.md或references里放几个输入输出对照的示例模型会模仿示例的风格。 示例的选择有讲究。不要只给一个示例至少给三个覆盖不同的输入情况。示例要典型不要选太特殊的案例。示例的输出要精心打磨因为模型会把它当作标准来模仿。 我有个文档摘要SKILL之前生成的摘要长度忽长忽短。后来在references里放了三个示例分别对应短文档、中等文档、长文档的摘要风格输出长度就稳定多了。 ### 6.3 用条件分支处理复杂场景 有些任务在不同情况下需要走不同的流程。比如代码审查SKILL审查新功能和审查bug修复的关注点不同。这时候可以在SKILL.md里写条件分支“如果变更类型是新功能重点检查接口设计和测试覆盖如果变更类型是bug修复重点检查根因分析和回归测试”。 条件分支不要写得太复杂两三层就够了。分支太多模型容易迷路。如果分支逻辑很复杂考虑拆成多个SKILL让模型根据场景选择加载哪个。 ### 6.4 持续迭代从能用 to 好用 SKILL不是写完就完了。实际使用中会发现各种问题需要持续迭代。我的习惯是每次使用SKILL后记录三个东西哪里执行得好、哪里执行得不好、下次怎么改进。积累几次之后针对性地修改SKILL.md。 迭代时要注意版本管理。每次修改前先提交当前版本修改后对比测试结果。不要一次性改太多地方否则出了问题不知道是哪个改动导致的。小步快跑每次改一两个点验证有效后再继续。 还有一个技巧是收集“失败案例”。每次SKILL执行出问题时把输入和输出保存下来作为后续测试的用例。这些失败案例是最宝贵的改进依据比凭空想测试用例有效得多。 ## 7. 关于SKILL工程化的一点个人体会 写了这么多SKILL之后我最大的体会是**SKILL的质量不取决于你写了多少而取决于你删了多少。** 我早期写的SKILL动辄两三千字恨不得把所有知道的东西都塞进去。后来发现真正好用的SKILL往往很精炼SKILL.md主体控制在五百字左右只写最核心的步骤和最容易出错的注意事项其他内容全部拆到外部文件按需加载。 另一个体会是SKILL的调试成本比写代码高。代码出错了有报错信息SKILL出错了往往只是“结果不太对”需要仔细对比输入输出才能定位问题。所以测试用例要准备充分执行日志要仔细看。我现在的习惯是每个SKILL至少跑二十个测试用例覆盖各种边界情况确认稳定后才正式使用。 最后一个体会是关于“去AI味”的。很多人写SKILL时喜欢用很正式、很书面化的语言觉得这样显得专业。但实际上模型对自然语言的指令理解得更好。用“检查一下有没有空值”比用“执行空值校验操作”效果更好。写SKILL时想象你在跟一个聪明但不太了解你业务的同事交代任务用最直接、最具体的语言效果往往最好。 如果你刚开始写SKILL建议从最简单的任务入手比如“把一段文字翻译成英文并保持格式”。写完之后反复测试观察模型在哪里出错然后针对性地修改。写三五个简单SKILL之后你对SKILL的运作机制就会有直观感受再写复杂SKILL就顺手多了。