我刚接触 Codex 时,看到 Skills、Plugin、MCP、AGENTS.md 这些词很容易混在一起。

后来我用一个比较简单的方法理解 Skill:

Skill 就像一份可以被 Codex 重复执行的工作说明书。

例如:

每次改完前端页面,都检查代码、执行构建,并确认实际页面效果。

这种具有固定步骤、以后还会反复执行的工作,就非常适合整理成一个 Skill。

严格来说,Skill 是一种可复用工作流,可以包含指令、参考资料、资源以及可选脚本。Codex 会先读取 Skill 的名称和描述,判断当前任务是否适合使用它,真正需要时才继续加载完整的 SKILL.md

1. Skill 适合解决什么问题

我不会为了每一个小问题都创建 Skill。

Skill 更适合下面这些会反复出现的工作:

  • 每次发版前都要走一遍固定检查;
  • 每次代码审查都要检查相同目录和相同规则;
  • 团队有固定的文档、测试或 Git 流程;
  • 某类任务总要参考同一份说明;
  • 某类工作总要执行相同的一组检查;
  • 一个流程需要固定输入、固定步骤和固定输出格式。

例如我做前端项目时,经常会遇到:

Text
修改页面
↓
检查代码
↓
执行 lint
↓
执行 build
↓
启动项目
↓
浏览器检查页面
↓
汇总验证结果

如果每次都在 Prompt 里重新解释一遍,其实很浪费时间。

把它做成:

Text
frontend-check

之后直接让 Codex 使用这个 Skill 即可。

相反,如果只是:

Text
帮我修改一下这个按钮颜色

这种一次性任务,直接告诉 Codex 要做什么通常更简单。

Skill 的真正价值不是让 Prompt 看起来更高级,而是把已经验证过的工作流程保存下来。

2. Skill、Plugin 和 MCP 先简单分清楚

现在 Codex 里经常会同时看到:

Text
Skill
Plugin
MCP

它们不是完全相同层级的东西。

可以先这样理解:

Skill:告诉 Codex「怎么做」

Skill 主要描述一个工作流程。

例如:

Text
检查前端代码
→ 执行 lint
→ 执行 build
→ 浏览器验证
→ 输出检查报告

这是一个典型 Skill。

MCP:给 Codex 提供「能调用什么」

如果 Codex 需要访问外部系统,比如:

Text
GitHub
Linear
数据库
设计工具
内部 API
文档系统

通常需要 Connector 或 MCP 提供对应工具和数据。

Skill 可以告诉 Codex:

去读取 Linear 任务,然后检查代码。

但真正让 Codex 有能力访问 Linear 的,是对应的外部工具连接。

Plugin:把这些能力打包起来

Plugin 更像一个可安装、可分发的软件包

一个 Plugin 可以包含:

Text
一个或多个 Skills
+
Connector
+
MCP Server
+
相关配置和资源

因此 Skill 和 Plugin 并不是互相替代的。

可以简单理解为:

Text
Skill
负责工作流

MCP / Connector
负责外部能力

Plugin
负责安装和分发这些能力

目前 ChatGPT 和 Codex 共用插件目录。如果已经存在适合某个工作的 Plugin,优先使用现成 Plugin 通常更方便;如果只是自己在本地写一个工作流程,则直接创建 Skill 会更轻量。

3. 在 Codex 桌面端安装现成 Skill

在自己写 Skill 之前,我建议先安装一个现成 Skill 看看它到底怎么工作。

ChatGPT 桌面应用的 Codex 支持独立 Skills,在侧边栏也可以看到 Skills 入口。

打开桌面端 Codex 后,可以先查看:

Text
Skills

看看当前已经有哪些 Skill。

Codex 本身还自带:

Text
$skill-installer

用于给本地 Codex 环境安装精选 Skill。

新建一个 Codex 任务,在输入框中输入:

Text
$skill-installer

然后告诉它自己需要什么。

例如:

Text
$skill-installer

我需要一个处理 GitHub PR Review 评论的 Skill。

也可以直接指定 Skill:

Text
$skill-installer gh-address-comments

gh-address-comments 是 OpenAI 当前 GitHub Plugin 中存在的一个 Skill,主要用于检查和处理 Pull Request 中尚未解决的 Review 评论。

安装完成以后,Codex 通常能够自动检测新 Skill。

如果没有出现,可以重启 Codex。官方目前也明确说明,$skill-installer 更适合本地配置和实验;如果希望把自己的 Skill 作为可复用能力进行分发,则更推荐打包成 Plugin。

4. 第一次使用 Skill,我会先做只读测试

安装完一个第三方 Skill 后,我不会马上让它修改重要代码。

例如安装:

Text
gh-address-comments

之后,我会先这样测试:

Text
$gh-address-comments

只列出当前 PR 尚未解决的 Review 评论,不要修改代码,不要回复评论。

这种方式有几个好处。

首先可以确认:

Text
Skill 是否已经加载

其次可以确认:

Text
Skill 是否理解当前任务

还可以检查:

Text
它准备调用哪些工具
它准备读取什么信息
它准备修改什么内容

等确认流程没问题,再让它真正处理代码。

对于会:

Text
修改文件
执行脚本
访问网络
调用 GitHub
提交代码
发送数据

的 Skill,我尤其建议这样做。

5. 安装第三方 Skill 前,我会看什么

Skill 本质上可以包含指令、脚本、参考资料和资源。

所以第三方 Skill 并不是装得越多越好。

至少需要检查下面三件事。

1. 来源

先看看:

Text
谁写的
从哪里来的
是否还在维护

优先选择:

Text
OpenAI 官方
可信 Plugin
可信团队
自己审核过的代码仓库

2. SKILL.md

安装之前最好看看:

Text
SKILL.md

重点看:

YAML
name:
description:

以及后面的实际执行流程。

尤其要检查:

Text
什么时候触发
会读取哪些文件
会执行哪些命令
会不会修改代码

3. scripts

一个 Skill 不只有 SKILL.md

它还可能包含:

Text
scripts/
references/
assets/
agents/

例如:

Text
my-skill/
├── SKILL.md
├── scripts/
├── references/
├── assets/
└── agents/

其中 scripts/ 可以包含真正会执行的程序。

所以遇到陌生 Skill,我还会确认脚本有没有:

Text
修改大量文件
安装依赖
访问网络
上传数据
调用系统命令
执行危险操作

官方同样建议 Skill 尽量保持单一职责,只有在需要确定性行为或外部工具时再加入脚本。

另外需要注意,一些旧教程会直接让你从 GitHub 复制某个 Skill 地址安装。

这种方式不是完全不能用,但不要对未知仓库盲目执行。

OpenAI 以前的 openai/skills 仓库目前已经在仓库首页标记为 deprecated,并提示当前 Codex Skill 和 Plugin 示例优先参考新的 OpenAI Plugins 仓库。

所以我的原则是:

优先使用 Plugin Directory、内置安装器以及当前官方维护的来源。

6. 写自己的第一个 Skill

接下来自己做一个最简单的 Skill。

例如我经常做前端项目,希望每次 UI 修改后 Codex 都执行一套固定检查:

Text
检查改动
↓
执行 lint / build
↓
页面验证
↓
输出检查结果

我把它叫:

Text
frontend-check

在项目根目录创建:

Text
.agents/
└── skills/
    └── frontend-check/
        └── SKILL.md

完整路径就是:

Text
.agents/skills/frontend-check/SKILL.md

Codex 会扫描代码仓库中的 .agents/skills 来发现项目级 Skill。

当然,这些文件也可以直接让 Codex 创建。

例如我会先明确限制它的修改范围:

Text
只在当前项目中创建:

.agents/skills/frontend-check/SKILL.md

不要修改其他文件。

SKILL.md 内容使用我下一条消息提供的文本。

这样可以避免为了创建 Skill,让 Codex顺便修改其他项目文件。

7. 编写 SKILL.md

然后创建:

Text
.agents/skills/frontend-check/SKILL.md

内容如下:

Markdown
---
name: frontend-check
description: Check a frontend change before delivery. Use when the user asks to verify a Vue or React UI change. Do not use for copy-only documentation edits.
---

1. Read the changed files and follow the applicable AGENTS.md instructions.

2. Run the project's existing lint or build command. Do not install dependencies unless asked.

3. For UI changes, verify the affected route in a real browser when a local server is available.

4. Report changed files, commands actually run, results, and anything not verified.

注意最开头:

YAML
---
name: frontend-check
description: Check a frontend change before delivery. Use when the user asks to verify a Vue or React UI change. Do not use for copy-only documentation edits.
---

这里是 YAML frontmatter。

上下两个:

Text
---

必须原样保留。

不要写成:

Markdown
**---**

也不要写成:

Markdown
\---

否则就不是正确的 Skill frontmatter 了。

官方当前的 Skill 格式要求 SKILL.md 至少包含:

YAML
name:
description:

Codex 会先读取这两个字段,用它们判断 Skill 是否适合当前任务。


8. name 应该怎么写

例如:

YAML
name: frontend-check

我通常使用:

Text
小写英文
+
-

也就是常见的 kebab-case:

Text
frontend-check
git-release-check
vue-code-review
project-deploy

并让 Skill 文件夹和名称保持一致:

Text
frontend-check/
└── SKILL.md

这样以后看到目录就知道对应哪个 Skill。

不要起得太模糊,例如:

YAML
name: helper

或者:

YAML
name: coding

以后 Skill 多了以后,很难知道它到底负责什么。

9. description 比 name 更重要

真正影响 Codex 是否自动触发 Skill 的,是:

YAML
description:

例如:

YAML
description: Check a frontend change before delivery. Use when the user asks to verify a Vue or React UI change. Do not use for copy-only documentation edits.

它实际上告诉 Codex 两件事情:

Text
什么时候使用
什么时候不要使用

如果只写:

YAML
description: Help me write frontend code.

范围就太宽了。

Codex 很难判断:

Text
修改 Vue 页面时用不用?
写 CSS 时用不用?
写 README 时用不用?
检查构建时用不用?

所以更推荐:

Text
Use when...
Do not use when...

把边界写清楚。

官方当前也特别强调:隐式调用依赖 description,因此应该把关键使用场景和边界写清楚。

10. Skill 不只是一个 SKILL.md

一个简单 Skill:

Text
frontend-check/
└── SKILL.md

已经可以工作。

但复杂 Skill 还可以这样:

Text
frontend-check/
├── SKILL.md
├── scripts/
├── references/
├── assets/
└── agents/

例如:

scripts

Text
scripts/check-build.js

用于执行固定检查。

references

Text
references/frontend-rules.md

用于存放:

Text
团队规范
接口规范
项目约定
检查标准

assets

可以保存:

Text
模板
资源文件
示例

agents/openai.yaml

还可以进一步配置:

Text
显示名称
描述
图标
默认 Prompt
依赖工具
是否允许隐式调用

例如官方目前支持通过:

YAML
policy:
  allow_implicit_invocation: false

关闭隐式调用。

这样 Skill 只有在用户显式指定时才会执行。

不过第一次写 Skill 完全不用弄这么复杂。

先把:

Text
SKILL.md

写好就够了。

11. 项目级 Skill 和全局 Skill

前面的例子放在:

Text
项目/.agents/skills/

属于项目级 Skill。

例如:

Text
my-project/
├── src/
├── package.json
├── AGENTS.md
└── .agents/
    └── skills/
        └── frontend-check/
            └── SKILL.md

这种 Skill 很适合:

Text
当前项目
当前代码仓库
当前团队

一起使用。

如果一个 Skill 希望自己的所有项目都能使用,可以放到用户目录:

Text
$HOME/.agents/skills

简单来说:

范围 位置
当前项目 .agents/skills
当前用户 $HOME/.agents/skills
管理员 /etc/codex/skills
系统内置 Codex 自带

对于 Git 仓库,Codex 会从当前工作目录开始向上扫描,一直到仓库根目录,并寻找沿途的 .agents/skills

所以:

项目专属流程放项目里,通用个人流程放用户目录。

通常就够用了。

12. 在桌面端使用自己的 Skill

保存:

Text
SKILL.md

以后,先回到桌面端侧边栏:

Text
Skills

确认:

Text
frontend-check

是否已经出现。

Codex 通常会自动检测 Skill 文件的变化;如果没有刷新,可以重启 Codex。

第一次测试时,我建议显式调用:

Text
$frontend-check

检查这次导航栏样式修改,不要修改代码,只报告验证结果。

Codex 支持两种 Skill 调用方式。

显式调用

直接指定:

Text
$frontend-check

这种方式最容易调试。

隐式调用

也可以直接说:

Text
检查一下我这次 Vue 页面修改是否可以提交。

如果这个任务和:

YAML
description:

匹配,Codex 可以自动选择:

Text
frontend-check

官方当前明确支持这两种方式:Codex 可以通过 $ 显式引用 Skill,也可以根据 description 自动匹配。

刚开始自己写 Skill 时,我建议优先:

Text
$技能名

显式调用。

因为如果没有执行,很容易判断到底是:

Text
Skill 没加载

还是:

Text
description 没匹配

13. Skill 没有出现怎么办

如果:

Text
frontend-check

没有出现在 Codex 中,我会按照下面顺序排查。

1. 检查目录

确认:

Text
.agents/
└── skills/
    └── frontend-check/
        └── SKILL.md

而不是:

Text
.agent/

或者:

Text
.skill/

2. 检查文件名

必须确认:

Text
SKILL.md

大小写和名称都不要写错。

3. 检查 YAML frontmatter

至少需要:

YAML
---
name: frontend-check
description: ...
---

不要写:

Markdown
**---**

4. 检查项目主文件夹

这是桌面端特别容易踩坑的地方。

一个 Codex 项目可以附加多个文件夹。

例如:

Text
frontend/
backend/
docs/

但其中会有一个:

Text
主文件夹

Codex 新聊天会从主文件夹开始。

这个主文件夹也是 Codex 默认用于:

Text
Git 操作
AGENTS.md 自动发现
Skills 自动发现
config.toml 自动发现

的位置。

其他附加文件夹虽然仍然可以:

Text
读取
搜索
修改

但不会作为自动发现这些项目规则的默认位置。

所以如果 Skill 明明存在却一直找不到,需要确认:

Text
.agents/skills

是不是放在当前项目正确的主文件夹中。

5. 显式调用一次

尝试:

Text
$frontend-check

如果显式调用可以,但平时自动触发不了,那么很可能不是加载问题,而是:

YAML
description:

范围写得不好。

6. 重启 Codex

官方文档说明 Codex 会自动检测 Skill 变更。

如果更新没有出现,可以重启 Codex。

桌面端直接:

Text
完全退出应用
↓
重新打开

即可。

14. Skill、AGENTS.md、MCP 到底分别放什么

这是我觉得最值得理解的一部分。

AGENTS.md

适合:

每次在这个项目工作都必须遵守的规则。

例如:

Text
项目只能使用 pnpm
不要修改 generated 目录
Vue 组件使用 Composition API
UI 修改后必须执行浏览器验证

这种规则不管 Codex 在做什么,都应该遵守。

因此适合放:

Text
AGENTS.md

SKILL.md

适合:

只有某种任务发生时,才需要执行的一套工作流程。

例如:

Text
发布前检查
PR Review
数据库迁移检查
前端交付检查
生成周报

适合做:

Text
Skill

MCP / Connector

适合:

Codex 需要连接外部系统。

例如:

Text
GitHub
Linear
数据库
Figma
Google Drive
内部平台

这类能力通常需要对应的 Connector 或 MCP。

Plugin

如果希望把:

Text
Skill
+
Connector
+
MCP
+
其他资源

打包成一个别人可以安装的完整能力,就适合:

Text
Plugin

可以整理成下面这张表:

需求 更适合放哪里
每次在项目工作都必须遵守 AGENTS.md
某类重复任务的固定流程 SKILL.md
访问 GitHub、数据库、设计工具等外部系统 Connector / MCP
把 Skills 和外部能力打包安装、分享 Plugin

例如:

Text
界面修改必须浏览器验证

属于长期项目规则:

Text
AGENTS.md

而:

Text
发版前执行完整检查并输出报告

属于重复流程:

Text
Skill

如果需要:

Text
读取 GitHub Pull Request

则需要:

Text
GitHub Connector / MCP

如果要把整套能力提供给其他人安装:

Text
Plugin

官方当前同样把 Skill 定义为工作流格式,而把 Plugin 定义为可安装、可分发的能力包。

15. 一个比较实用的组合

实际项目里,我现在更倾向于这样组织:

Text
project/
├── AGENTS.md
│
├── .agents/
│   └── skills/
│       ├── frontend-check/
│       │   └── SKILL.md
│       │
│       ├── code-review/
│       │   └── SKILL.md
│       │
│       └── release-check/
│           └── SKILL.md
│
├── src/
└── package.json

其中:

Text
AGENTS.md

负责项目长期规则。

Text
frontend-check

负责前端改动检查。

Text
code-review

负责代码审查流程。

Text
release-check

负责发布检查。

这样 Codex 的行为会比每次写一大段 Prompt 稳定很多。

16. 最后检查清单

写完一个 Skill 后,我会确认下面这些内容。

Skill 本身

  • [ ] 它解决的是重复任务,而不是一次性任务;
  • [ ] 文件名是 SKILL.md
  • [ ] YAML frontmatter 的 --- 没有写错;
  • [ ] 有 name
  • [ ] 有 description
  • [ ] description 写清楚什么时候使用;
  • [ ] description 写清楚什么时候不要使用;
  • [ ] Skill 只负责一个相对明确的任务。

项目位置

  • [ ] 项目级 Skill 放在 .agents/skills
  • [ ] 用户级 Skill 放在 $HOME/.agents/skills
  • [ ] 桌面端项目主文件夹选择正确。

安全

  • [ ] 第三方 Skill 检查过来源;
  • [ ] 看过 SKILL.md
  • [ ] 看过 scripts/
  • [ ] 知道它会不会联网;
  • [ ] 知道它会不会修改文件;
  • [ ] 知道它会不会安装依赖或调用外部服务。

测试

  • [ ] 第一次先用 $技能名 显式调用;
  • [ ] 第一次尽量做只读测试;
  • [ ] 确认输出符合预期以后再让它修改代码。

总结

刚开始接触 Codex Skills 时,很容易觉得它只是:

Text
一个更复杂的 Prompt

但真正用起来以后,我觉得它更像:

把自己平时反复执行的工作方法,正式交给 Codex。

一个比较健康的使用方式是:

Text
第一次:
自己完成任务
↓
第二次:
发现流程基本相同
↓
第三次:
把流程整理成 Skill
↓
以后:
让 Codex 按同样的标准执行

而不是看到什么都做成 Skill。

对于 Codex 项目,我现在会用这样一个简单标准判断:

Text
长期项目规则
→ AGENTS.md

重复任务流程
→ SKILL.md

外部系统能力
→ MCP / Connector

需要安装和分发整套能力
→ Plugin

如果只是想体验 Skill,我建议先通过:

Text
$skill-installer

安装一个现成 Skill。

等理解它的结构以后,再从最简单的:

Text
.agents/skills/frontend-check/SKILL.md

开始写自己的第一个 Skill。

不需要一开始就做脚本、MCP 或复杂 Plugin。

先把一个重复流程稳定下来,Skill 就已经开始产生价值了。

阅读进度 0%