Kombinieren Sie Werkzeuge in einem einzigen Aufruf
Auf dieser Seite
Aktualisiert am 2. November 2026 basierend auf der OpenAI-Dokumentation: Das Code-Interpreter-Werkzeug erfordert nun einen
container-Parameter (in allen Beispielen hinzugefügt), Texteingabeteile verwenden den Typinput_text, und die Websuche nutzt das Werkzeugweb_search(web_search_previewist nun ein veraltetes Werkzeug ohne Domänenfilter). Generierte Dateien werden mit den Funktionenfichiers_generesundtelechargeraus Lektion 10 abgerufen. An Dateien angehängte Nachrichten werden mit dem Zweckuser_datahochgeladen, was OpenAI für Modell-Eingaben empfiehlt (Dateieingaben). Quellen: Code Interpreter · Websuche.
Kombination von Werkzeugen in einem einzigen Aufruf
Bisher haben wir jedes Werkzeug isoliert betrachtet. In der Produktion stellen sich selten Fragen, die sich so formulieren lassen. Die Frage „Wie verhalten sich unsere Verkäufe im Vergleich zum Markt?” erfordert das Abrufen einer internen Kennzahl, einer externen Kennzahl und deren anschließenden Vergleich. Drei Werkzeuge, drei Quellen, ein Aufruf.
Was sich ändert, ist, wer die Reihenfolge bestimmt. Sie programmieren die Sequenz nicht: Sie deklarieren die verfügbaren Werkzeuge und beschreiben das erwartete Ergebnis, und das Modell erstellt seinen eigenen Plan. Das ist bequem, aber es ist auch der Punkt, auf den Sie achten müssen – ein impliziter Plan ist ein Plan, den Sie nicht überprüfen können. Der letzte Teil dieser Lektion zeigt, wie Sie die Kontrolle zurückgewinnen können, wenn die Reihenfolge wirklich wichtig ist.
Prinzip der Kombination
Alle Werkzeuge werden im selben tools-Array deklariert, und das ist der gesamte Mechanismus: Es gibt keine Kompositions-API, nur eine Liste verfügbarer Fähigkeiten. Das Modell liest Ihre Anfrage, leitet die erforderlichen Schritte ab und ruft das an, was es für notwendig hält, in der Reihenfolge, die es für sinnvoll erachtet. Ein Werkzeug, das deklariert wurde, aber für die Aufgabe nicht benötigt wird, wird einfach nicht aufgerufen – es kostet nichts außer den wenigen Tokens in seiner Beschreibung.
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.6-terra",
input="Vergleichen Sie unsere Verkaufsprognosen mit Markttrends, "
"und erstellen Sie ein Vergleichsdiagramm.",
tools=[
{"type": "file_search", "vector_store_ids": ["vs_previsions"]},
{"type": "web_search"},
{"type": "code_interpreter", "container": {"type": "auto"}}
]
)
Das Modell wird:
- Interne Prognosen über Dateisuche abrufen
- Markttrends über Websuche abrufen
- Ein Vergleichsdiagramm über den Code-Interpreter generieren
Komplettes Beispiel: Analytischer Assistent
with open("donnees_ventes.csv", "rb") as f:
fichier = client.files.create(file=f, purpose="user_data")
tools = [
# Suche in internen Dokumenten
{
"type": "file_search",
"vector_store_ids": ["vs_rapports", "vs_objectifs"],
"max_num_results": 10
},
# Websuche für Marktkontext
{
"type": "web_search",
"search_context_size": "medium"
},
# Codeausführung für Analyse
{"type": "code_interpreter", "container": {"type": "auto"}},
# Funktion zum Speichern des Berichts
{
"type": "function",
"name": "sauvegarder_rapport",
"description": "Speichern Sie einen Analysebericht im Dokumentsystem",
"parameters": {
"type": "object",
"properties": {
"titre": {"type": "string"},
"contenu": {"type": "string"},
"categorie": {
"type": "string",
"enum": ["analyse", "prevision", "audit", "comparaison"]
},
"tags": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["titre", "contenu", "categorie", "tags"],
"additionalProperties": False
},
"strict": True
}
]
response = client.responses.create(
model="gpt-5.6-terra",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": (
"Basierend auf dieser Verkaufsdatei: "
"1. Analysieren Sie Trends der letzten 12 Monate "
"2. Vergleichen Sie mit unseren Jahreszielen (suchen Sie in den Dokumenten) "
"3. Suchen Sie im Web nach Markttrends "
"4. Generieren Sie ein Vergleichsdiagramm "
"5. Verfassen Sie einen Zusammenfassungsbericht "
"6. Speichern Sie den Bericht"
)},
{"type": "input_file", "file_id": fichier.id}
]
}],
tools=tools,
instructions=(
"Sie sind ein leitender Unternehmensanalyst. "
"Verwenden Sie alle zur Verfügung stehenden Werkzeuge, um "
"eine vollständige, quellenbasierte Analyse zu erstellen."
)
)
Verwaltung des Mehrwerkzeug-Loops
Hier gibt es eine Asymmetrie, die Sie im Auge behalten müssen, da sie Ihre Code-Struktur bestimmt. Eingebaute Werkzeuge – Websuche, Dateisuche, Code-Interpreter – laufen bei OpenAI: Das Modell ruft sie auf, erhält das Ergebnis und setzt fort, alles in einer einzigen Round-Trip. Ihre benutzerdefinierten Funktionen laufen jedoch auf Ihrer Seite: Das Modell kann nur deren Ausführung anfordern, gibt dann die Kontrolle ab und wartet.
Daher der folgende Loop. Solange die Antwort Funktionsaufrufe enthält, führen Sie diese aus, geben die Ergebnisse zurück und starten neu. Setzen Sie eine maximale Anzahl von Iterationen fest: Ein Modell, das unendlich oft dasselbe Werkzeug aufruft, weil das Ergebnis es nicht zufriedenstellt, ist ein seltener, aber realer Fall, und ohne eine Schutzmaßnahme würde es Ihr Budget bis zur Erschöpfung verbrauchen.
import json
def boucle_multi_outils(prompt, tools, fichiers=None, max_tours=15):
"""Schleife für Funktionsaufrufe mit Mehrwerkzeug-Unterstützung."""
content = [{"type": "input_text", "text": prompt}]
if fichiers:
for fid in fichiers:
content.append({"type": "input_file", "file_id": fid})
messages = [{"role": "user", "content": content}]
for tour in range(max_tours):
response = client.responses.create(
model="gpt-5.6-terra",
input=messages,
tools=tools,
instructions="Verwenden Sie die erforderlichen Werkzeuge, um die Frage vollständig zu beantworten."
)
# Eingebaute Werkzeuge (web_search, file_search, code_interpreter)
# werden automatisch auf Serverseite ausgeführt.
# Wir behandeln nur benutzerdefinierte function_call-Elemente.
appels_custom = [
item for item in response.output
if item.type == "function_call"
]
if not appels_custom:
# Kein benutzerdefinierter Aufruf: Das Modell ist fertig
return {
"reponse": response.output_text,
"tours": tour + 1,
"tokens": response.usage.total_tokens
}
# Ausführen benutzerdefinierter Funktionen
resultats = []
for appel in appels_custom:
resultat = dispatcher_fonctions(appel.name, appel.arguments)
resultats.append({
"type": "function_call_output",
"call_id": appel.call_id,
"output": json.dumps(resultat)
})
# Vorbereiten der nächsten Runde
messages = response.output + resultats
return {"reponse": "Iterationslimit erreicht", "tours": max_tours}
Orchestrierungsstrategien
Die Werkzeugreihenfolge leiten
Automatische Orchestrierung funktioniert gut, solange die Reihenfolge keine Rolle spielt. Sie funktioniert nicht mehr, wenn ein Schritt den nächsten informieren muss: Zum Beispiel das Durchsuchen Ihrer Dokumente vor dem Web, weil das interne Vokabular die Relevanz der externen Abfrage konditioniert. Der Systemprompt ist der Hebel – nicht als technische Einschränkung, sondern als methodische Anweisung, die das Modell besser befolgt, wenn sie begründet ist.
# Strategie 1: zuerst suchen, dann handeln
instructions_recherche_dabord = (
"Bevor Sie eine Aktion ausführen, suchen Sie zuerst nach den "
"notwendigen Informationen in internen Dokumenten und im Web. "
"Bieten Sie keine Aktionen an, bis Sie alle Daten gesammelt haben."
)
# Strategie 2: Datenanalyse, dann Anreicherung
instructions_analyse_dabord = (
"Beginnen Sie mit der Analyse der Daten mit dem Code-Interpreter. "
"Anreichern Sie Ihre Schlussfolgerungen anschließend mit Websuchen. "
"Vergleichen Sie schließlich mit internen Dokumenten."
)
# Strategie 3: Querverifizierung
instructions_verification = (
"Verifizieren Sie jede wichtige Information in mindestens zwei Quellen: "
"internen Dokumenten UND Websuche. Melden Sie alle Widersprüche."
)
Werkzeuge nach Schritt einschränken
Der gegenteilige Ansatz besteht darin, die Wahl zu entfernen. Statt eines einzigen Aufrufs mit dem vollen Werkzeugkasten teilen Sie den Arbeitsablauf in mehrere Aufrufe auf, wobei jeder Aufruf nur das Werkzeug für seinen spezifischen Schritt deklariert. Sie verlieren die automatische Orchestrierung, gewinnen aber drei Dinge, die in der Produktion wichtig sind: garantierte Reihenfolge, vorhersehbare Kosten und isolierbare Fehler. Für einen kritischen Workflow ist dies fast immer der richtige Kompromiss.
# Schritt 1: Datenerfassung (kein Code)
response_collecte = client.responses.create(
model="gpt-5.6-terra",
input="Sammeln Sie Informationen zu Projekt Alpha",
tools=[
{"type": "file_search", "vector_store_ids": ["vs_projets"]},
{"type": "web_search"}
]
)
# Schritt 2: Analyse mit gesammelten Daten
response_analyse = client.responses.create(
model="gpt-5.6-terra",
input=f"Analysieren Sie diese Informationen und generieren Sie Diagramme:\n"
f"{response_collecte.output_text}",
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}]
)
Muster: Multi-Fähigkeits-Agent
Dieses letzte Beispiel kombiniert beide Ansätze: Ein Router wählt die Werkzeugkonfiguration basierend auf der Art der Anfrage aus und lässt das Modell dann innerhalb dieses eingeschränkten Bereichs orchestrieren. Es ist der Kompromiss, der in der Nutzung standhält – genug Freiheit, um die Vielfalt der Anfragen aufzunehmen, genug Struktur, um Kosten und Verhalten vorhersehbar zu halten.
class AgentMultiCompetences:
def __init__(self, vector_stores: list[str], fonctions: list[dict]):
self.client = OpenAI()
self.tools = [
{"type": "file_search", "vector_store_ids": vector_stores},
{"type": "web_search", "search_context_size": "medium"},
{"type": "code_interpreter", "container": {"type": "auto"}},
] + fonctions
def traiter(self, requete: str, fichiers: list[str] = None) -> dict:
return boucle_multi_outils(requete, self.tools, fichiers)
# Instanziieren des Agents
agent = AgentMultiCompetences(
vector_stores=["vs_docs", "vs_contrats"],
fonctions=[
{
"type": "function",
"name": "envoyer_email",
"description": "Senden Sie eine Benachrichtigungs-E-Mail",
"parameters": {
"type": "object",
"properties": {
"destinataire": {"type": "string"},
"sujet": {"type": "string"},
"corps": {"type": "string"}
},
"required": ["destinataire", "sujet", "corps"],
"additionalProperties": False
},
"strict": True
},
{
"type": "function",
"name": "creer_tache",
"description": "Erstellen Sie eine Aufgabe im Projektmanager",
"parameters": {
"type": "object",
"properties": {
"titre": {"type": "string"},
"assignee": {"type": "string"},
"priorite": {"type": "string", "enum": ["basse", "moyenne", "haute"]},
"echeance": {"type": "string"}
},
"required": ["titre", "assignee", "priorite"],
"additionalProperties": False
},
"strict": True
}
]
)
# Der Agent kann nun:
# - Dokumente durchsuchen
# - Im Web suchen
# - Daten analysieren
# - E-Mails senden
# - Aufgaben erstellen
resultat = agent.traiter(
"Analysieren Sie die Verkäufe im 1. Quartal, vergleichen Sie sie mit den Zielen "
"und erstellen Sie eine Aufgabe für den Vertriebsleiter, wenn wir hinterherhinken."
)
Kernaussagen
- Alle Werkzeuge koexistieren im selben
tools-Array - Eingebaute Werkzeuge laufen serverseitig, benutzerdefinierte Funktionen laufen clientseitig
- Das Modell orchestriert die Reihenfolge der Aufrufe automatisch
- Leiten Sie die Orchestrierungsstrategie über den Systemprompt
- Implementieren Sie einen Loop, um benutzerdefinierte Funktionsaufrufe zu verarbeiten