Featured image of post Codex 怎么装 Skill:六个扫描位置、三种装法、一份可抄的命令

Codex 怎么装 Skill:六个扫描位置、三种装法、一份可抄的命令

想给 Codex 加一个 Skill,搜中文教程,出现频率最高的操作是把想要的文件夹复制到 Codex 的技能目录。这个动作本身没错,但「复制到哪」这句话,各家说法不一样:有说 ~/.codex/skills/ 的,有说 .agents/skills/ 的,还有让人先 clone 一个仓库再挑目录的。

这篇按官方文档、内置安装器 $skill-installer 的 SKILL.md 原文、以及开放标准的规范,把当前该怎么做理一遍。命令可以直接抄,那张六个位置的表可以当清单用。顺带说两处官方材料自己没对齐的地方。

先分清 Skill 是什么

Codex 里的 Skill,定义比很多人想的窄:一个目录,里面有一个 SKILL.md,其余全都可以没有。

my-skill/
├── SKILL.md          # 必需:元数据 + 指令
├── scripts/          # 可选:可执行代码
├── references/       # 可选:文档
├── assets/           # 可选:模板、资源
└── agents/
    └── openai.yaml   # 可选:外观与依赖

SKILL.md 是 YAML frontmatter 加 Markdown 正文。frontmatter 里只有两个字段是必需的,而这两个字段的约束比想象中严:

字段 必需 约束
name 是 最长 64 字符,只能用小写字母、数字和连字符,不能以连字符开头或结尾,不能有连续两个连字符,而且必须和父目录同名
description 是 1 到 1024 字符,要同时写清「做什么」和「什么时候用」
license 否 许可证名,或指向目录里的许可证文件
compatibility 否 最长 500 字符,环境要求(目标产品、系统依赖、是否需要联网)
metadata 否 任意键值对,键和值都是字符串
allowed-tools 否 空格分隔的预批准工具列表,实验性

最后那条「必须和父目录同名」是最常见的第一号坑。你的目录叫 pdf-tools,frontmatter 里写 name: pdf-processing,这个 Skill 就是加载不起来,而且 Codex 通常不会给你一句明确的报错。

那为什么值得费这个劲装 Skill,而不是把同样的话写进 AGENTS.md?因为它的加载方式不一样。

Codex 用的是渐进式披露:启动时只把每个 Skill 的名字、描述和文件路径列进上下文,等你真要干某件事,它判断某个 Skill 对得上,才去读那个 SKILL.md 的完整内容。没被匹配上的 Skill 一点都不占上下文。

这个初始列表有预算:默认最多占上下文窗口的 2%,上下文窗口未知时按 8,000 字符算。装得太多的话,Codex 会先截短描述;再多就会直接从初始列表里省掉一些 Skill,并给一个警告。想调预算,在配置里设 skills.max_context_tokens,上限 10,000 tokens。

最后这句值得记:装了五十个 Skill 不是本事,能保证常看的那个不被挤出列表才是。

装到哪里:六个扫描位置

官方文档给了一张扫描位置表,我原样搬过来,照着抄就行:

范围 位置 建议用途
REPO $CWD/.agents/skills 你启动 Codex 的当前目录。团队可以把只跟某个微服务或模块相关的 Skill 签进仓库
REPO $CWD/../.agents/skills 在 Git 仓库里启动、CWD 的上一级。适合多层嵌套目录里的共享区域
REPO $REPO_ROOT/.agents/skills 仓库最顶层。放全仓库任何子目录都能用到的 Skill
USER $HOME/.agents/skills 个人目录,适用于你在任何仓库里都会用到的 Skill
ADMIN /etc/codex/skills 机器或容器级的共享位置。适合 SDK 脚本、自动化,以及给机器上每个用户都装一份默认 Skill
SYSTEM 随 Codex 由 OpenAI 内置 面向广泛受众的 Skill,比如 skill-creator 和 plan 类技能,所有人开箱可用

三件需要额外记住的事。

第一,仓库范围内看的是一整条路径:从当前工作目录一路向上扫到仓库根,每一层的 .agents/skills 都会被看到。

第二,如果两层里有两个 Skill 的 name 相同,Codex 不会合并,两个都会出现在选择器里。这种情况最容易让人误判:你以为后一个覆盖了前一个,其实是两个并列。

第三,Codex 支持符号链接的技能文件夹,扫描时会跟随链接目标。对想把一批 Skill 集中放一个目录、再往各个项目里软链的人来说,这条省事。

⚠️ 还有一个方向性的提醒:.codex/ 这个目录是用来放 config.toml 这类配置的,不要凭直觉把技能文件夹建到 ~/.codex/skills/ 去。规范路径是 .agents/skills。

三种装法,按推荐顺序

方式一:手动放目录(最稳,推荐)

一次安装就是一个文件夹。没有隐藏状态,没有版本解析,出问题肉眼可见。

# 项目级:只对这个仓库生效
mkdir -p .agents/skills
cp -R /path/to/my-skill .agents/skills/

# 用户级:任何仓库都能用
mkdir -p ~/.agents/skills
cp -R /path/to/my-skill ~/.agents/skills/

从 GitHub 上拿的话,先只拉那一个子目录会干净很多:

git clone --depth 1 --filter=blob:none --sparse https://github.com/<owner>/<repo> /tmp/skill-src
cd /tmp/skill-src && git sparse-checkout set <path/to/skill>

方式二:用内置的 $skill-installer

Codex 自带一个 SYSTEM 级的 Skill 叫 skill-installer,它的 SKILL.md 我读了,行为写得很具体。

在 Codex 里直接这么说:

$skill-installer gh-address-comments

它会按名字去 curated 列表里找并安装。装实验性的技能要给出路径:

$skill-installer install https://github.com/openai/skills/tree/main/skills/.experimental/create-plan

它的实际行为有两处值得先知道:

它装到 $CODEX_HOME/skills/<技能名>,默认就是 ~/.codex/skills。也就是说,官方这套安装器自己默认落在 .codex 目录下,而不是前面那张表里的 .agents/skills。这两处的不一致我放到后面单独讲。

它默认走直接下载,遇到鉴权或权限错误才回退到 git 稀疏检出;如果目标是私有仓库,可以靠已有的 git 凭据,也可以给 GITHUB_TOKEN 或 GH_TOKEN。另外,如果目标目录已经存在,它会直接中止,不会覆盖。想覆盖就先手动删。

支持的参数有几个:--repo <owner>/<repo>、--path <路径>(可以一次给多个)、--url、--ref <ref>(默认 main)、--dest <路径>、--method auto|download|git。

补一句取数来源:$skill-installer 默认是从 openai/skills 这个仓库的 .curated 目录按名字取技能的,所以那个仓库仍然是官方安装器的默认来源。它最近的定位变过,作为示例和对外贡献的入口已经搬到插件那边,但这不影响你用它装东西。

方式三:打包成插件(要分发给别人就用这个)

如果只是自己或团队用,前两种够了。一旦要把 Skill 发给仓库外的人,官方给的答案是把 Skill 做成插件再发。

插件就是把 Skill 和(可选的)MCP server 依赖打包成一个可安装单元。官方提供了 @plugin-creator 来脚手架一个插件,生成的结构大致是这样:

my-plugin/
├── .codex-plugin/
│   └── plugin.json      # 始终会创建
├── .mcp.json            # 可选
├── .app.json            # 可选
├── skills/              # 把你的 Skill 文件夹放这儿
├── hooks/
├── scripts/
└── assets/

清单里会声明 skills: "./skills/",所以只要把做好的 Skill 文件夹放进 skills/ 就能被引用。文档还提了一句兼容性:新的可移植格式把 OpenAI 特有的呈现配置放在根 plugin.json 的 extensions.com.openai 下,而老的 .codex-plugin/plugin.json 仍然作为兼容回退被支持。

两处官方材料自己没对齐的地方

我不想把这两处含糊过去,因为你照着做的时候很可能撞上。

第一处是安装目录。 官方那份 Build skills 文档的扫描表把 USER 范围定为 $HOME/.agents/skills;而 skill-installer 自己的 SKILL.md 明明白白写着「安装到 $CODEX_HOME/skills(默认 ~/.codex/skills)」。一个指向 .agents,一个指向 .codex。

我的处理办法是:想跨工具通用的,手动放到 .agents/skills,因为这是那个开放标准的位置,Claude Code 之类的工具也认;用 $skill-installer 装的,就接受它在 ~/.codex/skills 里,反正它自己认得自己的目录。真要较真,装完之后把目录移到 .agents/skills 再验证一遍,成本很低。

第二处是生效时机。 Build skills 文档说「Codex 会自动检测 Skill 变更,如果更新没出现就重启 Codex」;而 openai/skills 的 README 直接说「安装完 Skill 之后重启 Codex 以加载新技能」。一个说自动,一个说重启。

实操结论很简单:没出现就重启。这不是一个值得纠结的问题,但它说明这套机制还在快速演进,别把任何一处的措辞当成保证。

怎么确认装上了

装完别急着信,验证一下。

在 Codex CLI 或 IDE 扩展里跑 /skills,或者直接输入 $,会列出当前可见的 Skill。列表里出现,说明位置和 frontmatter 都对。

还要分清两种调用方式:显式调用是你在提示里直接点它(Codex 里用 /skills 或 $,ChatGPT 里用 @);隐式调用是 Codex 自己判断当前任务匹配某个 Skill 的 description,然后去加载。

隐式匹配失败通常是 description 写得太泛,跟 Codex 本身没关系。给一个最小验收流程:让 Codex 复述一下这个 Skill 要求它做的步骤,再让它跑一个只读的小任务。复述得出来,说明 SKILL.md 真被读进去了。

几个高频故障,照着排:

症状 原因 处理
列表里根本没有 name 和目录名不一致,或目录层级放错 让两者同名;确认它在六个位置之一
有,但从来不被自动用上 description 太泛或没写触发词 把使用场景和关键词前置到描述开头
装了很多之后有些不见了 初始列表预算被打满 用 skills.max_context_tokens 调预算;或删掉不用的 Skill
改完没反应 缓存或需要重启 重启 Codex

自己写一个,最短路径

三条路,按省事程度排:

$skill-creator 是内置的创建器,会问你三件事:这个 Skill 做什么、什么时候该触发、以及只要指令还是也要带脚本(默认只要指令)。

如果那个工作流你更擅长演示而不是描述,用 Record & Replay:它录下你的操作,检查步骤,然后起草出一个可复用的 Skill。

最后是手写,一个文件夹加一个 SKILL.md 就行:

---
name: my-skill
description: 干什么,以及在什么情况下该用、什么情况下不该用。
---

给 Codex 执行的指令,一步一步写。

写 description 的原则只有一条:它决定了隐式匹配,所以要写成「给匹配器看的」,不是「给人看的」。把触发词前置,因为 Codex 在装得太多时会先截短描述,前面那几个词是唯一稳的部分。反过来,明确写出「什么时候不该触发」也很值钱,不然这个 Skill 会在不该出现的时候冒出来。

装第三方 Skill 之前,请读一遍它的内容

这一点我想单独说,因为它是这套机制里风险最高的地方。

装一个 Skill,等于让 Codex 按别人写的指令干活;而且 Skill 目录允许带 scripts/,那是会真被执行的可执行代码。这正好是「技能供给链」这一类攻击的入口,站内之前写过 ClawHavoc 那批恶意 Skill 的事,335 个恶意技能、30 万个 Agent 暴露在风险里,机制跟这个是一样的。

我给三条可操作的建议:装之前把 SKILL.md 和 scripts/ 读一遍,尤其是脚本里有没有往外发数据、有没有读凭据文件;把来源固定到具体 commit,别跟着 main 漂;不用了就删掉,一个不再使用的 Skill 只是一份留在磁盘上的信任。

写在最后

给 Codex 装 Skill 这件事本身很简单,一个文件夹复制过去就完事了。麻烦的从来是「我照的那份教程是不是还成立」。

这次查下来最值得抄的是那张六个位置的表,它把「装到哪」从各家说法里收敛成了一份清单。另外官方文档内部有两处对不上(安装目录、生效时机),我按能实测的方式处理了,也在正文里标了出来。

所以这篇的用法是:前面那张六个位置的表可以直接抄,$skill-installer 的行为按上面写的预期去验,然后每次照教程做之前,先确认那份教程对应的版本还在不在。这套东西还在动。

相关阅读:

By AI博士 万戈