Codex Skill 内部结构解析:从 SKILL.md 到 scripts、references、assets
很多人第一次接触 Codex 的 skill 时,会把它理解成一段"提示词模板"。这个理解不能说完全错,但太浅了。
更准确地说,skill 是一个可以被 Codex 按需加载的能力包。它不只是告诉模型"你应该怎么做",还可以把脚本、参考资料、模板素材、界面元数据一起组织起来,让一次复杂任务变成可复用的工作流。
本文专门拆解 skill 的内部结构,并用本地预设 skill skill-creator 作为例子,看看一个比较完整的 skill 到底由哪些部分组成。
1. skill 本质上是一个文件夹
一个 skill 通常不是单个文件,而是一个独立目录。以本地预设的 skill-creator 为例,它的大致结构如下:
text
skill-creator/
├── SKILL.md
├── agents/
│ └── openai.yaml
├── assets/
│ ├── skill-creator-small.svg
│ └── skill-creator.png
├── references/
│ └── openai_yaml.md
├── scripts/
│ ├── generate_openai_yaml.py
│ ├── init_skill.py
│ └── quick_validate.py
└── license.txt
从这个结构可以看出,skill 并不是只靠一段自然语言说明运行。它更像一个小型项目目录:
SKILL.md负责描述什么时候使用这个 skill,以及真正的操作流程。agents/放产品或界面侧需要读取的元数据。scripts/放可执行脚本,用来处理重复、确定性强、容易出错的步骤。references/放补充文档,在需要时再加载。assets/放图标、模板、图片、字体等资源。
其中唯一必需的是 SKILL.md。其他目录都是可选的,但一个复杂 skill 往往会把这些能力组合起来。
2. SKILL.md 是 skill 的入口
每个 skill 都必须有一个 SKILL.md。它一般分成两部分:
- YAML frontmatter
- Markdown 正文
以 skill-creator 的开头为例:
yaml
---
name: skill-creator
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.
metadata:
short-description: Create or update a skill
---
这里最关键的是 name 和 description。
name 是 skill 的名字,通常也对应目录名。description 则非常重要,因为它决定 Codex 在什么场景下会想到这个 skill。
很多人写 skill 时容易把重点放在正文,忽略 description。但实际使用时,Codex 先看到的是 skill 的元信息,而不是完整正文。如果 description 写得太窄、太虚,skill 可能根本不会被触发。
一个好的 description 应该同时说明两件事:
- 这个 skill 能做什么。
- 用户说出什么类型的需求时应该使用它。
比如 skill-creator 的描述就很明确:当用户想创建或更新 skill,并且这个 skill 涉及专业知识、工作流或工具集成时,就应该使用它。
3. Markdown 正文不是说明书,而是执行流程
SKILL.md 的正文不是写给普通用户看的说明书,而是写给 Codex 的工作指令。
在 skill-creator 中,正文包含这些核心内容:
- skill 是什么。
- skill 能提供哪些能力。
- 编写 skill 的原则。
- skill 的目录结构。
- 创建 skill 的流程。
- 什么时候使用脚本、参考资料和素材。
- 如何验证一个 skill。
这类内容看起来像文档,但它真正的作用是约束 Codex 的行为。
例如 skill-creator 明确要求:创建新 skill 时应使用初始化脚本;修改完 skill 后应运行验证脚本;SKILL.md 要保持精简;详细资料应拆到 references/。这些不是普通建议,而是让 Codex 在执行任务时遵循的流程。
所以,设计 skill 时不要把正文写成"科普文章"。更好的写法是:
- 用清晰的步骤告诉 Codex 怎么做。
- 把关键规则写成可执行的约束。
- 把容易忘记的判断标准写出来。
- 把不需要每次加载的长资料移到引用文件。
4. agents/openai.yaml:给界面和产品层看的元数据
skill-creator 里有一个 agents/openai.yaml:
yaml
interface:
display_name: "Skill Creator"
short_description: "Create or update a skill"
icon_small: "./assets/skill-creator-small.svg"
icon_large: "./assets/skill-creator.png"
这个文件不是给模型正文推理用的,而更偏向产品或界面侧元数据。比如:
display_name控制界面展示名称。short_description控制简短说明。icon_small和icon_large指向图标资源。
可以把 SKILL.md 理解成"给 Codex 执行任务看的说明",把 agents/openai.yaml 理解成"给外层系统展示和管理 skill 用的配置"。
对于个人自用 skill 来说,agents/openai.yaml 不是永远必需。但如果你希望 skill 在列表、卡片、插件市场或 UI 入口里展示得更规范,它就很有价值。
5. scripts:把高确定性的操作固化下来
skill-creator 的 scripts/ 目录里有三个脚本:
text
scripts/
├── generate_openai_yaml.py
├── init_skill.py
└── quick_validate.py
这说明一个成熟 skill 不一定只靠自然语言指令。凡是重复性强、格式要求高、容易手写出错的步骤,都适合放进脚本。
以 skill-creator 为例:
init_skill.py用于初始化 skill 目录。generate_openai_yaml.py用于生成或更新agents/openai.yaml。quick_validate.py用于检查 skill 的基本格式、命名和必需字段。
这种设计有一个很重要的好处:把"每次都要重新想一遍"的操作,变成"每次都能稳定运行"的工具。
如果一个 skill 只写自然语言,Codex 每次执行都可能略有差异。对于写文章、分析问题、生成方案,这种弹性是好事;但对于初始化目录、校验 YAML、批量处理文件,确定性更重要。
因此可以用一个简单标准判断要不要写脚本:
如果这个步骤需要每次都一样,或者失败代价比较高,就优先考虑放进 scripts/。
6. references:延迟加载的知识库
skill-creator 里有一个 references/openai_yaml.md,专门解释 agents/openai.yaml 支持哪些字段、字段含义是什么、有哪些约束。
这体现了 skill 的一个重要设计原则:渐进式加载。
Codex 并不需要在一开始就读取所有资料。一个 skill 可以把最核心的流程放在 SKILL.md,把细节资料放进 references/。只有当任务真的涉及这些细节时,再读取对应文件。
这样做有两个好处:
SKILL.md不会膨胀成一本手册。- Codex 的上下文空间不会被无关资料占满。
比如创建普通 skill 时,Codex 可能只需要知道基本目录结构和创建流程;只有当任务涉及 agents/openai.yaml 的字段定义时,才需要打开 references/openai_yaml.md。
如果一个 skill 涉及多个方向,也可以把参考资料按主题拆开:
text
references/
├── aws.md
├── gcp.md
└── azure.md
当用户只问 AWS 部署时,Codex 就不需要加载 GCP 和 Azure 的资料。
7. assets:不是给模型读的,而是给产物用的
assets/ 通常放资源文件,比如:
- 图标
- 图片
- 模板
- 字体
- 示例工程
- 可复制的样板文件
在 skill-creator 中,assets/ 里放的是 skill 图标:
text
assets/
├── skill-creator-small.svg
└── skill-creator.png
这些文件通常不需要被 Codex 逐字读取。它们的价值在于被引用、复制或用于最终产物。
比如一个做 PPT 的 skill,可以把公司模板放在 assets/;一个前端项目生成 skill,可以把 React 项目骨架放在 assets/frontend-template/;一个品牌写作 skill,可以把 Logo、字体、配色样例放在 assets/。
简单说,references/ 是给 Codex 看的知识,assets/ 是给最终结果用的材料。
8. skill 的核心设计思想:渐进式披露
从 skill-creator 的结构可以看出,skill 背后有一个很重要的思想:渐进式披露。
它大致分三层:
第一层是元信息,也就是 name 和 description。这部分最轻量,用来判断 skill 是否该触发。
第二层是 SKILL.md 正文。只有 skill 被触发后,Codex 才需要读取它,用来理解工作流程。
第三层是脚本、参考资料和素材。只有任务需要时,Codex 才进一步读取或调用。
这种结构能避免两个极端:
- 把所有规则都塞进系统提示词,导致上下文又长又乱。
- 每次遇到任务都从零开始,导致工作流不可复用。
skill 的价值就在中间:让能力模块化,但又不让上下文一次性爆炸。
9. 一个 skill 应该怎么设计
如果自己要写一个 skill,可以按下面的思路拆:
首先写清楚触发条件。也就是用户说什么时应该使用这个 skill。这个信息要尽量写进 description,因为它决定 skill 能不能被发现。
然后写核心流程。把 Codex 真正需要遵守的步骤放进 SKILL.md,不要写太多泛泛而谈的背景知识。
接着判断哪些内容应该外置:
- 重复执行、要求稳定的操作,放进
scripts/。 - 大段规范、字段说明、业务资料,放进
references/。 - 模板、图片、图标、样例工程,放进
assets/。 - UI 展示相关信息,放进
agents/openai.yaml。
最后要验证。一个 skill 不是写完就算完成,它要能在真实请求中触发,并且让 Codex 做出更稳定、更符合预期的结果。
10. 常见误区
误区一:把 skill 写成超长提示词
skill 不是越长越好。越长的 SKILL.md,越容易稀释重点,也越占上下文。真正关键的是把核心判断和操作流程写清楚。
误区二:把所有资料都塞进 SKILL.md
如果某些内容只有特定场景才需要,就应该放到 references/。比如字段手册、API 文档、业务规则全集,都不适合每次都加载。
误区三:该写脚本的地方只写自然语言
如果任务需要稳定处理文件、生成目录、校验格式,只靠自然语言说明不够可靠。脚本能把这类操作变成确定性能力。
误区四:忽略 description
description 不是简介,而是触发器。它写得不好,skill 再强也可能用不上。
结语
skill 的内部结构可以概括成一句话:用 SKILL.md 组织流程,用 scripts/ 固化操作,用 references/ 承载知识,用 assets/ 提供素材,用 agents/ 补充产品侧元数据。
理解这一点后,就不会再把 skill 当成普通提示词模板。
它更像是给 Codex 装上的一个"专业工作包":既有说明书,也有工具箱;既能告诉模型该怎么判断,也能提供可执行脚本和可复用资源。
对于个人长期工作流来说,skill 的意义尤其大。只要某类任务会反复出现,比如写博客、处理 PDF、生成 PPT、创建项目、分析代码库,就可以考虑把经验沉淀成 skill。这样下一次不是重新解释一遍需求,而是让 Codex 直接进入已经设计好的工作方式。