RAG-Architektur

Wie RAG
tatsächlich verdrahtet ist.

Eine Architektur mit Trennung der Belange. Der Controller lenkt nur; das Embedding-Modell lebt auf dem nativen Inferenz-Daemon; der Vektor-Speicher lebt auf dem Daten-Worker. Drei Prozesse, drei Verantwortungen, eine Leitung. Diese Seite ist die technische Sicht für Power-User und Operatoren, die wissen wollen, warum die Form so ist und wie man sie biegen kann, wenn nötig.


Die Kette

Controller → Inferenced → Daten-Worker.

Bei einer Chat-Anfrage, die RAG auslöst, beteiligen sich drei Prozesse in dieser Reihenfolge:

  1. Controller (Port 8880) — empfängt die Anfrage, lenkt sie. Der RAG-Pfad läuft über zwei Routen: /api/v1/embeddings (Proxy zu Inferenced) und /api/v1/vector/search (Aggregator über Daten-Worker). Der Controller macht keine Inferenz in-process; alles ist Routing.
  2. Inferenced (Port 8883) — die native GGUF-Runtime. Hält ein quantisiertes Embedding-Modell (nomic-embed-text-Q4_K_M.gguf, 768-dim, ~80 MB) im Speicher geladen. Die Embeddings-Route des Controllers proxyt hierher.
  3. Daten-Worker (Port 8892) — speichert die indizierten Dokumente und die Vektor-Einträge. Der Vektor-Such-Aggregator des Controllers bettet die Anfrage ein (über #2), dann bittet er den Daten-Worker um die k-nächsten-Nachbarn-Treffer.

Die Chat-Completion-Anfrage läuft dann durch den Inferenz-Pfad mit den abgerufenen Passagen als Kontext injiziert und liefert die fundierte Antwort plus Zitat-Metadaten an den Client zurück.


Warum diese Form

Drei Gründe.

1. Der Controller bleibt rein lenkend.

Würde der Controller das Einbetten in-process erledigen, müsste jeder Knoten mit einem Controller das Embedding-Modell im Speicher halten — RAM-Verbrauch und Startzeit. Schlimmer: In Cluster-Setups ist der Controller womöglich nicht der GPU-Knoten, also würde er auf einer CPU einbetten, während eine GPU einen Host weiter herumsteht. Wenn der Controller ein reiner Router bleibt, ist das Skalieren der Embedding-Arbeit vom Skalieren der Routing-Arbeit entkoppelt.

2. Das Embedding-Modell ist GGUF und klein.

nomic-embed-text-Q4_K_M ist 80 MB auf der Platte, läuft komfortabel auf CPU und produziert 768-dimensionale Vektoren, die mit dem Storage-Layout des Daten-Workers kompatibel sind. Die Quantisierung auf Q4_K_M tauscht ein wenig Embedding-Präzision gegen ein Modell, das auf einem Raspberry Pi 4 in den Speicher passt und 1k Tokens auf jeder modernen CPU deutlich unter einer Sekunde einbettet. GGUF heißt, llama.cpp kann es direkt bedienen; Inferenced spricht GGUF bereits — also der natürliche Ort dafür.

3. Der Vektor-Speicher liegt, wo die Daten liegen.

Der Daten-Worker hält bereits die Quell-Dokumente, die Chunks, die Mandanten-Grenzen, das Audit-Protokoll und den Datei-Speicher. Vektor-Einträge neben die Chunks zu legen (statt in eine separate Vektor-Datenbank) heißt: Löschen, Neu-Einbetten, Mandanten-Isolation und Backup sind eine Operation, nicht fünf.


Eigene Topologien

Den Controller auf ein anderes Embedding-Backend zeigen lassen.

Die Standard-Topologie hat Inferenced und den Controller auf demselben Host (oder dort, wo der Controller Inferenced über das Cluster-Netz erreichen kann). Manche Installationen wollen etwas anderes — Inferenced auf einem dedizierten GPU-Host, ein externer Embedding-Dienst oder ein anderes GGUF-Modell ganz. Das wird über eine Umgebungsvariable am Controller geregelt:

# /etc/eldric/eldric-aios.env

ELDRIC_EMBED_BACKEND_URL=http://inferenced-host:8883

Jede URL, die den OpenAI-kompatiblen /v1/embeddings-Endpunkt spricht, funktioniert — Inferenced ist die Voreinstellung, aber Ollama erfüllt es ebenso, ebenso ein eigener llama.cpp-Server, vLLM, TGI oder jede Cloud-Embedding-API, wenn Sie Embeddings extern senden wollen (die meisten Kunden tun das nicht).

Nach dem Editieren der env-Datei den Controller neu starten (sudo systemctl restart eldric-aios-controller); das neue Backend wird beim nächsten Chat-Request übernommen.


Einzelknoten vs. Cluster

Wo jeder Prozess lebt.

Einzelknoten

Alles auf einem Host. Controller, Inferenced und Daten-Worker sind drei systemd-Units auf derselben Maschine. Inferenced teilt sich den Host mit der LLM-Inferenz-Arbeit; das Einbetten belegt einen Bruchteil des GPU-Speichers und läuft ohne Streit neben größeren Modellen.

Multi-Knoten

Der Controller lebt auf einem kleinen Management-Host. Inferenced lebt auf einem GPU-Host (oder auf einem Knoten mit genug CPU, wenn Sie dem Einbetten keine GPU widmen wollen). Der Daten-Worker lebt auf dem Storage-starken Host. Der Controller erreicht Inferenced über ELDRIC_EMBED_BACKEND_URL; den Daten-Worker erreicht er über die Topologie-Ermittlung (keine env-Variable nötig — über Heartbeat gepusht).

Edge

Auf einem Pi 4 oder NUC, der die minimale Edge-Runtime fährt, leben alle drei auf demselben Edge-Host (die Plattform liefert sie als Einheit). Der Edge-Knoten bettet lokal ein, indiziert lokal, fragt lokal an. Wenn ein zentraler Cluster konfiguriert ist, verschiebt der Bundle-Export-/-Import-Pfad ganze Wissensbasen zwischen Edge und Zentrum, ohne neu einzubetten.


Fehler-Modi

Was passiert, wenn etwas weg ist.

Wenn Inferenced unerreichbar ist, liefert der Controller einen strukturierten Fehler auf der Embeddings-Route (502 mit erklärendem Body). Neue Uploads schlagen beim Einbetten fehl und bleiben als „in Warteschlange“ markiert; die Plattform versucht es beim nächsten Upload-Zyklus erneut, sobald Inferenced wieder da ist. Chat-Anfragen, die RAG ausgelöst hätten, fallen auf den reinen Chat zurück (ohne Zitate), statt die ganze Anfrage scheitern zu lassen.

Wenn der Daten-Worker unerreichbar ist, liefert die Vektor-Suche 503; Chat-Anfragen fallen auf den reinen Chat zurück. Uploads über den Chunked-Upload-Pfad in der Oberfläche puffern am Controller und werden geleert, sobald der Daten-Worker zurück ist.

Wenn das Embedding-Modell nicht geladen ist, liefert die Embeddings-Route 404 mit einem Modell-nicht-geladen-Hinweis. Das Inferenced-Admin-Dashboard hat einen Laden-Knopf; klicken (die Datei liegt auf einer Standard-Installation unter /data/eldric/models/nomic-embed-text-Q4_K_M.gguf), und das Einbetten läuft beim nächsten Request wieder.


Weiter

Tiefer einsteigen.

Für die Anleitung für Endnutzer: RAG verwenden. Für die Chunking-Strategien je Inhaltstyp: Chunking-Strategien. Für die kompressionsbasierte Memory-Preview, die die Vektor-Suche bei Parallelität beschleunigt: Erweiterte Retrieval. Für die inferenzseitige Preview, die das Memory beim Eintreffen des Prompts konsultiert: Intelligente Memory-Inferenz.

Für den Rest des Systems, in dem der RAG-Pfad sitzt: Wie es funktioniert führt durch die gesamte 4-Ebenen-Architektur (Client → Edge → Controller / Router / Data → 10 Worker, inklusive Inferenced).