跳转至

07. 工具与技能管理

Codex 将工具和技能区分为两类能力。工具表示模型可以请求的动作,例如运行 shell 命令、应用补丁、更新计划、调用 MCP 工具或请求权限。技能表示模型可以阅读并遵守的任务说明,例如某类任务的处理流程、约束、依赖和输出要求。

工具影响模型的动作面,技能影响模型的工作方式。技能本身不执行动作,真正执行动作的是本地运行时中的工具处理器。

这个区分解决的是能力扩展问题。一个智能体既要能调用越来越多的本地和外部能力,又不能把所有能力无条件暴露给模型,更不能让任务说明绕过权限系统。Codex 因此把工具规范、处理器、技能文档、MCP 工具、动态工具和权限执行面拆成不同层。

flowchart LR Skill[技能文档<br/>任务方法/约束/依赖] --> Prompt[模型上下文] Specs[工具规范<br/>模型可见动作面] --> Prompt Prompt --> Model[模型] Model --> Call[工具调用] Call --> Router[工具路由器] Router --> Handler[工具处理器] Handler --> Permission[权限/沙箱] Permission --> Result[工具结果] Result --> History[历史] History --> Prompt

工具调用链路

模型请求工具时,会输出工具调用。运行时将工具调用解析为内部调用,找到对应工具,校验参数,进入权限和沙箱流程,执行本地动作,并把结果写回历史。

模型输出工具调用
  -> 运行时识别工具
  -> 处理器解析参数
  -> 权限和沙箱检查
  -> 本地执行
  -> 结果写回历史
  -> 模型下一次采样读取结果

模型不直接执行本地动作。工具调用只是请求,执行权在本地运行时。

工具调用链路保留了模型意图与本地结果之间的结构。运行时记录模型请求了哪个工具、参数是什么、本地如何处理、结果是什么。后续模型采样读取的是这条结构化链路,而不是无来源的日志文本。

工具规范

工具规范是模型可见的工具契约。它描述工具名称、参数结构、用途和返回语义。模型基于规范生成工具调用。

规范只定义模型能请求什么,不定义动作如何执行。一个工具要真正可用,还需要本地处理器。仅有规范会导致模型提出无人处理的调用,仅有处理器会导致模型看不到该工具。

规范还承担提示约束作用。清晰的参数结构能降低模型生成无效调用的概率,明确的用途说明能减少错误工具选择。规范的质量会直接影响工具调用质量,但不能替代处理器校验。

工具处理器

工具处理器(ToolHandler)是本地执行逻辑。处理器负责参数校验、语义检查、状态修改标记、执行前后事件、权限流程、实际执行和结果格式化。

会修改文件、运行命令或访问外部系统的处理器需要明确 mutating 语义,并接入审批、沙箱、差异和错误回填。处理器的返回值最终会转成模型下一次采样可见的工具结果。

处理器还负责把执行失败表达成模型可理解的结果。参数错误、权限拒绝、外部服务失败和工具内部异常应被区分,否则模型无法选择正确恢复策略。

工具路由器

工具路由器(ToolRouter)在每次采样前构建本轮工具集合。它同时服务两个方向:向模型提供模型可见规范,向本地运行时提供工具调用到处理器的路由。

模型可见工具集合不等同于运行时已注册处理器集合。部分工具用于内部兼容、延迟发现或延迟 暴露,处理器已存在但规范不直接暴露给模型。这个分离使 Codex 能控制上下文体积和工具暴露面。

工具路由器的构建发生在采样前,而不是会话启动时。它反映当前轮次的可用能力快照。MCP 刷新、连接器显式引用、动态工具恢复和功能开关变化都会影响本轮工具集合。

工具路由器的实现可以拆成“收集、过滤、注册、暴露”四步。收集阶段读取内置工具、MCP 工具、动态工具和插件连接器;过滤阶段根据当前轮次、显式引用和功能开关决定可见性;注册阶段准备处理器;暴露阶段只把模型可见规范放入采样请求。

为本次采样构建工具:
  收集内置工具
  收集 MCP 和连接器工具
  restore 动态工具
  按配置、认证、显式提及、功能开关过滤
  register 处理器
  return 模型可见规范 + 运行时 registry

工具集合的动态计算

工具集合会随轮次状态变化而变化。运行时会根据当前配置、MCP 服务端状态、插件连接器、动态工具、用户显式引用、功能开关和权限环境计算本轮可见工具。

这种动态计算支持按需暴露。模型初始可能只看到发现类工具,发现外部能力后,后续采样再看到具体 MCP 工具或连接器工具。工具集合也可以随着 MCP 服务端刷新或动态工具恢复而变化。

内置工具

Codex 内置 shell、补丁、计划、权限请求、查看图片、子智能体等工具。它们都通过规范暴露给模型,通过处理器在本地执行。

shell 工具需要处理当前目录、命令参数、环境变量、技能依赖注入、已批准权限、额外权限请求、审批策略、沙箱策略、标准输出/标准错误和退出码。补丁工具需要处理文件路径、写入范围、差异和安全评估。权限请求工具需要把模型的权限请求规范化并交给审批流程。

内置工具的可见性不等于无限执行能力。每个动作仍需通过本地运行时的权限检查。

内置工具还承担模型与运行时之间的语义桥接。计划工具影响客户端展示和任务组织,权限请求工具把模型的权限需求转成审批事件,查看图片工具把本地图片观察结果纳入模型上下文。这些工具不只是“函数”,而是智能体循环中的协议化动作。

MCP 工具

MCP 将外部服务端的能力接入 Codex。外部服务端提供工具列表,Codex 管理连接、认证、刷新、可见性和调用结果。

MCP 工具可以直接暴露,也可以延迟暴露。直接工具直接进入模型可见列表;延迟工具通过发现流程按需展开。该机制控制上下文体积,并降低模型误用不相关外部工具的概率。

MCP 工具进入 Codex 后仍遵循统一工具流程:规范暴露给模型,运行时解析调用,本地或外部处理器执行,结果回填历史。

MCP 的外部性不改变安全边界。认证状态、服务可用性、工具发现结果和调用错误都要被转成模型可理解的结构化结果。外部工具返回的数据也会进入历史,影响后续模型采样。

动态工具

动态工具是会话动态提供的工具定义。它们可能来自线程启动参数,也可能从持久化历史恢复。动态工具需要进入轮次上下文,并在恢复/分叉后恢复,否则历史中的工具调用无法继续解释。

动态工具可以直接暴露,也可以延迟暴露。其动态性只描述工具定义来源,不代表跳过工具路由、处理器或权限系统。

动态工具的持久化尤其重要。会话恢复后,模型历史中可能仍包含早先动态工具的调用和输出;若工具定义缺失,后续采样就无法保持调用语义一致。

技能

技能是按需注入的任务说明。Codex 会发现可用技能,并通常先将名称和描述纳入模型上下文。完整 SKILL.md 只在显式触发或本轮需要时注入。

技能描述应使模型能够判断适用场景;完整技能内容应描述处理流程、约束、依赖和输出要求。技能的作用是影响模型如何选择工具和组织任务,而不是增加新的执行权限。

技能注入改变的是上下文,而不是工具集合本身。一个技能可以告诉模型优先运行特定测试命令,但命令执行仍然必须通过 shell 工具和权限系统。技能也可以声明依赖,但依赖收集结果仍由运行时管理。

技能触发与依赖

技能可以通过结构化引用或文本提及触发。触发后,运行时读取完整技能文档并加入本轮上下文。若技能声明依赖,例如环境变量或用户提供值,依赖解析会在本轮发生。

缺失依赖可以通过用户输入收集,并进入会话依赖环境。依赖值用于后续工具执行,不会无差别暴露给所有任务。

技能的发现与注入分离。启动或配置变化时,系统扫描技能根目录并建立可用技能索引;轮次运行期间只把摘要放入基础上下文;显式触发后才读取完整文档。依赖解析发生在触发之后,因此未使用技能不会触发无关依赖请求。

flowchart TD Roots[技能根目录<br/>项目/用户/系统/插件] --> Index[技能索引<br/>名称 + 描述] Index --> Summary[可用技能摘要] Summary --> Prompt[基础上下文] User[用户显式引用技能] --> Resolve[解析技能] Resolve --> Full[读取完整 SKILL.md] Full --> Deps{依赖满足?} Deps -->|否| Ask[请求缺失依赖] Ask --> Env[session dependency env] Deps -->|是| Inject[注入本轮上下文] Env --> Inject Inject --> Prompt

工具与技能的协作

工具和技能在任务中协作。技能提供任务方法和约束,模型根据技能决定下一步,工具执行具体动作,工具结果回到历史后继续影响模型。

例如发布说明技能可以规定读取 changelog、检查已合并 PR、按模板生成摘要。模型根据技能选择读取文件或调用外部工具,执行结果再回到模型上下文。

暴露控制

Codex 不会把所有工具和技能全量注入模型。全量暴露会增加 token 消耗、误用概率、审批噪音和外部能力泄漏面。运行时通过摘要、显式触发、延迟发现和每轮工具重算控制可见能力。

工具和技能管理的核心是模型可见能力与本地可执行能力分离。模型看到足够完成当前任务的能力,本地运行时保持实际执行控制。

这种分离使 Codex 可以逐步暴露能力。模型先看到概览或发现工具,根据任务需要加载更具体的技能或 MCP 工具,再通过本地处理器执行动作。上下文体积、执行权限和任务相关性因此被分别控制。取舍是工具接入路径更长,但它避免了常见失败:工具太多导致误用,技能文档变成隐式权限,MCP 外部能力污染本地执行边界。