KI auf dem eigenen Server: Wie wir ein lokales LLM für die automatische Auswertung von Pflegeinformationen eingerichtet haben

Wir arbeiten seit einiger Zeit am Angehörigen-Kompass, einem Projekt, das pflegende Angehörige mit aktuellen Informationen zu Leistungen, Formularen und Prozessen unterstützen soll. Dabei stellt sich immer wieder die gleiche Frage: Woher kommen aktuelle, verlässliche Daten – und wie halten wir sie aktuell?

Gesetze ändern sich. Pflegegeld-Beträge werden angepasst. Formulare werden überarbeitet. All das manuell zu pflegen ist auf Dauer nicht realistisch. Also haben wir uns gefragt: Können wir ein LLM nutzen, um öffentlich zugängliche Informationen automatisch auszuwerten – und zwar lokal, ohne Daten an externe Dienste zu senden?

Die Antwort: Ja. Und das hier ist der Weg dahin.


Die Ausgangslage

Unser Projekt verarbeitet medizinische und pflegerische Daten. Externe KI-APIs wie OpenAI oder Claude kommen für die automatisierte Verarbeitung nicht in Frage – nicht weil sie schlecht wären, sondern weil wir die volle Kontrolle über die Daten behalten wollen. Gleichzeitig haben wir keinen Server mit GPU, und das Budget für dedizierte KI-Hardware ist schlicht nicht da.

Was wir haben: Einen Contabo Cloud VPS 30 mit 8 vCPU-Kernen, 24 GB RAM und 200 GB NVMe-Speicher für knapp 14 Euro im Monat. Kein Supercomputer, aber mehr als genug für unseren Ansatz.

Die Idee

Der Plan ist simpel:

  1. Ollama auf dem Server installieren – ein Tool, das LLMs lokal ausführt, auch ohne GPU
  2. n8n als Workflow-Engine daneben stellen
  3. Automatisierte Workflows bauen, die regelmäßig öffentliche Webseiten abrufen, den Inhalt an das lokale LLM schicken und strukturierte Daten zurückbekommen

Das Ganze soll als Batch-Job nachts laufen. Ob die Verarbeitung 5 Minuten oder 5 Stunden dauert, ist egal – Hauptsache, morgens liegen aktuelle Daten vor.

Ollama: LLM ohne GPU

Die Installation von Ollama auf Ubuntu ist ein Einzeiler:

curl -fsSL https://ollama.com/install.sh | sh

Ollama erkennt automatisch, dass keine GPU vorhanden ist, und läuft im CPU-only-Modus. Danach ein Modell ziehen:

ollama pull llama3.1:8b

Das Llama 3.1 mit 8 Milliarden Parametern belegt etwa 5 GB auf der Platte und braucht im Betrieb rund 6 GB RAM. Von unseren 24 GB bleibt damit mehr als genug übrig für n8n und das Betriebssystem.

Ein erster Test direkt auf der Kommandozeile zeigt, dass es funktioniert:

ollama run llama3.1:8b "Extrahiere die Pflegegeld-Beträge als JSON: 
  Pflegegrad 2: 347 Euro, Pflegegrad 3: 599 Euro, 
  Pflegegrad 4: 800 Euro, Pflegegrad 5: 990 Euro."

Ergebnis nach etwa 65 Sekunden:

{
  "pflegegeld": [
    {"pflegegrad": 2, "betrag_euro": 347},
    {"pflegegrad": 3, "betrag_euro": 599},
    {"pflegegrad": 4, "betrag_euro": 800},
    {"pflegegrad": 5, "betrag_euro": 990}
  ]
}

Langsam, aber korrekt. Für einen Batch-Job völlig ausreichend.

n8n: Der Workflow

n8n läuft bei uns als Docker-Container auf dem gleichen Server. Damit n8n und Ollama problemlos kommunizieren können, nutzen wir network_mode: host in der Docker-Compose-Konfiguration. So kann n8n Ollama einfach über localhost:11434 ansprechen.

Vor den Server haben wir Caddy als Reverse Proxy gesetzt, der automatisch SSL-Zertifikate von Let's Encrypt holt. n8n ist damit sicher über HTTPS erreichbar.

Unser erster Workflow – die Pflegegeld-Extraktion – besteht aus diesen Schritten:

Schedule Trigger → Läuft wöchentlich

HTTP Request → Ruft eine Webseite mit Pflegeinformationen ab

HTML bereinigen → Entfernt Scripts, Styles und HTML-Tags, behält den reinen Text

Ollama Extraction → Schickt den Text an das lokale LLM mit der Anweisung, die Pflegegeld-Beträge als JSON zu extrahieren

JSON validieren → Prüft, ob die Antwort gültiges JSON mit den erwarteten Feldern ist

Erfolgreich? → Ergebnis aufbereiten / Fehler protokollieren → Verzweigung je nach Validierungsergebnis

Logger → Protokolliert Laufzeit, Token-Verbrauch und Ergebnis

Die Learnings (und es waren viele)

Der Weg zum funktionierenden Workflow war alles andere als geradlinig. Hier die wichtigsten Erkenntnisse:

Das Kontextfenster muss explizit gesetzt werden

Ollama nutzt standardmäßig nur 4096 Tokens als Kontextfenster, obwohl Llama 3.1 eigentlich 128K kann. Ohne die Einstellung num_ctx: 16384 in den Optionen hat das Modell immer nur einen Bruchteil des Textes gesehen – und entsprechend unsinnige Ergebnisse produziert. Das war die Ursache für die meisten Fehlversuche.

CPU-Inferenz braucht großzügige Timeouts

Ein 8B-Modell mit 5000+ Tokens auf CPU braucht bei uns etwa 14 Minuten. Das sprengt jeden Standard-Timeout. Wir haben drei Stellen anpassen müssen: das HTTP-Timeout im Code-Node, die n8n-Umgebungsvariable N8N_RUNNERS_TASK_TIMEOUT, und den Ollama-Request selbst. Alle stehen jetzt auf 4 Stunden – bei einem nächtlichen Batch-Job ist das kein Problem.

Docker und Host-Netzwerk

Die Kommunikation zwischen n8n im Docker-Container und Ollama auf dem Host war tückisch. host.docker.internal funktionierte in unserem Setup nicht zuverlässig, und die Docker-Bridge-IP wurde von der Firewall blockiert. Die sauberste Lösung: n8n mit network_mode: host laufen lassen. Damit teilt sich der Container das Netzwerk des Hosts und localhost funktioniert einfach.

format: "json" ist der eigentliche Hebel

Kleinere Modelle lassen sich leicht ablenken. Unser erster Versuch mit dem vollen Seitentext führte dazu, dass das Modell statt JSON eine ausführliche Zusammenfassung der Pflegeleistungen schrieb. Die Ollama-Option format: "json" erzwingt auf API-Ebene eine JSON-Ausgabe – viel wirkungsvoller als Großbuchstaben im Prompt.

Nicht das LLM beschneiden, sondern ihm Zeit geben

Unsere erste Reaktion auf lange Laufzeiten war, den Input-Text zu kürzen. Das war der falsche Ansatz – wir mussten ja vorher wissen, wo die relevanten Informationen stehen, was den ganzen Zweck des LLM-Einsatzes untergräbt. Die richtige Lösung: den vollen Text schicken und dem Modell die Zeit geben, die es braucht.

Das Ergebnis

Nach einem langen Tag des Debuggens läuft der Workflow stabil. Das LLM extrahiert zuverlässig die aktuellen Pflegegeld-Beträge aus einer beliebigen Webseite und liefert sie als strukturiertes JSON:

{
  "stand": "2026",
  "pflegegeld": [
    {"pflegegrad": 2, "betrag_euro": 347},
    {"pflegegrad": 3, "betrag_euro": 599},
    {"pflegegrad": 4, "betrag_euro": 800},
    {"pflegegrad": 5, "betrag_euro": 990}
  ]
}

Die Verarbeitung dauert etwa 14 Minuten – für einen wöchentlichen Nacht-Job völlig akzeptabel. Und das Wichtigste: Alle Daten bleiben auf unserem Server. Keine API-Calls an externe Dienste, keine medizinischen oder personenbezogenen Daten, die das Haus verlassen.

Wie geht es weiter?

Dieser Workflow ist erst der Anfang. Die nächsten Schritte:

  • Weitere Quellen anbinden: Informationen von Bund, Ländern, Kranken- und Pflegekassen automatisch auswerten
  • PDF-Verarbeitung: Gesetzestexte und Broschüren als PDF einlesen und analysieren
  • Modell-Upgrade: Bei Bedarf auf ein 13B-Modell wechseln – der Server hat genug RAM
  • Integration in den Angehörigen-Kompass: Extrahierte Daten direkt in die Rails-Anwendung schreiben

Für unter 14 Euro im Monat haben wir eine lokale KI-Pipeline, die automatisch aktuelle Pflegeinformationen aus dem Web extrahiert. Nicht so schnell wie eine GPU, nicht so schlau wie GPT-4 – aber vollständig unter unserer Kontrolle, datenschutzkonform, und für unseren Zweck genau richtig.

Und als Bonbon gibt es dann hier noch den Workflow als JSON.


Dieses Projekt entstand als Zusammenarbeit zwischen einem menschlichen Entwickler und Claude (Anthropic) als KI-Pairing-Partner. Der gesamte Aufbau – von der Servereinrichtung über die Ollama-Installation bis zum fertigen n8n-Workflow – wurde in einer einzigen Pairing-Session umgesetzt. Ich empfehle es jedem das einmal zu probieren - wenn eine KI sich über die Halluzinationen einer anderen KI lustig macht sind das absolute Gold Momente 😃