Skip to main content

7. PTC / Code Mode:为什么让模型写代码来调用工具?

7.1 传统逐次工具调用有什么开销?

任务:“读取三个模块的风险结果,筛选高风险,合并重复项。” 基础做法让模型反复参与:请求工具 → 接收大 JSON → 生成下一次请求 → 接收数据 → 逐项总结。对于过滤、排序、分组、数值计算,模型不是最便宜也不是最可靠的执行器。 PTC 把可确定的步骤交给一段程序:
这里代码是在编排工具,不是在重新训练模型。工具可以仍来自 MCP、普通函数、Shell 等不同来源。

7.2 控制流与数据流的变化

如果 n 个结果各占 S token,直接全部展示约为 n*S 的结果负担;若代码压成 R token,则模型看到的数据可更接近 R,再加程序、工具定义和协议开销。原始工具 I/O 依然存在,不能把少传给模型等同于系统完全不处理这些数据。

7.3 OpenAI API PTC 与 Codex Code Mode 的区别

API PTC 文档描述的是托管 JavaScript 执行:启用 programmatic_tool_calling,按工具设置 allowed_callers,程序运行在隔离 V8 环境中。它没有一般 Node/文件系统/网络能力;应用自己的工具依然由应用执行。Programmatic Tool Calling Codex 公开源码还有本地/远程 Code Mode Host、runtime、session、cell、execute/wait 等模块。这些体现相似的”代码编排工具”理念,但与 API PTC 不是可直接互换的接口。源码中有 session 的显式 stored values 和 cell 生命周期,不能把它们写成 API PTC 也承诺跨程序全局变量持久化。Code Mode runtimeSession runtime

7.4 V8 isolate 是怎样接到工具上的?

以下为依据公开代码结构整理的原理示意,省略了具体传输细节:
固定源码能看到 RuntimeCommand 中的工具响应、错误、超时和终止,以及 RuntimeEvent 中的 ToolCall、Pending、YieldRequested、Result。这说明 isolate 之外还有宿主调度与消息桥接;“用了 V8”只描述其中一层。 V8 isolate 也不是完备的 OS 沙盒。要防止不可信程序滥用,还要限制能拿到的工具、调用次数、输出量、CPU/内存、执行时长、网络和文件权限。尤其不能给它一个无限制 shell 后就宣称”只能用安全 API”。

7.5 真实 API 接线最容易漏掉的字段

嵌套 function_call 带有 caller 元信息;回传 function_call_output 时,应保留调用返回的 caller,让服务端恢复正确的程序。无状态继续时还要完整保留 program、fingerprint、reasoning 等返回项,不能只拼接输出文本。
完整例子见 live_api.py ptc。它将 API 返回的程序交回托管运行时继续,不在本机使用 eval() 执行模型代码

7.6 为什么本地 Demo 使用 allSettled?

Promise.all 遇到一个 rejection 会立刻 reject,但其余工作不会自动取消。如果上层只看到整体异常,可能既丢了部分成功结果,也误以为所有动作都没发生。 ptc_demo.mjsallSettled 收集每一个结果,保留来源,并将缺失模块记为 partial。这适合只读聚合。它不意味着所有任务都应 allSettled:如果第一步失败后第二步无意义,应按依赖顺序停止;若是写操作,最好保持清楚的提交边界。

7.7 PTC 与 MCP 的关系

MCP 描述 Host、Client、Server 如何交换能力和数据;PTC 描述模型怎样用程序组织调用。一个是连接协议,一个是执行/编排方式,完全可以组合。MCP 架构规范
Anthropic 在公开文章中也讨论过 code execution 与 MCP 组合,以减少工具描述和中间数据带来的上下文负担。因此,说”代码调用工具只有 Codex 懂”并不成立。Anthropic:Code execution with MCP

7.8 面试回答

PTC 把确定性的控制流和数据处理从模型逐步对话里移到程序里,适合批量只读查询、过滤、聚合和可预测依赖链。收益主要是减少模型往返和中间上下文,不是消除工具执行成本。它与 MCP 正交,且每次嵌套调用仍需权限、预算和审计。