
过去几个月我一直在和一个问题较劲AI对话能力明明很强可真让它独立完成一件具体工作——比如把一份需求文档变成规范的代码、把小说章节转成分镜脚本——它总是差那么一步。不是不会是不够稳。直到我把工作方式改成“Skills驱动”这个问题才算真正解决。如果你也在折腾Claude、Codex这类Agent你大概率已经听过Skills这个词但我要说的是很多人其实没有真正理解它是什么只是把它当成了一种“高级Prompt”。这篇文章我尽量把Skills的第一性原理、执行链路、开发方法和实战中踩过的坑讲透希望能帮你少走弯路。1. 被低估的Skills先搞清楚它到底解决了什么问题1.1 一次真实的翻车现场长Prompt的极限之前我做过一个分镜脚本生成的自动化流程。当时最直接的想法是把分镜规则全部写进Prompt里景别怎么定、运镜怎么写、时长怎么算、对白格式是什么样洋洋洒洒写了两千字。前几次测试还行但只要场景一复杂模型就开始“发挥”了该给特写的时候给全景该标镜头号的时候直接跳过格式说变就变。这个问题的根源是长Prompt本身有三个无法规避的毛病上下文占用极高两千字的规范每次对话都要重复占用还没开始干活上下文窗口已经吃掉一大截模型注意力分散规范里信息太多模型分不清哪些是硬性要求、哪些是参考建议执行时容易自己“挑重点”无法复用和版本化规则改一个标点整套Prompt就得复制粘贴一次时间一长根本不知道线上跑的是哪个版本。后来我把这套分镜规则改成了Skill问题立刻缓解了不少。原因很简单Skill不是把规则塞进对话里而是把规则放在一个独立的、按需加载的文件中模型只在需要的时候才读取它。这个概念上的差别是关闭“不稳定”这个开关的关键。1.2 Skills和Prompt、Tool、Agent的分工很多人分不清这几个概念我打个比方。Prompt是口头交代任务你嘴上说得再清楚对方记不记得住、会不会理解偏取决于对方的临场状态。Function Calling或者Tool是给模型一把专用工具比如一个计算器、一个数据库接口它能帮你算一个数、查一条数据但工具本身不会告诉模型“该怎么用它”。而Skills是给模型一本SOP手册加一个配套工具箱手册写清楚什么时候用、按什么步骤操作、操作完输出什么格式工具箱里是可执行的脚本。至于Agent它是那个拿着工具箱干活的人负责判断、调度和结果整合。Skill是Agent的工具箱里的一个专业套件。这个区分非常重要。Tool解决的是“能做什么”的问题Skill解决的是“怎么把一件事做成”的问题。在真实业务里很多任务不是单点调用一个API就完事而是包含判断、拆解、执行、校验、输出这一整串流程这恰恰是Skill擅长覆盖的。1.3 为什么这类机制现在是热点Skills能在Claude、Codex这些主流Agent生态里迅速火起来核心原因是Agent应用正在从“演示”走向“生产”。演示阶段模型靠内化的知识就够了你让它写首诗、总结个文档它自己就能搞定。但生产环境里AI要交付的是稳定、可复现的结果知识不足的部分必须靠外部流程补足。Skills本质上是把行业经验沉淀成了可执行资产。一个成熟的开发团队可以把代码规范、审查要点、发布流程封装成一组Skill让Agent按照团队的标准工作一个编剧工作室可以把分镜规则、脚本格式、行业术语封装成一个Skill让Agent产出符合行规的内容。这些资产可以版本化、可以分享、可以不断迭代这是单纯靠模型自身能力无法做到的。2. 从第一性原理看一个Skill的完整执行链路2.1 Skill的物理形态一个目录就是一个技能一个标准Skill并不是什么神秘的二进制文件它的物理形态就是一个目录里面放说明书、脚本和资源文件。典型的目录结构长这样my-skill/ ├── SKILL.md # 说明手册模型主要读这个 ├── scripts/ │ ├── run.py # 具体执行逻辑 │ └── helper.py # 辅助模块 ├── assets/ │ └── template.md # 输出模板 └── requirements.txt # Python依赖声明其中最重要的是SKILL.md它通常由两部分组成开头的YAML元信息和正文。元信息里最关键的是name和descriptiondescription是模型判断“当前任务要不要调用这个技能”的重要依据。正文则是给模型看的操作手册描述这个技能怎么用、输入是什么、输出是什么、有哪些注意事项。我第一次写SKILL.md的时候有个误区以为description只要写清楚“这个技能是干什么的”就够了。后来才发现description里必须写清楚“什么时候该用、什么时候不该用”否则模型会在不该调用的时候乱调用反而拖慢任务节奏。2.2 模型实际执行Skill时的内部顺序理解了物理形态再来看执行链路就简单得多。一个Agent在运行中加载并执行Skill大致经历以下几个阶段用户提出请求模型根据请求内容结合已有Skill的description判断当前任务可能需要的技能模型通过内置工具读取对应目录下的SKILL.md模型解析SKILL.md中的元信息和正文逐步理解操作步骤模型按步骤调用脚本传入参数等待脚本返回结果模型结合脚本结果生成面向用户的最终回答。这个链路里最容易被忽略的一点是Skill内容是按需加载的并不常驻上下文。也就是说模型在没有遇到相关任务时可能只知道“存在一个技能它的描述是什么”并不知道技能内部的详细指令。只有判断需要使用时模型才会把SKILL.md读进来。这种设计让Skill可以做得非常厚实而不用担心日常对话被无关内容占用大量上下文。2.3 为什么“把说明书交给模型”比“训练模型记住”更可靠从第一性原理来看模型本质上擅长的是语言理解和语言生成它天生不擅长精确的、机械化的计算和操作。你让它心算一个复杂的财务指标它容易出错但你给它一个脚本让它调用脚本去算结果就是稳定的。反过来脚本虽然精确但它听不懂“帮我大概看一下这个日志有没有异常”这种模糊指令。Skills的价值就是让模型负责“判断解释”让脚本负责“执行计算”各干各擅长的活。同时Skill还解决了模型知识边界的问题。模型不可能知道你们公司内部的部署流程、你习惯的代码风格、行业特有的术语规范。但这些信息都能写进SKILL.md里让模型在需要时读取。这比在模型训练阶段注入这些知识要高效得多也更符合实际生产的可维护性需求。3. 主流Agent生态里的Skills落地现状与获取渠道3.1 两个典型生态的技能机制对比现在市面上主流的Agent生态对Skills的落地方式大同小异但在细节上各有特点。我主要用过Claude和Codex两套体系简单对比一下。对比项Claude生态Codex生态存放位置个人级目录或项目级目录统一管理通过配置文件声明加载触发方式模型按需读取SKILL.mdAgent按任务自动组合格式要求标准SKILL.md格式社区相对统一更灵活强调与仓库配置结合适合任务通用工作流、创意生产、文档处理编码辅助、仓库级任务、工程流程分享渠道官方社区、GitHub仓库、第三方聚合站GitHub仓库、开发者分享说实话两套机制没有绝对优劣选哪套主要看你的主力工具是什么。我个人的习惯是做内容生产、脚本写作、分析报告这类任务用Claude生态的Skills多一点做代码工程、仓库级重构这类任务Codex生态的技能机制更顺手。你在选择时不用纠结先把一个生态玩透再去迁移到另一个也不难——因为底层逻辑是相通的。3.2 去哪里找Skill、怎么判断质量关于“Skills下载平台有哪些”这个问题我不能给你一个固定的清单因为这个领域变化太快今天存在的站点明天可能就换了方向。但有一个相对稳定的原则优先从官方渠道和GitHub上活跃维护的开源仓库获取。你在逛Skill相关仓库时可以从几个维度判断一个Skill的质量description质量好的Skill描述里会写清楚触发条件、使用边界、输出格式而不是笼统地说“帮助用户完成XX任务”依赖声明如果一个Python类Skill连requirements.txt都没有大概率作者没怎么考虑可移植性测试用例哪怕只有一个简单的测试脚本也说明作者认真验证过维护活跃度看最近一次提交时间、issue回复情况。一个一年多没更新的Skill往往已经和当前模型版本脱节了。需要特别提醒的是Skills本质是代码加载第三方Skill相当于在本地执行别人的脚本。所以不管从哪个渠道下载我都建议你打开目录看一眼脚本内容别稀里糊涂就放进生产环境。3.3 安装与版本管理的关键细节安装Skill本身没有难度多数生态就是拷贝目录到指定位置。真正容易翻车的是版本管理。Skill是会演化的作者调整了某个参数格式、修改了输出模板你的使用方式就可能不兼容。我就遇到过前一天还好好的分镜Skill第二天作者更新后输出格式从Markdown表格变成了JSON我这边所有下游处理全部报错。所以我建议凡是重要的、长期使用的Skill尽量在自己这边用Git管理并锁定版本。不要直接引用第三方仓库的最新分支而是fork或者复制一份到自己的仓库确认测试通过之后再启用。生产环境最怕的不是功能缺失而是行为漂移——同样的输入今天的输出和昨天不一样这比功能缺失更难排查。4. 手写一个自己的Skills从选场景到本地调试4.1 选场景什么样的任务值得做成Skill不是所有任务都值得做成Skill。做成Skill的收益取决于任务的稳定性和复用频率。我总结了一个判断标准满足条件越多越值得做任务的执行流程是稳定的不会今天一个做法、明天换一套逻辑任务有明确的输入和输出可以结构化描述任务会反复出现你或你的团队每周都会遇到好几次任务执行中存在客观的规范、格式或校验规则不能全凭模型自由发挥。比如分镜脚本生成就满足全部条件镜头语言有行业规范输入是剧本片段输出是结构化的镜头表格而且创作者几乎每周都在做类似的事。再比如前端开发中的组件代码生成、论文写作中的格式排版、数据清洗中的标准处理流程都是典型的Skill场景。反过来说那些发散性很强的任务——比如“帮我想个创意”“陪我做头脑风暴”——就不太适合做成Skill因为这类任务的价值恰恰在于不设限强行封装反而会限制模型的表现。4.2 搭一个标准Skill骨架以分镜脚本生成为例下面我用分镜脚本生成这个例子演示一个完整Skill的搭建过程。先说目录结构storyboard-skill/ ├── SKILL.md ├── scripts/ │ ├── generate_storyboard.py │ └── output_template.md └── requirements.txtSKILL.md是核心内容大致长这样--- name: storyboard-generator description: 将剧本片段转换为专业分镜脚本。当用户提供小说章节、剧本段落或视频创意需要生成包含镜头号、景别、运镜、时长、画面描述、台词/对白、音效提示的分镜表格时使用。不适合用于非视觉类内容规划。 --- # 分镜脚本生成技能 ## 适用场景 - 输入一段叙事文本小说章节、剧本段落、创意描述 - 输出Markdown格式的分镜表格 ## 执行步骤 1. 阅读用户输入的文本识别场景数量 2. 每个场景按叙事顺序拆分为若干镜头 3. 对每个镜头填写以下字段 - 镜头号按场景编号如S1-01 - 景别远景/全景/中景/近景/特写 - 运镜固定/推/拉/摇/移/跟 - 时长以秒为单位单个镜头建议3-8秒 - 画面描述具体、可拍摄的画面内容 - 台词/对白镜头内出现的对白或旁白无则填“无” - 音效环境音、音乐提示等无则填“无” 4. 以表格形式输出结束时附一段创作说明 ## 注意事项 - 镜头拆分的粒度要适中避免一个镜头塞过多动作 - 景别和运镜术语使用行业通用表达不要自造词 - 如果用户没有明确风格要求默认采用电影叙事风格这个文件的写法有几个讲究description开头是“将剧本片段转换为专业分镜脚本”点明核心功能随后用“当...需要...时使用”描述触发场景最后用“不适合用于...”划清边界。这三层结构能显著提高模型判断的准确率。4.3 脚本逻辑与接口设计让模型能正确调用你再来看scripts/generate_storyboard.py。这个脚本要接收模型传来的输入并生成结构化结果。在设计脚本入口时我有一条重要经验参数越少越好最好让模型只传一个字符串把复杂的解析工作留给脚本内部处理。下面是这个分镜Skill里脚本的简化示例#!/usr/bin/env python3 从文本生成分镜表格的脚本。用法python generate_storyboard.py --input 文本路径 import argparse import json import re def parse_scenes(text): # 简化实现按空行或“场景”关键字切分 parts re.split(r\n\s*\n|场景[一二三四五六七八九十\d], text) return [p.strip() for p in parts if p.strip()] def generate_storyboard(scene_text, scene_id): # 这里可以接入本地规则或模型接口生成镜头示例为启发式实现 shots [] sentences scene_text.split(。) for idx, sentence in enumerate(sentences[:6], start1): if not sentence.strip(): continue shot { shot_id: fS{scene_id}-{idx:02d}, shot_size: infer_shot_size(sentence), camera_move: infer_camera_move(sentence), duration: min(8, max(3, len(sentence) // 10)), visual: sentence.strip(), dialogue: extract_dialogue(sentence), sound: infer_sound(sentence), } shots.append(shot) return shots def main(): parser argparse.ArgumentParser() parser.add_argument(--input, requiredTrue, help输入文本文件路径) args parser.parse_args() with open(args.input, r, encodingutf-8) as f: text f.read() scenes parse_scenes(text) all_shots [] for si, scene in enumerate(scenes, start1): all_shots.extend(generate_storyboard(scene, si)) print(json.dumps(all_shots, ensure_asciiFalse, indent2)) if __name__ __main__: main()这里的设计思路是模型只需要把一个文本文件的路径传给脚本脚本内部去做切分、推断、输出JSON。脚本不要求模型理解复杂的函数签名模型的任务只是“把用户的原始叙述保存成文件然后调用脚本并传入路径”这样出错概率会低非常多。至于infer_shot_size那几个函数你完全可以根据行业经验写成规则函数或者让模型在脚本内部二次调用大模型接口但底层原则不变对模型暴露的接口必须是简单清晰的。4.4 本地调试没有验证就不要上线写完Skill后调试是重中之重。我一般会按照下面这个流程走一遍先手动跑脚本用几段真实素材验证脚本本身能产出合理的分镜结果。这一步是确认脚本逻辑没有低级错误。接着才把Skill放入Agent环境构造几条测试指令比如“把这段小说第一章的内容转成10个镜头以内的分镜”观察模型是否会触发这个Skill、是否按SKILL.md里的步骤执行、参数传递是否正确、输出格式是否稳定。我在调试时特别关注四个指标触发准确率、参数传递正确率、脚本容错程度、最终输出格式稳定度。如果触发准确率低问题多半出在SKILL.md的description写法上如果参数传递错误率高问题多半出在脚本入口设计上如果输出格式不稳定问题则在SKILL.md的正文指令不够强硬。每个问题都有迹可循调试起来并不玄学。5. 实战中反复翻车的四类问题与修复记录5.1 描述写得太抽象模型误触发我最早写的一个前端开发类Skilldescription是“用于帮助用户完成前端开发任务”。听起来没什么问题实际跑起来却是灾难。用户只要提到任何“网页”“布局”“样式”相关话题模型就会把这个技能加载进来哪怕用户只是随口问一句“这个页面配色怎么样”模型也会进入组件代码生成的流程反而更慢。修复方式是把description改成了“仅在需要生成完整React组件代码且用户明确要求代码实现时使用。不用于页面配色咨询、不用于样式微调、不用于代码解释”。加上这些边界之后误触发率降到了很低的水平。写description时多花十分钟把边界说清楚能省下后面排查误触发的几个小时。5.2 脚本接口设计太复杂模型频繁传错参还有一个技能我希望它能处理多种输入格式于是给脚本设计了三个位置参数加一个配置文件路径参数。结果模型在调用时经常漏传参数或者把用户原话直接当作参数传进来脚本每次都在运行时崩溃。这个坑的根本原因是模型对“精确参数传递”这件事并不可靠它擅长的是理解自然语言不是像一个程序调用那样严格遵守签名。我的修复方案是把脚本改成只接收一个参数——输入文件路径所有其他配置都从文件内容中读取或者使用JSON格式的统一输入文件。这样模型只需要做一件事把用户输入保存到约定路径然后执行脚本。参数传递的错误率几乎降到了零。5.3 依赖与运行环境问题Skill在别人机器上跑不起来我在自己电脑上调试好的Skill发给同事用了之后同事反馈脚本报错。排查了半天发现我的脚本用了一个第三方库但没有写进requirements.txt同事机器上没装这个库自然跑不起来。此类问题在分享Skill时非常常见。修复方案很简单把所有依赖显式声明在requirements.txt里并且在SKILL.md正文里写明安装依赖的方式。另外还有两个细节值得注意一是脚本路径要用相对路径别写死你自己的绝对路径二是脚本在异常时需要向stderr输出清晰的错误信息这样模型在调用失败后才能根据错误信息调整策略而不是看着一段模糊的报错无从下手。5.4 技能输出过大把上下文塞爆有一个日志分析类Skill脚本会把整个日志文件读进来然后输出一个非常详细的审计报告。刚开始效果很好直到有人拿来一个几百MB的日志文件脚本输出的报告直接把上下文窗口塞满了后续对话直接瘫痪。这个问题提醒我一个原则Skill的输出要克制返回给模型的应该是摘要级信息而不是全量数据。我后来把脚本改成两级输出——默认只输出异常统计和关键事件列表模型如果需要深入细节可以再指定时间范围或关键词脚本二次过滤后输出更详细的内容。这样做既保住了信息量又避免了上下文过载。6. 从单个技能到Superpowers组合进阶与个人体会6.1 什么是“Superpowers”式的技能组合单打独斗的Skill解决了单点问题但真实的工作流往往是多个环节串联的。以写一篇深度文章为例一个完整的AI辅助工作流包括选题调研、大纲生成、素材收集、初稿写作、格式排版、校对润色。你可以为每个环节各自写一个Skill但更优雅的方式是让这些Skill协同工作形成一个复合技能包——社区里把这种复合能力称为Superpowers。Superpowers的精髓不是“更大更全”而是“可编排”。一个复合技能包里可以有一个主控Skill负责判断用户当前处于工作流的哪个阶段然后按需调度其他子Skill。比如当用户说“我准备开始写初稿了”主控Skill就会先检查大纲是否已生成如果还没有就自动调用大纲生成Skill而不是直接进入写作环节。6.2 设计一套组合技能的实战思路我倾向于把组合技能分成三层原子技能、流程技能、主控技能。原子技能负责一个不可再拆分的动作比如“生成分镜表格”“提取文章关键词”流程技能负责把一个场景内多个原子技能串起来比如“把大纲变成初稿”主控技能负责判断用户意图调度流程技能。层与层之间通过统一的中间产物衔接最常见的做法是约定一个固定的工作目录各技能把结果写入JSON或Markdown文件下一个技能读取这些文件继续处理。这种方式的好处是每个技能可以单独测试和替换。你今天觉得某个原子技能效果不好只需要替换那一个模块完全不影响其他环节。我在实践中的体会是组合技能的设计很考验人的流程抽象能力。一个必须想清楚的问题是哪些环节是机器稳定擅长的哪些环节是模型灵活擅长的。比如“判断文章结构是否合理”这种偏主观的任务交给模型判断就比写死规则高效“把分镜转换成符合某个软件格式的XML文件”这种精确转换任务则应该用脚本做。把这两种能力正确分配到不同组件里是一个组合技能是否好用的关键。6.3 个人经验与最后建议最后分享几个我在持续使用Skills过程中的体会。第一Skills迭代必须小步快跑。不要一开始就追求做一个“全能技能”从一个能解决单一问题的原子技能开始实际用上几天记录翻车点然后针对性修一版比闭门造车高效得多。第二调试时把“模型行为”和“脚本行为”分开看。如果脚本单独跑没问题但接入模型后输出不对多半是SKILL.md里的指令写得不够清楚而不是脚本的问题。很多人反复调试脚本却不去改SKILL.md方向就错了。第三不要迷信下载量。一个被下载一万次的Skill不一定适合你的工作流。下载后认真读一遍SKILL.md和脚本确认它和你对“正确输出”的理解一致再决定是否采用。尤其是第三方Skill除了安全审查还要注意它依赖的模型版本有些技巧在新版本模型上可能已经失效了。Skills这个机制的潜力其实还远远没有被挖掘完。它把“经验”这种不可见的东西变成了可打包、可分发、可组合的结构化资产。我到现在依然记得第一次在一个稳定的Skill工作流里跑完一整套内容生产管线时的感受——那不是效率提升多少的问题而是AI从“偶尔好用”变成了“稳定可用”。这个转变才是Skills最让人兴奋的地方。