Codex Skills 目录到底放哪:双目录迁移与维护实战

type
status
date
slug
summary
tags
category
icon
password
wechat_gate
notion image
Codex Skills 目录到底该放在 ~/.agents/skills,还是 ~/.codex/skills?按当前官方文档,个人自定义 Skill 应优先放在 ~/.agents/skills~/.codex/skills 更适合作为本机系统内容或旧工具的兼容入口,不应该再维护第二份可独立修改的同名副本。
这不是一个纯粹的目录洁癖问题。两份实体同时存在后,最先出现的通常不是报错,而是更隐蔽的版本漂移:你修改了 A,Codex 实际加载 B;旧脚本继续读旧路径;同名 Skill 在选择器里重复出现;几个月后已经没人敢确认哪一份才是真的。
我在整理 Mufeng 系列 Skill 时,正好经历了这一轮迁移、断链和修复。最终留下的原则只有五个词:
实体唯一、入口兼容、系统隔离、迁移可验、故障可回滚。

Codex Skills 目录为什么会同时出现两个路径

先把三个容易混淆的事实分开。
第一,OpenAI 当前的 Skills 文档把个人级目录列为:
项目级 Skill 则放在仓库内的 .agents/skills。Codex 会从当前工作目录向仓库根目录逐级扫描这些目录。官方文档还明确写到,扫描位置里的 Skill 目录可以是符号链接,Codex 会继续解析链接目标。
第二,~/.codex 仍然是 Codex 的产品状态目录。配置、会话、日志以及随产品提供的系统 Skill 都可能在这里。尤其是:
这一层由 Codex 管理,不应该当作普通用户 Skill 迁移、改名或合并。
第三,工具链仍处在过渡期。OpenAI 官方 openai/skills 仓库的公开 issue #420 记录过一个真实矛盾:公开文档已经指向 .agents/skills,而当时内置的 skill-installerskill-creator 仍默认把内容写入 $CODEX_HOME/skills,也就是常见的 ~/.codex/skills
所以,看到两个目录并不一定说明安装坏了。真正需要回答的是:
  1. 哪个目录保存唯一实体?
  1. 哪个路径只是为了兼容旧脚本?
  1. 哪些系统内容绝对不应该动?

先给结论:用一个实体目录解决版本漂移

对长期维护的个人自定义 Skill,我现在采用下面这套结构:
这里最关键的不是“两个路径都能打开”,而是只有一个路径保存真实文件。
~/.agents/skills/<skill-name> 里放 SKILL.mdscripts/references/assets/agents/openai.yaml。如果旧命令仍然硬编码了 .codex/skills/<skill-name>,就在旧位置放一个指向实体目录的相对符号链接。
需要强调一个边界:这个兼容链接首先解决的是文件路径兼容,不应该被描述成官方要求的第二套安装方式。当前官方文档列出的个人级发现目录是 $HOME/.agents/skills;不同 Codex 版本和内置安装器对 $CODEX_HOME/skills 的行为可能仍有差异。
notion image

我为什么没有直接删除旧目录

这次迁移的两个实体 Skill 是:
它们原来都位于 ~/.codex/skills。其中 Storybook 的说明和工作流文件里存在多处旧路径:
如果只把实体目录移动到 .agents/skills,旧命令会立即失效。反过来,如果为了兼容而复制一份,两个目录又会重新变成两套可独立修改的源码。
最后我选择的是:移动实体,然后在旧位置创建相对符号链接。
这样,维护入口已经收敛到 .agents/skills,旧命令仍能通过文件系统解析到同一份内容。
迁移完成后,我再次审计了当前 Mufeng 目录:~/.agents/skills 下有 10 个实体目录,~/.codex/skills 下有 9 个兼容符号链接,9 个链接均有效,没有断链。
notion image
这组数字只是当前本机事实,不是 Codex 的产品上限,也不是每个用户都应该照抄的数量。它能证明的只有一件事:这套“单一实体 + 兼容入口”的结构在本机已经完成闭环验证。

安全迁移 Codex Skills 的四个步骤

目录迁移本身不复杂,真正危险的是覆盖、意外嵌套和移动后才发现旧路径仍被大量引用。

第一步:确认源是实体,目标不存在

不要跳过目标检查。直接把一个目录 mv 到已存在的同名目录,结果可能不是覆盖,而是把源目录嵌套进目标内部,后续更难发现。

第二步:搜索旧路径依赖

如果结果中存在脚本命令、配置项或文档示例,先决定是保留兼容链接,还是同步修改引用。已经投入使用的 Skill,我更倾向于先保留链接,再逐步清理硬编码。

第三步:移动实体并立即补兼容入口

我优先使用相对符号链接。只要 .codex.agents 仍位于同一个用户主目录,整套用户目录迁移或从备份恢复后,链接比写死 /Users/某个用户名/... 更容易继续生效。

第四步:验证链接、内容和关键命令

验证不能只看 Finder 里有没有图标。至少要确认:
  1. 旧路径确实是符号链接。
  1. 链接目标存在。
  1. realpath 能解析到 .agents/skills 下的实体目录。
  1. 新旧路径都能读取同一个 SKILL.md
  1. 依赖旧路径的关键脚本仍能运行。

一次断链让我重新理解“名称一致”

迁移里最具体的一次失败来自 mufeng-writing
旧链接原本指向:
但这个目标目录根本不存在。真正存在的 Skill 叫:
它的 SKILL.md frontmatter 里也是:
问题不是符号链接语法写错,而是“兼容别名”和“规范名称”混在了一起。最后的修复是让旧入口 mufeng-writing 指向真实的 mufeng-blog-writing
这次失败给我的教训是:迁移验证不能只检查链接存在,还要检查目标存在、目录名与 frontmatter 的 name 一致,以及依赖方到底引用的是规范名称还是历史别名。
对新建 Skill,最省事的做法仍然是让三者完全一致:
兼容别名可以保留,但应该明确记录它只是别名,不能把别名再复制成第二个实体目录。

怎么判断一个兼容链接还要不要留

不是所有 Skill 都需要在 .codex/skills 保留入口。
情况
建议
Codex 已能从 .agents/skills 发现,内部没有旧路径引用
不必创建兼容链接
脚本、文档或自动化仍硬编码 .codex/skills
暂时保留相对符号链接
同名目录在两个位置都是实体
先比较差异,再选择唯一实体,不能直接删除
.codex/skills/.system 下的内容
保持原位,不迁移
插件缓存或版本化 marketplace 目录
交给插件管理器,不手工复制
这也是为什么 mufeng-materials-to-wechat-publish 当前没有同名 .codex/skills 链接:Codex 已经能从 .agents/skills 发现它,Skill 内也没有必须通过旧入口执行的命令。没有依赖,就没有必要为了“看起来整齐”再多造一个链接。

回滚要简单,但前提是先确认目标

迁移前如果保留了清晰的单一实体,回滚只需要两步:删除旧入口的符号链接,再把实体移回去。
这里应该使用 unlink 删除符号链接本身,不要用递归删除命令。执行前必须通过 readlinkrealpath 确认目标,避免删错实体目录。

后续维护只需要守住一条主线

目录问题看起来复杂,长期维护时其实只需要反复检查下面几件事:
  1. 用户自定义 Skill 是否只有一个实体目录。
  1. .codex/skills 下的自定义入口是否只是必要的有效链接。
  1. .codex/skills/.system 和插件缓存是否保持隔离。
  1. SKILL.mdname 是否与实体目录名一致。
  1. scripts/references/assets/agents/openai.yaml 的相对引用是否仍有效。
  1. 旧路径依赖是否已经减少到可以安全移除兼容链接。
  1. 重要迁移是否做过目标冲突、链接解析和关键命令验证。
如果只记住一个结论,就是:
双目录可以共存,双实体不要共存。
~/.agents/skills 负责承载长期维护的个人 Skill,.codex/skills 只在本机系统内容或旧路径兼容确有需要时出现。把“官方发现路径”“当前工具行为”和“自己的兼容策略”分开描述,后续升级时才不会把经验判断误当成稳定规范。

参考资料

2026.08.06 10:47 沪 · 赵巷
📌 声明:本文由 AI 辅助完成