Das Hochladen statischer Quellen als Trainingsdaten fuer Ihre AI-Agenten ist nuetzlich – aber was ist, wenn Ihre Datenbank riesig, stark strukturiert, extern gehostet oder in Echtzeit aktualisiert wird?
Es gibt keine praktikable Moeglichkeit, eine gesamte Datenbank in INNOCHATs statische Wissensbibliothek zu laden und gleichzeitig eine Live-Verbindung aufrechtzuerhalten…
Genau hier kommt Function Calling ins Spiel.
Ueber Function Calling koennen Sie Ihrem AI-Agenten in INNOCHAT waehrend einer laufenden Konversation Daten On-Demand zur Verfuegung stellen.
In diesem Beispiel zeigen wir, wie wir RAG-Anreicherung mit Abstracts aus wissenschaftlichen Publikationen von einem externen Aggregator realisieren: der Semantic Scholar API.
Einrichten und Testen der Funktion
Zunaechst benoetigen Sie einen API-Schluessel Ihres externen Datenanbieters, sofern dieser eine gesicherte API anbietet.
In unserem Fall haben wir einen Schluessel direkt von Semantic Scholar angefragt.
Da wir unsere LLM-Antworten mit Informationen aus der Forschung anreichern wollen, muessen wir den passenden API-Endpoint fuer die Suche finden.
Semantic Scholar stellt dazu eine gute Dokumentation bereit.
Was liefert dieser Endpoint zurueck?
Um die Rueckgabe zu inspizieren, haben wir ein kleines Skript geschrieben, das eine Anfrage mit fest kodierten Parametern ausfuehrt.
Der Source Code ist unten aufgefuehrt.
Sie benoetigen Ihren eigenen API-Schluessel, wenn Sie es selbst testen moechten.
Im Beispiel suchen wir nach relevanten Arbeiten zu „Multifidelity Optimization“ und „Gaussian Processes“:
import requests
import json
import os
# Set up the headers with the API key
headers = {
'X-API-KEY': "YOUR OWN API KEY"
}
# Specify the fields you want to fetch for each recommended paper
fields = "paperId,title,authors,abstract,url,referenceCount"
# Define the limit for the number of recommendations to return
limit = 20
# Make the request to get paper recommendations
response = requests.get(
'https://api.semanticscholar.org/graph/v1/paper/search',
headers=headers,
# json=payload,
params={'fields': fields, 'limit': limit, 'query':'multifidelity optimization, gaussian processes' }
)
# Check if the request was successful
if response.status_code == 200:
print(json.dumps(response.json(), indent=2))
else:
print(f"Error: {response.status_code}")
# It's better to print response.text for non-200 responses, as they may not be in JSON format
print(response.text)
Die Ausgabe sieht in etwa so aus:
{
"total": 12096,
"offset": 0,
"next": 20,
"data": [
{
"paperId": "b108e6e11f4a96d5058945f3b582a032e8204ade",
"url": "https://www.semanticscholar.org/paper/b108e6e11f4a96d5058945f3b582a032e8204ade",
"title": "Multifidelity Gaussian processes for failure boundary andprobability estimation",
"abstract": "...",
"referenceCount": 49,
"authors": [
{ "authorId": "98543101", "name": "Ashwin Renganathan" },
{ "authorId": "144321616", "name": "Vishwas Rao" },
{ "authorId": "143672238", "name": "Ionel M. Navon" }
]
},
{
"paperId": "963a5c60ada159d27641a284008f57d6419b26f2",
"url": "https://www.semanticscholar.org/paper/963a5c60ada159d27641a284008f57d6419b26f2",
"title": "Generative Transfer Optimization for Aerodynamic Design",
"abstract": "...",
"referenceCount": 16,
"authors": [
{ "authorId": "2149505113", "name": "Zhendong Guo" },
...
]
}
...
]
}
Die Funktion von Semantic Scholar liefert die Top-N-Ergebnisse nach Relevanz, basierend auf unseren Suchparametern.
Wie Sie sehen, kann die Antwort recht umfangreich sein; hier ist sie aus Platzgruenden gekuerzt.
Idealerweise erhalten Sie vom Endpoint eine klar strukturierte JSON-Antwort, so wie oben.
Unsere Analyse dieses Endpoints (mit den von uns abgefragten Feldern) ergab:
Jedes Ergebnis umfasst im Schnitt 400–500 Tokens.
Abhaengig vom reservierten Tokenlimit fuer Funktionsausgaben koennen Sie also nur eine begrenzte Anzahl an Treffern in den LLM-Kontext einfuegen.
Behalten Sie das im Hinterkopf, wenn Sie entscheiden, welche Informationen priorisiert an das LLM uebergeben werden sollen.
Nun wissen wir, was das LLM als Zusatzkontext aus dem Function Call erhaelt und koennen es mit unserem innoChat-Agenten verbinden.
Es ist IMMER empfehlenswert, Ihr eigenes Skript zu schreiben und die API-Antwort vorab zu testen. Sie sollten genau wissen, welche Informationen Ihrem AI-Agenten zur Verfuegung gestellt werden.
KI-Agent erstellen und vorbereiten
In Ihrem Chatbot in innoChat muessen Sie zunaechst einen passenden AI-Agenten erstellen, der diese Function-Calling-Faehigkeit erhalten soll.
In unserem Beispiel heisst der Agent „The Professor“. Dazu definieren wir eine Agentenbeschreibung und einen Base Prompt.
Wir verwenden im Beispiel das Modell GPT-4-0125-8k.
Unser einfacher Prompt ist im Screenshot unten zu sehen:
Anschliessend speichern wir den Agenten und wechseln in den Tab Knowledge, um das statische RAG aus der eigenen Wissensbibliothek zu deaktivieren.
Das ist nur notwendig, wenn Sie keine statischen Trainingsquellen verwenden wollen.
In unserem Beispiel haben wir ohnehin keine Trainingsdaten hochgeladen, aber wir deaktivieren es der Klarheit halber.
Speichern Sie den Agenten.
Funktion einrichten
Innerhalb des Agenten wechseln Sie in den Tab Functions.
Setzen Sie Response Context Limit auf den maximal erlaubten Wert und klicken Sie auf Add function.
Hier erklären Sie dem LLM:
was die Funktion macht
wie sie aufgerufen wird
welche Parameter sie erwartet
Das LLM entscheidet dann selbststaendig, wann es die Funktion benoetigt und mit welchen Parametern sie aufgerufen wird.
Name und Beschreibung der Funktion sind essenziell, damit die AI den Einsatzzweck versteht.
Achten Sie auf eine klare und ausführliche Beschreibung.
Sie darf maximal 1024 Zeichen inkl. Leerzeichen haben.
In unserem Fall:
Function name: paper_relevance_search
Function description:
This function searches Semantic Scholar, a scholarly literature database. The input parameters will be defined based on extracted information from conversation context. It will return search results containing academic paper metadata (with abstracts) in a JSON format.
The returned fields are defined as follows:
- title: paper title
- abstract: paper abstract
- paperId: paper uuid
- authors: paper authors
- year: paper publication year
- url: paper link
- referenceCount: number of references included in the paper
- citationCount: number of citations of this paper
API-Endpoint definieren
Der von uns genutzte Semantic-Scholar-Endpoint lautet:
https://api.semanticscholar.org/graph/v1/paper/search
Als HTTP-Methode verwenden wir GET.
Die Dokumentation Ihres Endpoints gibt an, ob GET, POST etc. verwendet werden soll.
Fixed Parameters
Fixed (Static) Parameters bleiben für alle API-Aufrufe gleich.
Sie repräsentieren globale Einstellungen, z. B. Format, aktivierte Felder oder Features.
Manche APIs verlangen, dass solche Parameter direkt an die URL angehängt werden.
Unser Semantic-Scholar-Beispiel braucht keine Fixed Parameters.
Ein komplexerer Endpoint wie:
https://app.outscraper.com/api-docs#tag/Businesses-and-POI/paths/~1maps~1search-v3/get
kann hingegen so aussehen:
https://api.app.outscraper.com/maps/search-v3?async=false&fields=name,full_address,phone,site
Öffentliche, aber sichere APIs erfordern fast immer Authentifizierung.
Semantic Scholar ist hier keine Ausnahme.
Im Header übergeben wir unseren API-Schlüssel.
Der Name des Header-Feldes hängt vom Anbieter ab.
In unserem Beispiel heisst er x-api-key:
Variable Parameters
Nun zu den variablen (dynamischen) Parametern.
Diese Parameter hängen von der aktuellen Nutzeranfrage ab und werden zur Laufzeit bestimmt.
Das LLM extrahiert aus dem Dialog selbst, welche Werte es setzen muss, und entscheidet, ob und wie der Function Call ausgeführt wird.
Für unsere Funktion definieren wir:
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The keywords, author names or exact paper IDs to search for"
},
"fields": {
"type": "string",
"description": "The information to be returned, default as 'title,abstract,paperId,authors,year,url,referenceCount,citationCount'"
},
"limit": {
"type": "string",
"description": "The number of papers users want to get, default as 2. Use the default for all cases."
}
},
"required": [
"query"
]
}
Wichtige Punkte:
Ganz oben steht “type”: “object” – das gesamte Parameterset ist ein JSON-Objekt.
Unter properties definieren Sie jeden einzelnen Parameter mit Typ und Beschreibung.
type kann z. B. string, integer, boolean, array usw. sein.
Die description erklaert dem LLM genau, was der Parameter bedeutet (und evtl. Standardwerte).
Je klarer Sie hier sind, desto geringer ist die Chance, dass das LLM falsche Werte waehlt.
Beispiel fuer ein komplexeres Schema mit Array:
{
"type": "object",
"properties": {
"tags": {
"type": "array",
"description": "labels that should be assigned to the user’s request",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the label"
},
"color": {
"type": "string",
"description": "The color of the label"
}
},
"required": ["name", "color"]
}
}
},
"required": ["tags"]
}
Die Funktion darf erst aufgerufen werden, wenn alle in required aufgeführten Parameter verfügbar sind.
Fehlt etwas, kann der Call nicht ausgeführt werden.
Eine gute Referenz zum JSON-Schema:
https://json-schema.org/understanding-json-schema/reference/type
Testen des Chatbots
Wenn alles konfiguriert ist:
Funktion speichern
Agent speichern
Zum Tab Preview wechseln
Sie können rechts oben den Debug Mode aktivieren.
Damit sehen Sie, ob und wie die Funktion aufgerufen wurde und welche Daten zurückkamen:
Und damit haben Sie Ihren KI-Agenten erfolgreich mit On-Demand-Daten von einem externen Anbieter ausgestattet.
In Zukunft werden wir zudem eine Anleitung bereitstellen, wie Sie eine eigene Datenbank-Suchfunktion implementieren und hosten können, die anschliessend mit innoChat integriert wird.