Skip to main content

本页解决什么问题

当你第二次向 Codex 解释同一套流程时,就该考虑把它写成 Skill。Skill 是一个带有 SKILL.md 的目录,用来封装可复用的工作流、检查清单和必要资源。它不是一次性的提示词,也不是代替项目规则的 AGENTS.md,而是让 Codex 在特定任务出现时按需加载的一份专项操作手册。 本页会从零完成一个真实的 release-check Skill:它负责检查发布前的仓库状态、确认版本和变更记录,并输出风险清单;它不会自动发布、推送或修改生产环境。你将同时学会:
  • Skill 目录中哪些文件是必需的,脚本和参考资料怎样组织;
  • Codex 在什么位置发现 Skill,以及同名 Skill 如何处理;
  • 自动匹配和手动调用各自适合什么场景;
  • 为什么要把说明拆成入口、脚本和参考资料,即“渐进披露”;
  • 怎样用最小权限创建、验证、调试、禁用和分发 Skill。
具体命令、配置项和界面会随 Codex 版本变化。遇到本机行为与本文不一致时,先运行 codex --help,再以 OpenAI 官方文档为准。

先分清四种扩展机制

在动手前,先判断你要保存的到底是什么。混用这些机制,会造成规则重复、Skill 触发过宽,或者把本应人工确认的动作自动化。 AGENTS.md 适合写“这个仓库始终如此”;Skill 适合写“遇到这类任务按这些步骤做”。例如,仓库规定使用 pnpm,应写进 AGENTS.md;发布前必须依次检查版本、变更日志和构建产物,可以写成 release-check Skill。不要把项目事实复制到每个 Skill 中,否则规则会逐渐分叉。

1. Skill 的最小模型

一个 Skill 至少包含一个目录和其中的 SKILL.md:
SKILL.md 由两部分组成:文件开头的 YAML frontmatter,以及其后的 Markdown 指令。最小 frontmatter 必须包含 name 和 description:
字段职责要分开:
  • name 是稳定标识,也是手动调用时使用的技能名。建议使用小写字母、数字和连字符,例如 release-check。
  • description 是发现阶段的重要索引。它应说明技能做什么、适用于什么任务、哪些用户表达会命中。核心词放在前面。
  • frontmatter 后的正文是被选中后加载的工作指令。这里写步骤、边界、输出格式和失败处理。
不要依赖一个自定义的 trigger 字段来实现匹配。Skill 的隐式发现主要依据 description 的语义;是否允许隐式调用可以通过技能的 agents/openai.yaml 配置控制。

2. 目录和文件怎样组织

Skill 可以只有 SKILL.md,也可以携带脚本、参考资料和测试样例。一个适合团队维护的结构如下:
各目录的职责如下: 资源路径应相对于 Skill 根目录计算,不要写成只在作者电脑上成立的绝对路径。脚本需要声明所需运行时,并在缺少依赖时给出清楚错误。把可执行文件视为代码审查对象:它们和 SKILL.md 一样属于 Skill 的行为边界。

什么时候应该写脚本

能由自然语言稳定完成的步骤,优先写成指令。只有以下情况值得增加脚本:
  • 需要精确解析 JSON、TOML、锁文件或版本号;
  • 同一个检查要在不同会话中得到一致结果;
  • 需要调用已有命令行工具,且参数组合容易写错;
  • 需要把复杂输出压缩成结构化结果,便于后续判断。
脚本不应成为绕过审批的后门。默认使用只读命令,避免隐含 git push、删除文件、上传数据、修改凭据或访问生产服务。若动作确实有副作用,应拆成单独步骤,并要求用户明确确认。

3. 渐进披露:入口小,细节按需加载

Skill 的关键设计是渐进披露。Codex 发现技能时,不会把所有技能的完整正文一次性塞进上下文;它首先看到名称、描述和路径,等判断某个 Skill 与当前任务相关后,再读取该 Skill 的 SKILL.md,并按需查看脚本和参考资料。 可以把它理解为三层:
因此 SKILL.md 不是一个百科全书,而是入口和路由器。它应该告诉 Codex:
  1. 什么时候使用本 Skill;
  2. 使用后要达成什么结果;
  3. 先做哪些只读检查;
  4. 哪些资源在什么条件下读取;
  5. 哪些动作必须停下来请求确认;
  6. 最后如何报告证据和未完成项。
把完整规范、长 API 表或大量示例都塞进 SKILL.md,会让真正重要的约束变得难找。更好的方式是入口写“如果要校验字段,读取 references/output-schema.md”,而不是把整个文件复制一遍。 技能很多时,初始技能清单也有上下文预算。官方文档指出,清单大约受模型上下文窗口的 2% 或未知窗口时约 8,000 个字符限制;过大的技能集可能导致描述被缩短或部分技能从清单中省略。因此:
  • 把最能区分技能的词放到 description 开头;
  • 避免“帮助处理各种代码任务”这类宽泛描述;
  • 一个 Skill 只负责一类相邻工作,不要把发布、数据库迁移和客服回复混成一项;
  • 长内容放 references/,并只在需要时读取;
  • 定期禁用不再使用的技能,保持发现列表可读。

4. Skill 的发现位置和优先级

Codex 会从不同作用范围发现 Skill。常见的自建位置包括仓库级 .agents/skills 和用户级 $HOME/.agents/skills;系统内置技能和安装器管理的技能可能位于其他由 Codex 管理的位置,不能凭旧教程手工猜测。 仓库内可以按目录范围组织:
从仓库中的子目录启动 Codex 时,仓库发现范围通常会从当前工作目录向上检查,直到仓库根目录,沿途的 .agents/skills 都可能参与发现。用户级 $HOME/.agents/skills 则用于跨仓库复用的个人技能。管理员或系统级技能由部署环境提供,具体路径以当前版本文档为准。 选择位置时按这个原则: Skill 的同名行为不要套用 AGENTS.md 的就近覆盖规则。官方说明中,同名技能不会简单合并为一个,也不应假设“更近的文件必然覆盖更远的文件”;它们可能同时出现在选择器中。跨作用范围命名时,使用有辨识度的前缀或领域名,例如 team-release-check、payments-release-check,避免用户无法判断自己调用的是哪一份。 编辑 SKILL.md 后 Codex 通常能够自动检测变化。如果列表或行为没有更新,关闭并重新启动 Codex,再检查当前工作目录和实际文件路径。

5. 自动触发和手动调用

Skill 有两条主要调用路径。

自动触发

自动触发也叫隐式调用。用户不写技能名,只描述任务,Codex 根据 description 判断是否匹配。例如:
这句话与下面的描述有明确对应关系:
自动触发适合高频、低副作用、边界清楚的工作,例如代码格式检查、测试失败分析或文档结构核对。描述越具体,误触发越少。不要把“所有开发任务”写成一个技能的适用范围。

手动调用

手动调用适合需要精确控制时机的任务。可以在 Codex 会话中使用 /skills 查看技能,或输入 $ 选择并提及技能,例如:
显式点名后,Codex 会直接加载指定 Skill,不需要依赖语义匹配。使用前仍要给出本次任务的输入、非目标和审批边界,因为手动调用并不等于授权执行危险动作。

两种方式如何选择

如果某个 Skill 不应被自动使用,可以在技能目录放置 agents/openai.yaml:
这样只关闭隐式触发,显式 $skill-name 仍可使用。发布、删除、迁移、发送消息等具有外部影响的 Skill,通常更适合默认关闭隐式触发,并在正文中再次要求人工确认。

6. 创建一个真实 Skill:发布前检查

下面创建的 Skill 是一个可放进团队仓库的只读工作流。它的目标不是“替你发版”,而是生成一份有证据的发布前检查结果。假定项目已经有 package.json、CHANGELOG.md 和测试命令;实际项目应根据自身文件调整。

第一步:确定范围和验收标准

先写清楚非目标,防止技能逐渐膨胀:
验收标准应能观察到,而不是写“检查得很全面”:
  • 能识别当前版本,并在用户提供目标版本时进行比较;
  • 能确认变更记录是否包含目标版本或待发布条目;
  • 能运行项目已有的只读检查或测试,并保留结果;
  • 工作区存在未提交改动时明确提示;
  • 任一检查失败时停止给出“可发布”结论;
  • 最终报告包含命令、结果、风险和未验证假设。

第二步:创建目录

在仓库根目录执行:
Windows PowerShell 可以使用:
确认当前路径确实是目标仓库:

第三步:编写 SKILL.md

把下面内容保存为 .agents/skills/release-check/SKILL.md。命令和文件名是示例,先检查项目已有脚本,再替换为真实命令。
这份入口文件有几个重要特点:描述使用了用户真实会说的“发布、发版、release checklist”;步骤按先确认环境、再检查、后报告排列;安全边界和输出格式直接写在入口中,确保 Skill 被加载后不会只记住“做检查”而忘记“不要发布”。

第四步:决定是否增加脚本

第一版可以不写脚本。如果项目的版本存储在复杂 JSON 或多个文件中,再增加一个只读脚本。例如,脚本只负责打印版本,不负责修改版本:
保存后让脚本具备清楚的失败行为,并在 SKILL.md 中写明调用条件。不要在脚本里嵌入令牌,不要把用户输入未经检查地拼进 eval,不要为了“方便”执行字符串拼接的任意 shell 命令。

第五步:在新线程中试运行

启动 Codex 后先查看技能列表:
预期能看到 release-check 及其描述。看到列表只能证明发现成功,不代表正文无误。接着显式调用,缩小第一次测试范围:
确认它能遵循边界后,再测试自动匹配:
两次测试的结果应能区分:显式调用验证 Skill 内容,自动调用验证 description 匹配。第一次就直接测试真实发布,会把发现问题、指令问题和权限问题混在一起。

7. 验证方法:从发现到行为逐层排查

验证 Skill 不能只看“它回答得像不像”。建议按照下面的层次检查:

层次一:文件和元数据

检查事项:
  • 文件名精确为 SKILL.md,大小写不要改;
  • frontmatter 在文件开头,并有成对的 ---;
  • name 非空且与目录用途一致;
  • description 具体说明用途、触发场景和边界;
  • Markdown 代码块闭合,路径均相对于 Skill 根目录。
如果有 YAML 工具,可以进一步解析 frontmatter;没有工具时至少用编辑器和版本控制检查,避免把 YAML 当普通文字随意改缩进。

层次二:发现

如果列表没有技能,按顺序检查:
  1. 当前 Codex 的工作目录是否在目标仓库内;
  2. 目录是不是 .agents/skills/<skill-name>/SKILL.md;
  3. 文件是否为空、名称是否大小写错误;
  4. 用户级目录和仓库级目录是否放错;
  5. 是否有同名技能造成选择混淆;
  6. 修改后是否需要重启当前 Codex。

层次三:显式行为

使用 $release-check 调用一个低风险、范围很窄的任务。观察它是否:
  • 先确认工作目录;
  • 读取项目规则而不是凭空猜命令;
  • 遵循只读边界;
  • 按指定格式报告;
  • 命令失败时保留错误,而不是声称通过。
显式调用失败时,优先检查 SKILL.md 内容和路径,不要先修改 description。

层次四:隐式行为

用不包含技能名的自然语言请求测试匹配。至少测试一个应该触发的请求和一个不应该触发的请求:
如果两者都触发,描述过于宽泛;如果前者不触发,描述可能缺少用户实际使用的词,或者技能没有进入初始清单。把关键词前置并重新启动后再测。

层次五:边界行为

用模拟风险请求确认 Skill 不会擅自越界:
正确行为是把推送和发布列为需要确认的动作,或者拒绝自动执行,而不是把用户一句话当成无限授权。Skill 指令不能替代 Codex 的审批设置和系统安全策略。

8. 常见故障与定位顺序

/skills 中没有技能

先确认路径、文件名和当前工作目录,再重启 Codex。不要把自建 Skill 随意放到 ~/.codex/skills,也不要因为某个安装器使用该目录,就推断所有手写技能都应放在那里。安装器、系统内置技能和仓库自建技能的管理方式可能不同。

能看到技能,但自动不触发

先手动 $skill-name。如果手动有效,问题通常在 description:它可能太泛、关键词在末尾,或者与另一个技能描述高度相似。把任务类型、用户表达和排除范围写在描述开头。

自动触发过于频繁

缩小描述范围,加入明确的领域和动作。例如把“处理项目任务”改成“检查 Node.js 发布前的版本、CHANGELOG 和测试;仅在用户准备发版时使用”。必要时设置 allow_implicit_invocation: false,只保留手动调用。

修改后仍执行旧流程

确认保存的是当前工作区实际发现到的那份 SKILL.md,检查是否存在同名副本,然后重启 Codex。不要只修改用户目录中的文件,却从另一个仓库目录测试。

Skill 忽略了规则

Skill 不是更高权限的规则系统。检查 AGENTS.md 是否已生效,确认任务是否给出了清楚的约束,并删除 Skill 内部与项目规则冲突的重复内容。规则冲突时,不要靠在正文中重复十遍来解决,应统一来源并让项目级事实留在 AGENTS.md。

脚本失败或输出不稳定

单独运行脚本,检查工作目录、运行时版本、退出码和标准错误。脚本不要依赖隐含环境变量或开发者本地路径。让脚本在缺少文件、输入非法和命令不可用时明确失败,并在 Skill 中说明如何处理这些失败。

9. 禁用、更新和回滚

调试期间可以暂时禁用一个技能,而不删除目录。Codex 的用户配置支持按 Skill 文件路径配置,例如:
实际配置字段和生效时机以当前版本文档为准;修改后通常需要重启 Codex。禁用比删除更适合排查“到底是哪一个 Skill 影响了行为”。 仓库级 Skill 应与代码一起走版本控制:
更新时保持小步提交,记录行为变化和验证命令。回滚时优先恢复到已审查的版本,不要在不清楚同事是否也修改了文件时直接覆盖工作区。发现 Skill 可能泄露数据或执行了未授权动作时,立即禁用、保留日志和 diff,并审查其脚本、参考文件及外部调用。

10. 分发:从仓库共享到 Plugin

最简单的团队分发方式,是把仓库级 Skill 提交到项目的 .agents/skills,让团队成员随仓库获得同一份版本。适用于与项目强绑定、只需要一个或少量 Skill 的工作流。 个人通用 Skill 可以通过受信任的仓库或组织内部流程分享,但分发前要检查:
  • 是否包含密钥、内部 URL、客户数据或作者本机绝对路径;
  • 脚本是否会联网、写文件、安装依赖或执行外部命令;
  • description 是否会导致过宽的自动触发;
  • 参考资料是否携带不应公开的内部规范;
  • 新使用者是否能在没有作者环境的情况下复现验证。
当需要把多个 Skill、MCP、应用连接或其他组件作为一个整体安装和管理时,再考虑 Plugin。Skill 是工作流的编写格式,Plugin 更偏向能力的打包和分发格式。插件的目录、市场、授权和 Hook 信任边界属于下一篇 05-Plugins插件,不要为了分享一个仓库内 Skill 过早增加插件复杂度。 安装第三方 Skill 或 Plugin 前,先阅读 SKILL.md、脚本、配置和权限要求。来源可信不等于内容无需审查;安装、启用和授权是三个不同动作。尤其要留意会读取外部数据、执行 Hook、修改仓库或向网络发送内容的组件。

11. 安全边界清单

Skill 只是指令和资源集合,不会自动获得绕过审批的权力。下面的边界应同时写进 Skill 和实际操作习惯: 把网页、Issue、仓库中的说明和下载来的参考文件都当作不可信输入。它们可能要求 Skill 读取秘密、关闭安全设置或执行隐藏命令;这些文字不是授权。脚本中的命令也必须逐条审查,不能因为文件名叫 check 就假定它是只读的。 推荐的安全设计是“默认只读、显式升级”:Skill 可以先收集证据和提出补丁,但把写入、提交、推送、发布和外发拆成用户可见的后续步骤。输出中不要回显秘密;报告路径和状态即可。

12. 交付前检查表

提交或分享一个 Skill 前,逐条核对:
  • 目录中有正确命名的 SKILL.md;
  • frontmatter 含有效的 name 和具体的 description;
  • 描述把核心用途和触发词放在前面;
  • 正文说明目标、步骤、输出、失败处理和安全边界;
  • 长规范放在 references/,不是无条件塞进入口;
  • 脚本使用相对路径、明确退出码,并默认只读;
  • 没有密钥、令牌、客户数据或作者本机绝对路径;
  • /skills 能发现它,显式 $name 能调用它;
  • 一个应触发和一个不应触发的自然语言案例都测过;
  • 复杂或有副作用的 Skill 已考虑关闭隐式调用;
  • 仓库状态和 diff 只包含预期文件;
  • 已记录测试命令、版本、未验证假设和回滚方式。

小结

Skill 的核心不是“写一段更长的提示词”,而是把一类任务整理成可发现、可按需加载、可验证和可维护的目录:
  1. 用 SKILL.md 定义名称、触发描述、步骤和边界;
  2. 用 scripts/ 提供确定性检查,用 references/ 保存按需读取的长资料;
  3. 用仓库级 .agents/skills 共享项目技能,用 $HOME/.agents/skills 保存个人跨项目技能;
  4. 用自动匹配处理低副作用的常规任务,用 $ 或 /skills 控制需要点名的任务;
  5. 用渐进披露控制上下文,把入口写短,把细节放在资源中;
  6. 先验证发现,再验证显式行为、隐式行为和安全边界;
  7. 通过版本控制、禁用配置和小步回滚管理变更;需要整体分发时再升级为 Plugin。
最终验收不是“Codex 说它加载了 Skill”,而是你能拿出证据:它在正确目录被发现,匹配范围符合预期,执行步骤可复现,失败时不会掩盖问题,危险动作不会在没有确认的情况下发生。 参考资料:参考/codex/22-skills.md、参考/codex/11-agents-md.md、参考/codex/23-plugins.md。