Tutorials  /  AI/ML

Die Ollama-API aus eigenen Anwendungen ansprechen

LLudwig · August 2026 ·10 Min. Lesezeit ·AI/ML, Tutorial

Ein lokal laufendes Modell hilft wenig, solange es nur interaktiv über ollama run erreichbar ist. Ollama startet zusammen mit dem Dienst einen HTTP-Server auf Port 11434, der dieselben Modelle über JSON-Endpunkte bereitstellt. Diese Anleitung zeigt, wie du diesen Server aus eigenem Code ansprichst: Requests, Streaming, strukturierte Ausgaben, Embeddings und die OpenAI-kompatible Schnittstelle.

Was ist die Ollama-API?

Die Ollama-API ist eine HTTP-Schnittstelle, die der Ollama-Dienst standardmäßig auf 127.0.0.1:11434 bereitstellt und lokale Sprachmodelle über JSON-Endpunkte wie /api/generate, /api/chat und /api/embed für eigene Anwendungen zugänglich macht.

Alle Endpunkte sprechen JSON, brauchen keinen API-Key und laufen ohne Cloud-Abhängigkeit. Die wichtigsten Routen im Überblick:

Endpunkt Methode Zweck
/api/generate POST Einzelner Prompt, eine Completion
/api/chat POST Dialog mit messages-Array und Rollen
/api/embed POST Embedding-Vektoren erzeugen
/api/tags GET Lokal verfügbare Modelle auflisten
/api/ps GET Aktuell geladene Modelle anzeigen
/api/pull POST Modell aus der Registry laden

Voraussetzungen

  • Ein Linux-Host mit installiertem Ollama, Version 0.5 oder neuer (ollama --version)
  • Mindestens ein geladenes Modell, etwa ollama pull llama3.2
  • curl und optional Python 3.10 oder neuer für die Client-Beispiele
  • Ausreichend RAM oder VRAM für das gewählte Modell: rund 5 GB für ein 7B-Modell in Q4-Quantisierung

Für erste Tests genügt eine skalierbare Linux-VM mit dedizierter CPU; kleine Modelle bis etwa 3B laufen dort brauchbar im RAM. Größere Modelle brauchen eine GPU, dazu weiter unten mehr.

Ollama für den Netzwerkzugriff konfigurieren

Der Dienst bindet in der Standardinstallation nur an 127.0.0.1. Anwendungen auf demselben Host erreichen ihn damit sofort, Requests von anderen Maschinen laufen in ein Connection refused. Die Bindeadresse steuerst du über die Umgebungsvariable OLLAMA_HOST, die du bei der systemd-Installation als Override setzt:

Konsole
$ sudo systemctl edit ollama

Trage im Editor den folgenden Block ein:

ini
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_NUM_PARALLEL=2"
Environment="OLLAMA_MAX_LOADED_MODELS=2"

Anschließend den Dienst neu starten und die übernommenen Variablen prüfen:

Konsole
$ sudo systemctl restart ollama
$ systemctl show ollama --property=Environment

OLLAMA_NUM_PARALLEL bestimmt, wie viele Requests ein geladenes Modell gleichzeitig bedient, OLLAMA_MAX_LOADED_MODELS, wie viele verschiedene Modelle parallel im Speicher liegen dürfen. Beide Werte multiplizieren den Speicherbedarf, setze sie also passend zum verfügbaren VRAM.

GPU

Passende Infrastruktur bei centron

Dedizierte NVIDIA-GPUs aus deutschen Rechenzentren, stundengenau abgerechnet und in Minuten startklar. GPU-Server mieten →

Der erste Request an /api/generate

Der Endpunkt /api/generate nimmt einen einzelnen Prompt entgegen und liefert eine Completion ohne Konversationskontext. Mit "stream": false bekommst du ein einzelnes JSON-Objekt statt eines Token-Streams:

Konsole
$ curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2",
  "prompt": "Erkläre in einem Satz, was ein Reverse Proxy ist.",
  "stream": false
}'

Die Antwort enthält neben dem Text auch Laufzeitmetriken in Nanosekunden:

json
{
  "model": "llama3.2",
  "created_at": "2026-08-17T09:12:44.118Z",
  "response": "Ein Reverse Proxy nimmt Client-Anfragen entgegen und leitet sie an interne Server weiter.",
  "done": true,
  "done_reason": "stop",
  "total_duration": 1894233000,
  "eval_count": 24,
  "eval_duration": 812004000
}

Aus eval_count und eval_duration berechnest du den Durchsatz: 24 Tokens in 0,81 Sekunden entsprechen rund 29 Tokens pro Sekunde. Diese Zahl ist der zuverlässigste Indikator dafür, ob dein Host für das gewählte Modell ausreicht.

Wie unterscheiden sich /api/generate und /api/chat?

/api/generate verarbeitet einen einzelnen Prompt-String ohne Rollen, während /api/chat ein messages-Array mit den Rollen system, user und assistant erwartet und damit mehrstufige Dialoge, Tool-Calls und Bild-Eingaben unterstützt.

Für Anwendungen mit Gesprächsverlauf ist /api/chat die richtige Wahl. Den Verlauf hält deine Anwendung selbst vor und schickt ihn bei jedem Request komplett mit; Ollama speichert keinen Sitzungszustand.

Konsole
$ curl http://localhost:11434/api/chat -d '{"model":"llama3.2","stream":false,"messages":[{"role":"system","content":"Antworte knapp und ohne Einleitung."},{"role":"user","content":"Was macht systemd-journald?"}]}'

Streaming-Antworten in Python verarbeiten

Mit "stream": true liefert Ollama NDJSON, also eine JSON-Zeile pro Token-Chunk, abgeschlossen von einem Objekt mit "done": true. Das folgende Beispiel nutzt requests und gibt die Tokens fortlaufend aus:

python
import json
import requests
URL = "http://localhost:11434/api/chat"
payload = {
    "model": "llama3.2",
    "messages": [{"role": "user", "content": "Nenne drei Vorteile von NDJSON."}],
    "stream": True,
    "options": {"temperature": 0.2, "num_ctx": 8192},
}
with requests.post(URL, json=payload, stream=True, timeout=300) as r:
    r.raise_for_status()
    for line in r.iter_lines(decode_unicode=True):
        if not line:
            continue
        chunk = json.loads(line)
        if chunk.get("done"):
            tps = chunk["eval_count"] / (chunk["eval_duration"] / 1e9)
            print(f"\n{chunk['eval_count']} Tokens, {tps:.1f} Tokens/s")
            break
        print(chunk["message"]["content"], end="", flush=True)

Wichtig sind zwei Details: Setze einen großzügigen timeout, weil das Laden eines Modells beim ersten Request Minuten dauern kann, und werte chunk.get("done") aus, statt auf leeren Content zu prüfen. Der Block options überschreibt Generierungsparameter pro Request. num_ctx legt das Kontextfenster in Tokens fest und funktioniert in allen Versionen; neuere Ollama-Versionen kennen zusätzlich die globale Variable OLLAMA_CONTEXT_LENGTH.

Wer keine eigene Parsing-Schleife schreiben will, nutzt das offizielle Paket pip install ollama, das dieselben Endpunkte als Generator kapselt.

Warum antwortet der erste Request so langsam?

Der erste Request ist langsam, weil Ollama die Modellgewichte erst von der Festplatte in VRAM oder RAM laden muss; danach bleibt das Modell für die Dauer von keep_alive geladen und antwortet ohne diese Verzögerung.

graph TD
    A["Client sendet POST /api/chat"] --> B{"Modell bereits im Speicher?"}
    B -- ja --> D["Prompt auswerten"]
    B -- nein --> C["Gewichte in VRAM laden"]
    C --> D
    D --> E["Tokens als NDJSON streamen"]
    E --> F{"keep_alive abgelaufen?"}
    F -- nein --> G["Modell bleibt geladen"]
    F -- ja --> H["Speicher wird freigegeben"]

Den Standardwert von fünf Minuten hebst du entweder global über OLLAMA_KEEP_ALIVE an oder pro Request über das Feld keep_alive. Der Wert -1 hält das Modell dauerhaft geladen, 0 gibt den Speicher direkt nach der Antwort frei:

Konsole
$ curl http://localhost:11434/api/generate -d '{"model":"llama3.2","prompt":"","keep_alive":-1}'

Ein leerer Prompt lädt das Modell, ohne Text zu generieren. Das eignet sich als Warmup nach einem Neustart. Ob die Antwortzeiten anschließend produktionstauglich sind, hängt an der Hardware: Auf CPUs bleibt ein 7B-Modell im einstelligen Token-Bereich pro Sekunde, während dasselbe Modell auf GPU-Instanzen für LLM-Inference je nach Karte 40 bis 100 Tokens pro Sekunde erreicht. Prüfe mit nvidia-smi, ob Ollama die GPU tatsächlich belegt; fällt der Dienst auf CPU zurück, steht der Grund im Log unter journalctl -u ollama.

Strukturierte JSON-Antworten erzwingen

Ab Ollama 0.5 akzeptiert das Feld format ein vollständiges JSON-Schema, an das die Ausgabe gebunden wird. Damit entfällt das fehleranfällige Nachparsen von Freitext:

Konsole
$ curl http://localhost:11434/api/chat -d '{"model":"llama3.2","stream":false,"format":{"type":"object","properties":{"hostname":{"type":"string"},"port":{"type":"integer"}},"required":["hostname","port"]},"messages":[{"role":"user","content":"Extrahiere Host und Port aus: db01.internal:5432"}]}'

Das Feld message.content enthält dann einen JSON-String, der dem Schema entspricht. Ältere Versionen kennen nur "format": "json", das lediglich gültiges JSON ohne Schemabindung garantiert. Setze zusätzlich "options": {"temperature": 0}, wenn du reproduzierbare Extraktionen brauchst.

Embeddings erzeugen

Der Endpunkt /api/embed erzeugt Vektoren für einen String oder ein Array von Strings und ist die Grundlage für semantische Suche und RAG-Pipelines:

Konsole
$ curl http://localhost:11434/api/embed -d '{"model":"nomic-embed-text","input":["Erster Satz","Zweiter Satz"]}'

Die Antwort enthält unter embeddings ein Array von Float-Arrays, bei nomic-embed-text mit 768 Dimensionen. Der ältere Endpunkt /api/embeddings verarbeitet nur einen einzelnen String und liefert das Ergebnis unter embedding. Für neue Integrationen nimm /api/embed, weil Batch-Requests dort deutlich weniger Overhead erzeugen.

OpenAI-kompatible Endpunkte nutzen

Unter /v1 stellt Ollama eine zum OpenAI-Schema kompatible Schnittstelle bereit. Bestehende Anwendungen brauchen damit nur eine andere base_url:

python
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
resp = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Was ist ein systemd-Target?"}],
)
print(resp.choices[0].message.content)

Das Feld api_key ist Pflicht, weil das SDK es erwartet; Ollama wertet den Wert nicht aus. Verfügbar sind /v1/chat/completions, /v1/completions, /v1/embeddings und /v1/models. Ollama-spezifische Parameter wie keep_alive oder num_ctx gibt es hier nicht, dafür brauchst du die nativen /api-Routen.

Zugriff absichern

Ollama bringt keine Authentifizierung mit. Sobald der Port über 127.0.0.1 hinaus erreichbar ist, kann jeder im Netz Modelle abfragen, laden und löschen. Setze einen Reverse Proxy mit TLS und Basic Auth davor und lasse den Port 11434 in der Firewall geschlossen:

nginx
server {
    listen 443 ssl;
    server_name <deine-domain>;
    location /api/ {
        auth_basic "ollama";
        auth_basic_user_file /etc/nginx/ollama.htpasswd;
        proxy_pass http://127.0.0.1:11434;
        proxy_buffering off;
        proxy_read_timeout 600s;
    }
}

proxy_buffering off ist bei Streaming zwingend, sonst hält nginx die NDJSON-Zeilen zurück und die Antwort erscheint erst am Stück. Das lange proxy_read_timeout verhindert Abbrüche beim ersten Laden eines großen Modells.

Verifikation

Drei Aufrufe zeigen, ob Dienst, Modelle und Speicherbelegung stimmen:

Konsole
$ curl -s http://localhost:11434
Ollama is running
$ curl -s http://localhost:11434/api/tags | jq -r '.models[].name'
llama3.2:latest
nomic-embed-text:latest
$ curl -s http://localhost:11434/api/ps | jq -r '.models[] | "\(.name) \(.size_vram)"'
llama3.2:latest 3489660928

Liefert /api/ps ein leeres Array, ist gerade kein Modell geladen. Zeigt size_vram den Wert 0, läuft die Inference auf der CPU.

Troubleshooting

  • curl: (7) Connection refused von einem anderen Host: OLLAMA_HOST steht noch auf 127.0.0.1. Override setzen, Dienst neu starten, mit ss -tlnp | grep 11434 die Bindeadresse prüfen.
  • 404 {"error":"model 'x' not found"}: Das Modell ist lokal nicht vorhanden. Mit ollama pull <modell> nachladen; Tags sind exakt, llama3.2 und llama3.2:1b sind verschiedene Modelle.
  • Antwort bricht mittendrin ab: num_predict begrenzt die Ausgabelänge, Standard ist unbegrenzt bis zum Kontextende. Prüfe done_reason im letzten Chunk. Steht dort length, ist das Kontextfenster voll, also num_ctx erhöhen oder den Verlauf kürzen.
  • Browser-Requests scheitern mit CORS-Fehler: Erlaubte Ursprünge über OLLAMA_ORIGINS setzen, etwa Environment="OLLAMA_ORIGINS=https://app.example.org".
  • Antworten werden mit jedem Request langsamer: Zu viele Modelle gleichzeitig geladen. OLLAMA_MAX_LOADED_MODELS senken und in /api/ps prüfen, ob Modelle in den RAM ausgelagert wurden.

Fazit

Die Ollama-API deckt mit /api/generate, /api/chat und /api/embed alles ab, was eine Anwendung für lokale Inference braucht, und die /v1-Routen machen bestehende OpenAI-Clients ohne Codeumbau nutzbar. Achte auf drei Punkte im Betrieb: keep_alive passend zur Nutzung setzen, num_ctx bewusst wählen und den Port niemals ohne vorgeschalteten Proxy exponieren. Als nächsten Schritt lohnt sich das Messen von eval_count und eval_duration pro Request, damit du Regressionen bei Modellwechseln sofort siehst.

Weiterlesen

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

Ludwig Technische Redaktion

Schreibt bei centron über Linux-Administration, Container und Datenbanken – mit Fokus auf Anleitungen, die im Betrieb tatsächlich funktionieren.

Kategorie AI/ML
Teilen
Noch offene Fragen?

Unser Team hilft Ihnen bei Ihrem konkreten Setup weiter – von Menschen, die die Plattform selbst betreiben.

War dieses Tutorial hilfreich?

Ihre Antwort wird anonym gespeichert und hilft uns, die Tutorials zu verbessern.

Kommentare

Noch keine Kommentare – stellen Sie die erste Frage zu diesem Tutorial.

Zum Kommentieren anmelden

Kommentare stehen centron-Kunden offen. Melden Sie sich in Ihrem Konto an, um eine Frage zu diesem Tutorial zu stellen.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren