先给结论

Async Tool Calling 适合“工具较慢,但模型还有独立内容可以继续处理”的 Responses API 工作流:在应用执行的 function 或 custom 工具上设置 async:true,应用立即登记并启动作业;完成后在后续请求中用原始 call_id 回传结果。它不会把作业交给 OpenAI 托管,也不是 Background mode。

OpenAI Async Tool Calling 怎么用?

先判断是否真的需要异步工具

普通函数调用在模型发出调用后会暂停当前回合,直到应用返回工具结果。异步工具允许模型先继续生成不依赖该结果的内容、调用其他合适工具,或在真正需要结果时再等待。若后续每一步都依赖工具结果,就没有可并行的工作,普通同步循环通常更简单。

任务形态推荐方式关键边界
单次快速查询,下一步立即依赖结果普通 Function Calling减少登记与续接复杂度
慢查询可提前启动,期间有独立工作Async Tool Calling应用仍负责执行、状态和重试
整个模型响应需要脱离连接长时运行Background mode异步的是响应生成,不是你的工具作业
用 JavaScript 聚合多个已授权工具Programmatic Tool Calling不能把 async 工具配置给 PTC

兼容范围先锁定

  • 官方当前说明支持 GPT-6 Astra 及之后模型;上线前仍应读取模型页。
  • 仅适用于应用自行执行的 function 和 custom 工具。
  • 不适用于 Web Search、File Search 等托管内置工具。
  • 使用直接工具调用,不要为 Programmatic Tool Calling 配置异步工具。
  • Multi-agent mode 中不要把 async 工具与 parallel tool calls 组合。

最小配置:在工具定义上设置 async:true

工具调用项目本身也会带有 async:true。下面同时加入全会话唯一的 task_handle,方便应用登记真实后台作业;不要把它误当成 OpenAI 自动生成的任务 ID。

const tools = [{
  type: "function",
  name: "lookup_price",
  description: "Look up one product price.",
  async: true,
  strict: true,
  parameters: {
    type: "object",
    properties: {
      sku: { type: "string" },
      task_handle: { type: "string" }
    },
    required: ["sku", "task_handle"],
    additionalProperties: false
  }
}];

const first = await client.responses.create({
  model: "gpt-6-astra",
  tools,
  instructions:
    "Start the lookup early. Continue independent work, " +
    "but do not invent the pending result.",
  input: "查询 SKU-123 的价格,同时先整理不依赖价格的检查项。"
});

响应可能同时包含异步调用和一段可用回答。不要因为已经出现文本就把异步调用丢掉,也不要在工具结果回来前让模型猜测结果。

应用端必须维护任务登记表

收到完整调用项目后,先验证名称与参数,再把 task_handle、原始 call_id、实际作业 ID、状态、租户和截止时间绑定。句柄要在整个会话内唯一,包括已经完成的任务和重复查询。

字段用途常见错误
task_handle模型和应用识别业务任务复用旧句柄导致结果串单
call_idResponses API 关联原始工具调用回传时新建 ID 或用错调用
job_id / status应用队列、Worker 和重试状态把 OpenAI 当成后台任务系统
latest_response_id继续最新对话状态期间续接后仍引用过期响应

工具完成后,用原始 call_id 回传

function 使用 function_call_output,custom 工具使用 custom_tool_call_output。如果作业期间发生其他对话轮次,previous_response_id 指向最新响应;但结果仍必须绑定最初调用的 call_id。

const call = first.output.find(
  item => item.type === "function_call" &&
          item.name === "lookup_price"
);

const job = runLookup(JSON.parse(call.arguments));

// 期间若有其他 Responses 续接,要持续更新这个值
let latestResponseId = first.id;
const result = await job;

const resumed = await client.responses.create({
  model: "gpt-6-astra",
  tools,
  previous_response_id: latestResponseId,
  input: [{
    type: "function_call_output",
    call_id: call.call_id,
    output: JSON.stringify(result)
  }]
});

使用流式输出时,可在完整的调用项目到达后立即启动作业,同时继续消费响应事件。不要在参数仍是增量片段时提前执行。

什么时候需要自定义 wait 工具?

官方示例里的 wait_for_tasks 不是内置 Responses 工具,而是应用定义的普通同步函数。只有当模型下一步依赖尚未完成的结果时才等待;结果已经完成时,先把每个工具结果按原始 call_id 回传,再返回 wait 调用自己的状态。

  1. 异步工具参数包含唯一 task_handle。
  2. 应用登记每个 handle 对应的原始 call_id 与真实作业。
  3. 模型调用同步 wait 工具并传入非空、去重后的 handles。
  4. 应用只等待所请求的作业,不阻塞无关任务。
  5. 下一次请求先发送新完成的工具结果,再发送 wait 的状态输出。
wait 工具不应变成无限阻塞

设置服务端截止时间、可取消状态和明确的 pending / completed / failed 结果;失败要返回结构化错误,让模型决定重试、降级或向用户说明,而不是静默等待。

异步询问用户也遵循同一模式

需要用户补充偏好时,可以定义 async:true 的自有函数。应用展示问题、保存原始 call_id,并让模型继续处理独立工作;用户回答后再把答案作为该调用的输出回传。不要在展示问题时就用“已展示”完成工具调用。若用户关闭或超时,返回明确的无答案状态。

可靠性、安全与幂等

  • 工具启动前校验租户、资源、权限与参数,不把模型生成的句柄当授权。
  • 用稳定幂等键防止网络重试重复扣款、重复写入或重复发送。
  • 为登记、执行、完成、回传和模型消费分别记录时间戳与错误。
  • 结果回传前核对任务仍属于当前会话、用户和原始 call_id。
  • 高影响写操作保留用户确认、应用审批和可撤销路径。
  • 设定最大并发、超时、重试次数、结果大小和过期清理策略。

成本与性能怎么评测?

异步不是免费并行。它可能减少模型等待,但会增加队列、状态存储、续接和额外响应轮次。以普通 Function Calling 为基线,在同一批真实任务上比较:

  • 首个可用回答时间、最终完成时间和 P95/P99 延迟。
  • 输入、输出、缓存和总 Token,以及每次成功任务成本。
  • 工具启动到完成时间、队列等待、重试和超时率。
  • 串单、重复执行、遗失结果与错误降级率。
  • 最终答案正确率、是否使用真实工具结果、是否提前猜测。

常见错误与排查顺序

  1. 模型仍然停住:确认所选模型支持,工具定义与返回调用项目确实有 async:true,并且提示中存在可独立完成的工作。
  2. 结果无法关联:检查是否保留原始 call_id,输出类型是否与 function/custom 匹配。
  3. 续接到旧对话:期间若产生新响应,更新 latest_response_id。
  4. wait 后仍无结果:先登记所有 launch,再处理依赖 wait;回传顺序先工具结果、后 wait 状态。
  5. 任务串单:检查 task_handle 是否全会话唯一,并验证租户与会话归属。
  6. 内置工具不异步:Hosted built-in 工具不在兼容范围。
  7. PTC 或 Multi-agent 冲突:改用直接调用;Multi-agent 下不要同时使用 parallel tool calls。

上线前检查清单

  • 重新核对模型与工具兼容范围,不依赖旧示例。
  • 同步路径和异步路径都能完成,并有相同权限校验。
  • 完整保存 task_handle、call_id、job 状态和最新 response ID。
  • 流式处理只在完整调用项目到达后启动任务。
  • 实现超时、取消、失败、重试、幂等和结果过期。
  • 用故障注入验证重复事件、乱序结果、断线和 Worker 重启。
  • 监控端到端延迟、Token、单位成功成本与正确率。

常见问题

OpenAI Async Tool Calling 和普通 Function Calling 有什么区别?

普通 Function Calling 会在调用后暂停模型当前回合,等待应用返回结果;Async Tool Calling 在函数或 custom 工具定义中设置 async:true 后,模型可先继续处理不依赖该结果的内容。工具仍由你的应用执行,完成后用原始 call_id 回传。

Async Tool Calling 和 Background mode 是一回事吗?

不是。Background mode 让响应生成本身异步运行;Async Tool Calling 让模型在你的应用执行工具时继续工作。它不会把工具任务交给 OpenAI 托管,也不会替你创建、监控或重试后台作业。

哪些模型和工具支持 Async Tool Calling?

官方当前说明支持 GPT-6 Astra 及之后模型;适用于由应用执行的 function 和 custom 工具,不适用于托管内置工具。应使用直接工具调用,不能把 async 工具配置给 Programmatic Tool Calling。

异步工具完成后怎样把结果交回模型?

在后续 Responses 请求的 input 中发送 function_call_output 或 custom_tool_call_output,call_id 必须使用原始异步调用的 call_id。若期间有其他对话续接,previous_response_id 应指向最新响应,但工具结果仍绑定最初的 call_id。

wait_for_tasks 是 OpenAI 内置工具吗?

不是。官方示例中的 wait_for_tasks 是应用自己定义的普通同步函数。应用要为每个异步调用维护全会话唯一的 task_handle,将它映射到原始 call_id 和实际作业,并只在模型下一步依赖未完成结果时等待。

Async Tool Calling 能与 Multi-agent 的 parallel tool calls 一起用吗?

官方当前兼容说明要求在 Multi-agent mode 中不要把 async 工具与 parallel tool calls 组合。先按单一并发策略设计,并用真实任务验证顺序、结果归属和失败恢复。

Async Tool Calling 一定更快或更省钱吗?

不保证。它只在慢工具可以提前启动、且模型有独立工作可做时可能降低等待时间;任务登记、续接、重试和额外模型轮次也会增加复杂度与成本。应比较端到端延迟、Token、成功率、重试和单位成功成本。

官方资料

需要执行终端命令?

如果任务需要多语言命令、文件转换或自有运行环境,请参阅 OpenAI Shell 工具教程;先区分托管容器与本地执行,并按最小权限限制文件、网络和命令。

本文核对日期为 2026-11-01。模型支持、异步字段、工具类型、响应项目和兼容限制可能调整;生产上线前请重新读取 Async Tool Calling、Function Calling、Background mode、Streaming 与 Deployment checklist 官方页面。

先用一个慢、只读工具建立基线

选择可安全重试的只读查询,对比同步与异步路径的正确率、首个可用回答时间、最终延迟、Token 和单位成功成本,再决定是否扩展到更多工具。