首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Programmatic Tool Calling:GPT 与 Claude 如何实现「代码编排工具」

Programmatic Tool Calling:GPT 与 Claude 如何实现「代码编排工具」

作者头像
tunsuy
发布2026-07-16 19:58:12
发布2026-07-16 19:58:12
890
举报

GPT-5.6 和 Claude Sonnet 4.5 几乎在同一时间段把 Programmatic Tool Calling(PTC,程序化工具调用) 推到了台前。名字一样,目标也一样:让模型不再「调一个工具 → 等结果 → 再想下一步」,而是写一段程序,在沙箱里批量协调工具、过滤中间结果,最后只把精炼后的结论送回上下文

但两家实现路径并不相同。理解这些差异,直接影响你怎么选型、怎么写集成代码、以及哪些场景该用 PTC、哪些不该用。


一、传统 Tool Calling 卡在哪里

先看传统模式。无论 OpenAI 还是 Anthropic,经典 tool calling 都是同一个五步循环:

代码语言:javascript
复制
用户提问 → 模型返回 tool_use → 你的服务执行工具 → 你把结果塞回上下文 → 模型再推理

每调一次工具,至少消耗一轮模型推理。任务稍复杂,代价就会叠加:

问题

典型场景

延迟叠加

查 20 个员工的报销记录 = 20 次模型往返,每次数百毫秒到数秒

Token 膨胀

每次工具结果都进上下文,2000 行报销明细 × N 次 = 数百 KB

编排脆弱

模型用自然语言「记住」上一步结果,多步依赖容易出错

无法并行

除非 API 支持 parallel tool calls,否则串行等待

PTC 的核心思路是:把「编排逻辑」从模型上下文里挪到沙箱代码里

代码语言:javascript
复制
传统模式:
  模型 → 工具A → 模型 → 工具B → 模型 → 工具C → 模型 → 答案

PTC 模式:
  模型 → 写程序 → [工具A → 工具B → 工具C](在沙箱内,不进上下文)→ 程序输出 → 模型 → 答案

Anthropic 的工程博客给过一个具体数字:团队报销合规检查,传统方式要 20 次模型往返、把数千行明细都拉进上下文;用 PTC 后,一个脚本跑完 20 次查询、过滤、聚合,模型最终只看到超预算的 2–3 个人——上下文从约 200KB 降到约 1KB。在 BrowseComp 等 Agent 搜索基准上,PTC 平均提升 11% 准确率,同时减少 24% 输入 token。


二、端到端流程:谁执行什么

理解 PTC,最容易混淆的一点是:用户侧到底执行什么? 一个常见的误解是——模型生成代码后,由用户下载并运行这段代码。实际上并非如此。

生成代码后的执行、暂停、恢复,全部发生在模型服务商的后台沙箱里。 用户只负责一件事:当沙箱里的程序需要调用「你提供的工具」时,由你的服务执行这些工具,并把结果回传给模型接口。

完整交互流程

代码语言:javascript
复制
你(调用方)                    模型服务商后台
│                                    │
│  ① 发请求(prompt + 工具定义)       │
│ ──────────────────────────────────>│
│                                    │  ② 模型生成编排代码(JS 或 Python)
│                                    │  ③ 在沙箱里开始执行这段代码
│                                    │
│                                    │  ④ 代码执行到「需要调你的工具」→ 暂停
│  ⑤ 收到响应:                        │
│     - 生成的代码(供观察/调试)        │
│     - 需要调用的工具名和参数          │
│     - caller / container 等续跑信息  │
│ <──────────────────────────────────│
│                                    │
│  ⑥ 你的服务执行工具                   │
│                                    │
│  ⑦ 把工具结果 + 续跑信息回传           │
│ ──────────────────────────────────>│
│                                    │  ⑧ 沙箱从断点继续执行代码
│                                    │     (可能再次暂停、再次要工具)
│                                    │
│        ... 可能循环多次 ...           │
│                                    │
│  ⑨ 代码跑完,输出精炼结果              │
│  ⑩ 模型基于最终结果生成回答            │
│ <──────────────────────────────────│

和传统 Tool Calling 的对比如下:

传统 Tool Calling

Programmatic Tool Calling

谁编排多步逻辑

模型(每步都要推理)

模型写的程序(在沙箱里跑)

每步工具结果

都进模型上下文

中间结果留在沙箱,不进上下文

用户执行什么

工具

只有工具,不执行生成代码

模型推理次数

N 次工具 ≈ N 次推理

通常 1–2 次(写程序 + 看最终结果)

五个关键细节

1. 代码不是你的服务执行的

代码语言:javascript
复制
❌ 用户拿到代码 → 自己跑这段 JS/Python
✅ 服务商沙箱跑代码 → 碰到你的工具时暂停 → 你把结果送回 → 沙箱继续跑

OpenAI 在隔离 V8 运行时里执行 JavaScript;Claude 在 Code Execution 容器里执行 Python。响应里返回的代码主要是给你观察、调试、审计用的,不是你的执行入口。

2. 回传的不只是「工具结果」,还有续跑凭证

不能把工具结果简单塞进任意上下文位置。必须带上运行时恢复程序所需的关联信息:

OpenAI 回传 function_call_output,并原样保留 caller

代码语言:javascript
复制
{
"type":"function_call_output",
"call_id":"call_inventory_123",
"output":"{\"sku\": \"sku_123\", \"available_units\": 42}",
"caller":{"type":"program","caller_id":"call_prog_123"}
}

Claude 回传 tool_result,且请求中必须带上 container ID:

代码语言:javascript
复制
{
"role":"user",
"content":[{
"type":"tool_result",
"tool_use_id":"toolu_def456",
"content":"[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
}]
}

缺少 callercontainer,后台无法从断点恢复执行。

3. 一次请求里可能暂停多次

不是「调一次工具就结束」。如果生成的代码里有循环:

代码语言:javascript
复制
for employee in employees:          # 20 个人
    expenses = await get_expenses(employee)  # 每次都会暂停
# 在沙箱内处理...

可能暂停 20 次——你回传 20 次工具结果,沙箱每次从断点继续,最后才一次性输出聚合结果。

4. 并非所有工具都要用户执行

类型

谁执行

例子

客户端工具(client-owned)

你的服务

查数据库、调内部 API

托管工具(hosted)

模型服务商后台

web search、code interpreter

只有你的自定义工具会「弹回」给你;托管工具在沙箱内直接完成,通常不会出现在你的回调里。

5. 用一句话概括角色分工

模型后台写程序、跑程序;程序需要你的工具时暂停并把请求弹回给你;你执行工具、送回结果;模型后台从断点继续跑程序;跑完后只把精炼结果交给模型做最后回答。

你的角色是工具提供者,不是代码执行者——这也是它叫 Programmatic Tool Calling,而不是「把代码发给你跑」的原因。


三、共同的设计模式

尽管实现细节不同,两家 PTC 共享一套架构模式:

1. Opt-in 机制:allowed_callers

不是每个工具都默认可被程序调用。你必须在工具定义上显式标注:

调用方式

OpenAI

Claude

仅直接调用

省略或 ["direct"]

省略或 ["direct"]

仅程序内调用

["programmatic"]

["code_execution_20260120"]

两者皆可

["direct", "programmatic"]

["direct", "code_execution_20260120"]

官方都建议:对每个工具只选一种模式,给模型更清晰的引导,而不是同时开两种。

2. 调用溯源:caller 字段

程序发起的工具调用,响应里会带 caller 字段,标明「这次调用是谁发起的」:

  • 直接调用caller.type = "direct"
  • 程序内调用caller 指向对应的程序 / code execution 实例

你的应用在回传工具结果时,必须原样保留 caller,运行时才能正确恢复暂停的程序。

3. 暂停-恢复循环

程序执行到需要客户端工具时暂停,API 把 tool_use / function_call 返回给你;你执行工具、回传结果;程序从断点继续。循环直到程序跑完,才把最终输出交给模型。

4. 中间结果不进模型上下文

这是 PTC 最大的价值点。工具返回的原始数据在沙箱内被过滤、聚合、转换,只有程序的 stdout / program_output 进入模型的下一轮推理。


四、OpenAI 的实现:JavaScript + 独立 PTC 工具

OpenAI 的 PTC 是 Responses API 的专属能力,随 GPT-5.6 正式推出(更早的 GPT-5.4+ 可能有限支持,需查模型页)。

架构概览

代码语言:javascript
复制
┌─────────────────────────────────────────────────────┐
│  Responses API Request                               │
│  tools: [                                            │
│    { type: "function", name: "get_inventory",      │
│      allowed_callers: ["programmatic"], ... },       │
│    { type: "programmatic_tool_calling" }  ← 开关    │
│  ]                                                   │
└──────────────────────┬──────────────────────────────┘
                       ▼
┌─────────────────────────────────────────────────────┐
│  模型生成 program 项(JavaScript 代码)               │
│  OpenAI 在隔离 V8 运行时中执行                        │
│  - 支持 top-level await                              │
│  - 无 Node.js、无网络、无文件系统、无 npm             │
│  - 只能通过 tools.* 调用已启用的工具                  │
└──────────────────────┬──────────────────────────────┘
                       ▼ 程序调用 client-owned 工具时暂停
┌─────────────────────────────────────────────────────┐
│  response.output 包含:                              │
│  - program(代码 + call_id + fingerprint)           │
│  - function_call(caller.caller_id → program)       │
└──────────────────────┬──────────────────────────────┘
                       ▼ 你的应用执行工具
┌─────────────────────────────────────────────────────┐
│  回传 function_call_output(保留 call_id + caller)   │
└──────────────────────┬──────────────────────────────┘
                       ▼ 程序恢复执行
┌─────────────────────────────────────────────────────┐
│  program_output(status: completed/incomplete)      │
│  → 模型收到精炼结果,生成最终 message                 │
└─────────────────────────────────────────────────────┘

关键配置

1. 启用 PTC

tools 数组中加入 {"type": "programmatic_tool_calling"},并对允许被程序调用的工具设置 allowed_callers: ["programmatic"]

2. 定义 output_schema

OpenAI 要求你为 function 工具定义 output_schema——描述工具返回的 JSON 结构。这样生成的 JavaScript 可以可靠地解析返回值:

代码语言:javascript
复制
{
"type":"function",
"name":"get_inventory",
"description":"Return an object with sku (string) and available_units (number).",
"parameters":{
"type":"object",
"properties":{"sku":{"type":"string"}},
"required":["sku"]
},
"output_schema":{
"type":"object",
"properties":{
"sku":{"type":"string"},
"available_units":{"type":"number"}
},
"required":["sku","available_units"]
},
"allowed_callers":["programmatic"]
}

3. 模型生成的代码长什么样

响应中的 program 项包含 JavaScript,通过 tools.* 命名空间调用工具:

代码语言:javascript
复制
const [stock, demand] = awaitPromise.all([
  tools.get_inventory({ sku: 'sku_123' }),
  tools.get_demand({ sku: 'sku_123' })
]);
text(JSON.stringify({
sku: stock.sku,
available_units: stock.available_units,
requested_units: demand.requested_units,
shortage_units: Math.max(demand.requested_units - stock.available_units, 0)
}));

程序用 text(...)image(...) 输出最终结果。

响应数据结构

PTC 在 response.output 中引入三类新 item:

代码语言:javascript
复制
生成的 JS 代码、call_id、fingerprint(用于恢复/重放)

示例(程序暂停,等待两个并行工具调用):

代码语言:javascript
复制
[
{
"type":"program",
"call_id":"call_prog_123",
"code":"const [stock, demand] = await Promise.all([...]); text(JSON.stringify({...}));",
"fingerprint":"opaque_replay_state"
},
{
"type":"function_call",
"call_id":"call_inventory_123",
"name":"get_inventory",
"arguments":"{\"sku\":\"sku_123\"}",
"caller":{"type":"program","caller_id":"call_prog_123"}
},
{
"type":"function_call",
"call_id":"call_demand_123",
"name":"get_demand",
"arguments":"{\"sku\":\"sku_123\"}",
"caller":{"type":"program","caller_id":"call_prog_123"}
}
]

应用侧循环(伪代码)

代码语言:javascript
复制
while (true) {
const response = await client.responses.create({
model: "gpt-5.6",
store: false,
    input,
    tools,
  });

  input.push(...response.output);

const calls = response.output.filter(item => item.type === "function_call");
if (calls.length === 0) {
// 收到最终 message,结束
break;
  }

for (const call of calls) {
const result = awaitexecuteTool(call.name, JSON.parse(call.arguments));
    input.push({
type: "function_call_output",
call_id: call.call_id,
output: JSON.stringify(result),
caller: call.caller,  // 必须原样保留
    });
  }
}

运行时环境特点

代码语言:javascript
复制
JavaScript(V8 隔离运行时)

与 Tool Search 的配合

Tool search 是 Responses API 的顶层工具,不能从程序内部的 JavaScript 调用。流程是:模型先用 tool search 加载 deferred 工具 → 再启动 program 调用它们。已在运行的 program 无法触发 tool search。


五、Claude 的实现:Python + Code Execution 容器

Claude 的 PTC 不走独立工具类型,而是建立在已有的 Code Execution 工具之上——模型写 Python,在沙箱容器里跑,容器内的代码以 async 函数形式调用你的工具。

2025 年 11 月作为 Advanced Tool Use 的一部分发布(Beta);2026 年 2 月随 Sonnet 4.6 发布转为 GA,不再需要 beta header。

架构概览

代码语言:javascript
复制
┌─────────────────────────────────────────────────────┐
│  Messages API Request                                │
│  tools: [                                            │
│    { type: "code_execution_20260120",                │
│      name: "code_execution" },        ← 沙箱开关    │
│    { name: "query_database",                         │
│      allowed_callers: ["code_execution_20260120"] }  │
│  ]                                                   │
└──────────────────────┬──────────────────────────────┘
                       ▼
┌─────────────────────────────────────────────────────┐
│  模型生成 server_tool_use(Python 代码)              │
│  Anthropic 在 Code Execution 容器中执行               │
│  - 工具被暴露为 async Python 函数                     │
│  - 支持 asyncio.gather 并行                          │
│  - REPL 状态可跨 cell 持久化(20260120 版本)         │
└──────────────────────┬──────────────────────────────┘
                       ▼ 代码调用 client-owned 工具时暂停
┌─────────────────────────────────────────────────────┐
│  response 包含:                                     │
│  - server_tool_use(code_execution 代码)             │
│  - tool_use(caller 指向 code_execution 实例)      │
│  - container.id(必须回传以恢复执行)                 │
│  - stop_reason: "tool_use"                           │
└──────────────────────┬──────────────────────────────┘
                       ▼ 你的应用执行工具
┌─────────────────────────────────────────────────────┐
│  回传 tool_result(user 消息,仅含 tool_result)      │
│  必须带 container ID                                 │
└──────────────────────┬──────────────────────────────┘
                       ▼ 代码从断点恢复
┌─────────────────────────────────────────────────────┐
│  code_execution_tool_result(stdout/stderr)          │
│  → 模型收到精炼结果,生成最终 text                     │
└─────────────────────────────────────────────────────┘

关键配置

1. 启用 PTC

不需要额外的 programmatic_tool_calling 开关。只需:

  • • 在 tools 中加入 code_execution_20260120
  • • 对允许被程序调用的工具设置 allowed_callers: ["code_execution_20260120"]

2. 工具描述要详细

Claude 官方强调:在 tool description 里写清楚返回格式(比如「返回 JSON 对象列表」),模型才能在 Python 代码里正确 json.loads() 处理结果。

3. 模型生成的代码长什么样

代码语言:javascript
复制
import json

rows = json.loads(await query_database({"sql": "SELECT ..."}))
top_customers = sorted(rows, key=lambda x: x['revenue'], reverse=True)[:5]
print(f'Top 5 customers: {top_customers}')

工具在容器内被暴露为 async Python 函数:接收一个 dict 参数,返回你回传的 tool_result 字符串。

响应数据结构

Claude 不引入新的 item 类型,而是复用 Messages API 的现有结构:

代码语言:javascript
复制
模型发起的 code execution 请求,包含 Python 代码

程序暂停时的响应示例:

代码语言:javascript
复制
{
"role":"assistant",
"content":[
{"type":"text","text":"I'll query the purchase history and analyze the results."},
{
"type":"server_tool_use",
"id":"srvtoolu_abc123",
"name":"code_execution",
"input":{"code":"import json\nrows = json.loads(await query_database({...}))\n..."}
},
{
"type":"tool_use",
"id":"toolu_def456",
"name":"query_database",
"input":{"sql":"SELECT ..."},
"caller":{
"type":"code_execution_20260120",
"tool_id":"srvtoolu_abc123"
}
}
],
"container":{
"id":"container_xyz789",
"expires_at":"2026-01-20T14:30:00Z"
},
"stop_reason":"tool_use"
}

应用侧循环(伪代码)

代码语言:javascript
复制
messages = [{"role": "user", "content": "..."}]
container_id = None

whileTrue:
    response = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=4096,
        messages=messages,
        tools=tools,
        container=container_id,  # 续传时必传
    )

    messages.append({"role": "assistant", "content": response.content})
    container_id = response.container.idif response.container elseNone

# 检查是否有程序发起的 tool_use
    programmatic_calls = [
        block for block in response.content
if block.type == "tool_use"
and block.caller.type.startswith("code_execution")
    ]

ifnot programmatic_calls:
break# 程序已结束或没有工具调用

# 回传工具结果:user 消息只能包含 tool_result,不能有 text
    tool_results = []
for call in programmatic_calls:
        result = execute_tool(call.name, call.input)
        tool_results.append({
"type": "tool_result",
"tool_use_id": call.id,
"content": json.dumps(result),
        })

    messages.append({"role": "user", "content": tool_results})

运行时环境特点

代码语言:javascript
复制
Python(沙箱容器)

Dynamic Filtering:PTC 思想在 Web Search 上的延伸

Claude 还把 PTC 的原则应用到了 web search——Dynamic Filteringweb_search_20260318)。模型写 Python 预处理搜索结果,过滤无关内容后再进入上下文。这不是独立的 PTC,而是同一套「在代码里过滤,少进上下文」哲学的原生工具层实现。


六、并排对比

架构层

维度

OpenAI (GPT)

Anthropic (Claude)

API

Responses API

Messages API

启用方式

独立的 programmatic_tool_calling 工具

复用 code_execution_20260120

程序语言

JavaScript(V8 隔离运行时)

Python(沙箱容器)

Opt-in 字段

allowed_callers: ["programmatic"]

allowed_callers: ["code_execution_20260120"]

程序 item

program(含 fingerprint)

server_tool_use(code_execution)

工具调用 item

function_call

tool_use

结果回传

function_call_output + caller

tool_result + container ID

程序完成 item

program_output

code_execution_tool_result

状态续传

fingerprint / previous_response_id

container ID(等待工具结果时必填)

能力层

维度

OpenAI

Claude

并行调用

Promise.all

asyncio.gather

返回 schema

显式 output_schema 字段

依赖 tool description 描述

可编排的托管工具

MCP、shell、code_interpreter、apply_patch

仅 client-side 自定义工具

MCP 程序化调用

支持(含 approval 暂停)

不支持

Tool Search 配合

需先加载 deferred 工具再开 program

独立的 tool search 工具

ZDR 兼容

支持(无需持久 container)

不支持

发布时间

2026.07(GPT-5.6)

2025.11 Beta → 2026.02 GA

限制层

限制

OpenAI

Claude

强制特定工具

不可用 tool_choice 强制 program 调用

不可用 tool_choice 强制

Strict schema 工具

未明确禁止

strict: true 工具不可用

禁用并行工具

未明确禁止

disable_parallel_tool_use: true 不可用

递归 $ref schema

未提及

返回 400 错误

回传格式

function_call_output 可混合其他 item

等待 program 结果时 user 消息只能含 tool_result

工具结果超时

未明确

约 4 分钟


七、一次完整流程的对比

以「查三个区域销售数据,找出收入最高的区域」为例。

OpenAI 流程

代码语言:javascript
复制
1. POST /v1/responses
   tools: [get_sales(region), programmatic_tool_calling]
   input: "查 West/East/Central 三地销售,找出最高收入区域"

2. 响应 output:
   ├─ program: "const results = {}; for (const r of ['West','East','Central']) {
   │     results[r] = await tools.get_sales({region: r});
   │   } text(JSON.stringify(results));"
   ├─ function_call: get_sales({region: "West"})  caller→program
   ├─ function_call: get_sales({region: "East"})  caller→program
   └─ function_call: get_sales({region: "Central"})  caller→program

3. 你的服务并行执行三个 get_sales,回传三个 function_call_output

4. 响应 output:
   └─ program_output: {"West": 120000, "East": 95000, "Central": 110000}

5. 响应 output:
   └─ message: "Central 区域收入最高,为 $110,000。"

你的应用跑了 1 次 API 请求 + 1 次续传(回传工具结果)+ 可能 1 次最终响应。模型推理 2 次,工具执行 3 次(并行)。

Claude 流程

代码语言:javascript
复制
1. POST /v1/messages
   tools: [code_execution_20260120, get_sales(allowed_callers: code_execution)]
   messages: [{role: user, content: "查三地销售..."}]

2. 响应:
   ├─ server_tool_use: code_execution (Python 循环代码)
   ├─ tool_use: get_sales({region: "West"})  caller→code_execution
   ├─ container: {id: "container_abc", expires_at: "..."}
   └─ stop_reason: "tool_use"

3. 你的服务执行 get_sales,回传 tool_result
   ⚠️ 必须带 container: "container_abc"
   ⚠️ user 消息只能含 tool_result

4. (可能重复 2-3 步,直到代码中所有工具调用完成)

5. 响应:
   ├─ code_execution_tool_result: stdout="{'West': 120000, ...}"
   └─ text: "Central 区域收入最高,为 $110,000。"

流程类似,但多了一步 container 管理,且回传格式约束更严格。


八、什么时候该用 PTC

两家官方指南高度一致:

适合 PTC

  • 多步可预测编排:查 N 个实体 → 过滤 → 聚合,逻辑可以用代码表达
  • 大数据过滤:工具返回大量数据,只需要摘要或 Top-K
  • 并行独立调用:查 50 个端点健康状态,互不依赖
  • 条件分支:根据工具 A 的结果决定调 B 还是 C
  • Token 敏感:中间结果不应污染模型上下文

不适合 PTC

  • 单次简单调用:一个工具就能回答
  • 每步需要模型判断:搜索结果应该影响下一步搜索策略(语义决策)
  • 审批敏感操作:写操作、资金操作——应走 direct tool calling 保留清晰授权边界
  • 需要保留引用/artifacts:最终答案需要引用原始工具输出的场景

混合模式(推荐)

两家都支持 allowed_callers: ["direct", "programmatic"](或等价的双模式),并建议在 prompt 里明确划分

代码语言:javascript
复制
<tool_orchestration>
对 [bounded stage] 使用 Programmatic Tool Calling,仅调用 [eligible tools]。
并行执行独立调用。处理中间结果后,输出恰好 [schema]。

对 [semantic judgment / approval / validation] 使用 direct tool calling。
</tool_orchestration>

OpenAI 额外强调:如果工具返回结构在写程序前不确定,应保持 direct calling,让模型先看结果再决定怎么用。


九、工程实践建议

1. 工具设计

代码语言:javascript
复制
程序需要解析,不是读自然语言

2. 集成复杂度

OpenAI

Claude

入门难度

中等:需理解 program / program_output 新 item 类型

中等:复用 Messages API 结构,但 container 管理增加复杂度

状态管理

store: false 时 replay 全部 output items;或 previous_response_id

必须跟踪 container ID,等待工具结果时必填

调试

program.code 可直接看到生成的 JS

server_tool_use.input.code 可直接看到生成的 Python

SDK 支持

OpenAI SDK 原生支持 Responses API

Anthropic SDK 支持,code_execution_20260120 需显式配置

3. 合规选型

如果你的组织有 Zero Data Retention 要求:

  • OpenAI PTC 明确支持 ZDR,无需持久化 code execution container
  • Claude PTC 不支持 ZDR,数据按标准 retention 保留

这可能是某些场景下的决定性因素。

4. 性能预期

不要假设 PTC 一定更快或更便宜。官方建议:

以 direct tool calling 为 baseline,在代表性任务上对比两种方案。

衡量维度:

  • • 最终答案的正确性、完整性、证据覆盖
  • • 输入/总 token、端到端延迟、成本
  • • 模型轮次、工具调用次数、重试和恢复行为
  • • 实际执行的路由是否符合预期工作流阶段

十、结语:同题异构

GPT 和 Claude 的 Programmatic Tool Calling 解决的是同一个问题——Agent 外循环(outer loop)的效率。传统 tool calling 让模型既当「调度器」又当「处理器」,每一步都要把中间结果读进上下文、做一次推理;PTC 把调度逻辑下沉到沙箱代码,模型只在开始(写程序)和结束(读结果)时出现。

但「同题异构」体现在:

OpenAI

Anthropic

哲学

新增独立的 PTC 运行时(V8 + JS)

复用 Code Execution 容器(Python)

接口

Responses API 新 item 类型

Messages API 现有 block + container

扩展

PTC 可编排 MCP、shell 等托管工具

PTC 仅限 client-side 工具,MCP 被排除

合规

ZDR 友好

标准 retention

成熟度

2026.07 随 GPT-5.6 发布

2025.11 Beta → 2026.02 GA,生态更久

对开发者来说,PTC 不是「升级版 tool calling」——它是一种工作流阶段的选型。Bounded、可预测、数据密集的阶段用 PTC;需要模型实时判断、审批、或保留完整引用的阶段用 direct calling。两家都支持混合模式,关键是在 prompt 和工具定义里把边界划清楚。

下一阶段的竞争,可能不是「谁的 PTC 更强」,而是谁能让开发者更低成本地在 direct 和 programmatic 之间切换——OpenAI 的 output_schema + fingerprint 重放,Claude 的 Dynamic Filtering 原生扩展,都是这个方向上的探索。


本文基于 OpenAI Programmatic Tool Calling 文档、Anthropic Programmatic Tool Calling 文档 及 Advanced Tool Use 工程博客(截至 2026 年 7 月)整理分析。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有文化的技术人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、传统 Tool Calling 卡在哪里
  • 二、端到端流程:谁执行什么
    • 完整交互流程
    • 五个关键细节
  • 三、共同的设计模式
    • 1. Opt-in 机制:allowed_callers
    • 2. 调用溯源:caller 字段
    • 3. 暂停-恢复循环
    • 4. 中间结果不进模型上下文
  • 四、OpenAI 的实现:JavaScript + 独立 PTC 工具
    • 架构概览
    • 关键配置
    • 响应数据结构
    • 应用侧循环(伪代码)
    • 运行时环境特点
    • 与 Tool Search 的配合
  • 五、Claude 的实现:Python + Code Execution 容器
    • 架构概览
    • 关键配置
    • 响应数据结构
    • 应用侧循环(伪代码)
    • 运行时环境特点
    • Dynamic Filtering:PTC 思想在 Web Search 上的延伸
  • 六、并排对比
    • 架构层
    • 能力层
    • 限制层
  • 七、一次完整流程的对比
    • OpenAI 流程
    • Claude 流程
  • 八、什么时候该用 PTC
    • 适合 PTC
    • 不适合 PTC
    • 混合模式(推荐)
  • 九、工程实践建议
    • 1. 工具设计
    • 2. 集成复杂度
    • 3. 合规选型
    • 4. 性能预期
  • 十、结语:同题异构
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档