DE ▾
API-Schlüssel erhalten

Ollama-API in Python und eine gehostete Alternative

Die Ollama-API in Python benötigt etwa zehn Zeilen, und dieselbe Code-Struktur funktioniert auch gegen einen gehosteten Endpunkt. Dieser Artikel zeigt beide Ansätze und erklärt, wann du welchen wählst.

Aktualisiert

Wichtige Punkte

  • Ollama hört auf Port 11434 und bietet eine native API sowie einen OpenAI-kompatiblen /v1-Endpunkt an.
  • Das ollama-Paket, plain requests und das OpenAI-SDK funktionieren alle; das OpenAI-SDK ist am portabelsten.
  • Der Wechsel zu einer gehosteten API bedeutet, die Basis-URL, den Schlüssel und den Modellnamen zu ändern.
  • Lokal ist am besten für Offline-Arbeit und feste Hardware; gehostet ist einfacher, wenn du keine GPU hast.
Ein lokaler Computer, der durch ein leuchtendes Kabel mit einem Cloud-Server verbunden ist, repräsentiert lokale und gehostete LLM-APIs

Die Kurzversion

Wenn du nach ollama api python suchst, willst du normalerweise eines von drei Dingen: ein Modell aufrufen, das auf deiner eigenen Maschine läuft, Token daraus streamen oder dasselbe Skript woanders ausführen. Ollama bietet dir alle drei Möglichkeiten. Es startet einen lokalen Server, standardmäßig unter http://localhost:11434, und du kommunizierst damit über das ollama Python-Paket, über plain HTTP oder über einen OpenAI-Client, der auf seinen /v1-Pfad zeigt.

Der Haken ist, dass das Modell auf deiner Hardware laufen muss. Ein Laptop ohne eine ordentliche GPU wird bei größeren Modellen langsam sein, und ein Server ohne eine ist eine schlechte Wahl. Für diesen Fall ist eine gehostete OpenAI-kompatible API der einfachere Weg, und da das Anfrageformat dasselbe ist, kostet dich der Wechsel nur drei Zeilen Konfiguration. Beide Wege werden unten abgedeckt, mit Code, den du einfügen kannst.

Ein lokales Modell mit dem ollama-Paket aufrufen

Installiere Ollama, zieh ein Modell herunter und stelle sicher, dass der Server läuft. Installiere dann den Python-Client:

pip install ollama
ollama pull llama3.2

Ein grundlegender Chat-Aufruf sieht so aus. Der Modellname ist der, den du heruntergeladen hast; llama3.2 ist nur ein Beispiel.

import ollama

response = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Explain DNS in two sentences."}],
)
print(response["message"]["content"])

Streaming

Gib stream=True an, und du erhältst einen Iterator von Chunks statt einer einzigen Antwort. Jeder Chunk enthält ein Stück der Antwort in message.content.

import ollama

stream = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Write a haiku about servers."}],
    stream=True,
)
for chunk in stream:
    print(chunk["message"]["content"], end="", flush=True)
print()

Den Client auf eine andere Maschine zeigen

Wenn Ollama auf einem anderen Host läuft, erstelle einen Client mit einer expliziten Adresse, zum Beispiel ollama.Client(host="http://192.168.1.20:11434"). Standardmäßig hört der Server nur auf der lokalen Maschine, also muss der Remote-Zugriff auf der Serverseite bewusst aktiviert werden. Exponiere ihn nicht öffentlich im Internet, ohne dass ein Proxy und eine Authentifizierung davor geschaltet sind, da die native API keine eigene Schlüsselprüfung hat.

Plain HTTP mit requests

Du brauchst das Paket überhaupt nicht. Der native Chat-Endpunkt ist POST /api/chat. Streaming ist dort standardmäßig aktiv, und der Stream ist newline-getrenntes JSON, kein SSE. Setze "stream": false, wenn du ein einzelnes Objekt zurückbekommen willst.

import requests

r = requests.post(
    "http://localhost:11434/api/chat",
    json={
        "model": "llama3.2",
        "messages": [{"role": "user", "content": "Name three HTTP status codes."}],
        "stream": False,
    },
    timeout=120,
)
r.raise_for_status()
print(r.json()["message"]["content"])

Setze einen großzügigen Timeout. Die erste Anfrage nach einem Pull muss das Modell in den Speicher laden, und das kann viel länger dauern als spätere Anfragen.

Das manuelle Auslesen des Streams ist nur wenige Zeilen mehr. Rufe requests.post(..., stream=True) auf, durchlaufe r.iter_lines(), überspringe leere Zeilen und wende json.loads auf jede Zeile an. Jedes Objekt enthält ein kleines Stück der Antwort, und das letzte enthält "done": true. Das ist praktisch in einem minimalen Container, in dem du kein weiteres Paket installieren möchtest, und es macht klar, was die Bibliothek für dich erledigt. Die gehostete API streamt anders, als SSE-Zeilen, die mit data: beginnen, was ein weiterer Grund ist, das Streaming für dich vom OpenAI SDK in portablen Code analysieren zu lassen.

Das OpenAI-SDK mit Ollama verwenden

Ollama stellt auch einen OpenAI-kompatiblen Endpunkt unter /v1 zur Verfügung. Das bedeutet, das offizielle openai-Paket funktioniert, und die meiste Software, die es dir erlaubt, eine benutzerdefinierte Basis-URL zu setzen, ebenfalls. Der Schlüssel wird vom SDK verlangt, aber von einem lokalen Ollama ignoriert, also reicht jeder String.

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": "Give me a one-line summary of TCP."}],
)
print(resp.choices[0].message.content)

Dies ist die nützlichste Form, weil sie deinen Code vom Server entkoppelt. Dieselbe Funktion kann heute mit einem lokalen Modell sprechen und morgen mit etwas anderem, was der nächste Abschnitt zeigt.

Derselbe Code gegen eine gehostete API

Die gehostete Option hier ist eine OpenAI-kompatible API mit einem einzelnen Modell, uncensored, betrieben von einem unabhängigen Anbieter und darauf abgestimmt, ohne Inhaltsablehnungen für die rechtmäßige Nutzung durch Erwachsene zu antworten. Es ist nur Text. Die Basis-URL ist https://api.ollamaapi.cc/v1, und du authentifizierst dich mit einem Bearer-Schlüssel von der API-Schlüssel-Seite.

Hier ist eine Version, die ihr Ziel aus Umgebungsvariablen liest, mit den gehosteten Werten als Standard. Um zu deinem lokalen Server zurückzukehren, exportiere zwei Variablen und ändere sonst nichts.

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.getenv("LLM_BASE_URL", "https://api.ollamaapi.cc/v1"),
    api_key=os.getenv("LLM_API_KEY", "YOUR_API_KEY"),
)
MODEL = os.getenv("LLM_MODEL", "uncensored")

resp = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "List four uses of a message queue."},
    ],
    temperature=0.7,
)
print(resp.choices[0].message.content)

Für lokale Läufe setze LLM_BASE_URL=http://localhost:11434/v1, LLM_API_KEY=ollama und LLM_MODEL=llama3.2. Der Quickstart hat dieselbe Einrichtung in curl und Node.

Streaming, JSON-Modus und Tools auf der gehosteten Seite

Der gehostete Endpunkt unterstützt Streaming über SSE, JSON-Modus, Tool Calling und die üblichen Sampling-Parameter (temperature, top_p, stop, seed und die Strafen). Streaming mit dem SDK ist dieselbe Schleife, die du für jeden OpenAI-kompatiblen Server schreiben würdest:

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Tell a two-paragraph story about a lighthouse."}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Für strukturierte Ausgabe setze response_format={"type": "json_object"} und sage im Prompt, dass du JSON willst. Parse immer in einem try-Block; ein Modell kann immer noch etwas zurückgeben, das du nicht erwartet hast.

Ein Unterschied zum lokalen Betrieb ist im Code wichtig: Limits. Ein voller Schlüssel erlaubt 8 parallele Anfragen und 300 Anfragen pro Minute, und eine gestreamte Anfrage behält ihren Slot bis zum Ende des Streams. Wenn du mit Threads ausfächerst, begrenze den Pool auf 8 und wiederhole bei HTTP 429 unter Verwendung des Retry-After-Headers, wenn er vorhanden ist.

Eine Konversation am Laufen halten

Weder der lokale noch der gehostete Chat-Endpunkt merkt sich etwas zwischen Aufrufen. Der Server sieht nur die Nachrichten, die du sendest, also ist ein Chatbot eine Liste, die du anhängst und erneut sendest. Das Muster ist für beide Ziele identisch, was ein weiterer Grund ist, den OpenAI-kompatiblen Client als deinen Standard zu behalten.

history = [{"role": "system", "content": "You are a helpful assistant."}]

def ask(text):
    history.append({"role": "user", "content": text})
    resp = client.chat.completions.create(model=MODEL, messages=history)
    answer = resp.choices[0].message.content
    history.append({"role": "assistant", "content": answer})
    return answer

print(ask("Pick a name for a hiking app."))
print(ask("Give me a tagline for it."))

Zwei praktische Hinweise. Erstens haben lokale Modelle eine Kontextlänge, die du festlegst und die der Speicher halten muss; wenn die Historie darüber hinaus wächst, werden ältere Turns abgeschnitten oder der Aufruf schlägt fehl, je nach Einstellungen. Das gehostete Modell akzeptiert ein 100.000-Token-Fenster einschließlich der Vervollständigung, was für die meisten Chats weit mehr ist als nötig, aber lange Historien kosten immer noch Input-Token bei jedem Turn. Zweitens, wenn eine Historie lang wird, fasse die ältesten Turns in eine kurze Nachricht zusammen, anstatt sie alle erneut zu senden. Das hält Latenz und Kosten auf beiden Backends stabil.

Höflich wiederholen

Bei der gehosteten API gibt eine temporäre Überlastung HTTP 429 mit einem Retry-After: 5-Header zurück. Ein kleiner Wrapper behandelt es:

import time
from openai import RateLimitError

def chat_with_retry(messages, tries=4):
    for attempt in range(tries):
        try:
            return client.chat.completions.create(model=MODEL, messages=messages)
        except RateLimitError:
            time.sleep(5 * (attempt + 1))
    raise RuntimeError("still rate limited")

Lokales Ollama setzt dir kein Ratenlimit, aber es wartet Anfragen in eine Warteschlange, wenn das Modell ausgelastet ist, daher schadet dieselbe Wrapper-Funktion dort nicht.

Lokal oder gehostet: Wie triffst du die Entscheidung

Keine Wahl ist allgemein besser. Nutze die folgenden Punkte als Checkliste.

  • Wähle lokales Ollama, wenn du offline arbeiten musst, wenn Daten die Maschine niemals verlassen dürfen, wenn du bereits eine leistungsfähige GPU besitzt oder wenn du schnell viele verschiedene Open-Weight-Modelle ausprobieren willst.
  • Wähle eine gehostete API, wenn du keine GPU hast, wenn du auf einem kleinen VPS oder in CI arbeitest, wenn mehrere Personen oder Dienste ein Backend teilen, oder wenn du ein langes Kontextfenster willst, ohne den Speicher selbst zu dimensionieren. Das gehostete Modell akzeptiert bis zu 100.000 Token für Prompt plus Vervollständigung.
  • Nutze beide während der Entwicklung: iteriere lokal und verweise in der Produktion über Umgebungsvariablen auf die gehostete URL.

Gehostete Nutzung wird pro Token abgerechnet, zu $0,15 pro 1M Input-Token und $0,50 pro 1M Output-Token, aus Prepaid-Guthaben. Die Preisseite listet Auflagebeträge auf, und neue Konten können ein $0,50 Testguthaben mit einem Klick beanspruchen, keine Karte nötig. Prompts werden nicht zum Training verwendet.

Fehler, auf die du stoßen wirst

SymptomWahrscheinliche UrsacheLösung
Verbindung auf Port 11434 verweigertDer Ollama-Server läuft nichtStarte die App oder führe ollama serve aus
Modell nicht gefundenDas Modell wurde nie gepullt, oder der Name hat einen TippfehlerFühre ollama list aus, dann ollama pull den Namen, den du verwendest
Der erste Aufruf läuft in ein TimeoutDas Modell lädt nochErhöhe das Timeout oder sende eine Warm-Up-Anfrage
Authentifizierungsfehler auf der gehosteten APIFehlender oder falscher Bearer-SchlüsselPrüfe LLM_API_KEY und die Basis-URL
HTTP 429 mit Code concurrencyMehr als 8 parallele Anfragen (2 bei einem Test-Schlüssel)Reduziere die Anzahl der Worker
HTTP 429 mit Code rate_limitedRatenlimit für Anfragen pro Minute überschrittenWarte kurz und versuche es erneut

Fehlgeschlagene oder abgelehnte Anfragen auf der gehosteten Seite werden nicht berechnet, daher kostet dich die Retry-Logik nichts für die fehlgeschlagenen Versuche.

Fragen und Antworten

Was ist die Standard-Adresse der Ollama API?

Ein lokaler Ollama-Server hört auf http://localhost:11434. Die nativen Endpunkte liegen unter /api, z. B. /api/chat, und der OpenAI-kompatible Endpunkt liegt unter /v1.

Kann ich das OpenAI Python SDK mit Ollama verwenden?

Ja. Setze base_url auf http://localhost:11434/v1 und gib einen beliebigen String als API-Schlüssel an. Das SDK sendet dann standardmäßige Chat-Vervollständigungsanfragen an dein lokales Modell.

Wie wechsle ich von Ollama zu einer gehosteten API?

Ändere die Basis-URL, den Schlüssel und den Modellnamen. Wenn dein Code sie aus Umgebungsvariablen liest, ist keine Codeänderung nötig.

Funktioniert die gehostete API ohne GPU bei mir?

Ja. Das Modell läuft beim Anbieter, daher benötigt dein Skript nur eine Internetverbindung und einen Bearer-Schlüssel. Du zahlst pro Token aus Prepaid-Guthaben.

Dein Schlüssel ist nur ein Formular entfernt

Erstelle ein Konto, kopiere den Schlüssel, ändere die Basis-URL. Das ist die gesamte Einrichtung.

API-Schlüssel erhalten