For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主导航

异步工具调用

在您的应用于后台运行工具时继续工作。

异步工具调用让模型在调用工具后继续工作,无需等待该工具的结果。您可以用它提前发起耗时的查询请求,回答请求中不依赖这些结果的部分,并在应用获取结果后传回结果。

异步工具的工作原理

普通的函数调用会暂停模型的当前轮次,以等待工具响应。在函数或自定义工具的定义中设置 async: true,即可让模型在发出调用后、您的应用返回输出前继续工作。

工具仍由您的应用执行。异步工具不会将执行工作转移到 OpenAI,也不会管理您的后台作业。

这与后台模式不同,后台模式以异步方式生成响应。异步工具调用则让模型在您的应用运行工具时继续工作。

作业完成后,在后续的 Responses 请求中包含其输出。使用原始 API call_id 将结果与对应的调用匹配:

工具类型调用项输出项
函数function_callfunction_call_output
自定义custom_tool_callcustom_tool_call_output

调用异步工具

在工具定义中添加 async: trueresponse.output 中的对应调用项会包含 async: true

在后台查询天气
import json
from concurrent.futures import ThreadPoolExecutor

from openai import OpenAI
from openai.types.responses import FunctionToolParam


def get_weather(city):
    # Demo data. Replace this function with your weather service.
    weather = {
        "Paris": {
            "city": "Paris",
            "temperature_c": 22,
            "condition": "Clear",
            "source": "demo weather snapshot",
        }
    }
    return weather[city]


worker = ThreadPoolExecutor()


def main():
    client = OpenAI()
    model = "gpt-6-astra"
    tools: list[FunctionToolParam] = [
        {
            "type": "function",
            "name": "get_weather",
            "description": "Read the demo weather snapshot for a city.",
            "async": True,
            "strict": True,
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
                "additionalProperties": False,
            },
        },
    ]

    instructions = (
        "Start the weather lookup and answer the independent packing "
        "question without waiting. Use the actual tool result when it "
        "arrives; never invent it. Identify the weather as demo data."
    )
    response = client.responses.create(
        model=model,
        tools=tools,
        instructions=instructions,
        input=(
            "Check the demo weather in Paris. Meanwhile, "
            "list three essentials for any city trip."
        ),
    )

    call = next(item for item in response.output if item.type == "function_call")
    arguments = json.loads(call.arguments)
    if call.name != "get_weather" or arguments != {"city": "Paris"}:
        raise ValueError("Expected a weather lookup for Paris")

    latest_response_id = response.id
    if call.async_:
        job = worker.submit(get_weather, **arguments)
        print(response.output_text)
        # Independent work or conversation turns can happen here.
        # Update latest_response_id after each continuation.
        result = job.result()
    else:
        result = get_weather(**arguments)

    response = client.responses.create(
        model=model,
        tools=tools,
        instructions=instructions,
        previous_response_id=latest_response_id,
        input=[
            {
                "type": "function_call_output",
                "call_id": call.call_id,
                "output": json.dumps(result),
            },
        ],
    )
    print(response.output_text)


if __name__ == "__main__":
    try:
        main()
    finally:
        worker.shutdown(wait=True)

响应可以同时包含异步调用和回答。如果在作业完成前又进行了其他对话轮次,请更新 latest_response_id,以从最新响应继续,同时保留原始工具调用的 call_id

使用流式传输时,若要更早启动作业,可在收到完整的调用项后立即启动该作业,同时继续接收并处理响应。

添加等待工具

等待工具让模型自行决定何时需要尚未返回的结果。例如,模型可以发起两个价格查询请求,先处理不依赖查询结果的工作,直到准备比较价格时才等待结果。

为每个异步工具添加 task_handle 参数。模型会为每次调用分配一个句柄,您的应用则将该句柄绑定到原始 API call_id 和正在运行的作业。请确保句柄在整个对话中保持唯一,包括已完成的任务和重复的查询请求。

将等待工具定义为普通的同步函数:省略 async,或将其设为 false。它的模式和行为由您的应用定义。wait_for_tasks 不是 Responses 的内置工具。

在请求的 tools 数组中使用这些定义:

[
  {
    "type": "function",
    "name": "lookup_price",
    "async": true,
    "description": "Look up a product price in the background. Choose a fresh task_handle unique within this conversation, including completed tasks.",
    "strict": true,
    "parameters": {
      "type": "object",
      "properties": {
        "sku": { "type": "string" },
        "task_handle": { "type": "string" }
      },
      "required": ["sku", "task_handle"],
      "additionalProperties": false
    }
  },
  {
    "type": "function",
    "name": "wait_for_tasks",
    "description": "Wait for selected tasks whose results you need. Pass a nonempty list of distinct task_handles from your earlier lookup_price calls. Results arrive on their original calls; this tool returns status only. Do not wait again for results that have already arrived.",
    "strict": true,
    "parameters": {
      "type": "object",
      "properties": {
        "task_handles": {
          "type": "array",
          "items": { "type": "string" }
        }
      },
      "required": ["task_handles"],
      "additionalProperties": false
    }
  }
]

注册每个作业

在处理依赖某些作业的等待调用前,请先注册并启动这些作业。调用可能在同一个响应中到达,也可能分散在多个响应中。以下输出项示例展示了两次启动调用,以及一个依赖这两次调用的等待调用:

[
  {
    "type": "function_call",
    "name": "lookup_price",
    "async": true,
    "call_id": "call_widget",
    "arguments": "{\"sku\":\"WIDGET\",\"task_handle\":\"widget_price_1\"}"
  },
  {
    "type": "function_call",
    "name": "lookup_price",
    "async": true,
    "call_id": "call_gadget",
    "arguments": "{\"sku\":\"GADGET\",\"task_handle\":\"gadget_price_1\"}"
  },
  {
    "type": "function_call",
    "name": "wait_for_tasks",
    "call_id": "call_wait",
    "arguments": "{\"task_handles\":[\"widget_price_1\",\"gadget_price_1\"]}"
  }
]

应用的注册表将每个句柄绑定到其原始调用和正在运行的作业:

任务句柄原始调用 ID作业
widget_price_1call_widgetWIDGET 价格查询
gadget_price_1call_gadgetGADGET 价格查询

请在整个对话期间保留注册表,防止重复使用已完成任务的句柄。

先传回结果,再传回等待状态

在注册表中查找请求指定的句柄,并且仅等待这些句柄对应的作业。先使用各自的原始 call_id 返回每个新完成的结果,再使用等待调用自身的 call_id 返回状态。按此顺序操作,可让模型在恢复运行时获得结果。

例如,在下一个请求的 input 数组中发送以下输出项。其中的价格仅作示例:

[
  {
    "type": "function_call_output",
    "call_id": "call_widget",
    "output": "{\"task_handle\":\"widget_price_1\",\"price_cents\":1200,\"currency\":\"USD\"}"
  },
  {
    "type": "function_call_output",
    "call_id": "call_gadget",
    "output": "{\"task_handle\":\"gadget_price_1\",\"price_cents\":1500,\"currency\":\"USD\"}"
  },
  {
    "type": "function_call_output",
    "call_id": "call_wait",
    "output": "{\"status\":\"completed\",\"completed_task_handles\":[\"widget_price_1\",\"gadget_price_1\"]}"
  }
]

previous_response_id 设为最新响应的 ID,并在后续请求中包含工具和指令。您的应用也可以在结果就绪时直接传回结果,无需等待调用。只有当模型的下一步依赖尚未返回的结果时,才使用等待工具。

兼容性

GPT-6 Astra 及后续模型支持异步工具调用。

异步执行适用于由您的应用运行的函数工具和自定义工具,不适用于托管的内置工具。请直接调用工具,不要为程序化工具调用配置异步工具。

多智能体模式下,请勿将异步工具与并行工具调用结合使用。