雨天小六

读懂 Codex(7.26):Skill 的 scripts/assets 读取边界与 MCP 依赖安装

· 更新于 2026-08-02 · 专栏:读懂 Codex

#Codex#Agent Runtime#Multi-Agent#Extension#软件架构

scripts/assets 是由 Skill 指令按需引用的资源,不自动进入 Prompt;结构化 dependencies 中的 MCP 项则在注入前检查缺失、按策略征求许可、写入全局配置、完成 OAuth 并刷新运行时。

本节只研究“Skill 资源与外部能力依赖”。输入是 SkillMetadata.dependencies、资源 locator、审批策略,状态由 Skill instructions、ExecutorFileSystem、MCP Skill Dependency 流程 持有,成功输出为 可读取资源和已满足的 MCP server 配置。相邻章节中看起来相似的对象如果由不同组件拥有,就不能用一个布尔状态替代。

先确定边界和状态所有者

问题本节答案
谁发起SkillMetadata.dependencies、资源 locator、审批策略
谁拥有可变状态Skill instructions、ExecutorFileSystem、MCP Skill Dependency 流程
成功产物可读取资源和已满足的 MCP server 配置
不在本节内Skill 资源与外部能力依赖之外的上游产品策略和下游业务实现

这张表的用途不是复述名词,而是约束实现顺序:校验必须发生在副作用之前;已经提交的状态只能由原所有者撤销;只读投影不能反过来成为控制权威。

端到端调用链

  1. 解析 Skill dependencies
  2. 收集缺失 MCP
  3. 规范化 transport 去重
  4. 提示/自动批准并写配置
  5. OAuth 后刷新 MCP runtime
Skill 的 scripts/assets 读取边界与 MCP 依赖安装的端到端机制流程,展示解析 Skill dependencies、收集缺失 MCP、规范化 transport 去重、提示/自动批准并写配置、OAuth 后刷新 MCP runtime
图 7.26-1:解析 Skill dependencies → 收集缺失 MCP → 规范化 transport 去重 → 提示/自动批准并写配置 → OAuth 后刷新 MCP runtime。图中每条箭头都表示下一层只接收上一层已经确认的状态。

这条链里至少有三种时间尺度:配置或身份在 Thread 创建时冻结,Turn 内状态由 Session 串行协调,Step 级目录与能力在每次模型采样前重新捕获。若把后一个时点的新状态拿去解释前一个时点已经发出的调用,就会产生跨代错误。

源码机制拆解

资源不做隐式批量加载

Skill 目录或正文只告诉 Agent 如何读取 scripts/assets/ 或 references;真正读取/执行仍通过普通文件与工具能力,保留权限和 token 边界。

这项约束直接决定了边界两侧的数据形状。实现时应先证明前置状态,再写入由 Skill instructions、ExecutorFileSystem、MCP Skill Dependency 流程 持有的对象;不能用日志、UI 状态或模型描述代替真实状态更新。

只处理声明为 MCP 的结构化依赖

依赖项按 type 过滤,缺失 server 根据 URL 或 command transport 规范化去重;同一后端不同别名不会重复弹窗安装。

这项约束直接决定了边界两侧的数据形状。实现时应先证明前置状态,再写入由 Skill instructions、ExecutorFileSystem、MCP Skill Dependency 流程 持有的对象;不能用日志、UI 状态或模型描述代替真实状态更新。

安装受产品与 Feature 门控

当前实现只在允许的 first-party/feature 条件下启用自动依赖流程;否则 Skill 仍可注入文字,但外部能力不会被悄悄写入配置。

这项约束直接决定了边界两侧的数据形状。实现时应先证明前置状态,再写入由 Skill instructions、ExecutorFileSystem、MCP Skill Dependency 流程 持有的对象;不能用日志、UI 状态或模型描述代替真实状态更新。

配置写入不是最后一步

需要认证的 server 还要执行 OAuth;成功后必须 refresh MCP runtime,使后续 Step 捕获新目录。当前 Step 已冻结的 binding 不被中途替换。

这项约束直接决定了边界两侧的数据形状。实现时应先证明前置状态,再写入由 Skill instructions、ExecutorFileSystem、MCP Skill Dependency 流程 持有的对象;不能用日志、UI 状态或模型描述代替真实状态更新。

Python 风格伪代码

下面的伪代码提炼状态机与错误顺序,不逐行翻译 Rust,也不假装 Python 对象具有 Rust 的所有权保证:

async def satisfy_skill_dependencies(skill, policy, mcp_runtime):
    missing = canonicalize_and_dedupe([
        dep for dep in skill.dependencies
        if dep.type == 'mcp' and not mcp_runtime.has(dep)
    ])
    for dep in missing:
        if not policy.feature_enabled or not await policy.approve(dep):
            continue
        await global_config.install_mcp_server(dep)
        if dep.requires_oauth:
            await oauth.authenticate(dep)
    if missing:
        await mcp_runtime.refresh()
    return dependency_statuses(missing)

阅读这段伪代码时要检查三件事:第一,输入是否在副作用前完成规范化;第二,异步等待是否仍携带原 Thread/Turn/Step 身份;第三,失败后究竟释放了什么、又保留了什么。只写快乐路径会把本节最重要的一致性条件删掉。

失败、取消与恢复

Skill 的 scripts/assets 读取边界与 MCP 依赖安装的三类失败分支、可观察结果和恢复责任
图 7.26-2:失败不会抹掉已经提交的状态;每条分支都由拥有该状态的组件执行恢复或补偿。
故障点已发生的状态可观察结果恢复责任
用户拒绝 MCP 安装Skill 正文可已选中依赖保持缺失模型按无依赖路径处理
全局配置写入失败未刷新 runtime注入流程报告错误不伪称 server 可用
OAuth 失败配置可能存在但未认证连接不可用重试认证/删除坏配置

取消不自动等于回滚,列表不自动等于权威存储,模型看见的描述也不自动等于已经获准执行。对于已经建立的 Thread、写入的 Edge、入队的 Mailbox、安装的插件或外部工具副作用,必须由相应所有者执行显式关闭、补偿或保留。

并发与一致性不变量

  • 同一身份不能在并发路径中被重复预留或重复注册;若允许幂等重试,幂等键必须是稳定路径、ThreadId、request id 或 catalog revision,而不是展示名称。
  • 一次模型采样看见的 Prompt、工具目录和执行入口必须来自同一个 Step 快照;刷新只影响后续 Step。
  • Watch/Activity/事件是通知机制,不是状态本身。被唤醒后必须重新读取 Registry、Session、Mailbox、Store 或 Binding 的权威值。
  • 失败路径不得“为了干净”删除仍可恢复的历史;同样也不得把只剩历史的对象伪报成当前仍驻留运行。

设计思路与代价

本节设计保护的核心不变量是:scripts/assets 是由 Skill 指令按需引用的资源,不自动进入 Prompt;结构化 dependencies 中的 MCP 项则在注入前检查缺失、按策略征求许可、写入全局配置、完成 OAuth 并刷新运行时。代价是同一个功能会跨越地址、配置、Session、队列、存储或扩展适配层,测试也必须覆盖正常、并发和中途失败。更短的单体实现虽然容易演示,却无法区分“存在、已加载、正在运行、可恢复、已关闭、模型可见”这些彼此独立的事实。

设计动机部分是根据生产类型、调用顺序和测试行为归纳;源码可直接证明的是字段、分支、状态所有者和失败结果。文章不会把推断写成服务端或产品层的未公开事实。

源码与测试证据

位置能证明什么
codex-rs/core-skills/src/model.rsSkill interface/dependencies 元数据
codex-rs/core/src/mcp_skill_dependencies.rs缺失收集、提示、配置、OAuth 与 refresh
codex-rs/core-skills/src/injection.rs依赖满足与全文注入的顺序
测试/可执行检查覆盖重点预期
codex-rs/core/src/mcp_skill_dependencies.rs正常、边界与状态转换应与本节不变量一致
codex-rs/core-skills/src/injection_tests.rs失败、并发或兼容行为应与本节不变量一致

当前环境没有 Cargo,本轮不伪报 Rust 测试执行;验证由锁定提交下的源码—测试静态对读、源文件存在性检查、Mermaid 渲染、Astro 生产构建和公开页面检查组成。

Mini Codex 复刻建议

Mini Codex 应先复刻本节的协议不变量:明确状态所有者、稳定身份、可回滚预留、同 Step 快照、超时/取消和单一终态。平台沙箱、远程 Executor、OAuth、Backend App Route 或第三方 MCP Server 的安全性质不能由一个本地 Python mock 证明,适配器只能验证调用顺序和故障处理。

本节结论

scripts/assets 是由 Skill 指令按需引用的资源,不自动进入 Prompt;结构化 dependencies 中的 MCP 项则在注入前检查缺失、按策略征求许可、写入全局配置、完成 OAuth 并刷新运行时。 掌握这一点后,再看相邻模块时就能判断它是在改变身份、运行状态、模型可见上下文、外部能力,还是仅提供观察快照。

阅读导航

上一节:Skill 元数据怎样进入 Prompt,全文怎样按需注入 · 下一节:MCP ConnectionManager 的并发启动、连接复用、认证与关闭

源码依据

本文基于锁定提交 fe01054a28fa4bd04716d9ceadb410f2443a50ce 的生产代码和相邻测试静态核对。关键入口如下:

评论


← 返回文章列表