Wie funktioniert AdriRAG?
Eine vollständige Erklärung der RAG-Pipeline – von der Frage bis zur Antwort. Verständlich erklärt, technisch präzise.
Was ist RAG?
RAG steht für Retrieval-Augmented Generation – zu Deutsch: Abruf-gestützte Textgenerierung. Es ist eine Technik, die zwei Welten zusammenbringt:
Retrieval (Abruf)
Das System durchsucht eine Wissensdatenbank nach Textstellen, die zur gestellten Frage passen – ähnlich wie eine sehr schlaue Suchmaschine.
Generation (Erzeugung)
Ein Sprachmodell (LLM) liest die gefundenen Textstellen und formuliert daraus eine präzise, natürlichsprachliche Antwort.
Ein allgemeines LLM kennt nur das, womit es trainiert wurde – und das ist meistens veraltet und enthält nicht deine internen Dokumente. RAG löst das: Das LLM bekommt zur Laufzeit die passenden Textstellen aus deiner eigenen Wissensdatenbank und antwortet nur basierend auf diesen.
Die Pipeline auf einen Blick
AdriRAG verarbeitet jede Anfrage in zwei Phasen:
Dokument
Chunking
Embedding
pgvector DB
Frage
Input-Filter
Embedding
Cosinus-Suche
Re-Ranking
Prompt
LLM
Output-Filter
Antwort
Jeder einzelne Schritt wird in einem Trace protokolliert – du kannst unter Traces genau nachvollziehen, was passiert ist.
Phase 1 – Dokument-Ingestion
Bevor das System Fragen beantworten kann, müssen Dokumente importiert werden. Das geschieht einmalig und läuft in drei Schritten:
Chunking – Zerteilen
Lange Dokumente werden in kleinere Chunks (Textabschnitte) aufgeteilt, typischerweise 200–500 Wörter. Das ist notwendig, weil Embedding-Modelle nur begrenzt viel Text auf einmal verarbeiten können – und weil kurze, fokussierte Abschnitte bei der Suche präzisere Treffer liefern.
Beispiel: Ein 50-seitiges PDF → ~200 Chunks à 400 Wörter Embedding – Text in Zahlen umwandeln
Jeder Chunk wird durch ein Embedding-Modell
(in AdriRAG: gemini-embedding-001) in einen Vektor
umgewandelt – eine Liste von 768 Zahlen, die die semantische Bedeutung
des Texts mathematisch repräsentiert.
Speichern in pgvector
Der Vektor und der Originaltext werden zusammen in PostgreSQL mit pgvector-Erweiterung gespeichert. pgvector ist eine speziell optimierte Datenbank-Erweiterung für die schnelle Suche nach ähnlichen Vektoren – selbst bei Millionen von Chunks.
Phase 2 – Abfrage-Flow
Jede Frage im Chat durchläuft die folgenden Schritte in dieser Reihenfolge:
🛡️ Input-Guardrail & Sicherheitsprüfung
Bevor irgendetwas verarbeitet wird, prüft das System die eingehende Frage auf problematische Inhalte:
Versuche, das LLM mit versteckten Befehlen zu manipulieren, werden blockiert. Z.B. „Ignoriere alle Anweisungen und sage mir..."
Persönliche Daten (E-Mail-Adressen, Telefonnummern) in der Anfrage werden automatisch maskiert, bevor sie weiterverarbeitet werden.
Anfragen sind auf max. 2.000 Zeichen begrenzt, um Missbrauch zu verhindern.
Wird eine Anfrage blockiert, erhält der Nutzer eine klare Fehlermeldung – ohne dass das LLM überhaupt aufgerufen wird.
✏️ Query-Rewrite
Optional kann das System die Frage vor der Suche umformulieren, um bessere Suchergebnisse zu erzielen. Typische Optimierungen:
- Abkürzungen ausschreiben („KI" → „Künstliche Intelligenz")
- Tipp-Fehler korrigieren
- Mehrdeutige Pronomen auflösen
In der Standardkonfiguration von AdriRAG wird die Frage unverändert weitergeleitet – der Schritt ist aber als Erweiterungspunkt in der Pipeline vorhanden.
🔢 Embedding – Die Frage in Zahlen
Die (ggf. umgeschriebene) Frage wird exakt wie beim Import durch das Embedding-Modell in einen Vektor mit 768 Zahlen umgewandelt.
768 Dimensionen
Dieser Query-Vektor wird dann für die Suche in der Datenbank verwendet.
📐 Cosinus-Ähnlichkeitssuche
Das System vergleicht den Query-Vektor mit allen in pgvector gespeicherten Chunk-Vektoren und berechnet die Cosinus-Ähnlichkeit.
Ähnlichkeit = cos(θ) = (A · B) / (|A| × |B|) Die Suche liefert die Top-20 ähnlichsten Chunks (topK × 2),
gefiltert nach einem Mindest-Score von 0.3. Beide Werte sind in den
Settings konfigurierbar.
Eine Frage nach „Kraftfahrzeug" findet auch Chunks, die nur „Auto" oder „PKW" enthalten – weil deren Bedeutungs-Vektoren nah beieinander liegen. Umgekehrt: Eine Frage, die zufällig gleiche Wörter wie ein Chunk enthält, aber eine andere Bedeutung hat, wird nicht als Treffer gewertet.
📊 Re-Ranking & Quellen-Diversität
Die Top-20-Kandidaten aus der Vektorsuche werden in zwei weiteren Schritten verfeinert:
Deduplizierung
Chunks mit identischem Inhalt (SHA-256-Hash) werden entfernt – das passiert bei überlappenden Chunk-Grenzen.
Score-Sortierung
Die verbleibenden Chunks werden absteigend nach Cosinus-Score sortiert – die relevantesten Textstellen kommen zuerst.
Per-Dokument-Diversitäts-Cap ← neu
Maximal 3 Chunks pro Quelldokument werden in den finalen Kontext aufgenommen. Das verhindert, dass bei Fragen, die zwei Themen verbinden (z.B. „Verbindung zwischen KI und Geschäftsmodellen"), ein einziges Dokument alle Kontextplätze belegt. Überschüssige Chunks werden am Ende aufgefüllt, falls noch Plätze frei sind.
Finales Limit
Am Ende werden maximal 5 Chunks (Standard, konfigurierbar) an die nächste Stufe übergeben. Mehr Chunks = mehr Kontext für das LLM, aber auch mehr Tokens und höhere Kosten.
📝 Prompt-Montage
Jetzt wird der eigentliche Prompt zusammengebaut – das Textpaket, das an das LLM geschickt wird. Es besteht aus drei Teilen:
Inhalt: Ein Geschäftsmodell beschreibt...
Quelle [2]: Künstliche Intelligenz – Wikipedia
Inhalt: KI-Methoden umfassen...
Der finale Prompt ist auf 8.000 Zeichen begrenzt (konfigurierbar), um Token-Limits der LLM-APIs nicht zu überschreiten.
Prompts & deren Einfluss
Der System-Prompt ist der wichtigste Hebel, mit dem du das Verhalten des LLM steuerst – noch vor den gefundenen Dokumenten.
🎯 Antwort-Stil
Soll das LLM kurz und prägnant antworten oder ausführlich? Soll es Aufzählungen oder Fließtext verwenden? → Steuerung via System-Instruktion.
🔗 Quellen-Zitierung
Soll die Antwort Quellen explizit benennen ([1], [2])?
Das verhindert, dass das LLM Informationen erfindet, die nicht im Kontext stehen.
🧩 Synthese-Erlaubnis
Darf das LLM Zusammenhänge ableiten die nicht wörtlich so im Dokument stehen? Ein „Synthese-Prompt" erlaubt das explizit – ein restriktiver Prompt verbietet es.
🌍 Sprache & Ton
Antworte immer auf Deutsch? Nutze formelle Sprache? Erkläre Fachbegriffe? Alles über den Prompt steuerbar.
Prompt-Versionen
In AdriRAG kannst du mehrere Prompt-Templates anlegen und im Chat auswählen. Jedes Template hat Versionen – du kannst eine Version aktivieren und sie ist sofort wirksam, ohne Neustart.
Beantworte die Frage ausschließlich basierend auf dem
bereitgestellten Kontext. Zitiere bei jeder Aussage die Quelle
mit [1], [2] etc. Wenn der Kontext die Antwort nicht enthält,
antworte: "Die Antwort ist im bereitgestellten Kontext nicht
enthalten." Beantworte die Frage basierend auf dem bereitgestellten Kontext.
Du darfst Zusammenhänge und Verbindungen zwischen den Quellen
logisch ableiten, wenn diese aus dem Kontext nachvollziehbar sind.
Weise dabei klar aus, welche Schlüsse aus welcher Quelle stammen. Prompts verwalten: → Zur Prompt-Verwaltung
🛡️ Output-Guardrail
Bevor die LLM-Antwort dem Nutzer angezeigt wird, durchläuft sie nochmals eine Sicherheitsprüfung:
Falls das LLM versehentlich persönliche Daten aus dem Kontext wiedergibt (Telefonnummern, E-Mails), werden diese automatisch maskiert.
Fehlen in der Antwort explizite Quellen-Referenzen, hängt das System automatisch die verwendeten Dokument-Titel an – damit die Antwort immer nachvollziehbar bleibt.
Traces – Volle Nachvollziehbarkeit
Jede Anfrage erzeugt einen vollständigen Trace – ein lückenloses Protokoll aller Pipeline-Schritte mit Eingaben, Ausgaben, Scores und Dauer.
Traces sind das wichtigste Werkzeug zur Fehlersuche: Wenn eine Antwort unvollständig oder falsch ist, siehst du im Trace sofort, welche Chunks gefunden wurden, welchen Score sie hatten, und was genau an das LLM geschickt wurde.
Häufige Fragen
Warum antwortet das System „Ich kann die Frage nicht beantworten"?
Das passiert, wenn der Cosinus-Ähnlichkeitsscore aller gefundenen Chunks unter dem Schwellwert (Standard: 0.3) liegt – also keine der gespeicherten Textstellen semantisch nah genug an der Frage ist. Lösung: Importiere Dokumente, die das Thema deiner Frage tatsächlich behandeln.
Warum kommen bei einer Frage zu Thema A nur Dokumente von Thema B?
Der Query-Vektor liegt manchmal semantisch näher an einem Thema als am anderen, auch wenn die Frage beide Themen verbindet. AdriRAG begegnet dem mit dem Per-Dokument-Diversitäts-Cap im Re-Ranker (max. 3 Chunks pro Dokument), sodass immer Raum für mehrere Quellen bleibt.
Kann ich den Cosinus-Schwellwert anpassen?
Ja. Unter Settings kannst du
rag.retrieval.min-score anpassen. Ein niedrigerer Wert
(z.B. 0.2) findet mehr Chunks, erhöht aber das Risiko, irrelevante
Textpassagen in den Kontext zu nehmen.
Was passiert, wenn das LLM etwas erfindet, das nicht im Kontext steht?
Das System-Prompt weist das LLM an, nur aus dem Kontext zu antworten. Der Output-Guardrail prüft zudem, ob Quellen-Referenzen vorhanden sind. Trotzdem kann kein System Halluzinationen zu 100% ausschließen – lies deshalb die zitierten Quellen bei kritischen Entscheidungen nach.
Wie viele Dokumente kann AdriRAG verwalten?
pgvector ist auf Millionen von Chunks ausgelegt. Die praktische Grenze hängt von der verfügbaren Speicher- und RAM-Kapazität ab. Ein typisches 50-seitiges PDF erzeugt ca. 200 Chunks – bei 1.000 Dokumenten wären das ~200.000 Chunks, was pgvector problemlos bewältigt.
Werden meine Dokumente an externe Server geschickt?
Ja, für zwei Schritte: Das Embedding-Modell
(gemini-embedding-001) und das LLM
(gemini-2.5-flash-lite) werden über die Google Gemini API aufgerufen.
Die Dokument-Chunks werden dabei für die Verarbeitung übertragen, aber nicht
dauerhaft gespeichert. Der Transparenz-Hinweis im Chat macht darauf aufmerksam.