Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La invocación programática de herramientas permite que un modelo use código para orquestar herramientas durante una solicitud de Responses API. En lugar de requerir un turno de modelo independiente para cada invocación de herramienta, el modelo puede generar un programa que llame a herramientas y procese sus resultados. El programa puede realizar operaciones como la bifurcación o la iteración.
En este artículo se explica cuándo la llamada a herramientas mediante programación es útil y cómo difiere de las llamadas a funciones, las llamadas a herramientas paralelas y la búsqueda de herramientas.
Consideraciones de disponibilidad
Antes de implementar llamadas a herramientas mediante programación, confirme que la implementación del modelo de Azure OpenAI y la versión del SDK de Azure admiten la característica. No suponga que la compatibilidad con la API de respuestas también establece compatibilidad con las llamadas a herramientas mediante programación.
Para la configuración del punto de conexión y la autenticación, consulte Uso de la API de respuestas de OpenAI de Azure.
Llamada a la herramienta mediante programación y llamada a funciones
Con las llamadas a funciones estándar, la aplicación normalmente participa en cada paso de llamada a herramientas:
Model -> tool call -> application executes tool -> model -> next tool call -> application executes tool -> model
Con la invocación programática de herramientas, el modelo puede generar código que organice varias operaciones de herramientas:
Modelo -> programa -> operaciones de herramientas -> resultado del programa -> modelo
Este enfoque puede reducir el número de turnos de modelo necesarios para los flujos de trabajo que implican varias herramientas.
Estos flujos ilustran la diferencia conceptual en la orquestación. No especifican qué operaciones ejecuta tu aplicación o el servicio.
Ejemplo: Comparar inventario con la demanda
En este ejemplo Python se exponen dos funciones definidas por la aplicación que devuelven datos de demanda y inventario de ejemplo. El modelo usa llamada programática a herramientas para comparar los resultados. La aplicación ejecuta las funciones y devuelve sus resultados para que el tiempo de ejecución pueda reanudar el programa generado.
Los bloques de código forman un único script. Combínelos en el orden que se muestra.
cliente de Azure OpenAI
Use una implementación de Azure OpenAI que admita llamadas a herramientas mediante programación y una versión del SDK de OpenAI que incluya output_schema, allowed_callers e información del llamador. Instale los paquetes openai y azure-identity en el entorno de Python:
pip install --upgrade openai azure-identity
Configure la autenticación de Microsoft Entra ID tal como se describe en Uso de la API de respuestas de OpenAI de Azure. La identidad necesita permiso para llamar a la implementación de Azure OpenAI.
Reemplace YOUR-RESOURCE-NAME por el nombre del recurso. El model valor más adelante en el ejemplo es el nombre de la implementación de Azure, no un identificador de catálogo de modelos.
import json
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import OpenAI
# Use the Azure OpenAI v1 endpoint and Microsoft Entra ID authentication.
endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
credential, "https://cognitiveservices.azure.com/.default"
)
openai = OpenAI(base_url=endpoint, api_key=token_provider)
Funciones definidas por la aplicación
Las funciones devuelven datos fijos de ejemplo: 42 unidades disponibles y 31 unidades solicitadas para la SKU especificada. Reemplace sus implementaciones por los orígenes de datos de inventario y demanda en su aplicación.
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,
}
Definiciones de herramientas
Cada función declara un esquema de entrada y un output_schema que describe el resultado JSON. Establecer allowed_callers en ["programmatic"] hace que la función esté disponible para programas generados en lugar de llamadas directas al modelo.
tools = [
{
"type": "function",
"name": "get_inventory",
"description": "Return the SKU and available inventory units.",
"strict": True,
"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"],
}
]
Agregue la función de demanda y la funcionalidad de llamada de la herramienta mediante programación a la misma lista:
tools.extend([
{
"type": "function",
"name": "get_demand",
"description": "Return the SKU and requested demand units.",
"strict": True,
"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"},
])
Resultados de la herramienta e información del llamante
La aplicación despacha llamadas a funciones por nombre y serializa cada resultado. Conserve la información de la llamada caller para que el tiempo de ejecución pueda reanudar el programa correcto. Los nombres de herramientas desconocidos y los argumentos no válidos generan errores en lugar de devolver resultados fabricados.
def run_tool(call):
run = implementations.get(call.name)
if run is None:
raise ValueError(f"Unknown tool: {call.name}")
arguments = json.loads(call.arguments)
if (
not isinstance(arguments, dict)
or set(arguments) != {"sku"}
or not isinstance(arguments["sku"], str)
):
raise ValueError(f"Invalid arguments for tool: {call.name}")
result = run(**arguments)
output = {
"type": "function_call_output",
"call_id": call.call_id,
"output": json.dumps(result),
}
if call.caller is not None:
output["caller"] = call.caller.model_dump(exclude_none=True)
return output
Continuación de la respuesta
Reemplace YOUR-MODEL-DEPLOYMENT por el nombre de la implementación compatible de Azure OpenAI.
Con store=False, la aplicación lleva la conversación hacia delante. Conserve todos los elementos de salida, incluidos los elementos del programa y de razonamiento, antes de agregar resultados de la herramienta. El bucle se detiene en una respuesta final o rechazo y genera un error si una respuesta falla o se alcanza el límite de solicitudes.
input_items = [
{"role": "user", "content": "Compare inventory with demand for sku_123."}
]
MAX_REQUESTS = 10
for _ in range(MAX_REQUESTS):
response = openai.responses.create(
model="YOUR-MODEL-DEPLOYMENT",
store=False, input=input_items, tools=tools,
)
if response.status != "completed":
raise RuntimeError(f"Response ended with status {response.status}")
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 calls:
input_items.extend(run_tool(call) for call in calls)
continue
if response.output_text:
print(response.output_text)
break
refusals = [
part.refusal for item in response.output if item.type == "message"
for part in item.content if part.type == "refusal"
]
if refusals:
print("\n".join(refusals))
break
else:
raise RuntimeError("Programmatic tool calling exceeded the request limit")
La respuesta final debe explicar que el inventario cubre la demanda: 42 unidades disponibles menos 31 unidades solicitadas deja 11 unidades. La redacción puede variar. En su lugar, se imprime una negativa si el modelo rechaza la solicitud.
La aplicación ejecuta las funciones de inventario y demanda, mientras que el programa generado coordina su uso y procesa los resultados.
Cuándo usar llamadas a herramientas mediante programación
Considere la invocación programática de herramientas cuando una tarea:
- Requiere varias llamadas a herramientas relacionadas.
- Contiene lógica condicional.
- Requiere iterar sobre los resultados de la herramienta.
- Realiza el procesamiento intermedio de datos antes de generar una respuesta.
- De lo contrario, requeriría turnos de modelo repetidos para coordinar las herramientas.
En el caso de flujos de trabajo simples que implican una o dos funciones independientes, es posible que la llamada a funciones estándar sea más fácil de implementar.
Llamada a herramientas programática y llamada a herramientas paralela
Las llamadas a herramientas paralelas y las llamadas a herramientas mediante programación abordan diferentes necesidades de orquestación.
Utiliza llamada de herramientas en paralelo cuando se pueden ejecutar varias operaciones independientes al mismo tiempo. Por ejemplo, recupere el tiempo de cinco ubicaciones independientes.
Usa la llamada a herramientas mediante programación cuando las operaciones de herramientas requieran coordinación, cálculo intermedio, bifurcación o iteración. Por ejemplo, recupere los pedidos de un cliente, seleccione pedidos que coincidan con una condición y consulte la información de envío de esos pedidos.
Llamada a herramientas y búsqueda programática de herramientas
La búsqueda de herramientas controla qué definiciones de herramienta se cargan en el contexto del modelo.
La llamada programática de herramientas controla cómo el modelo organiza las herramientas después de que estén disponibles.
La distinción es entre el descubrimiento de herramientas y la orquestación de herramientas. Su relación conceptual no establece si la implementación admite el uso de ambas características en la misma solicitud.
Consideraciones de seguridad
Trate los programas generados como código que no es de confianza.
Al mostrar las herramientas:
- Siga el principio de mínimo privilegio.
- Valide los argumentos de la herramienta.
- Restringir el acceso a operaciones confidenciales.
- Autentique y autorice las operaciones independientemente de la salida del modelo.
- Registre la ejecución de la herramienta para auditorías y diagnósticos sin registrar secretos ni datos confidenciales innecesarios.
- Evite exponer herramientas o datos innecesarios.
No se base en el código generado por el modelo como límite de autorización.