用AI编码助手半年,最让我崩溃的不是模型能力不够,而是我总在重复“教”它做事。前端改版、代码审查、写接口文档,这些活儿每周都在做,但每次新建会话我都得把自己的工作流程重新描述一遍,语气稍微歪一点,输出风格就跟着跑偏。直到我接触了Agent Skills这个概念,在本地把第一个skill跑通之后才反应过来,这玩意儿和“预设prompt”完全是两个物种。简单说,skill是把一套完整的工作流——包括前置检查、执行步骤、质量标准、参考示例——封装成文件,交给Agent按需调用。它不是让你少打字,而是让模型“本来就该会”,把每次对话里的反复试探直接省掉。这篇文章我尽量从原理讲到实操,把skills是什么、怎么装、怎么写、怎么排错,一次讲透。不管你是写代码的,还是做数据分析、做UI校验、写技术文档的,这套思路都能直接抄走用。
1. Skills到底是什么:从一次性提示词到可复用工作流
先说一个最常见的误解。很多人看到SKILL.md这个文件名,第一反应都是“这不就是把提示词写进Markdown里吗?”我一开始也这么想,直到试过之后才明白,Skills背后的逻辑不是“存文本”,而是一套面向Agent的工作流封装机制。
你可以把Skill理解成给Agent配的一份“岗位说明书”。假设你要让模型帮你做代码审查,如果没有Skill,你每次都得在对话里说:请检查我的代码,重点关注性能、安全性、命名规范、潜在Bug,给出修改建议,并用表格输出……说得越细,模型执行得越准,但你也越累。而且这些描述不会沉淀下来,换个会话又得从头再来。
有了Skill之后,你只需要把这份“岗位说明书”写进.claude/skills/code-review/SKILL.md这个文件里。Agent在启动或者任务匹配时,会自动发现这个文件,并把里面的流程当作自己的行为准则。它就像新员工入职第一天,你递给他的操作手册——不用你开口,他就知道该怎么干活。
1.1 Skill的常见文件形态与结构
一个标准的Skill目录通常长这样:
skills/ └── code-review/ ├── SKILL.md └── examples/ └── review-output.md核心文件就是SKILL.md,它由两部分组成:开头的YAML元信息和正文指令。
--- name: code-review description: 当用户要求审查代码质量、查找Bug或改进代码结构时使用。适用于PR/MR评审、提交前检查等场景。 --- # Code Review Playbook 1. 先快速浏览变更范围,判断本次审查的规模。 2. 从正确性、性能、安全、可读性、架构五个维度逐项分析。 3. 对每个发现的问题给出严重程度评级:Critical / Warning / Suggestion。 4. 最后输出一个摘要表,列出问题清单和修改建议。这里最关键的是description字段,它决定了Agent什么时候该启用这份技能。这个我后面会专门展开讲,因为它是我踩过最深的一个坑。
1.2 Prompt、Skill、Agent三者到底怎么分工
Prompt是提示词,Skill是技能包,Agent是执行者,这三者经常被混在一起说,但边界其实很清楚。
Prompt本质上是一次性的问答指令,你说了它做了,对话结束,一切归零。Skill是可持久化、可复用、可被动态发现的工作流定义,它不依赖某次具体的对话。Agent则是承载对话记忆、调用工具、决定是否使用Skill的那个运行时环境。举个例子:Prompt是“今天帮我换个轮胎”,Skill是“换轮胎标准作业程序SOP”,Agent就是那个拿着SOP干活的修车师傅。
对比一下更能说明问题:
| 维度 | Prompt | Skill | Agent |
|---|---|---|---|
| 生命周期 | 单次对话 | 持久存在,跨会话复用 | 常驻运行环境 |
| 存储形态 | 不会沉淀 | 文件/目录 | 进程或服务 |
| 能否动态发现 | 不能 | 能,按描述匹配 | 自身就是发现者 |
| 可维护性 | 差,散落在各处 | 好,可版本控制 | 配置繁琐 |
1.3 为什么主流工具都在转向Skills范式
原因其实很朴素:大模型的上下文窗口再大,也扛不住什么内容都往里塞。如果你把所有工作流程都写进系统提示词,Agent每次执行任何一个任务,都要把这堆冗余文本从头读一遍,既浪费token,又稀释了真正关键的指令。
Skills的读写方式彻底改变了这件事。它采用的是按需加载思路——Agent平时只读每个Skill的name和description,知道“这个工具有什么用”,但不会把整个技能体加载进来。只有当当前任务和某个Skill的描述匹配上了,它才会读取完整内容。这就相当于你家里有一整套工具箱,而不是把所有工具都钉在墙上。
这一点非常像CDN缓存和边缘计算的设计思路:内容分开放,需要时就近取。想明白这一层之后,你再去看各家工具的文档,思路就会顺畅很多。
2. 主流工具里的Skills生态:Claude Code、Codex和OpenCode怎么选
Agent Skills不是某一个工具独有的功能,过去一两年里,各种编码Agent和通用Agent开始陆续支持类似机制。我实际摸索过几套,下面按我接触的顺序把它们的生态和配置方式盘一遍。
2.1 三套主流工具的Skills约定对比
不同工具对Skills的存放路径、文件格式、加载机制有相似之处,但细节差异不小。我把实测过、也在社区里被讨论得比较多的配置方式整理成了表格。
| 工具 | 项目级路径 | 核心文件 | 加载机制 |
|---|---|---|---|
| Claude Code | .claude/skills/<skill-name>/ | SKILL.md | 启动时扫描目录,对话中按description自动匹配 |
| Codex CLI | 仓库根目录/自定义目录 | AGENTS.md或SKILL.md | 启动时读取项目说明,SKILL.md按需发现 |
| OpenCode | .opencode/skill/<skill-name>/ | SKILL.md | 安装时注册,任务匹配时动态组合 |
先说Claude Code,它把Skills放在了.claude/skills目录下,每个技能一个子目录,核心文件叫SKILL.md。这种设计最好的地方是目录即模块:技能要引用的示例、脚本、模板都可以放在同一个目录下,跟着技能走,不会被其他玩意干扰。
Codex CLI的思路稍微不一样,早期更多依赖AGENTS.md这种项目级说明文件,放在仓库根目录,让模型每次运行时都自动读取。后来社区开始把SKILL.md也放进仓库里,通过文件命名实现技能的显式声明。这种做法适合“仓库本身就是一个技能库”的玩法,比如你把全套代码审查规范、测试策略、发布流程都写进AGENTS.md,模型在仓库里干活时会自动遵循。
OpenCode我会提一下但不多说,它也是用SKILL.md作为技能描述文件,只是目录约定换成了.opencode/skill。如果你只是想在几个主流的工具里选一个先上手,Claude Code那一套文档最全,社区包也最多,入门最平滑。
2.2 社区生态:从Superpower Skills到垂直领域技能包
比工具本身更值得关注的是围绕Skills长出来的社区。比如搜索热词里反复出现的superpower skills,就是一个把高频工作流打包成技能集的仓库,里面收了很多可以直接安装的现成技能。还有vidmuse-skills这种专门做视频生成工作流的技能包,以及国内外各种开发者整理的前端开发、数学建模、UI/UX、安全测试方向的skills合集。
社区包的价值不在于“有别人写好的东西可以白嫖”,而在于你拿到一个打磨过的Skill,能顺着它的结构反推出原作者是怎么拆解工作流的。我自己的经验是,看20个开源SKILL.md,比看2小时文档管用得多。它让你直观理解什么样的description容易触发、正文该怎么组织步骤、示例该放多少。这个密度的案例库,目前只有社区能给到。
2.3 选型建议:先定场景再选工具
如果你只是个人写项目,GitHub Copilot那类实时补全配合简单的代码检查,用不太上Skills。真正需要Skills的是那种“固定周期、固定交付物、固定质量要求”的高频工作流——比如每周发版前的代码审查、每篇技术文章的排版、每月的数据分析报告。
当你发现自己开始复制粘贴同一段写好的指令给AI时,就是该上Skills的时候。工具选型上我的建议是:如果你主要在终端里写代码、跑命令,优先试Claude Code或者Codex CLI;如果你需要的是在GUI编辑器里完成日常编码,那不妨先把OpenCode或同类编辑器内集成的AI助手玩熟。方案没有绝对的好坏,只有和你工作流的匹配度。
3. 装好一套Skill的全过程:install命令、手动放置与源码安装
聊完生态,直接进入实操。这一步我把三种最常见的安装方式都过一遍,并附上每个命令背后的含义。因为网上的教程大多是复制粘贴命令就完事,很少讲清楚每个参数到底在干嘛,出了问题根本无从下手。
3.1 用npx一条命令安装现成技能包
现在不少技能包可以直接通过npx安装,官方推荐的方式是:
npx skills add sandai-org/vidmuse-skills --agent claude-code -g -y这条命令看起来简单,但我第一次用时心里是发虚的。拆开来说:
npx skills是执行一个叫skills的npm工具包;add sandai-org/vidmuse-skills表示从指定的Git仓库或npm包添加技能;--agent claude-code指定这套技能要为哪个Agent安装,因为不同Agent的目录结构不一样,不指定的话,工具不知道把文件放哪;-g是global的缩写,表示全局安装,技能会放到你的用户级配置目录里,对所有项目生效;-y是自动确认,跳过中间的那些交互式提问,脚本化部署时特别好用。
安装完成后,它会显示类似Installed skill to /home/you/.claude/skills/vidmuse-skills的输出。看到这个路径说明全局安装成功,你可以放心去看里面的SKILL.md。
3.2 手动放置:项目级Skill的搭建步骤
不是所有场景都想装全局的。比如你只希望某个仓库遵循专属于它的代码规范,那项目级Skill更合适。手动放置的步骤非常简单:
- 在项目根目录创建
.claude/skills/目录。 - 在下面建一个你给技能取的名字,比如
code-review。 - 在
code-review/里新建SKILL.md文件。 - 把写好的frontmatter和正文填进去。
- 重启Agent会话,让它重新扫描目录。
这种方式的优势是干净、隔离、可提交到Git仓库。团队里只要有人把Skill文件提交上去,其他人拉下来就能用,AI的工作流也能像代码一样做版本管理。我自己现在比较喜欢把和仓库强相关的技能放在项目里,把通用的、和个人写作风格相关的技能放在全局目录。
3.3 从源码安装:怎么自己扒一个技能下来
有时候你想安装的仓库没有做成一键npm包,那就要走源码安装。所谓源码安装,其实也就是手动把远程仓库clone下来,然后把对应的skill目录复制到Agent的skills目录里。
git clone https://github.com/xxx/awesome-skills.git cd awesome-skills # 查看目录结构,找到你要的那个skill ls # 把它复制到Claude Code的项目级或全局skills目录 cp -r code-review /path/to/.claude/skills/源码安装的好处是,你能直接看到原始仓库里有没有配套的示例、脚本、测试文件。有些技能包不只是SKILL.md,还会带一个scripts/目录,里面放着辅助脚本。你copy的时候记得连整个目录一起复制,别只拿一个Markdown文件,否则技能执行时很可能找不到附带资源。
3.4 验证安装是否成功
装完之后最尴尬的就是不知道有没有装成功。最笨也最有效的方法是直接发一个触发任务。比如你刚装的是code-review技能,那就故意让Agent“帮我审查一下src目录下的代码”,然后观察它是自己执行了完整的审查流程,还是像普通对话一样泛泛地聊两句。
如果触发了,输出里会出现你写在SKILL.md里的固定段落,比如“按照正确性、性能、安全等维度逐项分析”。如果没触发,可以去查看Agent的启动日志或调试输出,看它有没有扫描到skills目录。一些工具还提供了类似/skills的斜杠命令,可以直接查看当前加载了哪些技能。多种方式结合,基本能确认安装状态。
4. 手写自己的第一个Skill:代码审查工作流从设计到落地
说完了安装,下一步是你自己动手写。直接拿现成的技能包当然方便,但自己写一遍才能理解它的设计逻辑。我拿代码审查这个场景举例,走一遍从需求分析到落地测试的完整流程。
4.1 先想清楚:这个Skill到底要解决什么问题
写Skill之前最怕的就是什么都想往里塞。我的做法是先画一个问句:假如我是一个新入职的同事,手里只有这份文档,能不能独立完成这项工作?不能的话,说明流程还不够清楚;能的话,说明你已经拆解到位了。
拿代码审查为例。我把它拆成了几个子任务:
- 了解变更范围:不这么做,模型分析可能把整个项目都扫一遍,既费钱又慢。
- 定义检查维度:正确性、性能、安全、可读性、架构。
- 定义输出格式:问题清单、严重级别、修改建议。
- 定义结束标准:输出一个摘要表,并且给出“可合并/需修改”的明确结论。
这些子任务组合在一起,就形成了我希望Agent每次代码审查时都自动执行的最小流程。
4.2 一个完整的SKILL.md长什么样
下面是我实际在用的代码审查Skill骨架,去掉了一些我自己项目的特定细节,保留通用结构。
--- name: code-review description: 适合在代码提交前、PR评审、代码走查阶段使用。当用户要求检查代码质量、排查潜在Bug、优化性能或规范代码风格时,调用此技能。 --- # Code Review Workflow ## 步骤 1. 先读取当前Git状态,确定本次审查的文件变更范围。 2. 对每个变更文件,按以下维度逐项检查: - 正确性:是否存在逻辑漏洞、边界条件处理不当。 - 性能:是否存在不必要的重复计算、内存泄漏风险。 - 安全:是否处理了输入校验、敏感信息硬编码等问题。 - 可读性:命名是否清晰、函数是否过长、异常处理是否符合直觉。 - 架构:是否保持模块依赖清晰,是否有明显坏味道。 3. 在每个问题后面标注严重级别: - Critical:必须修复才能合并。 - Warning:强烈建议修改,但不阻塞合并。 - Suggestion:风格或优化层面,可选修改。 4. 最后输出markdown表格,列出问题清单。 ## 输出模板 | 文件 | 行号 | 级别 | 问题描述 | 修改建议 | |---|---|---|---|---| | src/utils.ts | 42 | Warning | 循环里重复调用API | 提取缓存或移到循环外 |注意看description的写法和正文的差异。正文是“怎么执行”,description是“什么时候执行”。description里我特意提到了“PR/评审/代码走查阶段”这类场景词,而不是简单地说“用来看代码的工具”。模型是拿description去做语义匹配的,描述得越贴近自然语言的使用场景,匹配成功率越高。
4.3 测试与迭代:别指望一次就写好
第一次写完SKILL.md,我兴冲冲地把一个PR丢给Agent去审查,结果它只给我回了一句“这段代码看起来不错,建议注意一下命名风格”。完全没按照我写的五维度去审查。问题出在哪?
我回头检查发现,我在正文里用了“审查”这个动作词,但在description里写的是“检查代码质量和Bug”。模型觉得用户只是想快速扫一遍问题,就没往深度审查方向走。我把description改成“用户要求进行完整的代码审查,包括正确性、性能、安全等多个维度”,再试了一次,输出立刻变了,五维度清单全列出来了。
这个教训让我总结出一个迭代方法:改动SKILL.md之后,强制自己开一个新会话再测。Agent的对话里是有上下文的,如果在同一个会话里连续改配置反复测,模型很容易被之前的历史内容干扰,让你误以为Skill仍然失效或仍然生效。新会话才能测出真实效果。
5. 模型到底怎么“看到”Skill:发现、加载与调度机制拆解
很多网上教程都停留在“怎么写Skill”这个层面,但我更想聊聊背后那层机制。理解了这套机制,你就明白了为什么同一个Skill换个工具、换段描述,效果会差那么多。
5.1 Description是触发器的第一道门
Agent在工作时,并不会真的把每个Skill的正文都读一遍。它首先看到的就是一系列技能的name和description。这个过程很像搜索引擎的索引页:索引上有每篇文章的标题和摘要,搜索引擎不会把文章全文全爬一遍再给你结果。
所以,description是否准确覆盖用户可能的表述,直接决定了Skill能不能被触发。我见过很多人写description,内容是“一个用于代码审查的工具”,这种写法在自然语言语义匹配里的得分往往不高。因为用户不会说“请使用代码审查工具”,而是会说“帮我看看这段代码有没有问题”“这个PR能合吗”这类自然表达。description里应该包含这些口语化意图词。
5.2 SKILL.md正文是怎么进入模型上下文的
当Agent判定某个Skill和当前任务匹配后,它会读取整个SKILL.md(也包括同目录下被引用的参考文件),并将其插入当前对话的上下文窗口。这个过程对用户是透明的,但你其实可以通过Agent的调试信息或日志观察到它“注入”了哪些内容。
这也解释了为什么SKILL.md的正文不宜过长。如果一份SKILL.md写了1万多字,模型每次用这个技能时都要把这1万字塞进上下文,反而会稀释关键指令,甚至导致执行缓慢或上下文空间不足。理想的情况是,SKILL.md只写流程骨架和决策规则,把需要大段查询的内容拆到同目录的参考文件里,正文里用“阅读examples/目录下的示例”一句话引导模型去按需读取。Skill文件之间也是可以做局部加载的。
5.3 Harness调度:Agent是如何在多个Skill之间做取舍的
如果你在项目里放了多个Skill,比如一个code-review、一个refactor-helper,当用户说“帮我看看这段代码要不要优化”,两个技能都可能和这句话沾边。这时,Agent会结合description的语义相似度、正在进行的任务类型、以及历史上下文来仲裁,选一个最合适的,或者把多个技能组合使用。
这就是为什么有人说“Skills再多也没用,关键在调度”,也就是社区里常说的skills harness。Harness可以理解成一套调度策略,它决定了最终哪些技能被加载、以什么顺序组合、会不会发生冲突。如果两个Skill的description高度重叠,调度时模型的注意力就会被分散,经常加载错那一个,输出质量直接下降。
我的经验是:技能库要精简,不要追求数量。同一个场景只保留一个最高质量的Skill,其余边缘场景直接在description里注明“本技能不适用”,反而能让调度更准确。强迫模型做选择题,不如主动给它唯一标准答案。
6. 我踩过的那些Skills坑:安装成功却失效的排错思路
最后这部分,把我自己实际遇到过的问题和排查思路完整列出来。技能写好了、装上了,但运行时就是不出效果,这种痛苦经历过的人都懂。我按排查链路一个个说。
6.1 坑一:安装成功但模型完全没调用
现象:技能文件躺在那儿,Agent却视而不见,给的回复和没装Skill时一模一样。
排查步骤:第一步查目录位置。全局安装和项目级安装的路径不同,如果项目里有自己的.claude/skills,而你把文件放到了全局目录,Agent可能优先读项目里的,全局目录在部分工具的配置里默认不扫描。第二步看description。这是最隐蔽也最常见的原因——模型扫描到了Skill,但它认为当前任务不匹配,所以不加载。我在4.3节里就遇到过这种情况。解法是重写description,把用户可能说的口语化表达都放进去。
6.2 坑二:SKILL.md里的相对路径失效
如果你的Skill里引用了examples/xx.md或者某个脚本,而Agent启动时的工作目录不在你放Skill的目录下,相对路径就可能失效。模型会提示找不到文件,或者干脆跳过这一段,直接凭“感觉”继续执行,输出结果自然就跑偏了。
解决办法是尽量在SKILL.md里用绝对路径,或者在正文开头加一条明确指令:“先执行cd /path/to/skill-dir,再读取examples/目录”。每次Agent加载技能时,让它自己先把工作目录切过去,比依赖默认启动路径靠谱得多。这个坑在手动复制技能包时特别容易触发,因为原作者大概率没考虑过你把它放到哪个位置。
6.3 坑三:Skill内容太厚,上下文被撑爆
我在5.2节提过一次,这里再强调一遍。很多人喜欢把InfoQ上的长文、内部规范PDF全部写进SKILL.md,最后这个文件可能比我这个项目代码还大。模型加载它的时候,上下文窗口被塞得满满当当,后续对话里稍微多问几句就超限,或者输出质量断崖式下跌。
如果你确实有大量参考资料,正确做法是单独建一个references/目录,把SKILL.md写成一个“索引文件”,只放主流程和关键决策点,然后用“读取references/checklist.md中的检查项”这类指令按需加载。参考内容是给模型看的,不需要也都塞进主文件里。
6.4 坑四:多个Skill互相抢活
当同一类场景有多个可用技能时,Agent经常发生“抢活”或“串味”。我经历过最典型的情况是,code-review和refactor-helper都认为用户想让自己上场,最后模型把两个技能的指令混在一起执行,输出一半是审查一半是重构建议,四不像。
处理方式就是我在5.3节提到的:精简技能库。如果两个技能确实都有用,可以在description里做显式互斥——审查技能写明“专注于质量评估,不提供重构实施”;重构技能写明“专注代码结构调整,不评估架构风险”。用description给模型划好边界,调度器才知道该派哪个上场。
6.5 坑五:改动后不生效,反复瞎试
最后一个坑不涉及技术,而是调试心态。SKILL.md改了一行,马上在同一会话里测,发现没变化,于是觉得是工具坏了、缓存没清、模型抽风……其实大概率是对话上下文还在影响模型,也就是我前面说的“同一个会话的惯性”。
我现在的做法是:改动文件后,直接开一个新会话,丢一个最典型的触发指令,观察输出是否按新逻辑执行。如果还不行,再打开Agent的调试日志看它到底有没有加载这个技能。一套流程走下来,问题百分之九十九都能定位。
这次写下来,最大的体会是:Skills做的不是“让AI更聪明”,而是“让AI更稳定”。它把那种靠临时发挥才能获得的好运气,变成了可以重复交付的基准线。我最近在写文档、做图表、跑数据分析时,也开始尝试把固定套路沉淀成各自的SKILL.md,效果还在持续提升。如果你也经常和AI协作处理固定流程的工作,真心推荐从最小的场景开始,花半小时写一个属于自己的Skill,跑通之后再慢慢加厚。那种“打开新会话它就直接进入状态”的感觉,值得体验一次。