Sie haben wahrscheinlich bemerkt, dass LLMs bemerkenswert intestine im Denken sind – aber allein können sie nicht das heutige Wetter überprüfen, Ihre Datenbank abfragen oder einen Kundendatensatz nachschlagen. Sie erzeugen Textual content. Funktionsaufrufe schließen diese Lücke.
Mit Funktionsaufrufen (auch Toolaufrufe genannt) können Sie ein LLM mit echten Python-Funktionen verbinden. Das Modell entscheidet, wann eine Funktion benötigt wird, teilt Ihrer Anwendung mit, welche Funktion mit welchen Argumenten aufgerufen werden soll, und verwendet dann das Ergebnis, um die endgültige Antwort zu verfassen. Am Ende dieses Artikels werden Sie genau verstehen, wie diese Schleife funktioniert, und über ein vollständiges, ausführbares Python-Beispiel verfügen, auf dem Sie aufbauen können.
Inhaltsverzeichnis
Was ist Funktionsaufruf?
Funktionsaufrufe sind ein Muster, bei dem ein LLM eine strukturierte Ausgabe zurückgibt – insbesondere ein JSON-Objekt, das einen Funktionsnamen und Argumente beschreibt – anstelle einer Textantwort. Ihre Anwendung liest diese Ausgabe, führt die eigentliche Funktion aus und sendet das Ergebnis zurück an das Modell. Das Modell verwendet dann dieses Ergebnis, um seine endgültige Antwort an den Benutzer zu schreiben.
Das Wichtigste, was Sie verstehen müssen, ist, dass das LLM Ihren Code niemals direkt ausführt. Es begründet, was passieren muss, und gibt eine Beschreibung der Aktion zurück, die ausgeführt werden soll. Ihre Bewerbung ist diejenige, die die eigentliche Arbeit erledigt.
Diese Anfrage-und-Antwort-Schleife sieht folgendermaßen aus:
Die Begriffe „Funktionsaufruf“ und „Toolaufruf“ beziehen sich auf dasselbe. Neuere API-Dokumentationen (einschließlich OpenAIs) verwenden tendenziell „Instrument-Aufrufe“, aber Sie werden feststellen, dass beide austauschbar verwendet werden.
Wie entscheidet das LLM, eine Funktion aufzurufen?
Wenn Sie eine API-Anfrage stellen, übergeben Sie dem Modell zusammen mit der Nachricht des Benutzers eine Liste von Tooldefinitionen. Jede Definition beschreibt eine Funktion: ihren Namen, ihre Funktion und die Argumente, die sie annimmt (utilizing). JSON-Schema).
Das Modell liest die Nachricht des Benutzers und die Werkzeugdefinitionen zusammen. Wenn festgestellt wird, dass die Anfrage des Benutzers eine Aktion erfordert, die Ihre Instruments verarbeiten können, wird anstelle einer Textantwort ein Toolaufruf zurückgegeben. Wenn die Nachricht des Benutzers allein mit dem Trainingswissen des Modells beantwortet werden kann, reagiert es regular.
So sieht eine einzelne Tooldefinition in Python aus:
instruments = (
{
"sort": "perform",
"perform": {
"title": "get_weather",
"description": "Get the present climate circumstances for a given metropolis.",
"parameters": {
"sort": "object",
"properties": {
"metropolis": {
"sort": "string",
"description": "Town title, e.g. 'London' or 'Tokyo'"
}
},
"required": ("metropolis"),
"additionalProperties": False
},
"strict": True
}
}
)
Der description Feld ist der wichtigste Teil für die Entscheidungsfindung des Modells. Es verwendet Ihre Beschreibung, um zu verstehen, wann diese Funktion angemessen ist. Vage Beschreibungen führen zu inkonsistentem Verhalten – eine Beschreibung wie "Will get climate" ist viel weniger zuverlässig als "Get the present climate circumstances for a given metropolis." Geben Sie genau an, was die Funktion bewirkt und wann sie verwendet werden soll.
Zwei Antwortfelder verraten Ihnen, was passiert ist. Wenn das Modell eine Funktion aufrufen möchte, erfolgt die Antwort finish_reason wird sein "tool_calls" und die Nachricht enthält a tool_calls Liste. Wenn das Modell über genügend Informationen verfügt, um direkt zu antworten (auch nach Erhalt Ihrer Funktionsergebnisse), finish_reason wird sein "cease" und die Nachricht enthält reinen Textual content content material.
Ein vollständiges Beispiel für einen Python-Funktionsaufruf, Schritt für Schritt
Das folgende Beispiel führt die vollständige Funktionsaufrufschleife mit dem durch OpenAI Python SDK. Wir verwenden eine simulierte Wetterfunktion – deutlich gekennzeichnet als simulierte Daten – sodass Sie diese mit nur einem OpenAI-API-Schlüssel ausführen können.
Installieren Sie zuerst das SDK, falls Sie dies noch nicht getan haben:
pip set up openai
Legen Sie dann Ihren API-Schlüssel als Umgebungsvariable fest:
export OPENAI_API_KEY="your-api-key-here"
Schritt 1: Definieren Sie das Instrument und die Mock-Funktion
import json
from openai import OpenAI
consumer = OpenAI()
# The device definition — that is what you move to the mannequin
instruments = (
{
"sort": "perform",
"perform": {
"title": "get_weather",
"description": "Get the present climate circumstances for a given metropolis.",
"parameters": {
"sort": "object",
"properties": {
"metropolis": {
"sort": "string",
"description": "Town title, e.g. 'London' or 'Tokyo'"
}
},
"required": ("metropolis"),
"additionalProperties": False
},
"strict": True
}
}
)
# Mock perform — in an actual app, this could name a climate API
def get_weather(metropolis: str) -> str:
mock_data = {
"London": "Partly cloudy, 15°C",
"Tokyo": "Sunny, 22°C",
"New York": "Wet, 10°C"
}
return mock_data.get(metropolis, f"No climate knowledge accessible for {metropolis}")
Notiz: Dieser Beitrag verwendet die Chat Completions API, die immer noch funktioniert, aber nicht mehr der von OpenAI empfohlene Endpunkt für Instrument-Aufrufe ist. Die konzeptionelle Schleife (Anfrage → Toolaufruf → Ausführen → Ergebnis → endgültige Antwort) ist in beiden APIs gleich, aber die Anfrage- und Antwortformen unterscheiden sich.
Schritt 2: Senden Sie die erste Anfrage
user_message = "What is the climate like in London proper now?"
messages = (
{"function": "person", "content material": user_message}
)
response = consumer.chat.completions.create(
mannequin="gpt-4o-mini",
messages=messages,
instruments=instruments
)
print(response.selections(0).finish_reason)
# tool_calls
print(response.selections(0).message.tool_calls)
# (ChatCompletionMessageToolCall(id='call_abc123', perform=Operate(arguments='{"metropolis":"London"}', title='get_weather'), sort='perform'))
Das Modell kam zurück finish_reason: "tool_calls" statt einer Textantwort. Es hat erkannt, dass für die Beantwortung der Frage Stay-Daten erforderlich sind, über die es nicht verfügt, und fordert Ihre Anwendung auf, diese abzurufen.
Beachten Sie das arguments ist eine JSON-codierte Zeichenfolge, kein Python-Dikt. Sie müssen es analysieren, bevor Sie es verwenden können.
Schritt 3: Führen Sie die Funktion aus
# Get the device name from the response
tool_call = response.selections(0).message.tool_calls(0)
# Parse the arguments — they arrive as a JSON string
arguments = json.hundreds(tool_call.arguments)
metropolis = arguments("metropolis")
# Name your precise perform
end result = get_weather(metropolis)
print(end result)
# Partly cloudy, 15°C
Schritt 4: Senden Sie das Ergebnis zurück
Dieser nächste Schritt ist ein häufiger Fallstrick, der Neulinge im Instrument-Calling verwirren kann. Sie müssen ein neues bauen messages Liste, die den gesamten Gesprächsverlauf enthält: die ursprüngliche Benutzernachricht, die Instrument-Name-Nachricht des Assistenten und eine neue device Rollennachricht, die das Ergebnis Ihrer Funktion enthält.
# Append the assistant's device name message to the historical past
messages.append(response.selections(0).message)
# Append the perform end result as a "device" function message
messages.append({
"function": "device",
"tool_call_id": tool_call.id,
"content material": end result
})
Nach Schritt 4 ist Ihr messages Liste sieht so aus:
| Rolle | Inhalt |
|---|---|
person |
„Wie ist das Wetter gerade in London?“ |
assistant |
(Werkzeugaufruf: get_weather mit {"metropolis": "London"}) |
device |
„Teilweise bewölkt, 15°C“ |
Der tool_call_id in Ihrer Ergebnisnachricht muss mit dem übereinstimmen id aus dem ursprünglichen Instrument-Aufruf. Auf diese Weise verfolgt das Modell, welches Ergebnis zu welcher Anfrage gehört – das ist besonders wichtig, wenn Sie mehrere Funktionsaufrufe in einer einzigen Runde haben.
Schritt 5: Erhalten Sie die endgültige Antwort
final_response = consumer.chat.completions.create(
mannequin="gpt-4o-mini",
messages=messages,
instruments=instruments
)
print(final_response.selections(0).finish_reason)
# cease
print(final_response.selections(0).message.content material)
# The climate in London proper now's partly cloudy with a temperature of 15°C.
Diesmal, finish_reason Ist "cease" – Das Modell verfügt über alles, was es benötigt, und hat eine Antwort in natürlicher Sprache zurückgegeben.
Hier ist das vollständige Arbeitsskript:
import json
from openai import OpenAI
consumer = OpenAI()
instruments = (
{
"sort": "perform",
"perform": {
"title": "get_weather",
"description": "Get the present climate circumstances for a given metropolis.",
"parameters": {
"sort": "object",
"properties": {
"metropolis": {
"sort": "string",
"description": "Town title, e.g. 'London' or 'Tokyo'"
}
},
"required": ("metropolis"),
"additionalProperties": False
},
"strict": True
}
}
)
def get_weather(metropolis: str) -> str:
# Mock knowledge — substitute this with an actual climate API name
mock_data = {
"London": "Partly cloudy, 15°C",
"Tokyo": "Sunny, 22°C",
"New York": "Wet, 10°C"
}
return mock_data.get(metropolis, f"No climate knowledge accessible for {metropolis}")
# Step 1: Preliminary request
messages = ({"function": "person", "content material": "What is the climate like in London proper now?"})
response = consumer.chat.completions.create(
mannequin="gpt-4o-mini",
messages=messages,
instruments=instruments
)
# Step 2: Test if the mannequin desires to name a perform
if response.selections(0).finish_reason == "tool_calls":
tool_call = response.selections(0).message.tool_calls(0)
# Step 3: Execute the perform
arguments = json.hundreds(tool_call.arguments)
end result = get_weather(arguments("metropolis"))
# Step 4: Add the assistant message and end result to historical past
messages.append(response.selections(0).message)
messages.append({
"function": "device",
"tool_call_id": tool_call.id,
"content material": end result
})
# Step 5: Get the ultimate response
final_response = consumer.chat.completions.create(
mannequin="gpt-4o-mini",
messages=messages,
instruments=instruments
)
print(final_response.selections(0).message.content material)
else:
# No device name wanted — the mannequin answered instantly
print(response.selections(0).message.content material)
Umgang mit mehreren Funktionsaufrufen
Das Modell kann in einer Runde mehr als eine Funktion anfordern. Dies wird als paralleler Instrument-Aufruf bezeichnet und geschieht, wenn das Modell feststellt, dass mehrere unabhängige Suchvorgänge erforderlich sind, um die Frage des Benutzers zu beantworten – beispielsweise wenn jemand gleichzeitig nach dem Wetter in London und Tokio fragt.
Weil tool_calls Da es sich immer um eine Liste handelt, sollten Sie diese durchlaufen, anstatt davon auszugehen, dass es genau einen Aufruf gibt:
if response.selections(0).finish_reason == "tool_calls":
# Append the assistant's message first
messages.append(response.selections(0).message)
# Then loop over all device calls and execute every one
for tool_call in response.selections(0).message.tool_calls:
arguments = json.hundreds(tool_call.arguments)
end result = get_weather(arguments("metropolis"))
messages.append({
"function": "device",
"tool_call_id": tool_call.id,
"content material": end result
})
Wenn Sie möchten, dass das Modell Funktionen einzeln und nicht parallel aufruft (z. B. wenn jeder Funktionsaufruf vom Ergebnis des vorherigen abhängt), legen Sie fest parallel_tool_calls=False in Ihrer API-Anfrage. Dadurch wird sichergestellt, dass das Modell höchstens einen Werkzeugaufruf professional Runde ausgibt.
Häufige Fehler beim Funktionsaufruf und wie man sie behebt
Die meisten Funktionsaufruffehler fallen in eine kleine Reihe von Mustern. Wenn etwas nicht funktioniert, überprüfen Sie zuerst diese Tabelle.
| Fehler | Was geht schief | Repair |
|---|---|---|
Behandeln arguments als Diktat |
KeyError oder TypeError beim Zugriff auf Felder |
Immer mit analysieren json.hundreds(tool_call.arguments) |
| Überspringe die Assistentennachricht im Verlauf | Modell verliert Kontext; kann den Werkzeugaufruf wiederholen | Anhängen response.selections(0).message vor dem Werkzeugergebnis |
| Vage Funktionsbeschreibungen | Das Modell ruft die falsche Funktion auf oder ruft sie nie auf | Schreiben Sie Beschreibungen, die genau angeben, wann die Funktion verwendet werden soll |
Keine Handhabung finish_reason: "cease" beim ersten Anruf |
Code stürzt ab, wenn kein Instrument-Aufruf erfolgt ist | Überprüfen Sie immer finish_reason vor dem Zugriff tool_calls |
| Der Funktionsname wird nicht validiert | Absturz, wenn das Modell einen nicht vorhandenen Funktionsnamen halluziniert | Überprüfen tool_call.perform.title Vergleichen Sie vor dem Anruf eine bekannte Liste |
Der letzte Fehler ist besondere Aufmerksamkeit wert, wenn Sie Open-Supply-Modelle verwenden. Modelle wie Llama, die lokal über Ollama ausgeführt werden, halluzinieren eher Funktionsnamen, die nicht existieren. Durch die Validierung des Funktionsnamens vor dem Aufruf werden schwer zu debuggende Abstürze verhindert.
Wann Funktionsaufrufe verwendet werden sollten
Der Funktionsaufruf ist das richtige Muster für eine bestimmte Gruppe von Problemen. Es ist nicht für alles das richtige Werkzeug.
Verwenden Sie es, wenn:
- Sie benötigen Echtzeit- oder dynamische Daten, die das Modell nicht in seinen Trainingsdaten haben kann (Wetter, Aktienkurse, Stay-Inventar, benutzerspezifische Datensätze).
- Sie möchten, dass das Modell Aktionen in Ihrem System auslöst (einen Kalendertermin erstellen, eine Nachricht senden, eine Datenbankzeile aktualisieren).
- Sie erstellen eine Schnittstelle in natürlicher Sprache über eine vorhandene API oder eine Reihe von Diensten
- Sie möchten, dass das Modell mehrere Datenquellen koordiniert, um eine einzelne Frage zu beantworten
Überspringen Sie es, wenn:
- Das Modell kann aus seinem Trainingswissen ohne externe Daten antworten
- Sie möchten lediglich eine strukturierte JSON-Ausgabe von einer Nur-Textual content-Eingabeaufforderung – verwenden Sie dazu strukturierte Ausgaben (Die
response_formatParameter), was einfacher ist und keine Funktionsschleife erfordert - Sie erstellen einen einfachen Chatbot, bei dem das Modell keine Maßnahmen ergreifen muss
Der strukturierte Leistungsvergleich kommt in der Praxis immer wieder vor. Wenn Sie nur möchten, dass das Modell seine Antwort als JSON entsprechend einem Schema formatiert, ist kein Funktionsaufruf erforderlich. Funktionsaufrufe sind für Fälle gedacht, in denen das Modell Informationen abrufen oder darauf reagieren muss, die Ihre Anwendung steuert.
Was Sie hier aufbauen können
Funktionsaufrufe verwandeln einen LLM von einem Textgenerator in einen aktiven Teilnehmer Ihrer Anwendung. Sobald Sie die Schleife verstanden haben – Werkzeuge definieren, einen Werkzeugaufruf empfangen, die Funktion ausführen, das Ergebnis zurückgeben, die endgültige Antwort erhalten – können Sie sie auf quick jede State of affairs anwenden, in der Ihre Benutzer Antworten von Systemen außerhalb der Trainingsdaten des Modells benötigen.
Das hier behandelte Muster ist die Grundlage für komplexere Setups: Verkettung mehrerer Funktionsaufrufe, Koordination zwischen mehreren Agenten oder Aufbau natürlichsprachlicher Schnittstellen über Ihre eigenen APIs. Der beste Weg, es zu verinnerlichen, besteht darin, die Wettersimulationsfunktion durch etwas aus Ihrer eigenen Arbeit auszutauschen.
Wenn Sie mit der Python- und LLM-Entwicklung weitermachen möchten, ist Dataquest’s Python für Knowledge Engineering Und KI-Grundlagen Die Pfade decken die Programmiergrundlagen ab, die Sie zum Erstellen von Pipelines und Anwendungen in Produktionsqualität benötigen. Beginnen Sie mit den Grundlagen und entwickeln Sie dann die Instruments, mit denen Sie arbeiten möchten.
FAQ
Was ist der Unterschied zwischen Funktionsaufruf und Toolaufruf?
Sie sind dasselbe. „Funktionsaufruf“ conflict der ursprüngliche Begriff, der 2023 eingeführt wurde. Die neueren APIs von OpenAI verwenden „Toolaufruf“, um zu verdeutlichen, dass sich das Muster über Funktionen hinaus auf andere Arten von Instruments erstrecken kann. Die meisten Entwickler verwenden beide Begriffe synonym.
Kann ich Funktionsaufrufe mit Open-Supply-Modellen wie Llama verwenden?
Ja – viele Open-Supply-Modelle unterstützen den Instrument-Aufruf, darunter Llama und Mistral. Sie können sie lokal mit ausführen Ollama Verwendung einer kompatiblen API. Die Mechanik ähnelt der OpenAI-Implementierung, aber Open-Supply-Modelle neigen eher dazu, Funktionsnamen zu halluzinieren, daher ist die Validierung des Funktionsnamens vor der Ausführung besonders wichtig.
Was ist der Unterschied zwischen Funktionsaufruf und RAG?
Retrieval-Augmented Technology (RAG) zieht relevante Dokumente in den Kontext des Modells, bevor eine Antwort generiert wird. Durch Funktionsaufrufe kann das Modell während einer Konversation bestimmte Daten oder Aktionen anfordern. Die beiden Muster können zusammen verwendet werden: Ein Funktionsaufruf könnte eine Vektorsuche auslösen und die Ergebnisse werden in die Konversation zurückgeführt.
Wie viele Funktionen kann ich gleichzeitig an das Modell übergeben?
Es gibt keine feste Grenze, aber die eigenen Leitlinien von OpenAI empfehlen, die Anzahl der anfänglich verfügbaren Instruments unter 20 zu halten, um die beste Genauigkeit zu erzielen. Mehr Instruments bedeuten, dass mehr Token verwendet werden und dass das Modell mehr Möglichkeiten hat, das falsche auszuwählen. Wenn Sie eine große Werkzeugoberfläche benötigen, schauen Sie sich um Werkzeugsuchewodurch das Modell Werkzeuge bei Bedarf laden kann, anstatt sie alle im Voraus zu erhalten.
Funktioniert der Funktionsaufruf mit Streaming?
Ja. Wenn Streaming aktiviert ist, erhalten Sie selections(0).delta.tool_calls(i).perform.arguments Ereignisse, die JSON-Teilargumente enthalten, die Sie in der vollständigen Argumentzeichenfolge akkumulieren. Der Gesamtablauf ist derselbe – Sie führen weiterhin die Funktion aus und senden das Ergebnis zurück. Siehe die OpenAI-Streaming-Dokumentation für Einzelheiten zur Implementierung.
Was ist der Unterschied zwischen Funktionsaufrufen und strukturierten Ausgaben?
Der Funktionsaufruf erfolgt, wenn das Modell externe Daten anfordern oder eine Aktion auslösen muss. Strukturierte Ausgaben (die response_format Parameter) sind für den Fall gedacht, dass das Modell seine Antwort in einem bestimmten JSON-Schema formatieren soll – es sind keine externen Aufrufe erforderlich. Wenn Sie möchten, dass das Modell nur ein JSON-Objekt anstelle von Prosa zurückgibt, verwenden Sie strukturierte Ausgaben. Reservefunktion, die aufruft, wenn tatsächlich eine Interaktion in der realen Welt erforderlich ist.