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 及後續模型支援非同步工具呼叫。

非同步執行適用於應用程式執行的函式工具和自訂工具,不適用於託管的內建工具。請直接呼叫工具;不要將非同步工具設定為用於以程式呼叫工具

多智慧體模式中,請勿將非同步工具與平行工具呼叫搭配使用。