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
Theme

Chamada programática de ferramentas

Permita que os modelos escrevam e executem código JavaScript para coordenar chamadas de ferramentas.

Com a chamada programática de ferramentas, o modelo pode escrever e executar código JavaScript para coordenar o uso de suas ferramentas. Um programa pode chamar ferramentas em paralelo, usar laços e condições e manter os resultados intermediários no ambiente de execução hospedado. Isso é útil quando uma tarefa exige uma sequência de chamadas relacionadas ou precisa processar grandes volumes de dados retornados pelas ferramentas antes de entregar um resultado.

Na API Responses, seu aplicativo define se a chamada programática de ferramentas está disponível e, para cada ferramenta compatível, se o modelo pode chamá-la diretamente, por meio de um programa ou das duas formas. O aplicativo continua responsável por executar todas as chamadas de ferramentas que cabem ao cliente. A API de Agentes habilita a chamada programática de ferramentas por padrão e gerencia o ciclo de execução do agente para você.

Consulte a página de modelos antes de habilitar a chamada programática de ferramentas.

Entenda o ambiente de execução

A OpenAI executa cada programa gerado em um novo ambiente V8 isolado. O ambiente permite usar JavaScript com await no nível superior, mas não oferece Node.js, instalação de pacotes, acesso direto à rede, sistema de arquivos de uso geral, execução de subprocessos nem console. Também não preserva o estado do JavaScript entre execuções. Os programas só podem interagir com sistemas externos por meio das ferramentas habilitadas na solicitação e podem emitir resultados com text(...) ou image(...).

Nas solicitações à API Responses, a chamada programática de ferramentas permite usar fluxos de trabalho com zero retenção de dados (ZDR) sem precisar de um contêiner persistente para executar código. É preciso habilitar a ZDR na organização ou no projeto. A configuração store: false permite continuar sem armazenar estado, mas não habilita a ZDR por si só. A elegibilidade para ZDR e a retenção dependem da solicitação completa, incluindo o modelo, as ferramentas e os serviços de terceiros utilizados. Consulte os controles de dados.

Quando usar a chamada programática de ferramentas

Use a chamada programática de ferramentas quando uma etapa tiver um fluxo de controle previsível e o código puder retornar um resultado estruturado mais compacto. Use chamadas diretas de ferramentas quando uma única chamada bastar, quando cada resultado exigir uma nova avaliação do modelo ou quando o trabalho exigir aprovação ou a preservação de citações ou artefatos nativos.

Tipo de tarefa Modo recomendado
Uma única consulta ou ação Use uma chamada direta de ferramenta.
Vários resultados que o código pode filtrar, combinar, classificar, deduplicar, agregar ou validar Use a chamada programática de ferramentas quando o programa puder retornar um resultado estruturado mais compacto.
Chamadas que dependem umas das outras e têm um fluxo de dados previsível Use a chamada programática de ferramentas quando o código puder determinar os argumentos das chamadas seguintes e estiverem explícitos os limites e o comportamento em caso de falha.
Busca adaptativa ou avaliação semântica Use chamadas diretas de ferramentas quando cada resultado precisar influenciar a próxima decisão do modelo.
Operações de gravação ou ações que exigem atenção à aprovação Use chamadas diretas de ferramentas por padrão para manter claros os limites da autorização.
Validação final de citações ou artefatos nativos Use chamadas diretas de ferramentas, a menos que o programa preserve a saída nativa e valide todos os itens obrigatórios.

Configure a chamada programática de ferramentas

Na API Responses, adicione a ferramenta hospedada programmatic_tool_calling à solicitação. Em seguida, configure allowed_callers em cada ferramenta compatível que o programa poderá chamar.

Habilite a chamada programática de ferramentas
[
  {
    "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"],
      "additionalProperties": false
    },
    "output_schema": {
      "type": "object",
      "properties": {
        "sku": { "type": "string" },
        "available_units": { "type": "number" }
      },
      "required": ["sku", "available_units"],
      "additionalProperties": false
    },
    "allowed_callers": ["programmatic"]
  },
  {
    "type": "programmatic_tool_calling"
  }
]

allowed_callers controla como o modelo pode chamar uma ferramenta:

Valor Comportamento
Omitido ou ["direct"] O modelo pode chamar a ferramenta diretamente.
["programmatic"] Somente o código de um item program pode chamar a ferramenta.
["direct", "programmatic"] O modelo pode chamar a ferramenta diretamente ou por meio de um programa.

parameters descreve os argumentos da função. Quando uma função retorna dados com estrutura previsível, output_schema descreve o objeto JSON codificado na string function_call_output.output. Defina ambos para que o código JavaScript gerado possa usar os campos retornados de forma confiável.

Ferramentas compatíveis

Os seguintes tipos de ferramenta aceitam allowed_callers: ["programmatic"]:

  • function e custom
  • mcp
  • apply_patch
  • shell local e hospedado
  • code_interpreter

Nas ferramentas MCP, a política require_approval da ferramenta pode pausar o programa até que você aprove a chamada.

Para ferramentas hospedadas pela OpenAI, consulte as orientações de retenção de dados e segurança da ferramenta antes de habilitá-la em um programa.

Combine chamadas programáticas com a busca de ferramentas

A busca de ferramentas é executada como uma ferramenta de nível superior da API Responses e não pode ser chamada de dentro do código JavaScript gerado. Ferramentas de função, personalizadas e MCP com defer_loading: true não ficam disponíveis para o programa de imediato. Depois que o modelo carrega uma ferramenta correspondente à busca, um programa iniciado posteriormente pode chamá-la por meio de tools.* se o campo allowed_callers dela incluir "programmatic". Um programa em execução não pode acionar a busca de ferramentas. Por isso, o modelo precisa carregar essas ferramentas antes de iniciar um programa que dependa delas.

Oriente a escolha quando os dois modos estiverem disponíveis

Quando seu aplicativo permitir que o modelo chame uma função diretamente ou por meio de um programa, associe cada modo a uma etapa específica do fluxo de trabalho. Instruções genéricas como “use a chamada programática de ferramentas com eficiência” não deixam claro em quais etapas usar cada modo. Por exemplo:

<tool_orchestration>
Use a chamada programática de ferramentas na etapa [bounded stage]. Use apenas [eligible tools].
Execute chamadas independentes em paralelo quando for seguro. Use apenas os campos de entrada
e saída documentados das ferramentas.

Processe e reduza os resultados intermediários. Em seguida, retorne o resultado exatamente no formato
[program result shape], incluindo as evidências necessárias para a resposta final.

Pare assim que a condição [condition] for satisfeita. Em caso de falha transitória, tente novamente
no máximo [R] vezes. Não repita chamadas concluídas nem execute ações com efeitos colaterais.
Se ainda faltar algum resultado obrigatório, retorne uma indicação de falha clara e estruturada.

Use chamadas diretas de ferramentas para [semantic judgment, approval, or final validation].
</tool_orchestration>

Veja um exemplo de como usar esse modelo de instruções:

<tool_orchestration>
Use a chamada programática de ferramentas para comparar o estoque de sku_123 com a demanda desse item.
Use apenas get_inventory e get_demand. Execute as duas chamadas em paralelo. Use apenas os campos
de entrada e saída documentados das ferramentas.

Processe e reduza os resultados intermediários. Em seguida, retorne exatamente um objeto JSON
com os campos sku, available_units, requested_units e shortage_units. Calcule shortage_units
como max(requested_units - available_units, 0). Inclua available_units e requested_units
para mostrar os valores usados no cálculo.

Pare assim que os resultados das duas ferramentas contiverem os campos obrigatórios. Em caso
de falha transitória, faça no máximo 1 nova tentativa. Não repita chamadas concluídas nem execute
ações com efeitos colaterais. Se ainda faltar algum resultado obrigatório, retorne uma indicação
de falha clara e estruturada.

Use chamadas diretas de ferramentas somente para obter aprovação antes de qualquer ação que altere o estoque.
</tool_orchestration>

Em fluxos de trabalho que exigem os dois modos, defina um único ponto de transição e evite alternar entre os modos ou repetir trabalho. Se houver uma alternativa segura em caso de falha, defina-a uma única vez e limite o número de novas tentativas.

Entenda os itens de resposta de um programa

Cada chamada à API continua retornando o objeto de resposta padrão da API Responses. A chamada programática de ferramentas não introduz um formato de resposta separado. Quando o modelo usa esse recurso, o array output da resposta pode conter:

  • Um item program com o código JavaScript gerado, um call_id e um identificador opaco (fingerprint) usado para retomar ou reproduzir a execução do programa.
  • Um item function_call que representa uma chamada feita pelo programa. Esse item tem seu próprio call_id, que o aplicativo usa para devolver o resultado da função. O valor de caller.caller_id corresponde ao call_id do programa.
  • Um item program_output com o resultado final e o status do programa. Seu call_id corresponde ao call_id do programa, e seu status é completed ou incomplete.

Esses itens aparecem separadamente no nível superior de response.output. O campo caller registra a relação entre eles durante a execução.

Por exemplo, um programa pode ficar em pausa enquanto seu aplicativo executa get_inventory e get_demand:

Programa e chamadas de função aninhadas
[
  {
    "type": "program",
    "id": "prog_123",
    "call_id": "call_prog_123",
    "code": "const [stock, demand] = await Promise.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) }));",
    "fingerprint": "opaque_replay_state"
  },
  {
    "type": "function_call",
    "id": "fc_123",
    "call_id": "call_inventory_123",
    "name": "get_inventory",
    "arguments": "{\"sku\":\"sku_123\"}",
    "caller": {
      "type": "program",
      "caller_id": "call_prog_123"
    }
  },
  {
    "type": "function_call",
    "id": "fc_456",
    "call_id": "call_demand_123",
    "name": "get_demand",
    "arguments": "{\"sku\":\"sku_123\"}",
    "caller": {
      "type": "program",
      "caller_id": "call_prog_123"
    }
  }
]

Esses exemplos mostram apenas os itens relevantes de response.output e omitem o restante do objeto padrão da API Responses. Depois que o aplicativo devolver os resultados das chamadas de função aninhadas, uma resposta posterior poderá conter o item program_output completo:

Saída do programa
{
  "type": "program_output",
  "id": "prog_out_123",
  "call_id": "call_prog_123",
  "result": "{\"sku\":\"sku_123\",\"available_units\":42,\"requested_units\":31,\"shortage_units\":0}",
  "status": "completed"
}

A string JSON em program_output.result segue o formato de resultado que você definiu nas instruções do programa. O item program_output que contém essa string segue o contrato da API mostrado acima. São contratos distintos. O item message final pode chegar junto com a saída do programa ou em uma resposta posterior. Continue até receber essa mensagem.

A OpenAI executa o código JavaScript gerado pelo modelo no ambiente hospedado. Seu aplicativo executa as chamadas de função retornadas que cabem ao cliente. Ele não executa o código JavaScript gerado.

Devolva o resultado da função em um item function_call_output. Copie caller da chamada de função sem alterar seu valor. O serviço usa esse valor para retomar o programa correto.

Continue após chamadas de função executadas pelo cliente

Um programa pode pausar várias vezes ao chamar ferramentas executadas pelo cliente. Continue até que a resposta contenha uma mensagem final do assistente:

  1. Envie a solicitação com a ferramenta hospedada e as funções que permitem chamadas programáticas.
  2. Execute todas as chamadas de função retornadas que cabem ao cliente.
  3. Devolva o resultado de cada função com os valores originais de call_id e caller.
  4. Se a resposta estiver incompleta, trate essa situação antes de continuar.
  5. Se a resposta não contiver itens function_call pendentes nem um item message final, continue a partir dessa resposta. Com store: false, reenvie os itens de saída. Se a resposta estiver armazenada, use previous_response_id.
  6. Pare quando a resposta contiver um item message final. Leia response.output_text ou o conteúdo de recusa da mensagem.

O exemplo a seguir usa store: false, preserva todos os itens de resposta e devolve ao programa o resultado de cada função:

Execute um ciclo de chamadas programáticas de ferramentas
import json

from openai import OpenAI

client = OpenAI()
model = "gpt-6-astra"


def get_inventory(sku):
    return {"sku": sku, "available_units": 42}


def get_demand(sku):
    return {"sku": sku, "requested_units": 31}


implementations = {
    "get_inventory": get_inventory,
    "get_demand": get_demand,
}

tools = [
    {
        "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"],
            "additionalProperties": False,
        },
        "output_schema": {
            "type": "object",
            "properties": {
                "sku": {"type": "string"},
                "available_units": {"type": "number"},
            },
            "required": ["sku", "available_units"],
            "additionalProperties": False,
        },
        "allowed_callers": ["programmatic"],
    },
    {
        "type": "function",
        "name": "get_demand",
        "description": "Return an object with sku (string) and requested_units (number).",
        "parameters": {
            "type": "object",
            "properties": {"sku": {"type": "string"}},
            "required": ["sku"],
            "additionalProperties": False,
        },
        "output_schema": {
            "type": "object",
            "properties": {
                "sku": {"type": "string"},
                "requested_units": {"type": "number"},
            },
            "required": ["sku", "requested_units"],
            "additionalProperties": False,
        },
        "allowed_callers": ["programmatic"],
    },
    {"type": "programmatic_tool_calling"},
]

input_items = [
    {
        "role": "user",
        "content": "Compare inventory with demand for sku_123.",
    }
]

while True:
    response = client.responses.create(
        model=model,
        store=False,
        input=input_items,
        tools=tools,
    )

    if response.status != "completed":
        raise RuntimeError(f"Response ended with status {response.status}")

    # Preserve every output item, including program and reasoning items.
    input_items.extend(item.model_dump(exclude_none=True) for item in response.output)

    calls = [item for item in response.output if item.type == "function_call"]
    if not calls:
        message = next(
            (item for item in response.output if item.type == "message"), None
        )
        if message:
            refusal = next(
                (part.refusal for part in message.content if part.type == "refusal"),
                "",
            )
            print(response.output_text or refusal)
            break
        continue

    for call in calls:
        run = implementations.get(call.name)
        if run is None:
            raise ValueError(f"Unknown tool: {call.name}")

        result = run(**json.loads(call.arguments))
        input_items.append(
            {
                "type": "function_call_output",
                "call_id": call.call_id,
                "output": json.dumps(result),
                # Preserve caller so the runtime can resume the correct program.
                "caller": call.caller.model_dump() if call.caller else None,
            }
        )

Quando você armazena as respostas, pode continuar a partir de previous_response_id sem reenviar todos os itens das respostas anteriores. Envie os novos itens function_call_output como a próxima entrada. Com store: false, reenvie a sequência completa na ordem original, incluindo todos os itens program, de raciocínio, de chamada de função, de saída de chamada de função e program_output.

Em solicitações sem estado a modelos de raciocínio, reenvie todos os itens de raciocínio retornados. Por padrão, cada item inclui encrypted_content. Consulte o guia sobre estado da conversa para conhecer o padrão geral de solicitações sem estado.

Projete ferramentas para uso em programas

  • Retorne dados estruturados e compactos que o código JavaScript possa examinar sem precisar interpretar texto corrido.
  • Use output_schema para definir os campos e tipos que cada ferramenta deve retornar e documente o comportamento em caso de erro. Se o formato do retorno não for conhecido de antemão, permita apenas chamadas diretas à ferramenta para que o modelo possa examinar o resultado.
  • Especifique o formato exato do resultado do programa e as evidências necessárias. Se o programa não conseguir produzir um resultado válido, retorne uma indicação de falha clara e estruturada.
  • Sempre que possível, torne as chamadas de função idempotentes. Uma nova tentativa ou a repetição da execução não deve repetir um efeito colateral inseguro.
  • Verifique os argumentos e as permissões de cada chamada no aplicativo, mesmo quando a chamada vier de um programa hospedado.
  • Dê às ferramentas nomes e descrições específicos para que o modelo possa combiná-las corretamente.
  • Exija aprovação no aplicativo antes de ações de alto impacto, independentemente de quem fizer a chamada.

Avalie a chamada programática de ferramentas

A chamada programática de ferramentas pode reduzir o volume de resultados intermediários das ferramentas incluídos no contexto do modelo, mas o efeito depende da tarefa e das respostas das ferramentas. Comece com chamadas diretas como referência e compare as duas abordagens em tarefas representativas.

Antes de medir a eficiência, defina o nível de qualidade exigido para a resposta final e as evidências necessárias. Ao avaliar o uso de tokens e as chamadas de ferramentas, verifique também se a resposta está correta e completa e se inclui as evidências necessárias. Deixe explícitas as perdas de qualidade que você aceita.

Avalie os seguintes aspectos:

  • Se a resposta final está correta e completa e inclui as evidências necessárias.
  • Número de tokens de entrada, total de tokens, latência de ponta a ponta e custo.
  • Número de turnos do modelo, chamadas de ferramentas e novas tentativas, além do comportamento durante a recuperação de falhas.
  • Resultados de segurança, especialmente quanto a efeitos colaterais e requisitos de aprovação.
  • Se o modo de chamada usado correspondeu ao previsto para aquela etapa do fluxo de trabalho.

API de Agentes

Na API de Agentes, a chamada programática de ferramentas é executada no harness do agente gerenciado pela OpenAI e vem habilitada por padrão. O harness fornece ao agente uma ferramenta exec e disponibiliza as ferramentas que o agente já tem para uso no código JavaScript gerado. Você não precisa criar programas de linha de comando para chamar essas ferramentas nem instalá-las no sandbox.

Para desabilitar a chamada programática de ferramentas, inclua esta entrada em agent.tools:

{
  "type": "programmatic_tool_calling",
  "enabled": false
}

Se você omitir a entrada ou o campo enabled, a chamada programática de ferramentas continuará habilitada. Uma entrada que especifica apenas o tipo, { "type": "programmatic_tool_calling" }, também mantém o recurso habilitado. A configuração de allowed_callers e o ciclo de continuação descritos acima se aplicam à integração com a API Responses.

A chamada programática de ferramentas também funciona em sessões apenas de conversa, com environment.type definido como none. O Bash, os servidores MCP executores e outras ferramentas que rodam em um sandbox continuam exigindo um ambiente de execução.

Coordenar uma ferramenta por meio de JavaScript não muda o local de execução dela. Uma chamada de shell executa comandos no sandbox. O próprio ambiente JavaScript não inicia processos do sistema. Os servidores MCP executores continuam usando o sandbox, e as ferramentas de função continuam chamando o servidor do aplicativo. O agente processa os resultados dessas ferramentas antes de decidir o que incluir no contexto do modelo.

Use as orientações acima sobre a escolha do modo de chamada para definir quais etapas do fluxo de trabalho devem usar código. Para configurar a API de Agentes e tratar as chamadas, siga os guias de funções e conexões MCP.

Guias relacionados

  • Use a chamada de função para definir funções executadas pelo cliente.
  • Use a busca de ferramentas para adiar o carregamento de definições extensas de ferramentas até que o modelo precise delas.
  • Use o estado da conversa para dar continuidade a solicitações da API Responses com respostas armazenadas ou sem estado.
  • Consulte os controles de dados antes de escolher um modo de armazenamento.