Use a busca em ferramentas com a API de Respostas do Azure OpenAI

A pesquisa de ferramentas permite que o modelo pesquise e carregue dinamicamente definições de ferramentas em seu contexto conforme necessário, para que você não precise carregar todas as definições de ferramentas antecipadamente. Essa abordagem pode reduzir o uso e o custo do token. A pesquisa de ferramentas também preserva o cache do modelo injetando ferramentas recém-descobertas no final da janela de contexto. Acesse a pesquisa de ferramentas por meio da ferramenta tool_search na API de Respostas do Azure OpenAI.

Note

A pesquisa de ferramentas é compatível com gpt-5.4 e modelos posteriores. Nos exemplos a seguir, substitua gpt-5.5 pelo nome da implantação do modelo.

A pesquisa de ferramentas na API de Respostas é diferente da pesquisa de ferramentas em uma caixa de ferramentas do Serviço do Foundry Agent. A ferramenta de busca da API Responses posterga as definições de ferramentas que você declara em uma requisição. A ferramenta de pesquisa da Toolbox localiza as ferramentas configuradas em uma Toolbox versionada do Foundry.

Pré-requisitos

  • Uma implantação de modelo Azure OpenAI que dá suporte à pesquisa de ferramentas.

  • Um método de autenticação:

    • Chave de API ou
    • Microsoft Entra ID (recomendado).
  • Instale as bibliotecas de cliente para seu idioma:

    • Python:

      pip install openai azure-identity
      
    • JavaScript:

      npm install openai @azure/identity
      
  • Para solicitações REST, defina AZURE_OPENAI_API_KEY para autenticação de chave de API ou AZURE_OPENAI_AUTH_TOKEN para autenticação Microsoft Entra ID.

Entender como funciona a pesquisa de ferramentas

Para ativar a busca de ferramentas:

  1. Adicione tool_search à tools matriz.
  2. Marque com defer_loading: true as ferramentas que você deseja adiar.

Você pode adiar funções individuais, funções dentro de um namespace e servidores MCP. Quando você adia uma ferramenta, o modelo não carrega sua definição completa no contexto até decidir que precisa da ferramenta. Em seguida, o modelo usa a pesquisa de ferramentas para carregar as ferramentas relevantes antes de as chamar.

Usar namespaces sempre que possível

Você pode usar a pesquisa de ferramentas com funções adiadas, namespaces ou servidores MCP. Use namespaces ou servidores MCP quando possível. Os modelos são treinados principalmente para pesquisar essas superfícies e geralmente fornecem maior economia de token.

Para namespaces, defer_loading aplica-se às funções dentro do namespace, não ao próprio objeto namespace.

No início de uma solicitação, o modelo ainda vê o nome e a descrição de cada superfície pesquisável. Para um namespace ou servidor MCP, o modelo vê apenas o namespace ou o nome do servidor e a descrição. Ele não vê as definições de função individuais até que a pesquisa de ferramentas as carregue. Para uma função adiada de forma individual, o modelo ainda vê o nome e a descrição da função, de modo que a busca de ferramentas adia principalmente o esquema dos parâmetros.

Para obter a maior economia de token, agrupe funções adiadas em namespaces ou servidores MCP. Dê a cada superfície uma descrição clara e de alto nível que resume seu conteúdo. Em seguida, o modelo pode pesquisar e carregar apenas as funções relevantes.

Dica

Mantenha cada namespace com menos de 10 funções para melhorar a eficiência do token e o desempenho do modelo.

A configuração da ferramenta a seguir define um namespace com uma função adiada:

{
  "tools": [
    {
      "type": "namespace",
      "name": "crm",
      "description": "CRM tools for customer lookup and order management.",
      "tools": [
        {
          "type": "function",
          "name": "list_open_orders",
          "description": "List open orders for a customer ID.",
          "defer_loading": true,
          "parameters": {
            "type": "object",
            "properties": {
              "customer_id": { "type": "string" }
            },
            "required": ["customer_id"],
            "additionalProperties": false
          }
        }
      ]
    },
    {
      "type": "tool_search"
    }
  ]
}

Um namespace pode misturar ferramentas adiadas e não adiadas. As ferramentas sem defer_loading: true podem ser chamadas imediatamente. As ferramentas adiadas no mesmo namespace são carregadas por meio da pesquisa de ferramentas.

Escolher um tipo de pesquisa de ferramentas

A busca de ferramentas suporta dois tipos de execução:

  • Pesquisa de ferramentas hospedada: Azure OpenAI pesquisa as ferramentas adiadas que você declara na solicitação e retorna o subconjunto carregado na mesma resposta.
  • Pesquisa de ferramentas executada pelo cliente: o modelo emite um tool_search_call. Seu aplicativo executa a pesquisa e retorna uma correspondência tool_search_output.

Comece com a pesquisa de ferramentas hospedadas quando souber as ferramentas candidatas ao criar a solicitação. Use a pesquisa de ferramentas executada pelo cliente quando a descoberta de ferramentas depende do estado do projeto, do estado do locatário ou de outro sistema que o aplicativo controla.

A pesquisa de ferramentas hospedadas é a opção mais simples quando você conhece o inventário completo de funções, namespaces ou servidores MCP que o modelo pode pesquisar. Declare o inventário, adicione {"type": "tool_search"}e deixe Azure OpenAI decidir quais ferramentas carregar.

Autenticação com o Microsoft Entra ID

O exemplo a seguir define um namespace que contém uma função imediatamente disponível e uma função adiada. O prompt requer a função adiada, portanto, o modelo pesquisa o namespace antes de criar uma chamada de função.

from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)

openai = OpenAI(base_url=endpoint, api_key=token_provider)

crm_namespace = {
    "type": "namespace",
    "name": "crm",
    "description": "CRM tools for customer lookup and order management.",
    "tools": [
        {
            "type": "function",
            "name": "get_customer_profile",
            "description": "Fetch a customer profile by customer ID.",
            "parameters": {
                "type": "object",
                "properties": {"customer_id": {"type": "string"}},
                "required": ["customer_id"],
                "additionalProperties": False,
            },
        },
        {
            "type": "function",
            "name": "list_open_orders",
            "description": "List open orders for a customer ID.",
            "defer_loading": True,
            "parameters": {
                "type": "object",
                "properties": {"customer_id": {"type": "string"}},
                "required": ["customer_id"],
                "additionalProperties": False,
            },
        },
    ],
}

response = openai.responses.create(
    model="gpt-5.5",
    input="List open orders for customer CUST-12345.",
    tools=[crm_namespace, {"type": "tool_search"}],
    parallel_tool_calls=False,
)

print(response.output)

Referência: Referência da API de respostas

Autenticar com uma chave de API

O exemplo de chave de API usa o mesmo namespace e prompt:

import os
from openai import OpenAI

endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
openai = OpenAI(
    base_url=endpoint,
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
)

crm_namespace = {
    "type": "namespace",
    "name": "crm",
    "description": "CRM tools for customer lookup and order management.",
    "tools": [
        {
            "type": "function",
            "name": "get_customer_profile",
            "description": "Fetch a customer profile by customer ID.",
            "parameters": {
                "type": "object",
                "properties": {"customer_id": {"type": "string"}},
                "required": ["customer_id"],
                "additionalProperties": False,
            },
        },
        {
            "type": "function",
            "name": "list_open_orders",
            "description": "List open orders for a customer ID.",
            "defer_loading": True,
            "parameters": {
                "type": "object",
                "properties": {"customer_id": {"type": "string"}},
                "required": ["customer_id"],
                "additionalProperties": False,
            },
        },
    ],
}

response = openai.responses.create(
    model="gpt-5.5",
    input="List open orders for customer CUST-12345.",
    tools=[crm_namespace, {"type": "tool_search"}],
    parallel_tool_calls=False,
)

print(response.output)

Referência: Referência da API de respostas

Quando o modelo precisa de uma ferramenta diferida, a resposta inclui dois itens de saída antes da chamada de função:

  • tool_search_call registra a etapa de pesquisa hospedada.
  • tool_search_output contém o subconjunto carregado que pode ser invocado.

O exemplo a seguir mostra uma resposta de pesquisa de ferramenta hospedada:

[
  {
    "type": "tool_search_call",
    "execution": "server",
    "call_id": null,
    "status": "completed",
    "arguments": {
      "paths": ["crm"]
    }
  },
  {
    "type": "tool_search_output",
    "execution": "server",
    "call_id": null,
    "status": "completed",
    "tools": [
      {
        "type": "namespace",
        "name": "crm",
        "description": "CRM tools for customer lookup and order management.",
        "tools": [
          {
            "type": "function",
            "name": "list_open_orders",
            "description": "List open orders for a customer ID.",
            "defer_loading": true,
            "parameters": {
              "type": "object",
              "properties": {
                "customer_id": { "type": "string" }
              },
              "required": ["customer_id"],
              "additionalProperties": false
            }
          }
        ]
      }
    ]
  },
  {
    "type": "function_call",
    "name": "list_open_orders",
    "namespace": "crm",
    "call_id": "call_abc123",
    "arguments": "{\"customer_id\":\"CUST-12345\"}"
  }
]

No modo hospedado, execution é server e call_id é null.

Para tarefas complexas, o modelo pode carregar vários namespaces ou servidores MCP em um.tool_search_call Por exemplo, se uma tarefa exigir funções de namespaces diferentes, o modelo poderá pesquisar e carregar essas superfícies juntas antes de criar as chamadas de função.

A pesquisa de ferramentas executada pelo cliente fornece ao aplicativo controle total sobre a descoberta de ferramentas. Use-o quando as ferramentas disponíveis dependem de informações que não são práticas para declarar na lista inicial tools .

Configure a ferramenta tool_search com execution: "client" e um schema para os argumentos de busca que sua aplicação espera:

from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)
openai = OpenAI(base_url=endpoint, api_key=token_provider)

first_response = openai.responses.create(
    model="gpt-5.5",
    input="Find the shipping ETA tool first, then use it for order_42.",
    tools=[
        {
            "type": "tool_search",
            "execution": "client",
            "description": "Find project tools needed to continue the task.",
            "parameters": {
                "type": "object",
                "properties": {"goal": {"type": "string"}},
                "required": ["goal"],
                "additionalProperties": False,
            },
        }
    ],
    parallel_tool_calls=False,
)

search_call = next(
    item for item in first_response.output
    if item.type == "tool_search_call"
)

loaded_tools = [
    {
        "type": "function",
        "name": "get_shipping_eta",
        "description": "Look up shipping ETA details for an order.",
        "defer_loading": True,
        "parameters": {
            "type": "object",
            "properties": {"order_id": {"type": "string"}},
            "required": ["order_id"],
            "additionalProperties": False,
        },
    }
]

second_response = openai.responses.create(
    model="gpt-5.5",
    input=[
        *first_response.output,
        {
            "type": "tool_search_output",
            "execution": "client",
            "call_id": search_call.call_id,
            "status": "completed",
            "tools": loaded_tools,
        },
    ],
)

print(second_response.output)

Referência: Referência da API de respostas

Para usar a autenticação de chave de API, substitua a credencial Microsoft Entra por sua chave de API, conforme mostrado no exemplo de chave de API de pesquisa de ferramentas hospedada.

Na primeira rodada, o modelo emite um tool_search_call e para:

[
  {
    "type": "tool_search_call",
    "execution": "client",
    "call_id": "call_abc123",
    "status": "completed",
    "arguments": {
      "goal": "Find the shipping ETA tool for order_42."
    }
  }
]

Seu aplicativo executa a pesquisa e retorna um tool_search_output que contém as ferramentas a serem carregadas:

[
  {
    "type": "tool_search_output",
    "execution": "client",
    "call_id": "call_abc123",
    "status": "completed",
    "tools": [
      {
        "type": "function",
        "name": "get_shipping_eta",
        "description": "Look up shipping ETA details for an order.",
        "defer_loading": true,
        "parameters": {
          "type": "object",
          "properties": {
            "order_id": { "type": "string" }
          },
          "required": ["order_id"],
          "additionalProperties": false
        }
      }
    ]
  }
]

Na próxima interação, a ferramenta carregada pode ser chamada como uma função normal:

[
  {
    "type": "function_call",
    "name": "get_shipping_eta",
    "namespace": "get_shipping_eta",
    "call_id": "call_xyz456",
    "arguments": "{\"order_id\":\"order_42\"}"
  }
]

No modo cliente, execution é client e call_id está definido. Repita o mesmo call_id de tool_search_call no tool_search_output correspondente.

Aplicar padrões de uso avançados

Use os padrões a seguir para melhorar a qualidade da descoberta e controlar como as ferramentas são adicionadas ao contexto.

Mantenha as descrições do namespace claras

Escreva descrições concisas de namespace que descrevem o caso de uso. O modelo usa essa descrição para decidir quando carregar funções do namespace. Coloque detalhes mais avançados nas descrições da função adiada, que são carregadas somente quando necessário.

Entenda o que é carregado

A tool_search_output.tools matriz contém as ferramentas que o modelo carrega dinamicamente. O modelo pode chamar essas ferramentas em turnos posteriores, portanto, o modo cliente não precisa carregar a mesma ferramenta novamente em turnos. As ferramentas que não estão nessa matriz não estão disponíveis para o modelo.

Para desabilitar uma ferramenta carregada, remova-a do tool_search_output item em que você define o conjunto de ferramentas carregado. Alterar o conjunto de ferramentas carregado interrompe o cache do modelo desse ponto em diante.

Usar padrões avançados de injeção

A maioria das integrações declara ferramentas no parâmetro da tools solicitação. A pesquisa de ferramentas executada pelo cliente também dá suporte a padrões avançados em que seu aplicativo retorna ferramentas que não estavam presentes na solicitação original. Valide os esquemas retornados com cuidado e exponha apenas definições de ferramentas confiáveis.

Preservar o cache

Tanto a busca de ferramentas hospedada quanto a executada no cliente carregam ferramentas no final da janela de contexto do modelo. Esse posicionamento preserva o cache do modelo entre solicitações, o que pode reduzir custos e melhorar a velocidade.

Adicionar ferramentas em um ponto específico na entrada

Use um item de entrada additional_tools para tornar ferramentas disponíveis em um ponto específico da conversa. Esse padrão é útil quando seu aplicativo carrega ferramentas fora do fluxo normal de pesquisa de ferramentas ou precisa preservar a ordenação de ferramentas adicionadas durante uma resposta anterior.

Defina role como developer e inclua as ferramentas no array do item tools:

{
  "type": "additional_tools",
  "role": "developer",
  "tools": [
    {
      "type": "function",
      "name": "get_customer",
      "description": "Look up a customer by ID.",
      "parameters": {
        "type": "object",
        "properties": {
          "customer_id": { "type": "string" }
        },
        "required": ["customer_id"],
        "additionalProperties": false
      }
    }
  ]
}

As ferramentas em um additional_tools item ficam disponíveis somente depois que esse item aparece na entrada. Quando você envia manualmente itens de conversa em solicitações posteriores, preserva a posição do item para que o modelo veja as mesmas ferramentas no mesmo ponto da conversa.

Sintoma Causa provável Corrigir
O modelo não pesquisa uma ferramenta adiada. O namespace, o servidor MCP ou a descrição da função não correspondem à tarefa. Reescreva a descrição para indicar a finalidade da superfície e as tarefas que ela dá suporte.
A pesquisa hospedada não carrega uma função esperada. A função não está marcada com defer_loading: true, ou sua superfície pai não está clara. Adicione defer_loading: true e melhore o namespace ou a descrição do servidor MCP.
A pesquisa executada pelo cliente não pode continuar. O tool_search_output.call_id não corresponde ao anterior tool_search_call.call_id. Repita a mesma tag call_id no item de saída.
Uma ferramenta carregada dinamicamente não pode ser chamada. A ferramenta não foi incluída em tool_search_output.tools. Retorne a definição de ferramenta completa e confiável na matriz de saída.
O cacheamento de prompts é interrompido em uma atualização da ferramenta. O conjunto de ferramentas carregado ou um item anterior no contexto foi alterado. Mantenha os itens anteriores estáveis e acrescente as ferramentas recém-carregadas no final do contexto.