Warum eine Eigenentwicklung
Wer heute ein RAG-System lokal betreiben will, findet eine Handvoll Open-Source-Lösungen — die meisten davon für den persönlichen Gebrauch gedacht. Ein Verzeichnis indexieren, ein paar PDFs durchsuchen, ein einzelnes Embedding-Modell. Für den Schreibtisch eines Einzelnen reicht das. Für ein Unternehmen mit Netzlaufwerken, Mail-Archiven, ERP-Daten und Compliance-Anforderungen nicht.
Kiara wurde von Anfang an als Unternehmens-KI konzipiert — mit dem Ziel, den gesamten relevanten Datenbestand einer Organisation einer KI zugänglich zu machen. Nicht ein Verzeichnis, sondern alle Datenquellen, die in einem Unternehmen typischerweise anfallen: Dateisysteme, Netzlaufwerke, WebDAV, E-Mail-Postfächer, SQL-Datenbanken, ERP-Systeme. Mehrbenutzerfähig, mit Berechtigungsmanagement, multimodaler Dokumentenverarbeitung und datenschutzkonform — auch bei Nutzung von Cloud-KI.
Dass der Weg von der Spezifikation zur Produktion trotzdem iterativ verlief, liegt in der Natur der Sache. Jede Skalierungsstufe brachte konkrete technische Grenzen zum Vorschein:
GPU-Server unter Kontrolle
Ollama ist ein Inference-Server — kein Orchestrierungswerkzeug. Ein selbstgeschriebener Proxy zwischen Kiara und dem GPU-Server ermöglich gleichzeitige LLM-Inferenz für Chat und Embedding für die Indexierung. Er routet Anfragen intelligent zwischen Ollama und dem Embedding-Deinst, startet und stoppt den DDU-Container nach Bedarf und warnt bei drohender GPU-Überlastung. Er macht all das transparent für die Anwendung.
Eigener Embedding-Server
Ollama behandelt Embedding-Modelle wie LLMs — mit dem gleichen Overhead beim Laden, der gleichen Quantisierung, dem gleichen Speichermanagement. Für kleine Modelle unter einer Milliarde Parameter ist das ineffizient. Ein eigener Embedding-Dienst auf Basis von Sentence-Transformers verarbeitet dieselben Modelle in voller FP16-Präzision, bei deutlich höherem Durchsatz und geringerem VRAM-Verbrauch.
Härtung der Ingestion-Pipeline
Jeder Neustart nach Feature-Updates der Plattform brach laufende Indexierungen ab — bei Datenquellen mit
hunderttausenden Dateien ein echtes Problem. Die Auslagerung in einen eigenständigen
Worker-Dienst ermöglichte die Ingestion parallel zur Entwicklung der Plattform.
Die Warmup-Phase bereitet das Backend auf die Ingestion vor und lädt alle benötigten modelle. Eine
automatische Pausierung sorgt dafür, dass die Ingestion nicht abbricht, wenn das Embedding-Backend nicht erreichbar ist
BM25 → Elasticsearch
Die Keyword-Komponente der Hybrid-Suche basierte auf einer In-Memory-Bibliothek, die den gesamten Korpus als Python-Datenstrukturen im Arbeitsspeicher hielt. Bei 500.000 Chunks verschlang allein das Tokenisieren 5 GB RAM, und der erste Request nach einem Neustart blockierte das gesamte System für über zwei Minuten.
Post-Filter → Pre-Filter
Berechtigungsfilter liefen als Post-Filter: Erst alle Chunks laden, dann in Python filtern. Bei 2 Millionen Chunks kostete allein der Aufbau des Berechtigungs-Sets 160 MB RAM — pro Anfrage. Die Lösung war ein Array-basierter Pre-Filter direkt in Qdrant.
Vektor-Store unter Last
Datei-Löschungen und Pfad-basierte Abfragen liefen über einen Volltext-Index — bei jeder Operation ein Substring-Scan über alle Einträge in der Vektordatenbank. Bei wenigen tausend Dateien fiel das nicht auf. Bei 4 Millionen Chunks dauerte eine einzelne Löschoperation so lange, dass sie in Timeouts lief. Die Lösung war ein zusätzlicher Schlüsselwort-Index für exakte Pfad-Matches: O(1) statt Full Scan — dieselbe Operation, die vorher in Timeouts lief, war danach nicht mehr messbar.