怎么写出好的 Skill?Skill 是给 AI 写的操作手册,不是给人写的技术文档。用最少的 token,在正确的层级,给 AI 最精准的约束,让它在边界内自由发挥。

你有没有遇到过这种情况——辛辛苦苦写了一份 Skill,喂给 AI,结果它要么根本不触发,要么触发了却干得一塌糊涂?问题往往不在 AI 身上。问题在于,你写的那份”指令”,其实并不是给AI看的,而是是一份给人看的文档。

接下来我就从 Codex 官方的 skill-creator入手,把它的 SKILL.md 逐层拆解,搞清楚一个核心问题:给 AI 写指令,和给人写文档,到底差在哪儿?

读完之后,你会拿到一套完整的 Skill 设计方法论——从文件怎么摆、到内容怎么写、到哪些事该交给脚本干,全都有章可循。

一、Skill 到底是个什么东西

Skill 就是一个文件夹,里面塞着 AI 完成某项专项任务所需的全部家当:操作说明、参考资料、现成的脚本、可直接使用的模板。并且Skill的概念可以跨平台通用。不管底层跑的是哪家模型、上面套的是哪个 Agent 框架,Skill 的设计思路都是相通的。

1. Skill的极简版

Skill 的最低配置就是一个 SKILL.md 文件:

weather-bot/
└── SKILL.md
  • 1.
  • 2.

这个文件分成两段。头部是一段 YAML 格式的元信息,用两行 — 包裹,声明名称和用途描述;下半段是 Markdown 格式的正文,写具体的执行步骤。

---
name: weather-bot
description: >-
  回答天气相关问题。当用户询问某地天气、
  气温预报或穿衣建议时激活此技能。
---

执行步骤:
1. 解析用户提到的城市名称
2. 调用天气 API 获取实时数据
3. 用自然语言回复用户
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

头部的 YAML 区域叫 frontmatter。AI 启动时会把所有已安装 Skill 的 frontmatter 扫一遍,根据 description 来决定当前对话该不该激活某个技能。这是触发的唯一判据——description 写得含糊,技能就可能被误触发或者错过。

下半段叫 body。只有 Skill 被选中之后,body 才会被加载进上下文。没被触发的话,AI 连看都看不到。

2. Skill的完整版

任务稍微复杂一点,一个文件就不够了。比如你要做一个处理 Excel 的技能——合并单元格的逻辑每次都一样,与其让 AI 每回现写,不如直接备一个写好的脚本。再比如做一个品牌物料生成器——公司 logo 和色号规范每次都要用,放个素材目录让 AI 随取随用更靠谱。

展开之后的目录结构大致是这个样子:

excel-processor/
├── SKILL.md              # [必需] 元信息 + 执行指令
├── agents/
│   └── openai.yaml       # [推荐] 界面展示用的元数据
├── scripts/              # [可选] 预写好的可执行代码
├── references/           # [可选] AI 按需查阅的参考资料
└── assets/               # [可选] 直接用于最终产出的素材
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

四类附属资源各有各的定位,后面会逐个展开。核心结论先记住:SKILL.md 是唯一的刚需文件,其余按实际需求添加。

二、Skill的读者

搞清楚结构之后,绝大多数人都会直接上手写——然后犯一个非常隐蔽的错误。来看个典型案例。假设要做一个代码review的Skill,初稿很可能长这样:

---
name:review-code
description:用于代码审查
---

# 背景
本技能凝聚了团队三年的codereview经验。

# 审查理念
-建设性、专业的沟通风格
-聚焦代码质量而非个人习惯
-在严格与宽容间找到平衡

# 如何使用
收到用户提交的代码后,全面审查并输出建议。

# 更新历史
-v1.0初始版本
-v1.1新增Python支持
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

如果递给一个刚入职的同事,这份文档没什么毛病。但 Skill 的读者是 AI,用这个视角再看一遍,问题就来了。那段凝聚三年经验的来源说明,AI 完全不需要——它只关心此刻要干什么,不关心这些经验从哪儿来。”建设性、专业的沟通风格”,人类读了能领会一个大致调性,AI 却会把”建设性”和”专业”自由组合出无数种输出,导致每次结果都不一样。”在严格与宽容间找到平衡”,一个老手心里有数,AI 没有这个直觉。”全面审查并输出建议”,太笼统了——AI 需要一份明确的检查清单:先看什么、后看什么、什么严重等级必须上报、什么可以忽略。版本记录更是多余——AI 每次醒来都是全新状态。

还有最要命的一处:description 只写了”用于代码审查”五个字。AI 就靠这五个字来判断要不要触发——用户说”帮我看看这段逻辑”,触发还是不触发?”这个接口有没有安全隐患”,算不算代码审查?五个字什么都判断不了。

这些一个共同点:全是面向人类读者的写法。其实写得多不等于写得对,写错了读者比什么都不写更糟。那面向 AI 的正确写法是什么样的?Codex 的 skill-creator 自身就是最好的教材——它自己的 SKILL.md 就是一份精心设计过的 AI 指令集。

三、Skill的整体设计原则

翻开 skill-creator 的 SKILL.md,370 行,不算短。但在逐行分析之前,先看看它要解决的核心矛盾是什么。一句话概括:怎么在有限的上下文窗口里,给 AI 传递最有效的指令?

围绕这个矛盾,它搭建了三个层次的解决方案。

  • 第一层是底线原则——简洁。AI 的上下文就像手机内存,系统进程、后台应用、当前任务全挤在里面。你的 Skill 一旦被加载,它的全部内容都会占用这块内存。塞得越多,留给其他用途的就越少,Skill的编写一定要简洁。
  • 第二层是两个架构决策。在简洁的前提下,写 Skill 始终要回答两个问题:这条信息该放到哪一层?这个任务该给 AI 多大的自主权?
  • 第三层是执行路径。有了原则和架构,还需要一条具体的可操作路线。skill-creator 提供了六步走的流程:理解场景、规划资源、脚本初始化、填充内容、自动校验、实战迭代。

1. 简洁约束

先说最内层。skill-creator 把这一点放在了最高优先级。它的原话是:上下文窗口是公共财产。既然是公共财产,你的 Skill 和系统提示、对话历史、其他技能的元数据共享这块空间。所以我们要尽可能节约的用这块空间,写的内容一定要简洁。所以写之前问自己两件事。第一,这个知识 AI 是不是天生就会?比如怎么发 HTTP 请求、怎么解析 JSON,这些不用教。第二,这段话占掉的空间值不值?一大段流程解释,也许用一个十几行的代码片段就能更精准地传达同样的意思。

2. 去除冗余文件

skill-creator 明确开了一份黑名单——以下文件不该出现在任何 Skill 目录里:README.md、INSTALLATION_GUIDE.md、QUICK_REFERENCE.md、CHANGELOG.md。

道理很直接:Skill 的消费者是 AI,不是接手项目的新人。这些文件都是写给人看的,AI不需要

3. 划清边界

不仅仅要少写冗余内容,还要知道怎么写约束条件。

skill-creator 做过一个写作风格技能(laotou-thought-style),它没有用正面描述来定义风格——没有写”请用温暖而有洞察的笔触”这样的话。因为”温暖”到什么程度、”洞察”跟”克制”怎么配比,AI 可以排列出无穷种组合,每次生成的结果都飘忽不定。

它换了一种方式:写一份反面案例清单。对白太密集怎么办——砍到只留一个场景,补一段提炼。全文充斥口号怎么办——把口号替换成当天就能做的具体动作。每条规则都指向一个明确的症状和对应的修改方案,没有任何理解上的弹性空间。

 

写完 SKILL.md 之后,可以做个快速检验:把你写的每条正面指令翻转成”禁止做 X”的形式。如果翻转之后更精确,那就用翻转后的版本。

 

4. 语气标准化

skill-creator 还有一条容易被忽视的规定:正文一律使用祈使句。这不是审美偏好,而是消歧义的手段。祈使句天然就是命令语态,AI 不用纠结你到底是在建议、在期望还是在要求——就是在下达指令。

四、信息放在哪一层

底线立好了,来看第一个架构决策:分层加载。

并非所有内容都需要一股脑塞进 AI。skill-creator 把信息拆成了三个层级,每个层级在不同的时间点进入上下文。

  • L1 是元数据层,就是 frontmatter 里的 name 和 description,总共约 100 个词。它的特征是永远在场——AI 每次对话开始都会扫描所有 Skill 的 L1,用 description 做匹配筛选。它的角色是门卫,从几十个候选技能里挑出跟当前对话最相关的那一个。
  • L2 是指令层,也就是 SKILL.md 的 body 部分,建议不超过 5000 词。只有当 Skill 被 L1 筛中、正式激活之后,body 才会被加载。它的角色是操作手册——告诉 AI 接下来该怎么干。内容太长会稀释 AI 的注意力,所以官方建议把正文控制在 500 行以内。
  • L3 是资源层,包含 scripts、references、assets 三类文件,总量不设上限。AI 在执行过程中判断需要时才会去取用。其中 scripts 最妙——AI 直接运行脚本拿结果,不需要把脚本源码读进上下文,实现了零 token 开销。

三层本质上构成了一个渐进式信息投放系统:从L1 到L3 ,层级越高,信息越丰富,但加载频率越低。

1. Description

frontmatter 虽然只有 name 和 description 两个必填项,但 description 的好坏几乎就是这个 Skill 的生死线。AI 完全靠这段话来判断是否激活技能。

看看 skill-creator 给自己写的 description:

description: >-
  Guide for creating effective skills. This skill
  should be used when users want to create a new
  skill (or update an existing skill) that extends
  Codex's capabilities with specialized knowledge,
  workflows, or tool integrations.
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

它做了两件事:说明功能范围和明确触发场景。

有一条需要注意:所有触发场景的描述都必须放在 description 里,不能放在 body 里。逻辑很简单——body 要等触发之后才加载,等 AI 看到 body 里的”何时使用”时,它已经做完了触发决策,这信息来得太迟了。

 

再看一个优秀范例,文档处理技能的 description 是这样写的:对文档的创建、编辑、分析能力做了说明,支持修订追踪、批注、格式保持和文本提取,然后明确列出了五种触发场景——新建文档、编辑内容、处理修订、添加批注、其他文档任务。AI 看一眼就能精准匹配。

 

2. 资源分类

完整的 Skill 里有三种资源,理清它们之间的边界是掌握整个系统的关键。

  • scripts/ 存放预写好的可执行程序。PDF 旋转、数据格式校验、文件格式转换——这类每次结果必须一模一样的操作就该放这里。AI 不读源码,直接调用拿结果。最大的好处是零 token 消耗:执行但不读入。偶尔 AI 可能需要读取脚本来做修补或适配环境,但绝大多数时候它只管跑。
  • references/ 存放参考资料。数据库表结构、第三方 API 文档、公司业务规则、领域专业知识——AI 在执行过程中觉得需要才去翻阅。和 scripts 的本质区别:references 是给 AI 看的知识,scripts 是给 AI 跑的工具。如果某份参考文档篇幅很长(超过万字),最好在 SKILL.md 里留一个关键词检索提示,帮 AI 快速锁定目标段落。
  • assets/ 存放直接嵌入最终产出的素材。HTML 脚手架、品牌 logo、PPT 模板、字体文件——AI 不需要理解一张 logo 的含义,只需要知道它叫什么、放在哪、什么时候把它塞进输出。

有一点需要注意:任何信息只在一个位置存放。SKILL.md 里写了的内容,references 里就不要再出现一遍。重复不只浪费空间,还会在某一方更新时制造不一致。

3. 怎么把内容拆到 references 里

知道需要把一部分skill拆到references 里,还得知道怎么拆。skill-creator 给了三种经过验证的拆分策略。

  • 第一种是概览加详情的分离。SKILL.md 里放核心流程和快速入门示例,而详细的 API 参考、完整的模式说明各自拆成独立文件,放到references。AI 需要深入某个分支时再单独加载。
  • 第二种是按业务领域切割。比如典型场景是一个跨部门的查询技能——把财务、销售、产品、市场的表结构各自拆成一份 reference。用户问营收指标时只读 finance.md,问获客成本时只读 marketing.md,不会把所有部门的数据结构都灌进来。
  • 第三种是基础加进阶的分层。常用功能的说明直接写在 SKILL.md 里,高级功能放进独立 reference 文件通过链接指过去。大多数对话用不到高级功能,它们自然也不会被加载。

无论用哪种策略,都有两点需要注意:

  • 第一,所有参考文件从 SKILL.md 直接链接,不要出现 A 引用 B、B 再引用 C 的嵌套跳转,AI 不应该为了找一条信息跳三次。
  • 第二,信息只在一处存在——要么在 body 里,要么在 references

五、自主权分配

搞定了信息放在哪里的问题,还有另一个维度需要决策:AI 在执行任务时,应该有多大的自主权?skill-creator 将AI的权利自由度分为了三个档位。

  • 高自由度适用于多种做法都合理的任务,比如理解用户需求、编写 SKILL.md 内容、设计技能结构。这类任务用文字指令引导方向,让 AI 自主判断。
  • 低自由度适用于脆弱操作——格式约束严格、容错空间为零的任务。比如初始化目录结构、生成配置文件、校验输出格式。这类任务用脚本锁死,AI 只负责提供参数值,脚本保证输出合规。
  • 中间地带是有最佳实践但允许变通的任务,可以用带参数的脚本或伪代码来处理。

判断一个任务该给多少自由度,问两个问题就够了。第一,做错了后果多严重?越严重,自由度越低。第二,有多少种正确的做法?越多,自由度越高。

什么时候该把一个操作封装成脚本?有几个清晰的参考方向:每次执行结果必须一样的、涉及精确格式或长度约束的、涉及命名规范转换的、需要校验规则匹配的、同样的代码每次都要重新写的——这些都该交给脚本。反过来,需要理解上下文的、有多种合理做法的、需要创造性判断的——这些留给 AI。

 

核心逻辑很简练:出错代价越大,自主权越小,越要靠脚本;正确路径越多,自主权越大,越要靠文字。

 

六、创建一个 Skill 的完整流程

理论讲完了,来看实操。skill-creator 给出了一个六步创建流程,把上面所有的设计思想变成可执行的动作。

动手之前有一个前置动作:把名字定下来。规则不复杂——只用小写字母、数字和连字符,统一转为 hyphen-case(”My PDF Tool” 变成 my-pdf-tool);总长度别超过 64 个字符;尽量用动词短语来体现动作意图;需要时可以加工具名前缀做命名空间(像 gh-review-pr 或 linear-triage-bug);文件夹名和技能名必须完全一致。

1. 理解技能场景

先搞清楚这个技能到底要覆盖哪些场景,用户会用什么样的话来触发它。这一步规划完,你要能够简单的写出这个skill的description了

2. 规划可复用资源

对着第一步的技能场景,做两个分析:从零做这件事需要什么?其中哪些是每次都一样的? 每次都一样的东西就是该被封装的。明确列出哪些东西该放进 scripts、references、assets。

3. 脚本初始化

用脚本来初始化我们的skill。skill-creator建议每次创建新 Skill 都必须用脚本来初始化而不是用手工来创建Skill目录和文件。显然按照前面权利自由度的说法来看的话,这里就是一个低自由度的场景。很适合用脚本来处理,这个脚本我们可以用python或者是shell来写都可以,注意脚本不是完成整个skill,而只是做一个初始化,帮我们固定Skill的格式,以及一些命名规范

4. 填充内容

这是整个流程中分量最重的一步,分两个阶段推进。

  • 先实现第二步规划的资源文件——写脚本、写参考文档、准备模板素材。脚本写完后必须实际运行测试,确保没有 bug 且输出符合预期。
  • 然后更新 SKILL.md。frontmatter 的 description 要把所有触发条件写进去,不要留到 body 里。body 用祈使语气写操作指令,只放 AI 不知道的信息,不放 AI 已有的常识。

5. 自动校验

运行校验脚本比如quick_validate.py,让它扫一遍 SKILL.md 的格式、字段、命名规范等。报错就改,改完重跑,直到全部通过。

6. 实战迭代

好的 Skill 不是一次写成的。在真实任务上用几次,你会发现哪些地方 AI 理解得不好、哪些步骤总是出问题、哪些场景漏掉了。把这些发现反馈到 SKILL.md 里,更新 description 的触发条件,补充 body里缺失的细节,修正脚本的逻辑,然后不断迭代。

把 Skill 拿到真实场景里跑一轮。在实际使用中观察哪些环节不顺畅——AI 是不是在某个步骤反复试错?是不是漏掉了某个场景?某个脚本的输出是不是不太对?对照问题修改 SKILL.md 或调整资源文件,然后再测。

七、小结

怎么写出好的 Skill?Skill 是给 AI 写的操作手册,不是给人写的技术文档。用最少的 token,在正确的层级,给 AI 最精准的约束,让它在边界内自由发挥。

还有最后一条:好 Skill 永远不是一稿定终身的。用起来,观察哪里不顺,回去改,再用,再改。这个循环本身就是设计的一部分。

Loading

作者 yinhua

发表回复