MCP 可以把工具做成远程服务具体做法见后面的动手开发 MCP 工具。但很多时候需求没那么重只是想把本地一些反复执行的操作固化下来每次一句话就能执行。这就是 Skill 要解决的问题。Codex 和 Claude Code 都支持 Skill。它的核心形式很简单一个目录里放一个SKILL.md用 YAML 头部声明名称和使用时机Markdown 正文记录具体流程还可以带脚本、模板和参考资料。两个工具读取的默认目录不同工具项目级 Skill 目录个人全局 Skill 目录Codex.agents/skills/~/.agents/skills/Claude Code.claude/skills/~/.claude/skills/SKILL.md的基本结构可以共用但两个工具的额外字段、手动触发方式和权限配置不完全一样后面会单独说明。下面先以 Codex 为例创建一个 Skill理解最通用的部分。同时使用 Codex 和 Claude Code如果你同时使用两个工具没必要维护两份 Skill。选一个目录保存真实文件另一个入口用软连接指过去就行。比如你主要使用 Codex把.agents/skills/作为真实目录可以这样兼容 Claude Codemkdir -p .claude ln -s ../.agents/skills .claude/skills如果项目原来已经在.claude/skills/维护 Skill也可以反过来给 Codex 建立入口mkdir -p .agents ln -s ../.claude/skills .agents/skills两种方式二选一不要同时创建。如果目标目录已经存在先检查并合并其中的内容不要直接覆盖。个人级的~/.agents/skills/和~/.claude/skills/也可以用同样的方式共享。¶做一个图片优化 Skill一个 Skill 就是.agents/skills/下的一个文件夹唯一必须的文件是SKILL.md其他文件脚本、模板、参考资料都是可选的。我们来做一个图片优化 Skill把图片压缩、缩放、转成 WebP。Skill 放在用户家目录~/.agents/skills/下是个人级的所有项目可用放在项目的.agents/skills/下是项目级的只在当前项目生效¶SKILL.mdSkill 的核心SKILL.md 分两部分YAML 头部两行---之间声明 Skill 叫什么名字、在什么情况下应该使用。其中name和description是最基本的字段。Markdown 正文---下方是给 Agent 看的操作说明告诉它加载这个 Skill 之后该怎么做。可以理解为一份操作手册。YAML 头部定义「我是谁、什么时候用我」Markdown 正文定义「具体怎么做」。¶固定的流程用脚本代码脚本主要用来封装固定流程比如这个示例里SKILL.md 引用了scripts/optimize.py用 Pillow 库做图片缩放、压缩和格式转换。如果每次都让 Agent 临时写一份脚本结果可能不一致还会额外消耗 token。把不变的流程沉淀成脚本再在 SKILL.md 中写清楚脚本的用法就能保证一致性。但代码脚本并不是必须的如果流程本身比较简单纯文本描述就够了。比如一个 git 提交规范检查 Skill--- name: commit-check description: 检查 commit message 是否符合规范。审查提交信息、准备 git commit 时使用。 --- 检查 git log 最近一条 commit message 是否符合格式 type(scope): description type 必须是 feat/fix/refactor/docs/test/chore 之一。 如果格式不对给出修改建议。这个 Skill 没有脚本也没有额外文件只靠自然语言描述工作流。Codex 和 Claude Code 都能理解这种基本结构。小技巧以我的经验来看主要有两种情况需要给 Skill 搭配脚本数据处理较复杂且对结果准确性要求较高比如上面的图片处理工具。需要对 Agent 生成的内容做确定性校验。比如在完成任务后执行检查脚本确保生成内容的格式和字段符合要求。¶如何使用 SkillCodex 会自动检测新增和修改的 Skill。如果刚保存的 Skill 没有出现重启 Codex 即可。Codex 可以用两种方式触发 Skill自动匹配用户需求与description匹配时Codex 判断是否加载它。明确指定输入$img-optimize指定这个 Skill或用/skills查看当前可用的 Skill。以我的实际经验来看如果description写得太模糊、Skill 比较多或者存在多个功能相近的 SkillAgent 就可能匹配错误。重要任务可以直接明确指定使用 $img-optimize 处理 screenshots 目录下的所有图片。Claude Code 的思路相同但手动调用时使用/skill-name。¶Skill 的渐进式加载机制你可能会想Skill 越写越多启动时全加载进来上下文窗口不会撑爆吗实际上不会。Skill 使用的是渐进式加载启动时只提供精简的元数据匹配到任务后再读取完整 SKILL.md执行到具体步骤时才按需读取脚本和参考文件。下面这张时序图展示了从启动到执行 Skill 的完整过程Skill 文件Coding Agent你Skill 文件Coding Agent你启动Level 1元数据上下文里只有 Skill 摘要Level 2指令正文匹配到 img-optimizeLevel 3附属资源按指令执行任务扫描 SKILL.md 的元数据name description path帮我压缩一下图片读取完整 img-optimize/SKILL.mdMarkdown 指令正文运行 scripts/optimize.py脚本执行结果¶Level 1元数据Agent 启动时只加载每个 Skill 的摘要信息。Codex 会提供name、description和文件路径让模型知道有哪些 Skill 可用但不会在一开始就把所有 SKILL.md 正文塞进上下文。工具会为这份 Skill 列表设置总预算。如果 Skill 特别多或者每个description都很长后面的描述可能被截断或省略。所以description要简明扼要把最关键的使用场景和触发词放在前面。¶Level 2指令正文当用户明确指定一个 Skill或者 Agent 根据description判断它适合当前任务时才会读取完整的 SKILL.md。Skill 的匹配不是简单的关键词搜索而是让 LLM 结合description和用户指令判断是否应该加载。比如img-optimize的 description 写了「压缩、缩放图片并转换为 WebP」用户只说「帮我把截图弄小点」Agent 也能根据语义考虑这个 Skill。¶Level 3附属资源Skill 目录里的脚本、模板和参考文档只在执行过程中真正需要时才读取。img-optimize 的 SKILL.md写清楚了脚本做什么、接受哪些参数、怎么调用。Agent 可以直接按操作手册执行不需要先把optimize.py的全部源码加载进上下文。Skill 脚本的编写技巧SKILL.md 中记录的脚本用法一定要正确脚本最好提供-h或--help显示详尽用法。脚本异常时要说明原因和排查方法。这样不用在 SKILL.md 里穷举所有问题Agent 也能根据脚本的报错进一步处理。¶Codex 和 Claude Code 的差异想让同一份 Skill 被多个工具共用最稳妥的做法是只把name、description和 Markdown 正文当作通用层不要默认某个工具的扩展字段在另一个工具中也有相同语义。Codex 用$skill-name明确指定 Skill用/skills查看当前可用列表。如果不想删除文件可以在~/.codex/config.toml里用[[skills.config]]禁用指定 Skill。Claude Code 用/skill-name手动调用 Skill还有一些自己的扩展字段和变量allowed-tools用来声明允许的工具调用。${CLAUDE_SKILL_DIR}指向当前 SKILL.md 所在的目录。disable-model-invocation: true用来禁止模型自动触发只允许手动调用。$ARGUMENTS用来接收用户在手动调用时传入的参数。这些是 Claude Code 的产品约定不要在给 Codex 编写的 Skill 里直接假设它们也会生效。如果共用 Skill 确实需要某个工具的专属能力可以把通用流程放在主 SKILL.md 里再给不同工具增加专门说明。¶用 skill-creator 自动生成 Skill手写 SKILL.md 当然没问题但有个更省事的办法。Codex 自带skill-creator直接在指令中调用$skill-creator 帮我创建一个 Skill用来 xxx。skill-creator 会询问使用场景、触发时机以及是否需要脚本然后生成一份初版 Skill。你还是要检查它的description、输入输出、脚本路径和安全边界不要把自动生成当成免审核。Claude Code 也可以安装 Anthropic 维护的 skill-creator然后用/skill-creator调用。两边的核心思路一样用自然语言说清工作流让生成器搭好目录和 SKILL.md然后由你检查和调整。如果你现在已经想到几个可以固化的重复流程可以先从一个边界清晰的小 Skill 开始实际使用几次后再根据匹配情况和执行结果逐步完善。上一篇