Fortgeschritten 13 minAPI

Funktionsaufrufe und strukturierte JSON-Ausgaben mit Ollama

Function Calling ermöglicht es einem LLM, selbst zu entscheiden, eine Funktion Ihres Codes aufzurufen – etwa das Wetter abzufragen, eine Datenbank abzufragen oder eine E-Mail zu senden –, indem es die Argumente im richtigen Format zurückgibt. Function Calling mit Ollama beruht auf zwei Bausteinen: dem Parameter format, der gültiges JSON gewährleistet, und dem Feld tools der API, in dem die verfügbaren Funktionen deklariert werden. Dieser Leitfaden zeigt beides in Python, welche lokalen Modelle tatsächlich zuverlässig sind und wie Sie das Ganze mit Schemavalidierung und Wiederholungsversuchen robust absichern.

Von Mohamed Meguedmi·Aktualisierung 2026-08-27·Unter Windows, macOS und Linux getestet

#Warum Function Calling lokal nutzen?

Ein LLM erzeugt Text, keine Aktionen. Function Calling schließt diese Lücke: Statt in Prosa zu antworten, gibt das Modell ein strukturiertes Objekt zurück, das besagt: „Rufe die Funktion get_meteo mit der Stadt Paris auf.“ Ihr Code führt die Funktion aus, ruft das tatsächliche Ergebnis ab und gibt es anschließend an das Modell zurück, das die endgültige Antwort formuliert. Das ist der grundlegende Mechanismus von Agenten und Assistenten, die mit der Außenwelt interagieren.

Im lokalen Betrieb gibt es zwei Herausforderungen. Zunächst muss sichergestellt werden, dass die Ausgabe zu 100 % als JSON geparst werden kann — ein geschwätziges Modell, das „Hier ist das JSON:“ hinzufügt, bringt Ihre gesamte Pipeline zum Scheitern. Dann muss sichergestellt werden, dass das Modell die richtige Funktion mit den richtigen Argumenten wählt, was bei kleinen Modellen schwierig wird. Ollama unterstützt beides über seine API, allerdings mit Schutzmechanismen, die Sie kennen müssen.

Garantierte JSON-Ausgaben
Der Parameter format schränkt die Dekodierung ein: Das Modell kann nur syntaktisch gültiges JSON erzeugen, gegebenenfalls auch JSON, das einem bestimmten Schema entspricht.
Function calling
Das Feld tools deklariert Funktionen im OpenAI-Format; das Modell gibt tool_calls mit den zu übergebenen Argumenten zurück.
100 % lokal
Alles läuft auf Ihrem Rechner über den Ollama-Daemon unter http://localhost:11434, ohne API-Schlüssel und ohne Datenlecks.

#Voraussetzungen und kompatible Modelle

Das Kit „Copilote Local“

Dieser Guide führt Sie zum Modell. Das Kit führt Sie zum Copiloten, der in Ihrem Editor Code schreibt.

  • Lebenslanger Online-Zugang
  • PDF + Dateien
  • Erstattung binnen 30 Tagen

Der JSON-Modus (Parameter format) funktioniert mit jedem Modell. Function Calling über tools erfordert dagegen ein Modell, das für die Werkzeugnutzung trainiert wurde — sonst bleibt das Feld tool_calls leer. Nicht alle Modelle sind gleichwertig: Ein auf dem Papier „kompatibles“ 3B-Modell verwendet häufig falsche Argumente, während ein Modell mit 14B oder mehr bei einfachen Schemata zuverlässig funktioniert.

Ollama installiert
Daemon gestartet und erreichbar auf http://localhost:11434. Prüfen Sie mit ollama list.
Python-SDK
pip install ollama pydantic — le client officiel plus Pydantic pour la validation.
Modell mit zuverlässiger Tool-Nutzung
qwen3.5:9b, mistral-small (24B) und gpt-oss:20b sind hervorragende Ausgangspunkte im Jahr 2026. In Q4: Qwen 3.5 9B ≈ 6,6 GB, ein 24B-Modell ≈ 14 GB VRAM.
Empfohlene GPU
Eine RTX 3060 mit 12 GB kann Qwen 3.5 9B problemlos ausführen; für eine wirklich zuverlässige Tool-Nutzung sollten Sie ein 20–24B-Modell anstreben (RTX 4070/4080 mit 16 GB).
i
JSON-Modus ≠ Funktionenaufruf
Der Parameter format garantiert gültiges JSON, löst aber keinen Funktionsaufruf aus: Das Modell füllt ein Objekt aus, das SIE interpretieren. Das Feld tools hingegen löst eine echte Auswahl einer Funktion durch das Modell aus. Häufig werden beide kombiniert.

#Ein gültiges JSON mit dem Parameter format erzwingen

Der einfachste Fall: Sie möchten, dass das Modell immer mit JSON antwortet, niemals mit freiem Text. Übergeben Sie format: 'json' beim chat-Aufruf. Ollama schränkt dann die Dekodierung Token für Token ein, um ein syntaktisch gültiges Objekt zu erzeugen. Wichtig: Behalten Sie im Prompt eine ausdrückliche Anweisung bei, die die erwarteten Felder beschreibt, sonst erfindet das Modell eine Struktur.

json_mode.py
import ollama
import json

resp = ollama.chat(
    model='qwen3.5:9b',
    messages=[{
        'role': 'user',
        'content': (
            "Extrais le nom, la ville et l'age de ce texte et reponds "
            "UNIQUEMENT en JSON avec les cles nom, ville, age. "
            "Texte : Marie, 34 ans, habite a Lyon."
        ),
    }],
    format='json',  # contraint la sortie a un JSON valide
    options={'temperature': 0},
)

data = json.loads(resp['message']['content'])
print(data)  # {'nom': 'Marie', 'ville': 'Lyon', 'age': 34}
→
Immer temperature 0
Setzen Sie für die strukturierte Extraktion temperature auf 0. Sie möchten deterministisches Verhalten und die Einhaltung der Vorgaben, keine Kreativität. Das reduziert Halluzinationen bei Feldern deutlich.

#Nach Schema strukturiertes JSON (Structured Outputs)

Seit Ende 2024 akzeptiert Ollama in format auch ein vollständiges JSON-Schema (nicht nur die Zeichenkette 'json'). Die Decodierung wird dann zur Einhaltung des Schemas gezwungen: Datentypen, Pflichtfelder und Aufzählungswerte. Das ist deutlich robuster als 'json' allein, da das Modell strukturell kein Objekt erzeugen kann, das dem Schema nicht entspricht. Mit Pydantic lässt sich das Schema automatisch erzeugen.

structured_output.py
import ollama
from pydantic import BaseModel

class Personne(BaseModel):
    nom: str
    ville: str
    age: int

resp = ollama.chat(
    model='mistral-small',
    messages=[{'role': 'user',
               'content': 'Marie, 34 ans, habite a Lyon.'}],
    format=Personne.model_json_schema(),  # schema JSON complet
    options={'temperature': 0},
)

# validation stricte : leve une erreur si non conforme
personne = Personne.model_validate_json(resp['message']['content'])
print(personne)  # nom='Marie' ville='Lyon' age=34

Hier ist die Decodierung auf die Struktur von Personne festgelegt, und model_validate_json führt auf Python-Seite einen weiteren Validierungsdurchlauf durch. Doppeltes Sicherheitsnetz: Die Ausgabe lässt sich garantiert parsen UND entspricht den deklarierten Typen. Das ist das empfohlene Vorgehen für jede Datenextraktion im lokalen Produktionsbetrieb.

#Die Tools-API Schritt für Schritt in Python

Kommen wir zum eigentlichen Function Calling. Die Funktionen werden im Feld tools im OpenAI-Format deklariert (name, description, parameters als JSON Schema). Das Modell liest diese Definitionen und gibt, wenn es den Aufruf einer Funktion für sinnvoll hält, einen oder mehrere tool_calls statt einer Textnachricht zurück. Sie müssen die Funktion ausführen und das Ergebnis zurückgeben.

  1. 01
    Funktionen beschreiben
    Geben Sie für jede Funktion einen eindeutigen name, eine präzise description (das Modell nutzt sie zur Auswahl) und parameters im JSON-Schema-Format an, das die Argumente auflistet und angibt, welche davon required sind.
  2. 02
    Den Aufruf mit tools senden
    Übergeben Sie die Liste tools an ollama.chat. Das Modell entscheidet selbst, ob es eine Funktion aufruft oder direkt antwortet.
  3. 03
    tool_calls lesen
    Prüfen Sie resp['message'].get('tool_calls'). Wenn tool_calls vorhanden ist, möchte das Modell eine Funktion mit den angegebenen Argumenten aufrufen.
  4. 04
    Ausführen und zurückgeben
    Rufen Sie die tatsächliche Python-Funktion auf und übergeben Sie anschließend deren Ergebnis wieder an das Modell, und zwar in einer Nachricht mit role 'tool', damit es die endgültige Antwort formuliert.
tools_definition.py
def get_meteo(ville: str) -> str:
    # ici un vrai appel API ; on simule
    return f"Il fait 22 C et ensoleille a {ville}."

tools = [{
    'type': 'function',
    'function': {
        'name': 'get_meteo',
        'description': "Renvoie la meteo actuelle d'une ville donnee.",
        'parameters': {
            'type': 'object',
            'properties': {
                'ville': {
                    'type': 'string',
                    'description': 'Nom de la ville, ex: Paris',
                },
            },
            'required': ['ville'],
        },
    },
}]

#Die Schleife: Aufruf → Ausführung → Antwort

Function Calling umfasst einen Hin- und Rückweg. Erster Aufruf: Das Modell gibt einen tool_call zurück. Sie führen die Funktion aus. Zweiter Aufruf: Sie senden das Ergebnis zurück, und das Modell formuliert die Antwort in natürlicher Sprache. Hier ist die vollständige Schleife, die sich für mehrere Funktionen wiederverwenden lässt.

boucle_tools.py
import ollama

dispatch = {'get_meteo': get_meteo}

messages = [{'role': 'user',
             'content': 'Quel temps fait-il a Marseille ?'}]

resp = ollama.chat(model='mistral-small',
                   messages=messages, tools=tools)
msg = resp['message']
messages.append(msg)

for call in msg.get('tool_calls') or []:
    fn = call['function']['name']
    args = call['function']['arguments']
    resultat = dispatch[fn](**args)  # execution reelle
    messages.append({
        'role': 'tool',
        'name': fn,
        'content': resultat,
    })

# second appel : le modele redige la reponse finale
final = ollama.chat(model='mistral-small', messages=messages)
print(final['message']['content'])
!
Verwenden Sie Argumente niemals ungeprüft zur Ausführung
Das Modell steuert den Funktionsnamen und die Argumente der Funktion. Verwenden Sie ein Dispatch-Dictionary (Whitelist) statt eval oder eines dynamischen getattr, und validieren Sie jedes Argument vor der Ausführung. Ein kompromittiertes oder halluzinierendes Modell darf nicht beliebige Funktionen aufrufen können.

#Schemavalidierung und Retry-Muster

Beim lokalen Betrieb machen kleine Modelle manchmal Fehler: fehlende Argumente, falscher Typ, nicht existierende Funktion. Vertrauen Sie niemals der unverarbeiteten Ausgabe. Validieren Sie jeden tool_call mit Pydantic. Schlägt die Validierung fehl, wiederholen Sie den Aufruf mit der Fehlermeldung im Kontext — oft korrigiert sich das Modell beim zweiten Versuch.

retry_validation.py
from pydantic import BaseModel, ValidationError

class MeteoArgs(BaseModel):
    ville: str

def valider_appel(call):
    fn = call['function']['name']
    if fn not in dispatch:
        raise ValueError(f"Fonction inconnue: {fn}")
    args = MeteoArgs.model_validate(call['function']['arguments'])
    return fn, args

def appel_avec_retry(messages, max_essais=3):
    for essai in range(max_essais):
        resp = ollama.chat(model='mistral-small',
                           messages=messages, tools=tools)
        try:
            calls = resp['message'].get('tool_calls') or []
            return [valider_appel(c) for c in calls], resp
        except (ValidationError, ValueError) as e:
            messages.append({
                'role': 'user',
                'content': f"Erreur: {e}. Corrige et reessaie.",
            })
    raise RuntimeError('Echec apres retries')
Vor dem Ausführen validieren
Ein Pydantic-Modell pro Funktion fängt fehlende oder falsch typisierte Argumente vor dem Erreichen Ihres Codes auf.
Retry mit Feedback
Das erneute Einfügen der Fehlermeldung in den Kontext führt das Modell zur Korrektur. 2 bis 3 Versuche reichen fast immer aus.
Whitelist von Funktionen
Lehnen Sie jeden Funktionsnamen ab, der nicht in dispatch enthalten ist. Das ist sowohl eine Sicherheitsmaßnahme als auch ein Schutz vor Halluzinationen.
Kontrollierter Fallback
Antworten Sie dem Nutzer nach N Fehlschlägen mit einer klaren Nachricht, statt das Programm abstürzen zu lassen – besonders bei einem kleinen Modell.

#Die Fallstricke kleiner Modelle beim Einsatz von Tools

Die Nutzung von Tools ist kognitiv anspruchsvoll: Das Modell muss die Absicht verstehen, die richtige Funktion auswählen, die Argumente zuordnen und das Format einhalten. Unter 7B sind die Ergebnisse unzuverlässig. Hier erfahren Sie, was beim lokalen Einsatz am häufigsten schiefgeht und wie Sie es beheben können.

tool_calls leer
Das Modell antwortet mit Text, statt die Funktion aufzurufen. Häufig liegt das an einem Modell, das nicht für die Nutzung von Tools trainiert wurde, oder an einer zu unklaren Funktionsbeschreibung. Wechseln Sie zu Qwen 3.5 oder Mistral Small und formulieren Sie die Beschreibungen sorgfältig.
Fehlerhafte Argumente
Das Modell erfindet oder vergisst Felder. Kennzeichnen Sie diese im Schema als required, reduzieren Sie die Anzahl der gleichzeitig bereitgestellten Funktionen und validieren Sie konsequent.
Halluzinierte Funktion
Das Modell ruft eine Funktion auf, die nicht existiert. Eine Positivliste ist bei der Weiterleitung der Funktionsaufrufe zwingend erforderlich.
JSON mit störendem Zusatztext
Ohne Formatvorgabe fügt ein kleines Modell zusätzlichen Text vor oder nach dem JSON ein. Verwenden Sie für die reine Extraktion immer format='json' oder ein Schema.
Zu viele Funktionen
Bei mehr als 5–6 Tools verlieren kleine Modelle den Überblick. Unterteilen Sie nach Teilaufgaben oder setzen Sie ein zweistufiges Routing ein.
→
Ein guter Kompromiss für den lokalen Betrieb
Für zuverlässiges Function Calling ohne High-End-GPU bietet mistral-small (24B) in Q4 (≈14 GB VRAM) auf einer RTX 4080 oft das beste Verhältnis von Qualität zu Ressourcenbedarf. Bei geringerem Ressourcenbudget eignet sich qwen3.5:9b (≈6,6 GB) für wenige, gut beschriebene Funktionen, und gpt-oss:20b ist eine sehr schnelle Alternative. Für einen klar auf Agenten ausgerichteten Einsatz ist glm-4.7-flash (MoE 30B-A3B, ≈19 GB) hervorragend geeignet, wenn Sie über 24 GB VRAM verfügen.

#Weiterführende Informationen

Function Calling ist der Grundbaustein für Agenten und fortgeschrittene Integrationen. Diese Leitfäden der Website führen den vorliegenden Leitfaden weiter:

Ollama über die REST-API in Python integrieren
Der OpenAI-kompatible Endpunkt auf :11434, Streaming und der JSON-Modus in einer echten FastAPI-/Flask-App.
Einen lokalen KI-Agenten mit LangChain und Ollama erstellen
Vom reinen Function Calling zu einem vollständigen Agenten übergehen, der Werkzeuge, Gedächtnis und Schlussfolgerungen miteinander verknüpft.
MCP und lokales LLM: MCP-Server mit Ollama verbinden
Den Zugriff auf Tools (Dateien, Web, Datenbanken) über das Model Context Protocol standardisieren, statt jede Funktion von Hand zu definieren.
Hat Ihnen dieser Guide geholfen?

Haben Sie Feedback, einen Fehler entdeckt oder möchten Sie etwas präzisieren? Geben Sie uns Bescheid – so wird der Guide für alle besser.