引言

Codex 体系中

  • Prompt 是一次 turn 内动态拼装出来的复合消息结构。
  • Skill 是一个包含发现、筛选、预算治理、注入与依赖接线的运行时能力层。

本章的问题

Codex 如何把模型能力转译成“可持续执行的工程流程能力”,又是怎样在上下文预算、误触发风险与生态扩展压力之间寻找平衡。

补充

共识

  • 渐进式加载是必要的:skills 元数据常驻、正文按需读取,才能控制上下文成本
  • 触发机制宜“显式优先 + 隐式兜底”:否则要么太笨,要么误触发
  • skill 的本质更接近“流程工程资产化”:承载如何做事的经验

1.本质是什么

Prompt 组装与 Skill 注入 可以理解为 Codex 中的“上下文编排层”,不是简单的写提示词。

  • 向上对接模型
  • 向内对接技能系统
  • 向下对接工具执行

skills 列表通过 developer 角色注入(develoer),skill 正文以 <skill> 标签包裹、走 user 角色注入。一个 turn 内同时存在多种来源、多种角色的片段,由 Prompt 组装与 Skill 注入 这层负责把它们拼成一份对模型可见的“当前上下文”。

OpenAI 引入的新角色,优先级

system > developer > user > tool

Prompt 与 Skill 双通道装配

User 输入

TurnContext

BaseInstructions

Skills Outcome

developer 段 skills list

显式技能 mentions

读取 SKILL.md

user 段

Prompt 组装

模型采样与工具调用

2. 解决核心问题和痛点

无限增长的能力声明有限上下文窗口及用户耐心之间建立了一套多层级的资源调度与治理机制,通过预算裁剪、显示/隐式触发消歧、路径越界校验、多级来源优先级以及依赖自动接线

核心矛盾

Skill 系统的根本矛盾是:可扩展的能力描述是无限增长的,而模型的上下文窗口是稀缺资源

五个冲突和解决方案

1、预算冲突:字符预算和三级裁剪
  • 字符预算 skill 元数据字符预算为 8000 或上下文窗口的 2%
  • 单个 Skill 元数据 名称最长为 64,描述最长为 1024,限制单个 Skill 元数据大小
  • 渐进式披露
    • 第一层(始终注入):所有可用 Skill(名称+短描述+路径),以 developer 角色注入,告诉模型有哪些能力可用
    • 第二层(按需注入):用户显式触发时(用$)才将 SKILL.md以 user 角色包裹在 <skill></skill>中注入
    • 第三层(模型自主读取):模型在执行过程中观测,按需通过工具隐式读取从而补充依赖
  • 第一层目录超预算时,执行三级裁剪(分层退化)
    1. 全部能放下,不裁剪
    2. 超出但裁剪描述后能放下,轮转分配每个 Skill 的描述长度(会导致描述被缩短,但模型仍能感知)
    3. 连裁剪描述都不能放下,按优先级保留(System>Admin>Repo>User), 系统 Skill 是基础能力,不能丢
2、触发冲突:显式命中与隐式语义的双轨制
pub fn collect_explicit_skill_mentions(
    inputs: &[UserInput],           // 用户输入(含 $skill-name 或路径链接)
    skills: &[SkillMetadata],       // 全量 Skill 清单
    disabled_paths: &HashSet<AbsolutePathBuf>,  // 被禁用的 Skill 路径
    connector_slug_counts: &HashMap<String, usize>,  // connector slug 计数
) -> Vec<SkillMetadata>

collect_explicit_skill_mentions函数签名揭示出发判定的核心逻辑:必须同时接收用户输入、全量 skill 清单、被禁用的 skill 路径 和 connector slug 计数器。

误触发与漏触发的平衡

  • 过宽风险:如果只看 $skill-name 可能会将代码注释里写的 $ 误判为技能调用
  • 过严风险:如果要求精确路径,用户体验极差,每次都要写完整路径

Codex 的解决方案是多重校验

  • $skill-name 只有在 skill 名唯一、未被禁用、且不与 connector slug 冲突(connector_slug_counts 中该 slug 计数为 1)时才会被选中
  • [$skill-name](skill://path) 这种路径链接更可靠,可以精准匹配 SKILL.md 路径,精准匹配的优先级最高
  • 隐式触发则完全交给模型的语义理解——developer prompt 中写明触发规则,模型根据目录中的 description 自行判断

connector_slug_counts 防止了当多个来源使用相同 slug 时产生歧义性触发

3、路径冲突:扫描深度与目录上限

MAX_SCAN_DEPTH = 6MAX_SKILLS_DIRS_PER_ROOT = 2000 解决的是文件系统层面的越界问题

  • 深度限制:防止恶意或错误配置的目录结构导致无限递归扫描
  • 数量上限:防止某个 root 下堆积数千个 Skill 目录,导致启动时间不可接受。

这两个常量常与沙箱策略配合,确保 Skill 系统只能读取被允许的根目录下的内容,不会越界访问用户工作区以外的文件。

4、来源冲突:5级 Root 的统一治理

Codex Skill 来自五个层级:repo / user / system / admin / plugin 之间存在优先级覆盖关系,当超预算需要生省略 skill 时,system 优先保留,user 最先被裁剪。系统内置 Skill 启动时安装,并通过哈希指纹确保不重复安装。

这种分层治理确保了:

  • 企业管理员可以通过 admin 层强制注入合规 Skill;
  • 项目维护者可以通过 repo 层定义团队共享 Skill;
  • 个人开发者可以通过 user 层添加私有 Skill;
5、扩展冲突:依赖自动接线

当一个 Skill 声明了外部依赖(MCP、环境变量),用户不手动接线。

collect_explicit_skill_mentions 被调用后,run_turn 中会紧接着处理 env_var / MCP skill 依赖,再由 build_skill_injections 读取完整 SKILL.md 并注入。

后续的依赖解析、环境准备、内容注入全部自动完成。

更多推荐