我用AI辅助写代码,前半年最大的痛苦不是它写不出代码,而是它每次写的代码风格都不一样。第一周让Claude按团队的ESLint规范调整格式化方式,它做到了;三天后新开对话,同样的要求它完全忘了;把规范写进提示词里,篇幅越堆越长,效果却撑不过十轮对话,还白白占掉大量上下文窗口。直到我认真研究并上手了Agent Skills——Claude Agent Skills、Codex Skills这条新路线,才意识到问题的解法根本不在"把提示词写得更长更多",而在于把"行为规范+核心示例+执行流程"绑成一个可复用、可检索、可随时安装卸载的模块。这篇就结合我自己踩过的坑,聊聊Skills到底是什么、底层怎么设计的、从零手写一个要抓哪些重点,以及面对社区里五花八门的"skills推荐""skills大全",到底该怎么选怎么用。
1. Skills机制出现前,我们都被提示词的长度逼疯过
1.1 提示词能把一件事说清,但镇不住一个长期项目的角落
先说一个特别典型的场景。我维护一个中型React项目,团队约定:组件必须用TypeScript、样式用Tailwind但不允许写@apply、函数组件超过60行必须拆分、路由懒加载有固定写法。这套规范如果用提示词表达,大概要写到800字以上。
问题来了:新建会话后,这800字不会自动出现。要么每次手打一遍,要么把它存成模板反复粘贴。就算你每次都粘贴,AI对它的"执行优先级"也远低于对代码本身的注意力——规范是"参考性文本",代码是"目标性文本",模型天然更关注后者。我实测过,把同样的规范放在系统提示词顶部、中部、底部,模型执行的结果都不一样,底部最容易丢。
更隐蔽的问题是上下文预算。Claude这类模型动辄数万token上下文,但真正干活时每个token都在消耗注意力。你塞了2000字规范进去,看着还有剩余空间,实际模型在长文本里提取有效约束的能力是衰减的。我给AI塞过一份包含20条项目约定的提示词,结果它在第13条之后就开始"选择性遗忘"。这不是模型笨,是提示词这个容器本身没有"按需加载"机制——它把所有内容一股脑全倒给模型,不分主次,不讲时机。
1.2 Skills带来的范式变化:从"一次性说明书"到"可检索的工具包"
Skills的逻辑完全不同。它的核心不是"把规定写进提示词让模型记住",而是构建一个"模型在需要时才会主动翻开"的手册。
我接触的第一份资料是Claude Agent Skills的深度解析文章,里面有个比喻很到位:传统的system prompt像入职第一天发给你的一本员工手册,你得从头读,但读完就忘;Skill像你工位旁边的一个抽屉,平时关着,遇到具体活计才拉开,里面是这项工作的标准流程和参考模板。
具体到机制上,Skill是一组放在项目目录下的文件,最核心的是SKILL.md。它有自己的描述信息,Agent在运行时会扫描所有可用Skill,根据当前任务与描述的匹配程度,决定要不要加载这份文件。你写代码时,前端相关的Skill被自动翻开;你处理数据时,那份和代码毫无关系的Skill根本不会进入上下文。这直接解决了两个痛点:规范不再是一股脑的"背景噪音",而且不同任务之间的规则可以隔离,互不打架。
这里要和MCP区分一下。MCP给Agent的是"外挂工具调用能力"——访问数据库、调用API、操作浏览器;Skills给Agent的是"特定领域的操作规范和行为模式"。用我自己的话总结:MCP是告诉AI"你可以用这个工具",Skill是告诉AI"遇到这种情况,按这个套路来"。两者是互补关系,不是替代关系。
2. 拆开SKILL.md的壳子:一个技能包的内部构造
2.1 一个Skill的最小完整形态
我在项目里实际建过完整的前端开发Skill,目录长这样:
my-project/ .claude/ skills/ frontend-dev/ SKILL.md references/ tailwind-rules.md component-structure.md scripts/ generate-component.sh assets/ example-component.tsx这个结构是在反复试验中确定的,几个目录各有用途。
SKILL.md是入口文件,承担"何时加载、核心要求、快速上手"三件事。references/放的是详细规则文档,这些内容不需要全部塞进上下文,模型只有在觉得基础文件不够用时才去翻。我试过把全部规则写进SKILL.md,结果每次加载都吃掉大量token,而且规则之间互相干扰;拆到references之后,模型只在需要进入细节时读取,上下文开销明显小一截。scripts/放自动化脚本,比如组件生成器、代码格式化脚本,方便模型调用外部命令完成任务。assets/作为可选的示例仓库,给模型提供正确范例——这对生成代码尤其重要,因为模型对"规范的抽象描述"理解不稳定,但对具体示例的模仿稳定得多。
2.2 SKILL.md的YAML前置块和正文,各自承担什么职责
SKILL.md的开头必须有YAML格式的元信息,这是它的"身份证",也直接决定了Agent什么时候加载它。我多次调整自己Skill的元信息后,总结出这套配置的关键字段:
--- name: frontend-dev description: 用于React+TypeScript+Tailwind项目的前端开发规范。在生成组件、修改样式、处理路由懒加载、进行代码审查时使用。包含组件结构、命名、可访问性和Tailwind约束。 ---这里最值得抠的是description。它不能太长,否则模型匹配时信息太分散;也不能太短,否则该触发时不触发。我的经验是:用"在xxx时使用"这种条件句式,把适用场景写明确,让"组件生成""样式修改""路由处理"这些具体动作词出现在字段里,触发率会高很多。
正文部分我用层次分明的Markdown结构组织,比如用## 操作流程、## 核心规范、## 示例这样的段落。实际上模型对Markdown的标题层级理解相当好,合理使用标题能让它在检索时更快定位。这也是我自己总结的心得:SKILL.md不是给人类读的文档,是给模型读的交互手册,所以小标题要带"检索关键词",句子要短促直接,命令语气,不要散文式表达。
2.3 加载机制背后的决策逻辑
很多人没注意到,Agent决定是否加载一个Skill,本质是当前任务文本与description的一段语义匹配。也就是说,你的Skill能不能被用上,很大程度上取决于description写得多聪明。
我踩过很典型的一个坑。我写过一个处理Excel数据的Skill,description写的是"数据处理工具,包含pandas与openpyxl规范"。听起来没毛病对吧?结果发现,当我让AI"分析这个CSV文件里的销售趋势"时,这个Skill居然没被触发。后来我明白了,模型面对的任务描述里没有出现"Excel""pandas",而是"CSV""销售趋势",我的description太"工具导向"了,没有覆盖"场景导向"的词汇。修改成"在读取、分析、清洗表格数据(CSV、Excel)时使用,涵盖pandas、openpyxl操作规范"之后,触发率就上来了。
这套机制决定了写Skill和写API文档有些神似:你的"接口描述"得让调用方(Agent)在真实场景下一眼认出该调用。从需求的动词到数据格式的名词,都要覆盖到。
3. 从零写一个前端开发Skill:语义压缩与边界设计
3.1 先定义它"该管什么、不该管什么"
真正落笔写SKILL.md之前,最重要的一步不是查语法,而是划定边界。我见过很多人的Skill文件写得像万能辅助,什么内容都往里塞——代码风格、数据库设计、部署流程、甚至简历写法,结果模型在大量混杂信息里迷失。
我写前端开发Skill时,给自己定了三条边界:
- 只管React+TypeScript+Tailwind相关的任务
- 只约束"行为规范"和"代码结构",不约束业务逻辑
- 不覆盖组件库的API细节,那些应该靠组件库文档解决
为什么要划边界?因为Skill的价值在确定性。当模型知道这份Skill只在特定场景生效时,它执行起来更果断;如果一份Skill试图覆盖所有场景,它的每条规则都会变成"仅供参考",效果大打折扣。
3.2 SKILL.md正文的写法:示例优先,抽象放后
以下是我打磨过很多轮的前端开发Skill核心正文(已经去掉真实的业务信息,结构保留):
## 操作流程 1. 先确认组件使用场景:页面级组件放入 pages/,可复用组件放入 components/,并导出对应 index 文件。 2. 使用TypeScript定义Props接口,类型用interface,不用type。 3. 样式优先使用Tailwind工具类,不允许写@apply。 4. 组件超过60行时,拆分子组件或自定义Hook,并在文件内注明拆分理由。 ## 组件结构示例 参考 assets/example-component.tsx 中的标准结构。 ## 禁止事项 - 不要使用 any,必要时使用 unknown 并做类型收窄。 - 不要在组件内直接写远程数据请求逻辑,应通过React Query的hook封装。 - 不要新增全局CSS类,除非有明确的设计系统扩展理由。这个结构是我反复调整后的版本,整体原则是"可验证"大于"可描述"。你让模型"遵循公司代码规范",它做不到;你让它"组件超过60行必须拆分"并给个具体示例,它就做得到。抽象规则写得再漂亮,不如一个正例加一条"禁止事项"管用。
3.3 references和scripts:层级化设计带来上下文红利
真正让Skill好用的不是把规则全写进SKILL.md,而是把SKILL.md写成"精炼入口",细节全部外置。我自己的SKILL.md正文不到1000字,所有Tailwind的边界规则、组件拆分细则都放到references文件里。这样设计的好处是:Agent加载Skill时只占用这么点上下文,只有在发现现有代码可能触碰边界时才进一步翻references。
我还写了一个简单的组件生成脚本,放在scripts里。这个脚本的功能是输入组件名,自动生成符合我们项目规范的.tsx文件和对应的类型导出。Agent在执行组件创建任务时,直接跑这个脚本,比我口头描述规范可靠得多。这也是我的一个体会:当规范复杂到语言说不清时,把它固化进脚本,让机器替你保证一致性。这是Skill和纯提示词拉开差距的关键——Skill不只是文本,它是文本+脚本+示例的组合。
3.4 手写Skill时的第一批细节错误
我前几次写的Skill文件,现在回头看全是问题。这里记录几个最容易犯的错误:
- description写成论文式长句,Agent匹配不到关键词。
- 正文用"应该""尽量"这类模糊副词,模型执行时充满随机性。
- 规则之间互相矛盾,比如前面说"优先用Tailwind",后面又举例写了CSS Module。
- 没有给正例。模型对"禁止事项"的遵守程度明显低于对正例的模仿。
每一条都是我实打实吃亏吃出来的,现在社区里大量新发布的Skill也普遍存在这类问题。所以拿到一个别人的Skill千万别直接用,先检查description是否具体、正文是否有明确动作指令、有无正例。
4. 社区里的Skills生态:从GitHub到官方市场怎么选
4.1 GitHub上的开源Skills仓库:看星星不如看这些指标
现在GitHub上带"awesome"前缀的Skills集合已经多到看不过来,什么 Nature Skills 、Superpower Skills之类的项目满天飞。面对这么多选择,我的挑选原则和看开源库不太一样,有四个硬指标:
- 最近一年有没有实际提交。Skills这个概念迭代非常快,几个月前的写法可能已经不适配新版客户端了,长期停更的仓库要谨慎。
- 有没有把示例文件和目录装齐。只有SKILL.md没有references、没有scripts的仓库,大概率是拿提示词改了个文件名,价值有限。
- 有没有作者自己的项目实践案例。我在GitHub上看到过一个"codex写论文的skills",作者贴出了完整的论文产出流程和踩坑记录,这种就比只有安装说明的强得多。
- 是不是"大而全"的超级包。看到那种号称覆盖全领域、一个文件解决所有问题的"skills大全",我一般直接跳过。上面说过,Skill的价值在于边界清晰,一个包什么都能干,通常意味着什么都干不精细。
我自己用的几个比较满意的Skill,都是从这种仓库里扒下来、再改造成适合自己项目的版本。所以选Skills不能像选软件一样"下载即用",更接近"fork之后二次开发"。
4.2 官方市场与第三方下载平台,各适合什么场景
现在各家AI编程工具都在推自己的官方Skills市场,这确实是获取高质量Skill最省心的渠道。官方市场的优点在于审核相对严格、格式统一、更新维护有保障。我在官方市场找过论文写作、分镜规划这类垂直方向的Skill,质量整体比开源社区高,安装也更方便——通常一条命令就能搞定,不用自己处理目录结构。
第三方下载平台和GitHub资源站则更适合找"场景非常具体"的Skill。我之前为了找"前端开发skills"专门逛过几个技能聚合站,优点是分类细,从React优化到样式规范都有;缺点是质量参差不齐,有的明显是从一篇博文硬转成SKILL.md格式的,元信息都没填对。用第三方平台的Skill,我建议先看下载量和最近的用户评价,那些标注"作者亲自维护""有GitHub仓库同步"的,可靠性会好得多。
4.3 按照真实场景做一张选型参考表
我根据自己和身边同事的实际使用,整理了一张场景选型表,纯粹是经验分享,不涉及具体项目名:
| 使用场景 | 优先从哪找 | 看什么指标 | 装完后第一件事 |
|---|---|---|---|
| 前端开发(React/Vue) | GitHub搜索+自己改造 | 组件示例、样式规范、脚本工具 | 拿一个老组件跑一遍验证 |
| 论文写作 | 官方市场 | 引用格式、段落结构、参考文献处理 | 用小样章测试格式稳定性 |
| 分镜脚本 | 第三方聚合站 | 分镜术语、镜头语言示例 | 看它是否覆盖不同画幅比例 |
| 授权安全测试/渗透(挖洞类) | GitHub定向搜索 | 授权声明、操作流程清晰度 | 只在有授权的靶场环境测试 |
| 数据分析 | 自己从常用数据处理操作改造 | pandas/openpyxl封装程度 | 先用CSV小样本验证 |
这张表的核心思路是:不同的获取渠道对应不同的信任等级,别人的Skill永远是半成品,装完之后的第一件事永远是测试,而不是直接放到正式环境里跑。尤其是涉及安全和合规方向的技能,必须在明确授权、完全合规的测试环境里验证,这是底线。
5. 调试Skills的实战记录:最常踩的坑和我怎么绕过
5.1 加载失败桌面下的迷雾:description到底匹配了什么
调试Skills最痛苦的经历,是"我明明装了,Agent却从不使用它"。有一段时间我对自己写的代码审查Skill完全无感,翻日志也看不出它到底加载了没有。
后来我做了个控制变量试验:把任务从"帮我审查这个组件"改成"用frontend-dev的规范审查这个组件",结果Skill就被加载了。这个试验让我意识到,问题出在description触发条件太苛刻。修改description之后我再测,发现不带Skill名,只是说"检查一下这个页面的代码质量"也能触发。触发词的选择真的是一门玄学,但核心逻辑是:把你希望接收任务的常见说法、同义词全部放进description里,同时保持语句自然。
如果调试时发现Skill死活加载不上,务必要按这个顺序排查——先看description里的动作词与任务文本有没有重叠;再看文件路径是否放在Agent默认扫描的目录(比如.claude/skills/);最后看YAML格式是否正确,哪怕缩进错一个空格都会导致整个文件被忽略。这些都是我一个个排除过的。
5.2 上下文膨胀:加载的不是一个Skill,而是一整个文件夹
另一个高频问题是:Skill确实加载了,但Agent表现得"整个人被带偏",反而忘了用户原本的需求。我碰到过的情况是,一份描写数据分析的Skill,每次提数据相关内容,它不仅加载了SKILL.md,还把我放在references里的所有文件全读了一遍,上下文中突兀地塞进了几千字与当前任务无关的细节。
要解决这个问题,我在设计Skill时做了一件事:给references里的文件也写清楚"何时阅读"。比如在SKILL.md正文这样写:
## 参考文件 - references/tailwind-rules.md:仅当修改样式定义或讨论Tailwind配置时阅读。 - references/component-structure.md:仅当创建新组件、拆分组件时阅读。别小看这个细节,加上它之后,Agent加载的文本量肉眼可见地减少了。Skill的设计本质上是在和上下文预算做博弈——你给的信息越模块化、附带的读取条件越明确,模型越知道什么该看什么不该看。这比单纯压缩字数要有效得多。
5.3 规则冲突:项目级约定与Skill同时存在,谁听谁的
使用Claude Code或Codex这类工具时,项目根目录往往还有一份全局规则文件,比如CLAUDE.md或AGENTS.md,它定义了整个项目的底线规范。Skill加载后很容易和它产生冲突。
我自己遇到过一个具体矛盾:项目全局规范要求"不引入新的UI依赖",而我写的前端Skill里推荐"使用某个开源组件库"。结果Agent在生成代码时,一度表现出摇摆,有时遵循Skill,有时遵循全局约定。这让我意识到,Skill的文件里开头就要声明优先级。
我的解决方案是在Skill的元信息description里加了一句"本Skill仅用于组件结构和样式规范,依赖引入必须遵守项目根目录AGENTS.md约定"。通过这样显式声明,冲突范围被明确切分——Skill管"怎么写组件",项目约定管"能不能引入这个库"。如果你之间的规则有真正重叠,那就要果断合并,不要同时保留两份互相冲突的命令。
5.4 建立自己的Skill调试清单
经过几轮折腾,我给自己拟定了一张调试清单,每次写完一个Skill就按这个过一遍:
- 输入一个必须触发此Skill的任务,确认加载是否成功。
- 输入一个不应该触发此Skill的任务,确认它不会强行加载。
- 加载后检查上下文里是否出现了references中的无关文件。
- 让Agent执行一遍"禁止事项"中的动作,看是否能拦截。
- 在项目有全局规则文件时,故意制造一个冲突场景,看优先级是否符合预期。
清单里的第三、四条往往能筛出七八成的问题。Skill是否真的有效,不是看文件写得有多漂亮,而是看"该出手时出手、不该出手时安静"。
6. 我的经验收尾:别把Skill当成万能钥匙,也别低估它
6.1 真正不值得用Skill的场景
聊了这么多Skill的好处,也要说清楚它的边界。我自己踩过的坑是:有一段时间给所有重复性任务都建了Skill,连"写周报"都搞了一套。效果是,Agent每次都很认真地加载这份Skill,然后按照固定格式生成一段千篇一律的周报,我要的"这个项目到底卡在哪个环节"的判断反而没有了。
所以我现在判断要不要写Skill,就看两件事:第一,这个任务是不是有足够稳定的"标准操作程序";第二,这个标准是不是能落到可验证的规则上。凡是需要临场判断、创造性发挥的工作,比如产品方案设计、架构权衡,都不适合做成Skill。还有一类是"通用常识型"任务,比如"写代码前先理清需求",这种内容放在全局系统提示词里就够了,做成Skill反而是给上下文添负担。
6.2 从"装Skill"到"写Skill",才算真的打开了新世界
很多人在"skills下载平台""skills大全"里囤了一堆包,装完就扔,最后留下一堆占空间、抢上下文、互相冲突的规则文件。我个人建议:先从一个最小、最贴近自己日常的Skill写起,比如针对你现在手头最痛的前端开发或者数据处理环节,亲手搭一个目录、写一份SKILL.md,跑通一次加载和验证。这个过程中获得的体感,比下载二十个现成的还管用。
我自己的体会是,Skill真正值钱的地方不在于它把"AI变聪明了",而在于它把"我脑子里的项目经验和团队规范,固化成了AI能随时检索的资产"。装再多的现成技能包,都不如把你自己天天在做的那套判断,变成AI的肌肉记忆。这才是Skills这条路线给我最大的启发——从今天起别再收藏skills大全了,花一个下午,为你最熟悉的那项工作写个属于自己的Skill吧。