Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Mit programmgesteuerten Toolaufrufen kann ein Modell Code verwenden, um Tools während einer Anfrage an die Responses API zu koordinieren. Anstatt für jeden Toolaufruf einen separaten Modellschritt zu erfordern, kann das Modell ein Programm generieren, das Tools aufruft und deren Ergebnisse verarbeitet. Das Programm kann Vorgänge wie Verzweigung oder Iteration ausführen.
In diesem Artikel wird erläutert, wann programmgesteuerte Toolaufrufe nützlich sind und wie sie sich von Funktionsaufrufen, parallelen Toolaufrufen und Der Toolsuche unterscheiden.
Überlegungen zur Verfügbarkeit
Vergewissern Sie sich vor der Implementierung von programmgesteuerten Toolaufrufen, dass Ihre Azure OpenAI-Modellbereitstellung und SDK-Version das Feature unterstützen. Gehen Sie nicht davon aus, dass die Unterstützung für die Responses API auch bedeutet, dass programmgesteuerte Toolaufrufe unterstützt werden.
Informationen zum Einrichten von Endpunkten und zur Authentifizierung finden Sie unter Verwenden der Azure OpenAI Responses API.
Programmgesteuertes Aufrufen von Tools und Funktionen
Bei standardmäßigen Funktionsaufrufen nimmt Ihre Anwendung in der Regel an jedem Toolaufrufschritt teil:
Modell -> Toolaufruf -> Anwendung führt Tool aus -> Modell -> nächster Toolaufruf -> Anwendung führt Tool aus -> Modell
Mit programmgesteuertem Aufrufen von Tools kann das Modell Code generieren, der mehrere Toolvorgänge koordiniert:
Modell -> generiertes Programm -> Tooloperationen -> Programmergebnis -> Modell
Dieser Ansatz kann die Anzahl der Modell-Interaktionen reduzieren, die für Workflows mit mehreren Tools erforderlich sind.
Diese Abläufe veranschaulichen den konzeptionellen Unterschied bei der Orchestrierung. Sie geben nicht an, welche Vorgänge Ihre Anwendung oder der Dienst ausführt.
Beispiel: Lagerbestand mit der Nachfrage vergleichen
In diesem Python Beispiel werden zwei anwendungsdefinierte Funktionen verfügbar gemacht, die Beispielinventar- und Bedarfsdaten zurückgeben. Das Modell verwendet programmgesteuerte Toolaufrufe, um die Ergebnisse zu vergleichen. Ihre Anwendung führt die Funktionen aus und gibt deren Ergebnisse zurück, damit die Laufzeit das generierte Programm fortsetzen kann.
Die Codeblöcke bilden ein Skript. Kombinieren Sie sie in der angezeigten Reihenfolge.
Azure OpenAI-Client
Verwenden Sie eine Azure OpenAI-Bereitstellung, die programmgesteuertes Aufrufen von Tools unterstützt, und eine OpenAI SDK-Version, die output_schema, allowed_callers und Informationen zu Aufrufern enthält. Installieren Sie die Pakete openai und azure-identity in Ihrer Python-Umgebung:
pip install --upgrade openai azure-identity
Konfigurieren Sie die Microsoft Entra ID-Authentifizierung, wie unter Verwenden der Azure OpenAI Responses API beschrieben. Ihre Identität benötigt die Berechtigung, Ihre Azure OpenAI-Bereitstellung aufzurufen.
Ersetzen Sie YOUR-RESOURCE-NAME durch Ihren Ressourcennamen. Der model Wert weiter unten im Beispiel ist Ihr Azure Bereitstellungsname, nicht ein Modellkatalogbezeichner.
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)
Anwendungsdefinierte Funktionen
Die Funktionen geben feste Beispieldaten zurück: 42 verfügbare Einheiten und 31 angeforderte Einheiten für die angegebene SKU. Ersetzen Sie ihre Implementierungen durch Ihre Bestands- und Bedarfsdatenquellen in Ihrer Anwendung.
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,
}
Tooldefinitionen
Jede Funktion deklariert ein Eingabeschema und eine output_schema-Beschreibung des JSON-Ergebnisses. Durch das Festlegen von allowed_callers auf ["programmatic"] wird die Funktion für generierte Programme verfügbar gemacht – anstatt für direkte Modellaufrufe.
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"],
}
]
Fügen Sie der gleichen Liste die Nachfragefunktion und die programmgesteuerte Toolaufruffunktion hinzu:
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"},
])
Toolergebnisse und Anruferinformationen
Die Anwendung ruft Funktionsaufrufe anhand des Namens auf und serialisiert jedes Ergebnis. Bewahren Sie die Informationen des Aufrufs caller auf, damit die Laufzeit die Ausführung des richtigen Programms fortsetzen kann. Unbekannte Toolnamen und ungültige Argumente lösen Fehler aus, anstatt erfundene Ergebnisse zurückzugeben.
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
Fortsetzung der Antwort
Ersetzen Sie YOUR-MODEL-DEPLOYMENT durch den Namen Ihrer unterstützten Azure OpenAI-Bereitstellung.
Mit store=False führt die Anwendung die Unterhaltung weiter. Bewahren Sie alle Ausgabeelemente, einschließlich Programm- und Begründungselemente, auf, bevor Sie Toolergebnisse hinzufügen. Die Schleife stoppt bei einer endgültigen Antwort oder einer Ablehnung und löst einen Fehler aus, wenn eine Antwort fehlschlägt oder der Anforderungsgrenzwert erreicht ist.
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")
Die endgültige Antwort sollte erklären, dass der Bestand die Nachfrage abdeckt: 42 verfügbare Einheiten minus 31 angeforderte Einheiten, es bleiben 11 Einheiten übrig. Der Wortlaut kann variieren. Stattdessen wird eine Ablehnung gedruckt, wenn das Modell die Anfrage ablehnt.
Die Anwendung führt die Bestands- und Bedarfsfunktionen aus, während das generierte Programm deren Verwendung koordiniert und die Ergebnisse verarbeitet.
Wann programmgesteuerte Toolaufrufe verwendet werden sollten
Erwägen Sie programmgesteuerte Toolaufrufe, wenn eine Aufgabe Folgendes erfordert:
- Erfordert mehrere verwandte Toolaufrufe.
- Enthält bedingte Logik.
- Erfordert Iteration über Toolergebnisse.
- Führt vor der Erstellung einer Antwort eine Zwischenverarbeitung von Daten durch.
- Wenn andernfalls wiederholte Modellschritte erforderlich wären, um Tools zu koordinieren.
Bei einfachen Workflows, die eine oder zwei unabhängige Funktionen umfassen, ist die Implementierung von Standardfunktionsaufrufen möglicherweise einfacher.
Programmgesteuertes Aufrufen von Tools und parallele Toolaufrufe
Parallele Toolaufrufe und programmgesteuerte Toolaufrufe erfüllen unterschiedliche Orchestrierungsanforderungen.
Verwenden Sie parallele Toolaufrufe , wenn mehrere unabhängige Vorgänge gleichzeitig ausgeführt werden können. Rufen Sie beispielsweise Wetter für fünf verschiedene Standorte ab.
Verwenden Sie programmgesteuerte Toolaufrufe, wenn bei Toolvorgängen Koordination, Zwischenberechnung, Verzweigung oder Iteration erforderlich sind. Rufen Sie beispielsweise die Bestellungen eines Kunden ab, wählen Sie Bestellungen aus, die einer Bedingung entsprechen, und fragen Sie Versandinformationen für diese Bestellungen ab.
Programmatische Toolaufrufe und Toolsuche
Die Toolsuche steuert, welche Tooldefinitionen in den Kontext des Modells geladen werden.
Programmgesteuertes Aufrufen von Tools steuert, wie das Modell den Einsatz von Tools orchestriert, nachdem sie verfügbar sind.
Der Unterschied besteht zwischen tool discovery und tool orchestration. Ihr konzeptioneller Zusammenhang lässt nicht erkennen, ob Ihre Implementierung die Nutzung beider Funktionen innerhalb derselben Anfrage unterstützt.
Sicherheitsüberlegungen
Behandeln Sie generierte Programme als nicht vertrauenswürdigen Code.
Beim Bereitstellen von Tools:
- Befolgen Sie das Prinzip der geringsten Privilegien.
- Überprüfen Sie die Tool-Argumente.
- Beschränken Sie den Zugriff auf vertrauliche Vorgänge.
- Authentifizieren und autorisieren Sie Vorgänge unabhängig von der Modellausgabe.
- Protokollieren Sie die Toolausführung zur Auditierung und Diagnose, ohne geheime oder unnötige vertrauliche Daten aufzuzeichnen.
- Vermeiden Sie das Verfügbarmachen unnötiger Tools oder Daten.
Betrachten Sie modellgenerierten Code nicht als Autorisierungsgrenze.