In den letzten beiden Artikeln haben wir Ollama als Plattform zur Ausführung lokaler LLMs kennengelernt. Zusätzlich haben wir Open WebUI als UI für Anfragen an Ollama (in Docker) installiert. Eine Frage, die noch offen ist: wie kann Open WebUI auf Ollama zugreifen? Die Antwort ist ganz einfach: Ollama stellt eine REST Schnittstelle zur Verfügung, die wir uns etwas genauer anschauen wollen.
Dokumentation REST api
Das Ollama REST API ist unter https://github.com/ollama/ollama/blob/main/docs/api.md dokumentiert. Von dieser API wollen wir uns konkret anschauen, wie man eine Liste aller heruntergeladenen Ollama Modelle (LLMs) bekommt und wie man Anfragen an ein konkretes Modell machen kann.
Setup
Zunächst ist eine lokale Installation von Ollama erforderlich. Heruntergeladen werden kann Ollama unter https://ollama.com/download. Standardmässig läuft Ollama auf Port 11434. Die lokale Installation kann man einfach mittels curl testen:
curl http://localhost:11434
Die Meldung Ollama is running sollte erscheinen. Wenn Ollama nicht installiert oder nicht aktiv ist, erscheint folgende Fehlermeldung: Failed to connect to localhost port 11434. Mehr Informationen rund um Ollama gibt es unter https://javapro.io/de/lokale-llms.
Auflisten der lokalen Modelle
Folgender HTTP GET Aufruf liefert eine Liste der in Ollama heruntergeladenen Modelle:
GET /api/tags
In der Console kann man das mittels curl ausprobieren:
curl http://localhost:11434/api/tags
Zurück kommt ein JSON, der (falls nur das Modell llama3.2 in Ollama heruntergeladen ist) ungefähr so aussieht:
{
"models": [
{
"name": "llama3.2:latest",
"model": "llama3.2:latest",
"modified_at": "2025-06-20T16:44:14.900225906+02:00",
"size": 2019393189,
"digest": "a80c4f17acd55265feec403c7aef86be0c25983ab279d83f3bcd3abbcb5b8b72",
"details": {
"parent_model": "",
"format": "gguf",
"family": "llama",
"families": [
"llama"
],
"parameter_size": "3.2B",
"quantization_level": "Q4_K_M"
}
}
]
}
Eine Umsetzung dieses REST Aufrufs in beliebigen Programmiersprachen ist möglich. Als Beispiele implementieren wir das in Python und Java.
Implementation in Python
Wir möchten wissen, welche Modelle in Ollama lokal heruntergeladen worden sind. Dabei interessieren v.a. der Name und die Grösse des Modells.
Die requests Library bietet eine get() Funktion, die einen HTTP GET Request macht. Die Library kommt mit der Python Standard Installation mit. Mehr Informationen dazu gibt es unter: https://www.w3schools.com/python/ref_requests_get.asp.
get() liefert ein JSON (in Python als Mix von Dictionaries und Lists) zurück. Die gewünschten Informationen (Name und Grösse des Modells) können mit der Funktion _extract_models_name_and_size() extrahiert werden. Mithilfe von _format_size() kann die Grösse des jeweiligen Modells in leserliche GB formatiert werden.
import requests
ONE_GB = 1_000_000_000
def list_models() -> list[tuple[str, str]]:
url = "http://localhost:11434/api/tags"
response_models = requests.get(url)
return _extract_models_name_and_size(response_models.json())
def _extract_models_name_and_size(json_data: dict) -> list[tuple[str, str]]:
data = []
for _, models in json_data.items():
for model in models:
name = model["name"]
size = model["size"]
item = (name, _format_size(size))
data.append(item)
return data
def _format_size(size: int) -> str:
rounded_size = round(size / ONE_GB, 1)
return f"{rounded_size} GB"
Mit folgendem Code kann man dies testen:
models_data = list_models()
for model_data in models_data:
print(model_data)
Falls die llama3 und gemma3 Modelle in Ollama lokal heruntergeladen worden sind, sieht die Ausgabe folgendermassen aus:
('llama3.2:latest', '2.0 GB')
('llama3.1:latest', '4.7 GB’)
('gemma3:1b', '0.8 GB')
Implementation in Java
Die Umsetzung in Java ist etwas aufwendiger. Gründe dafür sind einerseits die Typisierung und andererseits die fehlende Unterstützung von JSON in Java selbst. Um diese Herausforderungen zu meistern, benutzen wir:
- die gson Library von Google für die Verarbeitung von JSON (Umwandlung eines Strings in Modellklassen/Records)
- Java Records für die Typisierung von Anfragen und Antworten (seit Java 14)
- und die Java HttpClient Library von Java selbst (seit Java 11). Mehr Informationen zum HttpClient gibt es hier: https://jenkov.com/tutorials/java-networking/httpclient.html
Eine mögliche Implementierung könnte so aussehen:
- Via HttpRequest.newBuilder() einen HttpRequest erstellen.
- Mit der send() Funktion der HttpClient Library eine GET Anfrage durchführen. Die Rückmeldung ist eine HttpResponse<T>. Der Input für die send() Funktion ist der erstellte HttpRequest und ein HttpResponse.BodyHandler. Der BodyHandler bestimmt den Typ der HttpResponse. Im gezeigten Beispiel wurde mittels HttpResponse.BodyHandlers.ofString() der Typ String ausgewählt. Daher wird das Resultat als eine HttpResponse<String> präsentiert, aus welcher mit body() die benötigte Antwort als (JSON) String extrahiert werden kann.
- gson.fromJson() convertiert schliesslich den JSON String in Java Records vom Typ ModelList.
public class OllamaRest {
private final HttpClient client = HttpClient.newHttpClient();
private final Gson gson = new GsonBuilder().create();
public ModelList list_models() {
var url = "http://localhost:11434/api/tags";
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.build();
try {
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
return gson.fromJson(response.body(), ModelList.class);
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Das Fehlerhandling ist hier nur ganz einfach umgesetzt, indem eine RuntimeException geworfen wird. In produktiven Anwendungen sollte die Fehlerbehandlung differenzierter gestaltet werden.
Die dazu benötigten Records (die benutzerdefinierte Implementierung von toString zur Formatierung der Modelgröße wurde hier zur besseren Übersichtlichkeit ausgelassen):
public record ModelList(List<Model> models) {}
public record Model(String name, long size) {}
Dies kann man testen mit:
var ollamaRest = new OllamaRest();
var modelList = ollamaRest.list_models();
modelList.models().forEach(System.out::println);
Chat Anfrage an ein Modell
Mit folgendem HTTP POST Aufruf kann eine Chat Anfrage an ein Modell gestellt werden:
POST /api/chat
Für folgende Parameter müssen Daten mitgegeben werden:
- model: Name des Modells, z.B. llama3.2
- messages: eine Liste mit den Fragen. Jede Frage besteht aus einer Rolle (role) und dem content. Für Anfragen an ein Modell ist Rolle immer user.
- stream: für false wird das gesamte Resultat und für true auch Zwischenresultate zurückgegeben
In der Console kann man dies mittels curl ausprobieren. Die Frage lautet: Was ist die Hauptstadt von Frankreich?:
curl http://localhost:11434/api/chat -d '{
"model": "llama3.2",
"messages": [
{
"role": "user",
"content": "What is the capital of France?"
}
],
"stream": false
}'
Zurück kommt ein JSON. Für llama3.2 sieht das Resultat folgendermassen aus:
{
"model": "llama3.2",
"created_at": "2025-07-08T10:22:45.26838Z",
"message": {
"role": "assistant",
"content": "The capital of France is Paris."
},
"done_reason": "stop",
"done": true,
"total_duration": 3777670333,
"load_duration": 3594171250,
"prompt_eval_count": 32,
"prompt_eval_duration": 74249000,
"eval_count": 8,
"eval_duration": 106682000
}
Diesen REST Aufruf implementieren wir nun in Python und Java.
Tipp zur Arbeit mit dem REST API und JSON Daten:
Wenn der JSON String nicht valid ist bzw. das JSON nicht der Spezifikation des REST API entspricht, kann es zu Fehlern kommen. Folgende Schritte können bei der Fehlersuche helfen:
- Zuerst den JSON String mit einem Online Tool validieren, z.B. mit https://jsonformatter.org
- Dann den REST Call mit curl in der Console ausprobieren.
- Und erst wenn die beiden ersten Punkte erfolgreich sind, mit der Implementierung in Python/Java beginnen.
Implementation in Python
Für die Umsetzung in Python wird wiederum die requests Library genutzt. post() macht einen POST Request ans Modell. Mehr Informationen dazu gibt es unter: https://www.w3schools.com/python/ref_requests_post.asp
Die benötigten Parameter für den POST Request können in Python als Mix von Dictionaries und Lists direkt im Code modelliert werden. Das sieht dann dem JSON vom curl Beispiel schon sehr ähnlich. Benötigt werden der Modellname und die Frage. Die Frage selbst ist verpackt in eine Liste von messages. Jede message hat eine role (hier user) und einen content (die eigentliche Frage).
Auf der Antwort wird die json() Funktion aufgerufen. Diese gitb das Resultat als ein JSON Objekt (Mix von Dictionaries und Lists) zurück. Daraus kann mit den Dict Zugriffen [“message”][‘content’] die gesuchte Anwort extrahiert werden.
import requests
def chat(model_name: str, question: str) -> tuple[str, str]:
url = "http://localhost:11434/api/chat"
data = {
"model": model_name,
"messages": [
{
"role": "user",
"content": question
}
],
"stream": False
}
response_chat = requests.post(url, json=data)
content = _extract_chat_content(response_chat.json())
return model_name, content
def _extract_chat_content(json_data: dict) -> str:
return json_data["message"]['content']
Dies kann getestet werden mit:
responseFrance = chat('llama3.2', 'What is the capital of France?')
print(responseFrance)
llama3.2 liefert folgende Antwort:
('llama3.2', 'The capital of France is Paris.’)
Implementation in Java
Für die Umsetzung in Java werden gson, Java Records und die HttpClient Library verwendet.
Hier die wichtigsten Punkte:
- Die Parameter (modelName, question) werden via die Factory Methode ChatRequest.create() in einen Java Record gepackt.
- Der Code für den Http Request ist sehr ähnlich dem Code aus dem vorherigen Java Beispiel. Diesmal wird jedoch ein POST Request erstellt, der nun Parameter mit Daten benötigt. Die Parameter sind als Java Records modelleliert, werden aber vor dem Senden via gson in einen JSON String umgewandelt und dem HttpRequest mitgegeben.
- Das eigentliche Senden des Requests, das Extrahieren des Resultats und die Konvertierung in Modell Klassen (Java Records) ist analog dem vorherigen Beispiel.
public class OllamaRest {
private final HttpClient client = HttpClient.newHttpClient();
private final Gson gson = new GsonBuilder().create();
public ChatResponse chat(String modelName, String question) {
var url = "http://localhost:11434/api/chat";
var data = ChatRequest.create(modelName, question);
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(data)))
.build();
try {
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Error: " + response.statusCode() + ": " + response.body());
}
return gson.fromJson(response.body(), ChatResponse.class);
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Und die Java Records dazu:
public record ChatRequest(String model,
List<Message> messages,
boolean stream) {
public static ChatRequest create(String model, String question) {
return new ChatRequest(model,
List.of(new Message(USER, question)),
false);
}
}
public record Message(String role, String content) {}
public record ChatResponse(String model, Message message) {}
Dies kann getestet werden mit:
var ollamaRest = new OllamaRest();
var responseFrance = ollamaRest.chat("llama3.2", "What is the capital of France?");
System.out.println(responseFrance);
Fazit
Wir haben das Ollama REST API kennengelernt, mit dem man auf die Ollama Modelle zugreifen kann. Zwei konkrete Funktionalitäten haben wir in Python und Java umgesetzt: das Auflisten der Modelle in Ollama und Anfragen an ein konkretes Modell.
Nur so am Rande: Wer gerne auf die OpenAI Modelle zugreifen will … auch dafür gibt es ein REST API: https://platform.openai.com/docs/api-reference/introductio. Zusätzlich bietet OpenAI noch Libraries an (in Python und Javascript), die auf dem REST API aufsetzen und ein komfortableres Arbeiten ermöglichen.
Eine Frage bleibt noch offen: wie funktioniert das, dass man mit einem Modell einen ganzen Chat Verlauf führen kann (und nicht nur einzelne unabhängige Anfragen)? Das Zauberwort heisst Context, und das wollen wir uns im nächsten Artikel genauer anschauen.
Links
Ollama
- Ollama Installation: https://ollama.com/download.
- Infos zu Ollama und Open WebUI: https://javapro.io/de/lokale-llms
REST
- Ollama REST API Doku: https://github.com/ollama/ollama/blob/main/docs/api.md
- OpenAI REST API: https://platform.openai.com/docs/api-reference/introduction
Python
- requests Library – GET: https://www.w3schools.com/python/ref_requests_get.asp
- requests Library – POST: https://www.w3schools.com/python/ref_requests_post.asp
- Source Code der Beispiele in Python: https://github.com/clean-coder/ollama_rest_py
Java
- HttpClient Library: https://jenkov.com/tutorials/java-networking/httpclient.html
- Source Code der Beispiele in Java: https://github.com/clean-coder/ollama_rest_java
