Die Architektur des Funktionsaufrufs in der Responses API
Auf dieser Seite
Aktualisiert am 2. November 2026 basierend auf der OpenAI-Dokumentation: Das Tool Code Interpreter erfordert nun einen
container-Parameter (in allen Beispielen hinzugefügt), Eingabetexte verwenden den Typinput_text, und die Websuche nutzt das Toolweb_search(web_search_previewist nun ein veraltetes Tool ohne Domänenfilter). Generierte Dateien werden über die Funktionenfichiers_generesundtelechargeraus Lektion 10 abgerufen. Quellen: Code Interpreter · Websuche.
Die Architektur des Funktionsaufrufs in der Responses API
Der Funktionsaufruf ist der Kernmechanismus, der es OpenAI-Modellen ermöglicht, mit der Außenwelt zu interagieren. In der Responses API wurde dieser Mechanismus neu gestaltet, um robuster, vorhersehbarer und nativ integriert mit integrierten Tools wie Websuche und Code Interpreter zu sein.
Das fundamentale Prinzip
Das Modell führt niemals Aktionen direkt aus. Es emittiert strukturierte Absichten, die Ihr Code abfängt und ausführt. So formuliert klingt dies nach einer technischen Einschränkung; in der Realität ist es jedoch die Designentscheidung, die alles andere erst möglich macht.
Betrachten Sie die Alternative. Wenn das Modell Aktionen selbst ausführen würde, müssten Sie Ihre Datenbankzugangsdaten, API-Schlüssel und Schreibrechte übergeben – und Sie hätten keinen Punkt, an dem Sie etwas verifizieren könnten. Durch die Entkopplung durchläuft jede Absicht Ihren Code: Sie validieren Argumente, erzwingen Geschäftsregeln und verweigern die Ausführung bei Bedarf. Das Modell schlägt vor, Ihr Code entscheidet, und diese Grenze ist es, die es Ihnen ermöglicht, den Funktionsaufruf in die Produktion zu bringen, ohne die Kontrolle zu verlieren.
from openai import OpenAI
client = OpenAI()
# Deklaration eines benutzerdefinierten Tools
tools = [{
"type": "function",
"name": "rechercher_client",
"description": "Sucht einen Kunden im CRM nach Name oder E-Mail",
"parameters": {
"type": "object",
"properties": {
"terme": {
"type": "string",
"description": "Kundenname, E-Mail oder ID"
},
"champ": {
"type": "string",
"enum": ["nom", "email", "id"],
"description": "Suchfeld"
}
},
"required": ["terme"]
}
}]
response = client.responses.create(
model="gpt-5.6-terra",
input="Finden Sie den Kunden Jean Dupont",
tools=tools
)
Anatomie einer Antwort
Eine Antwort enthält weder nur Text noch Tool-Aufrufe: output ist eine heterogene Liste, die beides mischen kann. Die Gewohnheit, ab der ersten Zeile Ihres Codes zu iterieren über diese Liste statt output[0] zu lesen, ist entscheidend. Ein Modell, das seine Überlegungen vor dem Aufruf einer Funktion darlegt, erzeugt genau diesen Fall, und Code, der das erste Element liest, wird am ersten Tag, an dem er Kommentare hinzufügt, brechen.
for item in response.output:
if item.type == "function_call":
print(f"Call ID : {item.call_id}")
print(f"Function : {item.name}")
print(f"Args : {item.arguments}")
Die call_id ist essenziell: Sie verknüpft den Aufruf mit seinem Ergebnis, wenn Sie die Antwort an das Modell zurücksenden. Bei einem einzelnen Aufruf fällt sie kaum auf; bei drei parallelen Aufrufen ist sie das einzige Mittel, um zu verhindern, dass Sie das Wetter in Lyon der Anfrage über Marseille zuordnen. Senden Sie das Ergebnis stets mit der call_id zurück, die Sie erhalten haben, niemals mit einer ID, die Sie selbst neu konstruieren.
Der vollständige Zyklus
Dieser vierstufige Zyklus ist invariant: Er gilt für eine Funktion oder zwanzig, für einen einfachen Aufruf oder einen Agenten, der zehn Tools hintereinander schaltet. Alle Komplexität, die Sie später antreffen – Parallelität, Fehler, Fallbacks – besteht darin, diesen Zyklus zu instrumentieren, niemals ihn zu ersetzen.
import json
# 1. Erster Aufruf mit deklarierten Tools
response = client.responses.create(
model="gpt-5.6-terra",
input="Was ist das Guthaben für den Kunden [email protected]?",
tools=tools
)
# 2. Erkennung und Ausführung von Funktionsaufrufen
resultats = []
for item in response.output:
if item.type == "function_call":
if item.name == "rechercher_client":
args = json.loads(item.arguments)
resultat = votre_crm.rechercher(args["terme"])
resultats.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(resultat)
})
# 3. Rücksendung der Ergebnisse an das Modell
response_finale = client.responses.create(
model="gpt-5.6-terra",
input=response.output + resultats,
tools=tools
)
# 4. Das Modell formuliert seine natürliche Antwort
print(response_finale.output_text)
Wesentliche Unterschiede zu Chat Completions
Die Responses API bringt mehrere architektonische Verbesserungen mit sich.
Nativer Umgang mit integrierten Tools
Integrierte Tools werden genau wie Ihre Funktionen deklariert, werden aber auf der Seite von OpenAI ausgeführt. Die praktische Konsequenz ist angenehm: Sie schreiben dafür keinen Schleifen. Das Modell ruft auf, erhält das Ergebnis und fährt fort, alles in einer einzigen Rückreise. Die oben beschriebene Schleife betrifft nur Ihre Funktionen – die auf Ihrem Gerät laufen.
# Mischen von integrierten und benutzerdefinierten Tools
tools = [
{"type": "web_search"},
{"type": "code_interpreter", "container": {"type": "auto"}},
{
"type": "function",
"name": "ma_fonction",
"description": "Meine benutzerdefinierte Funktion",
"parameters": {"type": "object", "properties": {}}
}
]
Stabile Aufruf-Identifikatoren
Jeder Funktionsaufruf erhält eine eindeutige call_id, die es Ihnen ermöglicht, genau zu verfolgen, welchem Aufruf welches Ergebnis entspricht, selbst bei parallelen Aufrufen.
Vereinfachter Fluss
Es besteht keine Notwendigkeit, die Rollen assistant und tool in Nachrichten manuell zu verwalten. Das Feld input akzeptiert direkt die Verkettung vorheriger Ausgaben mit Funktionsergebnissen.
Wann ruft das Modell eine Funktion auf?
Das Modell entscheidet sich für einen Funktionsaufruf, wenn die Benutzeranfrage Informationen erfordert, die es nicht besitzt, wenn die Beschreibung der Funktion dem identifizierten Bedarf entspricht und wenn die erforderlichen Parameter aus dem Kontext abgeleitet werden können.
Drei Bedingungen müssen daher gleichzeitig erfüllt sein, und das ist nützlich für die Fehlerbehebung: Wenn eine Funktion nicht aufgerufen wird, obwohl sie es sollte, liegt die Ursache fast immer bei der zweiten – eine Beschreibung, die nicht abdeckt, wie der Benutzer seine Anfrage formuliert hat. Der Parameter tool_choice ermöglicht es Ihnen, das Verhalten zu erzwingen, wenn die Beschreibung nicht ausreicht:
# Das Modell entscheidet selbst
tool_choice = "auto"
# Erzwingung eines Aufrufs einer spezifischen Funktion
tool_choice = {"type": "function", "name": "rechercher_client"}
# Verbot aller Funktionsaufrufe
tool_choice = "none"
# Anforderung mindestens eines Aufrufs ohne Spezifikation
tool_choice = "required"
Kernaussagen
- Der Funktionsaufruf ist ein Protokoll für Absichten, kein Ausführungsprotokoll
- Der Zyklus aus Aufruf, Ausführung und Rückgabe ist das fundamentale Muster
- Integrierte und benutzerdefinierte Tools koexistieren im selben
tools-Array call_idgewährleistet die Nachverfolgbarkeit für jeden Aufruftool_choiceermöglicht eine feine Steuerung des Modellverhaltens