先讲个我常碰到的情况:很多人一听说“skill”,第一反应就是“哦,不就是把一段很长的 prompt 整理一下吗”,然后照着网上的模板填一填,塞进 agent 的工具目录,跑通一个例子就算完事了。结果真到换场景或者换数据源的时候,要么完全不动,要么改一处崩三处,最后只能放弃,回头继续手写 prompt。我这两年折腾 skill 相关的事情,最大的体会是:skill 不是一个 prompt 文件,而是一次“能力建模”。它能不能跨场景复用、能不能被 agent 稳定地调用、能不能在团队里交给别人维护,靠的不是灵光一现的措辞,而是一套可重复的方法。
这篇文章想分享的,就是我从大量实践里抽象出来的一套创建流程。核心是五个阶段:锁定需求场景、抽象能力模型、实现最小可用版本、验证并打磨边界、复盘归档;外加一份 Review 清单,用来给 skill 的质量兜底。不管你在用的是 Claude Code、Codex,还是其他支持自定义技能包的 agent 工具,这套方法的思路都是通用的。适合三类人看:一是写过几个 skill 但总觉得不好用的人,二是准备在团队里把 skill 工程化、规范化的人,三是对 agent 自动化感兴趣、想少走弯路的开发者。
1. Skill 到底在解决什么问题
1.1 Skill、Prompt、Workflow 和 Agent 的关系
很多人把 skill 和 prompt 混为一谈,这是很多问题的根源。我用一个比较生活化的类比来解释。
Prompt 就像你随口跟一个新来的实习生说“帮我把这份会议记录整理一下”。实习生可能听懂了,也可能没听懂,整理出来的格式全看他的发挥。Workflow 是你给实习生画了一条固定流程:第一步做什么,第二步做什么,判断条件是什么,做完以后递给你什么。Agent 是那个实习生本人——他能自己看情况调用各种工具、拆解任务、逐步执行。
Skill 是什么呢?Skill 不是“一句话指令”,而是一种可以反复调用的能力包。它通常包含一个说明文档、若干示例、必要的模板或者参考文件。你交给 agent 的不仅仅是一句话,而是一整套“操作手册 + 模板 + 工具包”。下次再遇到同类任务,agent 可以直接把整个能力包拿出来用,而不是临时理解你的一句话。
用表格看会更清楚:
| 名词 | 本质 | 类比 | 复用性 |
|---|---|---|---|
| Prompt | 一次性指令 | 随口交代 | 低 |
| Skill | 可复用的能力封装 | 操作手册 + 模板 + 工具箱 | 高 |
| Workflow | 固定步骤的流程编排 | SOP 流程图 | 中 |
| Agent | 自主执行任务的载体 | 能看情况办事的实习生 | 最高 |
结论是:如果你的任务只做一次,写 prompt 完全够用;但如果你发现自己每隔几天就要用类似的方式处理类似的事,那就该把它 skill 化了。
1.2 大多数 skill 写出来不好用的原因
我在实际看过不少别人写的 skill,也 review 过团队里提交上来的 skill,发现一些高度重复的问题。
第一类是为了写而写。有些人看到别人发了 skill,自己也照着格式写一个,但根本没想清楚这个 skill 要在什么场景下、给谁用、解决什么痛点。结果就是“这也能叫 skill?”,一点存在感都没有。
第二类是贪多求全。一个 skill 想覆盖十几种场景,文档写了几千字,示例五花八门,agent 加载以后光读说明书就要消耗大量上下文,执行起来反而犹豫不决、频繁跑偏。
第三类是缺少边界处理。只在理想场景下测试过,稍微遇到一点格式异常、输入缺失,就崩了。比如让模型提取日期,结果用户给的是“上周五”,而你的 skill 只认“YYYY-MM-DD”,它就直接报错或者乱提取。
第四类是可维护性太差。所有说明、示例、参数塞在一个超大文件里,后来要改一个小逻辑,简直是牵一发而动全身,最后只能推到重写。
这些问题不是靠“多写几次”能解决的,而是需要一个稳定的流程来约束。这也是我为什么要写这篇方法论,把从需求到复盘的全过程固定下来。
2. 高效创建 skill 的五步流程
2.1 第一步:锁定需求场景,而不是直接想 prompt
很多人写 skill 的第一个动作是打开编辑器开始敲字,这是错的。正确顺序是先回答几个问题,把场景锁死。
- 这个 skill 要在什么场景下被使用?是每周一次的例行整理,还是偶尔出现的批量处理?
- 谁来用?是只给自己用,还是团队成员都会用?他们使用的时候会不会补充额外说明?
- 输入的原始材料长什么样?是会议录音转写文本、聊天记录导出,还是代码仓库里的 Markdown 文件?
- 期望的输出物是什么?格式、长度、颗粒度有没有硬性要求?
- 如果输入不符合预期,希望 skill 怎么做?是报错、跳过,还是自动修复后继续?
这一步产出物是一段“场景描述”。举个例子:不要写“帮我整理会议纪要”,而要写“我每周五下午会导出一周以来的会议转写稿,每篇大约 2000 到 5000 字,语言是中文,夹杂英文术语。我需要你提取每场会议的目标、决策、待办事项、风险点,并生成一份按会议分节、按议题归并的周报,总字数不超过 800 字,待办需要标出负责人和截止时间”。
看到没有,锁定了场景以后,后面的抽象和实现才有依据。没有这个基础,写出来的 skill 就是无根之萍。
2.2 第二步:抽象能力模型,把需求变成接口
场景锁定之后,不要急着写文案,先做抽象。抽象的目标是把“一个一个的具体任务”归纳成“一类能力”。
我常用一个三步法:
- 列变体:把所有可能遇到的任务变体都列出来。同样一个“会议纪要整理”,可能会有“周会、项目评审会、1对1 沟通”等不同场景,输出要求也可能完全不同。
- 找公共骨架:这些变体里,哪些是不变的流程?几乎都会有“读取原始文本 → 理解讨论脉络 → 提取要点 → 按固定结构输出”这几步。
- 参数化差异点:变体现在不同的地方,比如输出语言、是否需要生成待办、标题格式等,把它们变成可配置的参数,而不是各自写死。
抽象完以后,你会得到一个“能力模型”,它包含四个要素:输入接口、输出接口、处理步骤、可配置参数。此时你还没有写任何具体的 prompt,但已经知道这个 skill 长什么样子了。
这里有个判断标准:如果你发现这个 skill 的输入输出接口跟另一个已有的 skill 高度重合,那就需要考虑是不是该合并,或者拆分成“获取输入 → 处理 → 输出”的子能力。抽象的目的不是把东西变复杂,而是让每次新增场景时的“增量成本”尽量小。
2.3 第三步:实现最小可用版本,重点是结构
抽象完成后,才开始动笔写实现。一个典型的 skill 目录结构通常是这样的:
my-skill/ ├── SKILL.md # 主说明文件,含 frontmatter 和核心指令 ├── examples/ # 示例输入和输出,方便 agent 理解 │ ├── example-input.md │ └── example-output.md ├── references/ # 参考资料、详细规则、模板 │ ├── template.md │ └── rules.md ├── scripts/ # 可选的辅助脚本 │ └── preprocess.py └── assets/ # 可选的静态资源这里的核心是 SKILL.md。它不应该是一篇说明文,而应当是面向模型的结构化指令。我习惯把 frontmatter 里写好 name 和 description,description 尤其关键,因为 agent 依靠它来判断“什么时候该用这个 skill”。description 写得太宽泛,agent 容易在无关场景调用;写得太狭窄,该用的时候又找不到。
--- name: meeting-minutes description: 将会议转写稿或聊天记录整理为结构化纪要。适用于周会、评审会、1对1沟通等场景。输入为原始转写文本,输出为含会议目标、决策、待办、风险的结构化文档。 ---正文部分建议用“角色 + 背景 + 步骤 + 输出格式”的结构,但别写太长。一个常见的误区是以为写越多模型执行得越准,实际上超过模型上下文舒适区以后,多余的说明反而会稀释注意力。把长内容放进 references,在 SKILL.md 里只保留索引和关键决策点,是我强烈建议的做法。
“最小可用版本”的意思就是先别追求完美,先把主流程跑通。从 0 到 1 的阶段,你只需要覆盖 60% 的“黄金场景”,剩下的边界可以后面再补。
2.4 第四步:验证并打磨边界,别急着宣布成功
我第一次写 skill 的时候,跑通了一个例子就觉得自己完成了,结果换个场景立刻翻车。后来我总结了三层验证法。
第一层是黄金场景验证:直接把最容易出现的那个场景拿来做测试,看输出是否符合预期。比如会议纪要这个例子,就拿一份真实的周会转写稿来试,而不是用自己虚构的素材。
第二层是变体验证:针对你抽象时识别的“参数化差异点”,逐个改变参数再测试。比如把语言改成英文、把输出格式从 Markdown 改成表格、把输入长度增加三倍,看模型是否还扛得住。
第三层是对抗验证:故意给那些可能让 skill 崩溃的输入,比如空文本、全符号文本、输入内容里没有会议信息等。你要确认的是它不会“硬编造”一份纪要出来,而是会报错、要求补充信息,或者输出一个明确的“无有效内容”的占位结构。
这一步产出的是一张测试记录表。哪条过了、哪条没过、改动以后影响什么,全部记下来。这张表后面会直接变成你 Review 清单的素材。
2.5 第五步:复盘、命名与归档
很多人的 skill 写完就开始用,用完了也不复盘,导致同类问题在下一次写新 skill 时再次踩坑。我建议每次完成一个 skill 以后,抽出 10 分钟做一个轻量复盘。
复盘要回答三个问题:抽象出的能力模型是否真的覆盖了实际使用场景?验证阶段暴露的问题有没有共性,能不能沉淀成一条“编写规范”?这个 skill 的命名和描述是否足够让人(或让 agent)一眼看懂它该何时使用?
命名这里有个小建议:用“动词 + 对象”的格式,比如generate-report、extract-contacts、summarize-changelog,尽量避免用utils、helper、misc这种含糊的名字。归档的时候,把还在迭代中的版本放到工作目录,把稳定版本放到正式的 skills 目录,把废弃版本直接移走或是打上 deprecated 标记,不要留在原地干扰 agent 的判断。
3. 方法抽象是核心中的核心
3.1 抽象不是想当然,而是找到“可跨场景复用的那一层”
做 skill 设计的时候,“抽象”这个词是最容易误导人的。有些人一上来就想要一个“万能 skill”,什么都能处理,结果什么都处理不好。这里要分清抽象层级。
我把抽象分成三层:
- 操作级抽象:处理某个具体的原子操作,比如“把 Markdown 表格转成 CSV”“提取一篇文章的关键词”。
- 任务级抽象:完成某个完整的任务,比如“把会议转写稿整理成结构化纪要”。它内部会组合多个操作。
- 角色级抽象:模拟某种身份或专业角色,比如“资深产品经理”“数据分析师”。这类 skill 通常不绑定具体任务,而是提供思维方式。
选择哪个层级,取决于复用场景。如果你只需要在多个任务中复用“把表格转 CSV”这一步,那操作级就够了;如果你每周都有“整理会议纪要”的完整任务,那就应该落到任务级;只有当你想给 agent 建立一种长期稳定的“行为方式”时,才需要考虑角色级。
大多数失败的 skill 都是因为层级没选对。把角色级当操作级用,会显得空泛;把操作级当任务级用,又扛不住复杂输入。
3.2 参数化:把“差异”变成“变量”,而不是派生效副本
这是方法抽象里最重要的一步。
我在实际项目里见过一种反面典型:因为要支持“中文会议”和“英文会议”,有人直接复制了整份 skill,改了几个词变成两个文件。这样当然也能用,但一旦要修改公共逻辑,就得同步改两份,改到后面必然出现不一致。
正确做法是把差异点参数化。我拿“会议纪要整理”继续举例:
| 变化维度 | 一次性做法 | 参数化做法 |
|---|---|---|
| 语言 | 写死“中文” | language: zh/en |
| 输出格式 | 只输出 Markdown | format: markdown/table/json |
| 待办要求 | 不生成待办 | include_todos: true/false |
| 摘要长度 | 固定 200 字 | max_summary_words: 200/500/800 |
| 发言人标注 | 不需要 | with_speaker: true/false |
参数不是越多越好。我见过一个日志分析 skill 列了二十多个参数,结果 agent 在执行的时候光理解参数就花掉了大量上下文。我个人的经验是:保留那些真正会改变处理逻辑的参数,把那些只是微调表述的参数砍掉。如果两个参数导致的结果差异只有 5%,大概率不值得暴露给用户。
参数化之后,使用 skill 的方式就变成了在调用时传入参数,而不是为每种场景维护一个副本。这也是“方法抽象”最直观的收益。
3.3 警惕两种抽象失败:过度抽象与过浅抽象
抽象这件事,失败案例往往比成功案例更有教育意义。
过度抽象的典型表现是:为了让 skill“更通用”,把步骤写得模棱两可,比如“根据材料类型选择合适的处理方式”。这句话表面上看是灵活,实际等于没写,模型根本不知道该怎么选。每次调用结果都像开盲盒。
过浅抽象的典型表现是:只抽取了一个参数,其他所有内容都是复制粘贴改词。这种 skill 本质上还是“一堆 prompt 副本”,没有解决复用问题。
我给自己定了一个检验标准:当一个新的同类场景出现时,改动能不能控制在“一个文件、一个参数、一个段落”以内?如果不能,说明抽象层级选错了或者抽象得不够。
还可以用一个公式来衡量抽象的收益:复用收益 = 复用次数 × 每次节省的时间。只有当收益明显大于抽象成本时,才值得把某个能力从一次性需求里“抽”出来。有些任务一年就用两次,抽象它纯属自我感动。
4. Review 清单:把质量底线固定下来
4.1 为什么靠感觉靠不住,必须用清单
人有两种典型的判断偏差:第一,自己写的东西怎么看都顺眼;第二,能跑通一次就默认“没问题”。这两种偏差放到写 skill 上,会直接导致质量失控。
评审清单的作用不是限制创造力,而是把基础的质量底线固定下来。就像写代码要有 code review 一样,写 skill 也应该有 review。对于个人开发者,这份清单能在发布前帮自己“泼一盆冷水”;对于团队协作,这份清单则可以作为合并到主分支之前的门禁。
我把清单分成两层:门禁级和加分项。门禁级不满足就绝对不能合并,加分项可以根据实际情况取舍。
4.2 主清单:从结构到体验的九个检查项
我整理了九个检查域,基本覆盖了我 review 过的 skill 里会反复出现的问题。
| 检查域 | 检查项 | 通过标准 | 常见失败案例 |
|---|---|---|---|
| 结构完整性 | 目录和文件是否齐全 | SKILL.md、examples、references 齐备,引用路径正确 | 示例文件路径写错,agent 找不到 |
| 接口明确性 | 输入输出是否有清晰描述 | 描述可被 agent 检索到,且不依赖用户额外解释 | description 写得太泛,导致无关场景误调用 |
| 示例有效性 | 示例是否覆盖主流程 | 至少有一个完整输入输出对,能引导模型理解任务 | 示例与真实任务差异过大,模型照猫画虎反而出错 |
| 边界处理 | 非法输入是否有兜底 | 遇到格式异常能报错或输出占位结构,不硬编造 | 输入为空时,模型生成了虚构的会议纪要 |
| 上下文预算 | 主文件是否控制篇幅 | SKILL.md 在 1000 字以内,长内容放 references | 文档超过 4000 字,模型加载后频繁偏离主任务 |
| 安全与权限 | 是否避免高危操作 | 不诱导模型执行系统级命令,脚本有权限校验 | skill 让模型直接删除目录,酿成事故 |
| 可维护性 | 是否便于后续迭代 | 参数集中定义,公共逻辑无重复 | 两个参数作用重叠,改动互相影响 |
| 可发现性 | 名称和描述是否准确 | 命名符合“动词+对象”,描述能匹配触发场景 | 名叫utils,agent 根本不会主动调用 |
| 最终体验 | 是否值得被反复使用 | 输出结果稳定,模型没有频繁犹豫或返工 | 同一个输入反复跑,每次结果差异巨大 |
这九个检查项不需要每次全部做到完美,但至少门禁级(结构完整、接口明确、边界处理、上下文预算、安全)必须过关。
4.3 10 分钟快速 review 法
如果觉得完整清单太重,可以用一个轻量版本的快速 review。它只需要三个问题:
- 一个完全没接触过这个 skill 的 agent,拿到文件后能不能不追问就完成主流程?如果可以,说明结构清晰、示例有效;如果需要猜测,说明描述和示例还没到位。
- 当输入不符合预期时,skill 是会优雅降级还是直接崩溃?优雅降级包括报错、输出占位结构、要求补充信息;直接崩溃包括编造结果、无限循环、执行危险命令。
- 我要新增一个同类场景时,改动量是多少?如果超过一个小节,就说明抽象层级或者参数化做得不够。
这三个问题分别对应着可读性、鲁棒性和可扩展性。每次发布新 skill 之前,花 10 分钟过一遍这三个问题,能过滤掉绝大多数低级问题。
4.4 一份可以直接复制的 Review 清单模板
下面的模板可以直接粘贴到你的项目仓库里,作为 skill 合并前的必检项。
## Skill Review Checklist - [ ] SKILL.md 存在于根目录,frontmatter 包含 name 和 description - [ ] description 能在目标场景下被 agent 正确触发 - [ ] 输入接口和输出格式有明确、具体的说明 - [ ] 至少有一个完整的主流程示例(输入 + 正确输出) - [ ] 对空值、格式异常等边界输入有兜底行为 - [ ] SKILL.md 主体不超过 1000 字,长内容放 references - [ ] 不包含任何危险操作或未授权的副作用 - [ ] 参数集中定义,不同参数之间没有职责重叠 - [ ] 命名遵循“动词 + 对象”,无歧义 - [ ] 经过至少一个真实场景的测试,且测试结果已记录5. 一次真实案例复盘:一个“客户反馈周报” skill 的诞生
5.1 需求背景:看似简单,其实暗藏很多坑
有一段时间,我每周都要把散落在各种群聊、邮件、文档里的客户反馈整理成周报。任务是:找出客户提了哪些问题、哪些需求,按产品和优先级分类,再生成一份给团队看的周报。
一开始我完全不觉得这需要写 skill,直接让 agent 读我粘贴的内容就行。第一周效果还不错,第二周换了新的聊天记录,它把我同事之间互相吐槽“这个功能真是难用”也当成了客户反馈,整理出来的周报失真的离谱。我意识到问题不在于“让 agent 理解自然语言”,而在于“如何定义客户反馈”。
5.2 重新进入五步流程:从场景锁定到参数化
我重新走了一遍流程。
第一步锁定场景后,我明确了这个 skill 的输入不是我随手粘贴的文本,而是“客户在公开渠道或售后渠道产生的内容,不包括内部同事讨论”。同时输出必须有“反馈原文摘录、对应产品模块、问题/需求分类、优先级”四个部分。
第二步抽象能力模型时,我发现真正核心的能力其实是“从非结构化聊天文本里,识别出哪些内容属于‘外部用户反馈’,剔除掉内部讨论和无关闲聊”。这一步属于任务级抽象,可以复用到别的场景,比如舆情监控、竞品分析。
第三步实现时,我把“反馈识别规则”写进了 references/rules.md,在 SKILL.md 里只放主流程和调用路径。所有关于“什么是客户反馈”的详细判据,放在规则文件里,后续想调整判断标准不必动主文件。
5.3 踩过的三个坑
坑一:开始没管输入范围,导致 agent 把研发群的技术讨论误判成客户反馈。解决方式是加了一个前置步骤:先标记“消息来源”,再根据来源决定是否进入反馈分析流程。
坑二:参数塞太多。我在第一版里加了include_sentiment、include_version、include_channel、include_priority等一堆参数,结果模型光理解参数就消耗了大量上下文,整理出来的周报反而丢了三项重要信息。后来砍到只剩format和max_items两个参数,效果立刻稳定下来。
坑三:示例太长。最初我在 examples 里放了一份接近 3000 字的完整聊天记录,想“展示真实场景”,结果 agent 处理新输入时总是往示例的格式和内容上“靠”,而不是按规则处理。后来我把示例压缩到只有两段对话,同时附上标准的输出结构,问题就消失了。
5.4 最终版本的输出效果
最终的 skill 在测试里,对一份包含 120 条消息的聊天记录,能正确识别出其中 18 条客户反馈,准确率和召回率都比我预期的要好,而且输出稳定,同一个输入跑三次结果基本一致。这件事之后我更加确信:好的 skill 不是一次写出来的,而是在验证和复盘里磨出来的。
6. 常见问题速查表
6.1 一张表解决 80% 的排查
我自己写 skill 过程中遇到过的典型问题,整理成了一张速查表,可以按图索骥。
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| agent 在无关场景调用了 skill | description 太宽泛,触发条件不明确 | 收紧 description,增加“仅当…时使用” |
| 该用的时候 agent 却不用 | 描述与触发场景不匹配,或命名太难理解 | 用具体场景词重写 description,测试不同措辞 |
| 执行结果忽好忽坏,不稳定 | 示例不足或示例与真实输入差异过大 | 增加高质量示例,压缩规则文本 |
| 输出格式经常跑偏 | 输出格式说明不具体,示例缺失 | 提供明确模板和反例 |
| 模型加载 skill 后上下文不够用 | SKILL.md 太长,或 references 被整体加载 | 压缩主文件,长内容拆分为按需读取 |
| 修改一个参数后别的环节崩了 | 参数职责重叠或文档前后不一致 | 集中定义参数,检查文档是否同步更新 |
| 遇到空输入或异常输入时编造结果 | 缺少边界处理指令 | 加入“如果输入无有效信息,则输出占位结构”等兜底规则 |
| skill 在团队里没人用 | 缺乏可发现性或名字太含糊 | 改名、补充 description、写一份简短使用说明 |
6.2 三个容易忽略但很要命的细节
第一,frontmatter 里的 description 不是给人看的,是给模型检索用的。很多人把 description 写成给同事看的简介,结果 agent 判断是否调用时抓不住关键信息。建议包含触发场景、输入类型、输出类型三个要素,并且用“仅当”“当……时”这类约束词。
第二,格式问题不只是美观问题。YAML frontmatter 的缩进、SKILL.md 里的标题层级、列表符号,都会影响模型解析。同一个 skill 在一种模型上表现良好,换一个模型可能就因为解析差异完全失效。发布前至少在每个目标模型上跑一次主流程。
第三,skill 的“品味”需要有意积累。很多 skill 功能上没问题,但用起来就是“不对劲”,这大多出在对示例、措辞、细节的品味上。我的建议是,遇到一个你觉得“这个 skill 真聪明”的实现,不要只是收藏,拆开看看它的示例怎么选的、规则怎么排布的、参数怎么命名的。看得多了,写出来的 skill 自然会有质感。
最后分享一个我自己一直在用的小技巧:我会在工作目录里保留一个名字叫scratch的草稿 skill,任何新想法先丢进去,随便写、随便改,等它跑通了、稳定了,再走一遍正式流程把它收拾干净。这样做的好处是,不会因为“还没想好”就干脆不写,也不会让半成品污染正式目录。写 skill 和写代码一样,最难得的不是“会写”,而是“有一套稳定的流程让自己每次都写得可靠”。希望这份流程和清单,能帮你少走一些我走过的弯路。