OpenAI (ChatGPT) API Tutorial – Teil #3 Funktionen (Function calling) 

5. Juli 2023

Einleitung

Im Teil #2 der Tutorial-Reihe habe ich dir einen Überblick über die unterschiedlichen Modelle gegeben und etwas unterhaltsamer gezeigt, wie man mit Dall-E Bilder anhand eines Prompts generieren lassen kann.

In diesem (letzten) Teil möchte ich dir ein relativ neues Feature vorstellen: Funktionsaufrufe oder function calling. Das klingt auf den ersten Blick nicht so spannend aber dahinter verbirgt sich eigentlich etwas sehr Nützliches. Eventuell kennst du schon die Plugins, die man bei der Verwendung von ChatGPT in der Bezahlversion nutzen kann. Mit den Funktionsaufrufen kannst du ähnliches auch über die API erreichen und sogar viel mehr, denn wir können unsere eigenen Funktionen einbinden.

Function calling

Ok was ist das jetzt genau? Grundsätzlich können wir bei der „Unterhaltung“ mit dem Sprachmodell eine Liste von Funktionen mitgeben. Zu jeder Funktion gibt es eine Beschreibung, wofür die Funktion gut ist. Das hilft dem Sprachmodell bei der Entscheidung, ob es notwendig oder hilfreich ist, diese Funktion zum Lösen der Aufgabe aufzurufen. Zusätzlich zu der textuellen Beschreibung müssen wir auch die Parameter der Funktion angeben. Auch hier gehört zu jedem Parameter eine textuelle Beschreibung dazu, damit das Sprachmodell weiß wozu ein Parameter dient.

Aber ruft jetzt OpenAI die Funktion auf? Nein. Es ist vielmehr so, dass das Sprachmodell uns als Antwort mitteilt, dass ein Funktionsaufruf notwendig ist, den wir dann mit unserem Programm ausführen. Die API gibt dabei an, mit welchen Parametern und Werten die Funktion aufgerufen werden soll.

Wenn die Antwort des Funktionsaufrufes vorliegt, übermitteln wir das Ergebnis an das Sprachmodell und es arbeitet also weiter mit diesen Daten und erzeugt entweder eine Antwort und wenn nötigt, fordert uns auf weitere Funktionen aufzurufen.

Ob ein Funktionsaufruf notwendig ist, entscheidet das Modell selbst. Auch wenn wir eine Reihe von Funktionen angeben, so kann das Modell entscheiden, dass ein Funktionsaufruf nicht notwendig ist. Allerdings kann man das auch beeinflussen. So kann man entweder eine bestimmte Funktion vorgeben oder man kann auch angeben, dass keine Funktion ausgeführt werden soll.

Demoanwendung

Schauen wir uns ein Beispiel an. In dem Beispiel definiere ich eine Funktion, die in der Lage ist die Feiertage in Deutschland zurückzugeben. Da das Sprachmodell auf dem Datenstand von 2021 (zum Zeitpunkt der Erstellung) ist, kann es u.U. nicht wissen, welche Feiertage aktuell sind. Gut rein hypothetisch kann es das wissen, denn Feiertage werden ja nicht ausgewürfelt und stehen lange im Voraus fest. 

Hierfür nutzen wir eine öffentliche REST-Schnittstelle, die tatsächlich von der Bundesrepublik betrieben wird. Hier übrigens eine Liste aller Schnittstellen: https://bund.dev/apis

Schauen wir uns den ersten Code-Ausschnitt an:

import openai
import json
import requests
openai.api_key = "Füge hier deinen API-Key ein"
feiertage_api_url = "https://feiertage-api.de/api/"
prompt = "Wir haben den 3.7.2023, wann ist der nächste gesetzliche Feiertag in Hessen?"
messages = [{"role": "user", "content": prompt}]
def feiertage(jahr):
print(f"Hole Feiertage für Jahr {jahr}")
print(feiertage_api_url + "?jahr=" + jahr)
return requests.get(feiertage_api_url + "?jahr=" + jahr).json()

Als erstes importieren wir eine Reihe von Bibliotheken. Die Bibliotheken json und requests benötigen wir für die Kommunikation mit der Feiertage-API.

Anschließend übergeben wir, wie wir das schon kennen, den API-Key an openai. 

Der Prompt, der uns hier interessiert , fragt nach dem nächsten Feiertag in Hessen. Theoretisch weiß das Modell nichts über Feiertage nach 2021 und das sollte dazu führen, dass ein Funktionsaufruf notwendig wird. Da das Modell auch nicht weiß, welches Datum wir aktuell haben, sind wir so nett und geben das mit an.

Zuletzt definieren wir unsere Funktion feiertage. Diese akzeptiert einen Pflichtparameter für das Jahr, in dem der Feiertag liegen soll. Das Einzige was die Funktion macht, ist den Feiertags-Endpunkt aufzurufen und das Resultat als JSON zurück zu geben.

Jetzt wo wir die Funktion fertig haben, ist es Zeit die Übergabe an das Modell vorzubereiten:

functions = [
{
"name": "feiertage",
"description": "Ermittelt die gesetzlichen Feiertage in Deutschland",
"parameters": {
"type": "object",
"properties": {
"jahr": {"type": "string", "description": "Das Jahr in dem die Feiertage liegen sollen, Beispiel '2023'"},
},
"required": ["jahr"],
},
}
]

Wir legen eine Variable functions an, die eine Liste von Funktionsdefinitionen enthält.

Das Feld „name“ enthält wenig überraschend den Namen der Funktion. In dem Feld „description“ beschreiben wir, was die Funktion leistet. Wie schon weiter oben beschrieben, dient es dazu dem Modell mitzuteilen was die Funktion leistet.

Anschließend beschreiben wir die Parameter der Funktion. Der entscheidende Teil dabei ist „properties„. Wir benennen dort die Parameter und geben an welchen Datentyp sie haben. Ganz wichtig natürlich die Beschreibung, damit das Modell weiß wozu der Parameter dient.

Die Pflichtangaben landen in der Liste „required„, hier in unserem Fall ist der Parameter „jahr“ ein Pflichtfeld.

Jetzt ist es so, dass das Modell sich einen Funktionsaufruf wünschen kann. Dabei gibt es den Namen der Funktion plus die Werte der Parameter an. Das bekommen wir mehr oder weniger in textueller Form als JSON. Damit wir die Funktion anhand dessen aufrufen können, schreiben wir uns eine Hilfsfunktion, dessen Aufgabe es ist, mithilfe der Antwort die passende Funktion inkl. Parameter aufzurufen und das Ergebnis zurück liefert. 

def execute_function_call(message):
if message["function_call"]["name"] == "feiertage":
jahr = json.loads(message["function_call"]["arguments"])["jahr"]
results = feiertage(jahr)
else:
results = f"Fehler! Es existiert keine Funktion mit dem Namen: {message['function_call']['name']}"
return results

Unserer Hilfsfunktion nimmt eine OpenAI-API-Antwort als Parameter an. Sie wirft dann einen Blick auf das Feld „function_call“ und schaut, welche Funktion gemeint ist.

Wir kennen aktuell nur eine Funktion, nämlich „feiertage“. Kommt etwas anderes zurück, so geben wir lediglich eine Fehlerantwort zurück.

Andernfalls extrahieren wir die Parameter aus der Antwort und rufen die Funktion auf und geben das Ergebnis zurück.

Jetzt sind wir soweit, dass wir die OpenAI-API aufrufen können:

response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
functions = functions
)
print(response)
ai_msg = response["choices"][0]["message"]
messages.append(ai_msg)
if ai_msg.get("function_call"):
results = execute_function_call(ai_msg)
print(results)
messages.append({"role": "user", "content": ""})
response = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=messages,functions = functions)
print(response)

Wir rufen, so wie wir das bereits kennen, die ChatCompletion API auf. Neben der Liste der Prompts und die Angabe des Modells, übergeben wir nun auch die Liste der Funktionen über den Parameter functions.

Da wir uns im Chat-Modus befinden, fügen wir die Antwort der AI in die Liste der Nachrichten ein (siehe den ersten Teil der Tutorial-Reihe, falls dir unklar ist, warum wir das so machen).

Jetzt kann es sein, dass das Modell anstelle eines menschlich lesbaren Textes nur einen Funktionsaufruf anfordert. Das prüfen wir in dem wir in der Antwort nachschauen, ob das Feld „function_call“ mit einem Wert befüllt ist. Ist das der Fall, so rufen wir unsere Hilfsfunktion execute_function_call auf, die ihrerseits unsere Feiertags-Funktion aufruft.

Das Resultat des Funktionsaufrufes fügen wir in die Liste der Prompts ein und rufen erneut die ChatCompletion API auf. Jetzt bekommt das Sprachmodell die notwendigen Daten und kann uns eine finale Antwort liefern:

{
"id": "chatcmpl-7YqFEqFINsLnzX2GJa3uYeGo6UNNO",
"object": "chat.completion",
"created": 1688538336,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"function_call": {
"name": "feiertage",
"arguments": "{\n  \"jahr\": \"2023\"\n}"
}
},
"finish_reason": "function_call"
}
],
"usage": {
"prompt_tokens": 99,
"completion_tokens": 18,
"total_tokens": 117
}
}
Hole Feiertage für Jahr 2023
https://feiertage-api.de/api/?jahr=2023
{'BW': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Heilige Drei Könige': {'datum': '2023-01-06', 'hinweis': ''}, 'Gründonnerstag': {'datum': '2023-04-06', 'hinweis': 'Gemäß § 4 Abs. 3 des Feiertagsgesetzes von Baden-Württemberg[10] haben Schüler am Gründonnerstag und am Reformationstag schulfrei. In der Regel legt das Kultusministerium die Ferientermine so fest, dass diese beiden Tage in die Osterferien bzw. in die Herbstferien fallen.'}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': 'Gemäß § 4 Abs. 3 des Feiertagsgesetzes von Baden-Württemberg[10] haben Schüler am Gründonnerstag und am Reformationstag schulfrei. In der Regel legt das Kultusministerium die Ferientermine so fest, dass diese beiden Tage in die Osterferien bzw. in die Herbstferien fallen.'}, 'Allerheiligen': {'datum': '2023-11-01', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'BY': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Heilige Drei Könige': {'datum': '2023-01-06', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': ''}, 'Augsburger Friedensfest': {'datum': '2023-08-08', 'hinweis': 'Das Augsburger Friedensfest ist nur im Stadtgebiet Augsburg (nicht jedoch im angrenzenden Umland) gesetzlicher Feiertag (Art. 1 Abs. 2 Bayerisches Feiertagsgesetz[7]).'}, 'Mariä Himmelfahrt': {'datum': '2023-08-15', 'hinweis': 'Mariä Himmelfahrt ist in Bayern in von den derzeit 1704[8] (Zensus 2011, bis 2013: 1700) Gemeinden mit überwiegend katholischer Bevölkerung gesetzlicher Feiertag, in den restlichen 352 (Zensus 2011, bis 2013: 356) Gemeinden nicht. Gemäß Art. 1 Abs. 3 des Bayerischen Feiertagsgesetzes[7] ist es Aufgabe des Bayerischen Landesamtes für Statistik und Datenverarbeitung, festzustellen, in welchen Gemeinden Mariä Himmelfahrt gesetzlicher Feiertag ist. Die aktuelle Festlegung beruht auf dem Ergebnis der letzten in der Bundesrepublik Deutschland durchgeführten Volkszählung vom 25. Mai 1987. Gemäß Art 4. Abs. 3 des Bayerischen Feiertagsgesetzes entfällt im gesamten Bundesland zu Mariä Himmelfahrt an Schulen aller Gattungen der Unterricht. Diese Festlegung gilt ausdrücklich auch in den Teilen Bayerns, in denen dieser Tag kein gesetzlicher Feiertag ist. Eine Übersichtskarte aller Gemeinden, in denen Mariä Himmelfahrt ein Feiertag ist, kann beim Bayerischen Landesamt für Statistik und Datenverarbeitung heruntergeladen werden (Link siehe unter "Weitere Weblinks").'}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Allerheiligen': {'datum': '2023-11-01', 'hinweis': ''}, 'Buß- und Bettag': {'datum': '2023-11-22', 'hinweis': 'Gemäß Art. 4 Nr. 3 des Bayerischen Feiertagsgesetzes[7] entfällt im gesamten Bundesland am Buß- und Bettag an allen Schulen der Unterricht.'}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'BE': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Frauentag': {'datum': '2023-03-08', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'BB': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostersonntag': {'datum': '2023-04-09', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstsonntag': {'datum': '2023-05-28', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'HB': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'HH': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'HE': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'MV': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Frauentag': {'datum': '2023-03-08', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'NI': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'NW': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Allerheiligen': {'datum': '2023-11-01', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'RP': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Allerheiligen': {'datum': '2023-11-01', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'SL': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': ''}, 'Mariä Himmelfahrt': {'datum': '2023-08-15', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Allerheiligen': {'datum': '2023-11-01', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'SN': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': 'Fronleichnam ist kein gesetzlicher Feiertag außer in folgenden katholisch geprägten Gemeinden des sorbischen Siedlungsgebietes im Landkreis Bautzen:\n\t\t\t\tBautzen (nur in den Ortsteilen Bolbritz und Salzenforst), Crostwitz, Göda (nur im Ortsteil Prischwitz), Großdubrau (nur im Ortsteil Sdier), Hoyerswerda (nur im Ortsteil Dörgenhausen), Königswartha (nicht im Ortsteil Wartha), Nebelschütz, Neschwitz (nur in den Ortsteilen Neschwitz und Saritsch), Panschwitz-Kuckau, Puschwitz, Räckelwitz, Radibor, Ralbitz-Rosenthal und Wittichenau. Entscheidend ist dabei der Arbeitsort, nicht der Wohnort eines Arbeitnehmers.\n\t\t\t\tDie gesetzliche Grundlage für diese durch die Fronleichnamsverordnung festgelegte Regelung ergibt sich aus § 1 Abs. 1 des Sächsischen Feiertagsgesetzes.[5]'}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, 'Buß- und Bettag': {'datum': '2023-11-22', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'ST': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Heilige Drei Könige': {'datum': '2023-01-06', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'SH': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'TH': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Fronleichnam': {'datum': '2023-06-08', 'hinweis': 'Fronleichnam ist kein gesetzlicher Feiertag außer im gesamten Landkreis Eichsfeld (79 Gemeinden am 31. Dezember 2013, Auflistung siehe dort) sowie in folgenden Gemeinden des Unstrut-Hainich-Kreises und des Wartburgkreises:\n\t\t\t\tAnrode (nur in den Ortsteilen Bickenriede und Zella), Brunnhartshausen (nur in den Ortsteilen Föhlritz und Steinberg), Buttlar, Dünwald (nur in den Ortsteilen Beberstedt und Hüpstedt), Geisa, Rodeberg (nur im Ortsteil Struth), Schleid, Südeichsfeld und Zella/Rhön.\n\t\t\t\tDie gesetzliche Grundlage für diese Regelung ergibt sich aus § 2 Abs. 2 und § 10 Abs. 1 des Thüringer Feiertagsgesetzes.[6]'}, 'Weltkindertag': {'datum': '2023-09-20', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, 'Reformationstag': {'datum': '2023-10-31', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}, 'NATIONAL': {'Neujahrstag': {'datum': '2023-01-01', 'hinweis': ''}, 'Karfreitag': {'datum': '2023-04-07', 'hinweis': ''}, 'Ostermontag': {'datum': '2023-04-10', 'hinweis': ''}, 'Tag der Arbeit': {'datum': '2023-05-01', 'hinweis': ''}, 'Christi Himmelfahrt': {'datum': '2023-05-18', 'hinweis': ''}, 'Pfingstmontag': {'datum': '2023-05-29', 'hinweis': ''}, 'Tag der Deutschen Einheit': {'datum': '2023-10-03', 'hinweis': ''}, '1. Weihnachtstag': {'datum': '2023-12-25', 'hinweis': ''}, '2. Weihnachtstag': {'datum': '2023-12-26', 'hinweis': ''}}}
{
"id": "chatcmpl-7YqFGOa3vJ6Ls9YiPj0JRolY6O0Zy",
"object": "chat.completion",
"created": 1688538338,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\n  \"jahr\": \"2023\"\n}\nDer n\u00e4chste gesetzliche Feiertag in Hessen nach dem 3.7.2023 ist der Tag der deutschen Einheit am 3. Oktober 2023."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 124,
"completion_tokens": 50,
"total_tokens": 174
}
}

Das hier ist natürlich die unverarbeitete Antwort, um besser zeigen zu können, was passiert.

Zuerst sehen wir nämlich, dass das Modell einen Funktionsaufruf haben möchte und gibt uns für den Parameter „jahr“ den Wert „2023“ an.

Wir sehen dann, dass unserer Funktion die Feiertage von der API anfragt und die Antwort enthält alle Feiertage für dieses Jahr.

Nachdem das Model diese Daten verdaut hat, sehen wir die finale Antwort: „{„jahr“: „2023“} Der nächste gesetzliche Feiertag in Hessen nach dem 3.7.2023 ist der Tag der deutschen Einheit am 3. Oktober 2023.„.

Wir haben ja keine Angaben gemacht, wie die Antwort ausgegeben werden soll, daher die etwas fummelige Ausgabe mit der Angabe des Parameters vor dem eigentlichen Text.

Hinweise

Der Beispielcode ist äußerst rudimentär und müsste deutlich überarbeitet werden. Wenn wir auf den ersten Prompt keine Funktionsaufruf-Empfehlung bekommen hätten, dann würde sich das Programm ohne jede weitere Ausgabe einfach beenden. Das müsste man viel eleganter gestalten und eine Routine schrieben, die sich darum kümmert zu schauen, ob wir eine Text- oder Funktions-Antwort vorliegen haben und entsprechend handelt.

Außerdem ist es nicht so schön wie der OpenAI-API Aufruf einfach in den if-Block kopiert wurde. Das gehört natürlich ein eigene Funktion ausgelagert etc.

Zu guter Letzt noch ein Hinweis zu einem optionalen Parameter, den wir mitgeben können: „function_call“ (so ähnlich wie in der Antwort). Damit können wir steuern, welche Funktion angesprochen werden soll oder ob gar keine Funktionsaufrufe gewünscht sind. Beispiele:

# Bestimmte Funktion soll aufgerufen werden
function_call: {"name": "<Name der Funktion>"}
# Kein Funktionsaufruf erwünscht:
function_call: "none"
# Standardwert ist "auto"
function_call: "auto"

Ende

Das war jetzt der letzte Teil der Serie. Mit den Funktionsaufrufen haben wir ein mächtiges Werkzeug kennengelernt. Es ermöglicht uns eine Art Plugins bereit zu stellen und Daten, die dem Modell sonst unzugänglich wären, bereit zu stellen.

Den Code findest du in meinem GitHub-Repository unter: https://github.com/ki-zeitalter/openai-api-tutorial/blob/main/openai_functions_tutorial.ipynb.

Mit den Funktionen können wir auch so etwas wie Agenten implementieren. D.h. die Funktionsaufrufe können zu weiteren automatisch erzeugten Prompts führen, z.B. um eine komplexe Aufgabe in viele Teilschritte zu teilen.

Was wir in dieser Tutorialreihe gesehen haben ermöglicht uns sehr coole Sachen umzusetzen. Allerdings ist es nicht der eleganteste Weg, wie man das erreichen kann. Es gibt Frameworks, die das Ganze kapseln und die Komplexität verbergen. Insbesondere möchte ich hier LangChain empfehlen. Ein Tutorial zu LangChain ist bereits in Arbeit! wink

Ich hoffe dir haben die Tutorials gefallen und ich würde mich über jedes Feedback sehr freuen!

Die anderen Teile der Serie

Teil 1: OpenAI (ChatGPT) API Tutorial – Teil #1 

Teil 2: OpenAI (ChatGPT) API Tutorial – Teil #2 Modelle und Dall-E

0 Kommentare

Einen Kommentar abschicken

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert