前两篇,我们已经分别分析了 Codex 扩展体系中最基础的两层能力:
第一篇: Codex 的目录与配置结构 第二篇: AGENTS.md 的发现、继承与覆盖到这里,我们已经可以建立一个基本分工:
AGENTS.md → 持续生效的项目指导 config.toml → Harness 的运行配置 Skill → 某一类任务的可复用工作流但 Skill 真正值得分析的地方,并不是:
目录里有一个 SKILL.md而是:
Codex 如何把一个文件夹中的 Metadata、Instructions、References、Scripts 和 Tool Dependencies,逐步转化为一个模型可发现、可选择、可执行的真实能力?
这一篇,我们选择 Codex 官方内置的:
skill-creator作为主要案例。
它本身就是一个真实 Skill,用来指导 Codex:
创建新的 Skill 修改已有 Skill 设计 Skill 目录 生成标准文件 生成 openai.yaml 执行结构校验 进行真实任务测试通过它,我们可以完整观察一个 Codex Skill 从磁盘文件到 Harness Runtime 的整个生命周期。
整篇文章围绕下面这条主线展开:
Skill Directory ↓ Metadata ↓ Skill Registry ↓ Semantic Routing ↓ Progressive Disclosure ↓ Tool / Script ↓ Approval / Sandbox ↓ Runtime Result一、Codex Skill 到底是什么
1. Skill 在 Codex 扩展体系中的位置
Codex 当前已经形成了一套比较完整的能力分层:
AGENTS.md → 长期项目指导 Skill → 可复用任务流程 MCP → 外部工具能力 Subagent → 专业执行角色 Plugin → Skill 和 Connector 的分发单元其中 Skill 主要解决的是:
当某一类任务反复出现时,如何把“正确的工作方法”沉淀下来,让 Agent 下次不必重新摸索。
例如:
修复 GitHub CI 数据库迁移 代码安全审查 发布版本 生成技术报告 创建新的 Skill这些任务都不是简单的一次 Tool Call。
它们通常包含:
任务识别 步骤规划 参考资料 工具选择 脚本执行 结果校验因此,一个成熟 Skill 更接近:
Procedural Knowledge + Workflow Instructions + Reusable Resources + Optional Deterministic Execution而不是一条长 Prompt。
2. Skill 不等于 Prompt Template
最简单的 Skill 确实可以只有:
SKILL.md但完整的 Skill 可以包含:
Skill ├── SKILL.md ├── scripts/ ├── references/ ├── assets/ └── agents/ └── openai.yaml所以更准确地说:
Skill = Metadata + Instructions + References + Scripts + Assets + Tool Dependencies其中不同部分承担不同职责:
Metadata → 告诉模型“这个能力是什么、什么时候用” Instructions → 告诉模型“应该怎么完成任务” References → 提供详细知识 Scripts → 提供确定性执行 Assets → 提供最终产物所需资源 Tool Dependencies → 声明外部能力依赖这也是为什么 Skill 更像一个:
面向 Agent 的 Workflow Package。
3. 为什么选择skill-creator
skill-creator是一个很好的分析案例,因为它自己就在教 Codex:
如何创建 Skill换句话说:
Skill → 用来创建 Skill它包含:
Skill 设计原则 目录规范 命名规范 Metadata 编写 Reference 组织 Script 设计 openai.yaml 生成 Skill Validation Forward Testing因此,从它身上几乎可以看到 Codex Skill 的所有核心设计思想。
二、一个真实 Skill 在磁盘上长什么样
先不讨论它怎么触发,只看静态结构。
一个典型的skill-creator可以理解为:
skill-creator/ ├── SKILL.md ├── scripts/ │ ├── init_skill.py │ ├── generate_openai_yaml.py │ └── quick_validate.py │ ├── references/ │ └── openai_yaml.md │ └── agents/ └── openai.yaml整个目录可以分成四层。
1.SKILL.md:核心工作流
Skill 最低要求是:
my-skill/ └── SKILL.md典型内容:
---name:code-reviewdescription:Review code for correctness,security,concurrency,and maintainability. Use when reviewing code changes,pull requests,or implementation quality.---Review the requested code.Focus on:1. correctness 2. security 3. concurrency 4. maintainability这个文件实际上分成两个部分:
YAML Frontmatter → Skill Metadata Markdown Body → Skill Instructions这两个部分虽然写在同一个文件中,但进入 Runtime 的时机完全不同。
后面会详细解释。
2.references/:延迟知识层
成熟 Skill 往往需要大量领域知识。
例如数据库迁移 Skill:
database-migration/ ├── SKILL.md └── references/ ├── mysql.md ├── postgresql.md └── oracle.md这里:
SKILL.md → 保存核心迁移方法 references/ → 保存具体数据库的详细规则当任务涉及 PostgreSQL 时:
只需要读取 postgresql.md而不是把:
MySQL PostgreSQL Oracle全部塞进上下文。
所以 References 的本质是:
On-demand Knowledge3.scripts/:确定性执行层
skill-creator中存在类似:
init_skill.py generate_openai_yaml.py quick_validate.py这些操作为什么不完全交给模型?
因为它们属于:
高度结构化 重复执行 结果应该确定 格式错误不可接受例如:
创建标准 Skill 目录 校验 YAML 验证 Skill Name 生成 openai.yaml这类操作如果每次都让 LLM 自己生成:
同一任务 ↓ 可能生成不同结果 ↓ 容易遗漏字段因此更合理的模式是:
LLM → 决定做什么 Script → 精确执行怎么做也就是:
Probabilistic Planning + Deterministic Execution4.agents/openai.yaml:Host Metadata
SKILL.md主要是给 Agent 看的。
但 OpenAI 产品本身还需要知道:
Skill 在 UI 中叫什么 是否允许自动触发 需要哪些 Tool 有没有 MCP 依赖这些信息可以进入:
agents/openai.yaml典型结构可以理解为:
interface:display_name:"OpenAI Docs"short_description:"Search OpenAI developer documentation"policy:allow_implicit_invocation:falsedependencies:tools:-type:mcpvalue:openaiDeveloperDocs因此:
SKILL.md → Agent Semantic Interface agents/openai.yaml → Host Runtime Interface两者解决的是不同问题。
三、Skill 是如何被 Codex 发现和匹配的
磁盘上有 Skill,并不意味着模型已经读取了整个 Skill。
Codex 首先要解决的是:
有哪些 Skill? 哪个 Skill 适合当前任务?这也是 Skill Registry 的核心。
1. Skill 可以来自哪些位置
Codex 当前可以从多个 Scope 发现 Skill。
主要包括:
Repository User Admin System Plugin常见目录:
Repository: repo/.agents/skills/ User: ~/.agents/skills/ Admin: /etc/codex/skills/ System: Codex 内置 Skill在 Monorepo 中,Codex还可以沿当前工作目录到 Repository Root 的路径发现多级:
.agents/skills例如:
repo/ ├── .agents/skills/ │ └── release/ │ └── services/ ├── .agents/skills/ │ └── service-review/ │ └── payment/ └── .agents/skills/ └── payment-audit/如果当前目录是:
repo/services/payment则这些 Skill 都可能被发现:
release service-review payment-audit这与AGENTS.md不同。
AGENTS.md → 多层内容拼接 Skill → 多个能力分别注册2.name:Skill 的逻辑身份
SKILL.mdFrontmatter 中必须有:
name:skill-creatorName 负责:
逻辑标识 显式调用 Skill Selector 展示 能力区分通常建议:
目录名 = Skill Name例如:
gh-fix-ci/ └── SKILL.md name: gh-fix-ci这样可以保持:
文件系统身份 = 逻辑身份 = 调用身份3.description:真正的语义路由入口
Skill 自动匹配最关键的其实不是:
name而是:
description例如:
description:Fix failing GitHub Actions checks. Use when PR checks are failing,CI jobs are red,or the user asks to inspect Actions logs and implement a fix.它同时回答:
Skill 做什么? 什么时候应该使用? 什么任务与它相关?因此可以把 Description 看成:
Capability Routing Metadata4. 为什么“什么时候使用”必须写在 Description
假设你在正文里写:
## When to use Use this skill when working with DOCX files.问题在于:
模型决定要不要加载 Skill 发生在 读取 Skill Body 之前也就是说:
模型还没看到“什么时候用” 就已经需要决定“要不要用”所以真正用于路由的信息必须进入:
description:这形成一个非常重要的设计原则:
Metadata → 决定是否加载 Body → 决定加载后怎么做5. Skill Metadata 如何进入上下文
Codex 启动或刷新 Skill 后,会先建立类似:
Skill Catalog其中每个 Skill 主要暴露:
name description path可以抽象成:
扫描 Skill ↓ 读取 SKILL.md Frontmatter ↓ 提取 name + description ↓ 记录 source path ↓ 加入 Skill Registry ↓ 向模型提供 Skill Catalog模型此时知道:
“有哪些 Skill”但还不知道:
“这些 Skill 具体怎么执行”6. Skill Catalog 本身也有预算
这是 Codex Skill 架构非常重要的一点。
如果用户安装:
10 个 Skill问题不大。
如果安装:
500 个 Skill就不能把所有 Description 无限塞进 Context。
因此 Skill Catalog 本身有上下文预算。
可以理解为:
Context Window ↓ 只划一部分给 Skill Metadata当 Skill 太多时:
先压缩 Description ↓ 仍然太多 ↓ 部分 Skill 可能无法全部进入初始 Catalog这意味着:
Skill 数量并不是无限增长没有成本。
7. Description 为什么必须“前重后轻”
因为 Description 可能被压缩,最重要的信息应该放在前面。
不推荐:
This skill provides a comprehensive framework designed to help developers... 经过很长背景介绍 最后一句: Use this for GitHub Actions failures.更好:
Fix GitHub Actions failures. Use when PR checks are red, CI jobs fail, or Actions logs need investigation...也就是:
Capability + Trigger + Scope尽量靠前。
8. 显式调用:$skill-name
用户可以直接指定 Skill:
$skill-creator 帮我创建一个 Spring Boot 代码审查 Skill。显式调用表示:
用户已经确定要使用哪个 Skill运行链可以简化为:
$skill-name ↓ Skill Resolver ↓ 定位 Skill ↓ 加载 SKILL.md此时不需要先进行语义路由。
9. 隐式调用:模型自动匹配
用户也可以直接说:
当前 GitHub PR 的 CI 挂了, 帮我看看 Actions 日志并修复。如果 Catalog 中存在:
gh-fix-ci模型可能根据 Description 自动选择:
User Prompt ↓ Skill Metadata ↓ Semantic Match ↓ 选择 gh-fix-ci这本质上属于:
LLM-based Semantic Routing而不是硬编码:
if prompt contains "CI"10. 可以禁止隐式触发
某些 Skill 不适合模型自动选择。
例如:
deploy-production delete-cloud-resource publish-release send-customer-email可以配置:
policy:allow_implicit_invocation:false此时:
模型不能自行触发用户仍然可以显式使用:
$deploy-production这实际上建立了一层:
Capability Invocation Policy四、Skill 被选中以后,如何渐进式进入 Context
Codex Skill 真正专业的地方,在于:
它没有把 Skill 当成一整个 Prompt Package 一次性加载。
而是采用:
Progressive Disclosure可以分成三层。
1. Level 1:Metadata
启动时加载:
name description path解决的问题是:
系统有哪些能力?这一层尽量小。
2. Level 2:完整SKILL.md
当 Skill 被显式或隐式选中后:
Skill Catalog ↓ Skill Match ↓ 加载 SKILL.md Body此时模型才真正知道:
任务应该如何执行 有哪些阶段 如何判断分支 什么时候使用 Tool 什么时候读取 Reference这一层解决:
这个任务具体应该怎么做?3. Level 3:References、Scripts 和 Assets
即使 Skill 已经被触发,也不需要立刻加载所有资源。
完整链是:
SKILL.md ↓ 任务执行到某一步 ↓ 真正需要某资源 ├── Reference ├── Script └── Asset这一层才是:
Task-specific Resource Loading4. References 如何按需读取
假设:
bigquery/ ├── SKILL.md └── references/ ├── finance.md ├── sales.md ├── marketing.md └── product.md用户问:
分析最近三个月销售漏斗。Skill 只需要:
references/sales.md没有必要同时读取:
finance.md marketing.md product.md因此:
Skill Body → 决定需要什么知识 Reference → 在真正需要时补充上下文5. Reference 为什么不应该无限嵌套
不推荐:
references/ └── index.md ↓ database/index.md ↓ postgres/index.md ↓ schema.md更推荐:
references/ ├── mysql.md ├── postgres.md └── oracle.md原因很简单:
Agent 也需要探索文件层级越深:
探索成本越高 遗漏概率越大 Token 浪费越严重6. Script 为什么不需要全部进入 Context
假设:
scripts/process_pdf.py有 1500 行。
Agent 要执行:
python scripts/process_pdf.py input.pdf并不一定需要先把:
1500 行 Python全部读进上下文。
于是形成:
Script Code → 留在文件系统 Agent → 只知道如何调用 Runtime → 执行脚本 Model Context → 主要看到输入和结果因此:
File Resource ≠ Prompt Context这是 Skill 能够携带大量确定性能力的重要原因。
7. Assets 为什么又不同
Assets 与 References 很容易混淆。
可以简单区分:
references/ → 给 Agent 阅读 assets/ → 给最终结果使用例如:
品牌规范 → references/brand-guidelines.md 公司 Logo → assets/logo.png再比如:
报告格式说明 → references/report-format.md Word 模板 → assets/report-template.docx资产不需要被完整“理解”,可以直接被复制或用于输出。
8. 三层 Progressive Disclosure 总结
最终可以形成:
Level 1 Metadata ↓ 有没有能力? Level 2 SKILL.md ↓ 应该怎么做? Level 3 Reference / Script / Asset ↓ 当前任务具体需要什么?这也是 Skill 系统能够扩展的重要基础。
五、Skill 如何真正进入 Harness Runtime
到目前为止,Skill 主要还停留在:
发现 匹配 加载上下文但一个 Skill 真正产生价值,还需要:
执行 Tool 运行 Script 访问 MCP 创建 Subagent此时就正式进入 Harness Runtime。
1. Skill 只产生执行意图
例如SKILL.md里写:
Run scripts/validate_migration.py这只是:
模型获得了一条执行指导并不意味着:
脚本已经拥有执行权限真正执行仍需要进入:
Tool Runtime2. Script 如何经过 Approval
完整链可以理解为:
Skill Instructions ↓ 模型决定运行 Script ↓ 生成具体执行操作 ↓ Approval Policy ↓ Sandbox ↓ Process Execution因此:
Skill ≠ Permission Grant这是一个非常重要的安全边界。
3. Approval 和 Sandbox 分别负责什么
可以这样区分:
Approval → 要不要停下来问用户 Sandbox → 就算执行,能访问什么例如:
Skill 要求执行 deploy.sh可能出现:
Approval → 用户批准 Sandbox → 仍然禁止访问生产凭证因此最终权限来自:
Workflow ↓ Tool Request ↓ Approval ↓ Sandbox ↓ Effective Capability4. Skill 如何依赖 MCP
很多 Workflow 本身没有能力访问外部系统。
例如:
Skill: 处理 Linear Issue MCP: 真正提供: search_issue create_issue update_issue这时可以在:
agents/openai.yaml声明:
dependencies:tools:-type:mcpvalue:linear于是:
Skill → 定义流程 MCP → 提供外部能力这也是 Skill 与 MCP 最重要的边界。
5. 缺少 MCP 时如何处理
运行链可以是:
Skill 被触发 ↓ 检查 Tool Dependency ↓ MCP 是否存在? ├── 存在 │ ↓ │ 正常执行 │ └── 不存在 ↓ 提示安装或配置 ↓ 用户确认 ↓ 注册 MCP ↓ 继续任务因此 Skill 开始具备:
Dependency-aware Workflow的特征。
6. Skill 与 Subagent 如何组合
Skill 解决:
怎么做Subagent 解决:
谁来做例如一个安全审查 Skill:
Main Agent ↓ 匹配 Security Review Skill ↓ 加载审查方法 ↓ Skill 建议委托 security-reviewer ↓ 创建 Subagent ↓ 独立执行代码审查 ↓ 返回结果这里:
Skill → Workflow Subagent → Specialized Executor7. 一个完整运行案例
假设项目存在:
.agents/skills/ └── database-migration/ ├── SKILL.md ├── references/ │ ├── mysql.md │ └── postgresql.md ├── scripts/ │ └── validate_migration.py └── agents/ └── openai.yaml用户输入:
给 users 表增加 status 字段, 要求零停机发布。完整链路可以抽象为:
User Prompt ↓ Skill Catalog ↓ 匹配 database-migration ↓ 加载 SKILL.md ↓ 识别当前数据库 PostgreSQL ↓ 加载 references/postgresql.md ↓ 生成迁移策略 ↓ 需要查询线上 Schema ↓ 调用 Database MCP ↓ 需要验证 Migration ↓ 运行 validate_migration.py ↓ Approval ↓ Sandbox ↓ 获取验证结果 ↓ 输出最终迁移方案这才是 Skill 从:
一个文件夹变成:
真实 Agent Capability的完整过程。
六、从 Skill 看 Codex 的扩展架构
经过前面的分析,可以把 Skill 放回 Codex 整个 Harness 中重新理解。
1. Skill 与 AGENTS.md:Always-on 与 On-demand
AGENTS.md → Always-on Guidance Skill → On-demand Workflow例如:
AGENTS.md: 所有 Java 修改都必须运行测试。 Skill: 生产数据库迁移应该如何执行。如果一个流程只在少数任务中使用,就不应该长期塞在:
AGENTS.md里。
2. Skill 与 MCP:How 与 What
可以这样理解:
Skill → How MCP → What例如:
GitHub MCP → 能获取 PR、评论、Check PR Review Skill → 定义: 先获取 PR 再检查 CI 再分析 Diff 再总结风险所以:
MCP 提供能力 Skill 编排能力3. Skill 与 Subagent:方法与执行者
Skill → Method Subagent → Executor同一个 Skill:
代码审查方法可以由:
Main Agent直接执行。
也可以交给:
reviewer Subagent执行。
4. Skill 与 Plugin:创作单元与分发单元
这是下一篇最重要的铺垫。
Skill → Authoring Unit Plugin → Distribution Unit开发一个工作流时:
写 Skill本地项目共享时:
放进 Repo/.agents/skills需要跨用户、跨 Workspace 分发时:
打包成 Plugin一个 Plugin 可以继续包含:
多个 Skills MCP / Connector Presentation Metadata所以:
Skill ≠ Plugin5. Codex Skill 的核心优势
Progressive Disclosure
只在需要时加载真正内容。
文件化
可以直接放在 Git 仓库中版本管理。
可组合
可以组合:
Skill + Script + MCP + Subagent可以逐步增强
从:
只有 SKILL.md逐渐发展成:
SKILL.md + References + Scripts + Assets + Dependencies6. Codex Skill 的局限
自动路由仍然依赖 LLM
Description 写不好,Skill 就可能:
漏触发 误触发 选错Workflow 不是强类型 DAG
大部分流程仍然存在于自然语言中。
Skill Catalog 有预算
安装越来越多 Skill 后:
Metadata 也会消耗 ContextReferences 是否读取仍由 Agent 决定
有文件:
≠ 一定读取Tool Dependency 增加供应链复杂度
一个普通 Skill 可能最终带来:
MCP 安装 网络访问 外部 Secret因此需要治理。
七、对自研 Harness Skill 系统的启发
如果设计自己的 Harness Marketplace,可以直接借鉴 Codex 的三层加载模型。
1. Skill Descriptor
启动阶段只建立:
publicrecordSkillDescriptor(Stringid,Stringname,Stringdescription,Pathpath,SkillScopescope,StringpluginId){}模型初始主要获得:
name descriptionHarness 内部保留:
path source pluginId scope2. Skill Registry
Skill Discovery ↓ SkillDescriptor ↓ SkillRegistry不要启动时读取全部正文。
3. Semantic Router
User Task ↓ Skill Metadata ↓ Semantic Match ↓ Skill Selection还可以增加:
Confidence Priority Scope Trigger Policy4. Skill Loader
只有触发后:
SkillDescriptor ↓ SkillLoader ↓ SKILL.md5. Resource Resolver
继续负责:
Reference Script Asset按需加载。
6. Tool Dependency Resolver
例如:
dependencies:tools:-type:mcpvalue:database运行时:
检查 Tool Registry ↓ 存在? ├── 是 → 使用 └── 否 → 安装 / 审批 / 返回缺失7. Policy Engine
可以进一步结构化:
policy:implicitInvocation:truescripts:approval:requiredtools:allow:-database.querynetwork:allow:-database.internal让 Skill 不只是自然语言 Workflow,也有明确运行边界。
8. Skill Trace
企业级 Harness 最好记录:
Skill ID Source Version Trigger Mode Matched Description Loaded References Executed Scripts Tool Calls Approval Decisions Subagents Result这样才能真正回答:
为什么选中了这个 Skill? 读取了哪些资料? 执行了哪些程序? 访问了哪些外部系统? 失败在哪一步?总结
Codex Skill 不是简单的 Prompt 文件,而是一套围绕 Agent Workflow 设计的能力包。
它的典型结构是:
Skill ├── SKILL.md ├── scripts/ ├── references/ ├── assets/ └── agents/ └── openai.yaml其中:
name + description → Semantic Routing SKILL.md Body → Workflow Instructions references/ → On-demand Knowledge scripts/ → Deterministic Execution assets/ → Output Resources openai.yaml → UI / Policy / Tool DependenciesCodex 并不会在启动时读取所有 Skill 的完整内容,而是采用:
Level 1 Metadata ↓ Level 2 SKILL.md ↓ Level 3 References / Scripts / Assets这样的 Progressive Disclosure 模型。
完整运行链可以概括为:
Skill Directory ↓ Metadata Discovery ↓ Skill Registry ↓ Semantic Routing ↓ Load SKILL.md ↓ Load Reference ↓ Resolve Tool Dependency ↓ Execute Script / MCP / Subagent ↓ Approval ↓ Sandbox ↓ Result因此,从 Harness 的角度看,一个 Codex Skill 更准确的定义是:
一个以 Metadata 作为语义路由入口,以
SKILL.md作为程序性知识主体,以 References 和 Assets 作为延迟资源,以 Scripts 和 MCP 作为确定性执行能力,并由 Approval 与 Sandbox 控制最终运行边界的可复用 Agent Workflow Package。
而下一层 Plugin 所解决的问题,不再是:
这个 Workflow 怎么写而是:
这个 Workflow 如何被打包、安装、共享和治理所以下一篇就可以继续进入:
Harness Marketplace 剖析系列 - 之 Codex:Plugin、Marketplace 与通用插件目录
重点分析:
Codex Plugin 到底是什么 Plugin 与 Skill 的边界 一个真实 Plugin 的目录结构 Plugin Manifest 如何定义 Plugin 如何携带多个 Skill Plugin 如何携带 MCP / Connector Universal Plugin Directory 是什么 OpenAI Curated / Workspace / Shared 如何区分 Plugin 如何安装、启用和禁用 Plugin 能力如何进入 Codex Skill Registry Plugin 是否存在本地 Cache Plugin 如何跨 ChatGPT 与 Codex 复用 Plugin 更新和卸载如何处理这样整个 Codex 系列的主线就会非常清楚:
AGENTS.md → 项目长期规则 Skill → 单个可复用工作流 Plugin → 多能力分发包 MCP / Agent → 真实执行能力 Harness → 统一加载和运行