For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegação principal

Chamada assíncrona de ferramentas

Continue trabalhando enquanto sua aplicação executa ferramentas em segundo plano.

A chamada assíncrona de ferramentas permite que o modelo continue trabalhando após chamar uma ferramenta, sem esperar pelo resultado dela. Use esse recurso para iniciar consultas demoradas com antecedência, responder a partes independentes de uma solicitação e fornecer os resultados quando sua aplicação os tiver.

Como funcionam as ferramentas assíncronas

Uma chamada de função normal pausa o turno do modelo para aguardar uma resposta da ferramenta. Configure async: true na definição de uma função ou ferramenta personalizada para permitir que o modelo continue trabalhando após fazer a chamada, antes de sua aplicação retornar a saída.

Sua aplicação continua responsável por executar a ferramenta. As ferramentas assíncronas não transferem a execução para a OpenAI nem gerenciam suas tarefas em segundo plano.

Isso difere do Modo em segundo plano, que executa a geração de respostas de forma assíncrona. A chamada assíncrona de ferramentas permite que o modelo continue trabalhando enquanto sua aplicação executa uma ferramenta.

Quando uma tarefa terminar, inclua sua saída em uma requisição posterior à API Responses. Use o call_id original da API para associar o resultado à chamada correspondente:

Tipo de ferramentaItem de chamadaItem de saída
Funçãofunction_callfunction_call_output
Personalizadacustom_tool_callcustom_tool_call_output

Chame uma ferramenta assíncrona

Adicione async: true à definição da ferramenta. Os itens de chamada correspondentes em response.output incluem async: true.

Execute uma consulta meteorológica em segundo plano
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)

A resposta pode conter tanto a chamada assíncrona quanto uma resposta à solicitação. Se houver outros turnos na conversa antes de a tarefa terminar, atualize latest_response_id para continuar a partir da resposta mais recente, mantendo o call_id original da ferramenta.

Para antecipar a execução com streaming, inicie a tarefa assim que o item de chamada completo chegar, enquanto continua consumindo a resposta.

Adicione uma ferramenta de espera

Uma ferramenta de espera permite que o modelo escolha quando precisa de um resultado pendente. Por exemplo, ele pode iniciar duas consultas de preços, trabalhar em algo independente e aguardar apenas quando estiver pronto para comparar os preços.

Adicione um argumento task_handle a cada ferramenta assíncrona. O modelo atribui um identificador a cada chamada, e sua aplicação o associa ao call_id original da API e à tarefa em execução. Mantenha os identificadores únicos ao longo de toda a conversa, incluindo tarefas concluídas e consultas repetidas.

Defina a ferramenta de espera como uma função síncrona comum: omita async ou defina seu valor como false. O esquema e o comportamento dela são definidos pela sua aplicação. wait_for_tasks não é uma ferramenta integrada à API Responses.

Use estas definições no array tools da requisição:

[
  {
    "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
    }
  }
]

Registre cada tarefa

Registre e inicie cada tarefa antes de processar uma espera que dependa dela. As chamadas podem chegar juntas ou em respostas diferentes. Os itens de saída a seguir ilustram o início de duas tarefas e uma espera que depende de ambas:

[
  {
    "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\"]}"
  }
]

O registro da sua aplicação associa cada identificador à chamada original e à tarefa em execução:

Identificador da tarefaID da chamada originalTarefa
widget_price_1call_widgetConsulta de preço de WIDGET
gadget_price_1call_gadgetConsulta de preço de GADGET

Mantenha o registro durante toda a conversa para impedir a reutilização do identificador de uma tarefa concluída.

Envie os resultados antes do status da espera

Localize os identificadores solicitados no registro e aguarde apenas as tarefas correspondentes. Retorne cada resultado recém-concluído com seu call_id original e, em seguida, retorne o status com o call_id da própria chamada de espera. Essa ordem disponibiliza os resultados para o modelo quando ele retoma a execução.

Por exemplo, envie estes itens de saída no array input da próxima requisição. Os preços são ilustrativos:

[
  {
    "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\"]}"
  }
]

Defina previous_response_id como o ID da resposta mais recente e inclua as ferramentas e as instruções na requisição de continuação. Sua aplicação também pode enviar os resultados à medida que ficam disponíveis, sem uma chamada de espera. Use a ferramenta de espera apenas quando a próxima etapa do modelo depender de resultados que ainda não chegaram.

Compatibilidade

O GPT-6 Astra e os modelos posteriores oferecem suporte à chamada assíncrona de ferramentas.

A execução assíncrona se aplica a ferramentas de função e ferramentas personalizadas executadas pela sua aplicação. Ela não se aplica a ferramentas integradas hospedadas. Use chamadas diretas de ferramentas; não configure ferramentas assíncronas para chamada programática de ferramentas.

No modo de múltiplos agentes, não combine ferramentas assíncronas com chamadas paralelas de ferramentas.