Zum Inhalt springen
🔍 Architektur-Guide

RAG-Systeme On-Premise — Ihre Dokumente, Ihr Wissen

RAG (Retrieval-Augmented Generation) verbindet Ihr LLM mit Ihren eigenen Dokumenten — Verträge, Handbücher, E-Mails, Wikis — ohne das Modell neu zu trainieren. Auf eigener Hardware betrieben, verlässt kein einziges Dokument Ihr Netzwerk. Dieser Guide zeigt die komplette Architektur eines On-Premise RAG-Systems: von der Document Ingestion über die Vektordatenbank bis zur Antwortgenerierung.

RAG-Architektur im Überblick

Ein RAG-System besteht aus drei Hauptkomponenten, die in einer Pipeline zusammenarbeiten:

1 📄 Ingestion Dokumente laden, parsen, chunken, embedden
2 🗄️ Retrieval Relevante Chunks aus Vektordatenbank abrufen
3 🤖 Generation LLM generiert Antwort mit Kontext

Jede Komponente kann unabhängig skaliert und ausgetauscht werden. Das ist ein entscheidender Vorteil gegenüber monolithischen Lösungen: Sie können die Vektordatenbank wechseln, ohne die Ingestion-Pipeline anzupassen, oder das LLM austauschen, ohne die Retrieval-Logik zu ändern.

Document Processing Pipeline

Die Qualität Ihres RAG-Systems steht und fällt mit der Document Processing Pipeline. Hier werden Ihre Rohdokumente in semantische Einheiten zerlegt und als Vektoren gespeichert.

Schritt 1: Document Loading

Unterstützen Sie alle relevanten Formate in Ihrem Unternehmen:

  • PDF: PyMuPDF (fitz) oder Unstructured — OCR-Unterstützung für gescannte Dokumente
  • DOCX/PPTX/XLSX: python-docx, python-pptx, openpyxl
  • E-Mail: IMAP-Integration, MSG/EML-Parser
  • Confluence/SharePoint: REST-API-Konnektoren
  • Datenbanken: SQL-Connectors für strukturierte Daten
# Beispiel: Document Loading mit LangChain
from langchain_community.document_loaders import (
    PyMuPDFLoader,
    UnstructuredWordDocumentLoader,
    ConfluenceLoader,
)

# PDF laden
pdf_loader = PyMuPDFLoader("/data/vertraege/vertrag_2024.pdf")
documents = pdf_loader.load()

# Confluence-Wiki laden (On-Premise Confluence)
wiki_loader = ConfluenceLoader(
    url="https://confluence.intern.example.de",
    username="rag-service",
    api_key="INTERNAL_KEY",
    space_key="DOCS",
)
wiki_docs = wiki_loader.load()

Schritt 2: Chunking — die kritischste Entscheidung

Die Chunking-Strategie hat den größten Einfluss auf die RAG-Qualität. Zu große Chunks verwässern die Relevanz, zu kleine verlieren den Kontext.

Strategie Chunk-Größe Geeignet für Nachteile
Fixed-Size 500–1000 Tokens Einfache Texte, Blogs Zerschneidet Sätze/Absätze
Recursive Text 500–1000 Tokens Allgemeine Dokumente Braucht gute Separatoren
Semantic Variabel Heterogene Dokumente Langsamer, braucht Embeddings
Document-Aware Nach Struktur Verträge, Handbücher, PDFs Aufwändig zu implementieren
Parent-Child Klein + Eltern-Ref Komplexe Dokumente Höhere Komplexität
# Empfohlene Chunking-Strategie für deutsche Texte
from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,           # ~800 Zeichen pro Chunk
    chunk_overlap=200,        # 200 Zeichen Überlappung
    separators=[
        "\n\n",               # Absätze
        "\n",                 # Zeilenumbrüche
        ". ",                 # Satzenden (Deutsch: Punkt + Leerzeichen)
        "! ",                 # Ausrufezeichen
        "? ",                 # Fragezeichen
        "; ",                 # Semikolon
        ", ",                 # Komma
        " ",                  # Wortgrenzen
    ],
    length_function=len,
)

chunks = splitter.split_documents(documents)
💡 Best Practice für deutsche Texte: Verwenden Sie 800–1000 Zeichen pro Chunk mit 200 Zeichen Überlappung. Deutsche Komposita und lange Satzstrukturen brauchen mehr Kontext als englische Texte. Testen Sie verschiedene Chunk-Größen mit Ihren spezifischen Dokumenten und messen Sie die Retrieval-Qualität.

Schritt 3: Metadata-Enrichment

Reichern Sie jeden Chunk mit Metadaten an, die beim Retrieval als Filter dienen:

# Metadaten für jeden Chunk hinzufügen
for chunk in chunks:
    chunk.metadata.update({
        "source": "vertrag_2024.pdf",
        "department": "legal",
        "date": "2024-03-15",
        "document_type": "vertrag",
        "access_level": "confidential",  # DSGVO-relevantes Zugangslevel
        "language": "de",
    })

Embedding-Modelle für deutsche Texte

Embedding-Modelle wandeln Text in hochdimensionale Vektoren um, die semantische Ähnlichkeit abbilden. Für On-Premise-Betrieb nutzen Sie Open-Source-Modelle, die lokal auf Ihrer GPU laufen.

Modell Dimensionen Max. Tokens Deutsche Qualität VRAM Lizenz
BAAI/bge-m3 1024 8192 ⭐⭐⭐⭐⭐ ~2 GB MIT
intfloat/multilingual-e5-large 1024 512 ⭐⭐⭐⭐ ~1.4 GB MIT
nomic-ai/nomic-embed-text-v1.5 768 8192 ⭐⭐⭐⭐ ~550 MB Apache 2.0
sentence-transformers/all-MiniLM-L6-v2 384 512 ⭐⭐⭐ ~250 MB Apache 2.0
Alibaba/gte-Qwen2-7B-instruct 3584 32768 ⭐⭐⭐⭐⭐ ~15 GB Apache 2.0

Unsere Top-Empfehlung für deutsche Enterprise-Dokumente ist BAAI/bge-m3: Es bietet exzellente multilinguale Performance, unterstützt lange Kontexte (8192 Tokens) und benötigt nur ~2 GB VRAM — das passt neben dem LLM auf dieselbe GPU.

# Lokales Embedding mit Ollama
# ollama pull nomic-embed-text

from langchain_community.embeddings import OllamaEmbeddings

embeddings = OllamaEmbeddings(
    base_url="http://localhost:11434",
    model="nomic-embed-text",
)

# Oder mit Sentence Transformers (mehr Kontrolle)
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("BAAI/bge-m3")
vectors = model.encode(
    ["Dieser Vertrag regelt die Zusammenarbeit..."],
    normalize_embeddings=True,
)

Vektordatenbanken im Vergleich

Die Vektordatenbank speichert Ihre Embeddings und ermöglicht die schnelle Ähnlichkeitssuche. Für On-Premise-Betrieb kommen drei Hauptkandidaten in Frage:

Feature Qdrant Milvus ChromaDB
Sprache Rust Go + C++ Python
Deployment ✅ Einfach (Docker) ⚠️ Komplex (etcd, MinIO) ✅ Sehr einfach
Max. Vektoren 100 Mio.+ 1 Milliarde+ ~10 Mio.
Suchgeschwindigkeit ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
Metadata-Filterung ✅ Erweitert ✅ Erweitert ✅ Basis
Hybrid Search ✅ Sparse + Dense ✅ Sparse + Dense
Multi-Tenancy ✅ Payload-basiert ✅ Partitionen ⚠️ Eingeschränkt
Hochverfügbarkeit ✅ Raft-basiert ✅ Distributed
RAM-Bedarf (1 Mio. Vektoren) ~4 GB ~6 GB ~8 GB
RBAC / Auth ✅ API-Keys ✅ Vollständig
Lizenz Apache 2.0 Apache 2.0 Apache 2.0

Qdrant — unsere Enterprise-Empfehlung

Qdrant bietet den besten Kompromiss aus Performance, Einfachheit und Enterprise-Features. In Rust geschrieben, ist es extrem speichereffizient und schnell. Das Docker-Deployment ist in unter 5 Minuten erledigt:

# Qdrant mit Docker starten
docker run -d \
  --name qdrant \
  -p 6333:6333 -p 6334:6334 \
  -v qdrant_data:/qdrant/storage \
  --restart unless-stopped \
  qdrant/qdrant:latest

# Collection erstellen
curl -X PUT "http://localhost:6333/collections/documents" \
  -H "Content-Type: application/json" \
  -d '{
    "vectors": {
      "size": 1024,
      "distance": "Cosine"
    },
    "optimizers_config": {
      "indexing_threshold": 20000
    }
  }'

Milvus — für sehr große Datenmengen

Milvus ist die richtige Wahl, wenn Sie >100 Millionen Vektoren verwalten müssen. Das Deployment ist komplexer (etcd, MinIO als Dependencies), aber die Skalierung ist nahezu unbegrenzt. Nutzen Sie Milvus, wenn Sie Kubernetes und ein MLOps-Team haben.

ChromaDB — für Prototypen und kleine Teams

ChromaDB ist die einfachste Option — ein einziger pip install chromadb genügt. Ideal für Prototypen und Teams mit <10.000 Dokumenten. Für Produktion fehlen jedoch wichtige Features wie Hochverfügbarkeit und granulares Access Control.

Retrieval-Strategien

Die einfachste Retrieval-Strategie — „finde die ähnlichsten Vektoren" — funktioniert für viele Fälle, aber es gibt deutlich bessere Ansätze:

Hybrid Search: Semantic + Keyword

Kombinieren Sie semantische Vektorsuche mit klassischer Keyword-Suche (BM25). Das verbessert die Retrieval-Qualität besonders bei Fachbegriffen und Eigennamen, die in Embeddings manchmal nicht gut abgebildet werden.

# Hybrid Search mit Qdrant
from qdrant_client.models import models

results = client.query_points(
    collection_name="documents",
    query=dense_vector,           # Semantische Suche
    using="dense",
    query_filter=models.Filter(   # Metadata-Filter
        must=[
            models.FieldCondition(
                key="department",
                match=models.MatchValue(value="legal"),
            ),
            models.FieldCondition(
                key="access_level",
                match=models.MatchAny(any=["public", "internal"]),
            ),
        ]
    ),
    limit=10,
)

Re-Ranking mit Cross-Encoder

Nach dem initialen Retrieval können Sie die Ergebnisse mit einem Cross-Encoder re-ranken. Cross-Encoder sind langsamer als Bi-Encoder (Embeddings), aber deutlich genauer bei der Relevanzbeurteilung:

# Re-Ranking mit Cross-Encoder
from sentence_transformers import CrossEncoder

reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-12-v2")

# Top-20 Ergebnisse holen, dann re-ranken auf Top-5
pairs = [(query, doc.text) for doc in initial_results]
scores = reranker.predict(pairs)

# Nach Score sortieren
ranked_results = sorted(
    zip(initial_results, scores),
    key=lambda x: x[1],
    reverse=True,
)[:5]

Multi-Query Retrieval

Lassen Sie das LLM mehrere Varianten der Nutzeranfrage generieren und suchen Sie für jede Variante separat. Das verbessert die Abdeckung deutlich:

# Multi-Query: LLM generiert 3 Varianten der Frage
original: "Welche Kündigungsfristen gelten für unsere Mietverträge?"
variant1: "Mietvertrag Kündigungsfrist Regelung"
variant2: "Wie lang ist die Frist zur Kündigung eines Mietverhältnisses?"
variant3: "Vertragliche Bestimmungen zur Beendigung von Mietverträgen"

# Ergebnisse aller Varianten kombinieren (Union + Deduplizierung)

Antwortgenerierung & Prompting

Der letzte Schritt ist die Generierung einer Antwort durch das LLM. Der entscheidende Faktor ist das Prompt-Design:

SYSTEM_PROMPT = """
Sie sind ein hilfreicher Assistent für die Example GmbH.
Beantworten Sie Fragen ausschließlich basierend auf den bereitgestellten Dokumenten.

Regeln:
1. Zitieren Sie die relevanten Quellen in Ihrer Antwort.
2. Wenn die Dokumente keine Antwort enthalten, sagen Sie das ehrlich.
3. Spekulieren Sie nicht und erfinden Sie keine Informationen.
4. Antworten Sie immer auf Deutsch in professionellem Ton.
5. Bei rechtlichen Fragen weisen Sie darauf hin, dass dies keine Rechtsberatung ist.

Bereitgestellte Dokumente:
{context}
"""

Qualitätssicherung & Evaluation

Ein RAG-System ohne Evaluierung ist ein Risiko. Messen Sie regelmäßig die Qualität Ihres Systems mit diesen Metriken:

Metrik Was sie misst Zielwert
Retrieval Recall@5 Wie oft ist das richtige Dokument in den Top-5? > 90%
Answer Correctness Stimmt die generierte Antwort faktisch? > 85%
Faithfulness Basiert die Antwort auf den bereitgestellten Dokumenten? > 95%
Answer Relevance Beantwortet die Antwort die gestellte Frage? > 90%
Latenz (E2E) Gesamtzeit von Frage bis Antwort < 5 Sekunden

Tools wie RAGAS (Retrieval Augmented Generation Assessment) automatisieren diese Evaluierung und erzeugen Reports, die auch für DSGVO-Audits nützlich sind.

Praxisbeispiel: RAG für eine Kanzlei

Eine mittelgroße Kanzlei mit 50 Anwälten möchte ihre Mandantenakten durchsuchbar machen, ohne Daten an Cloud-Dienste zu übertragen (Pflicht gemäß § 203 StGB).

Setup:

  • Hardware: 1x Server mit NVIDIA A100 80 GB (→ GPU-Guide)
  • LLM: Llama 3.1 70B via Ollama
  • Embedding: bge-m3 (1024 Dim., lokal auf derselben GPU)
  • Vektordatenbank: Qdrant (Docker, gleicher Server)
  • Dokumente: ~50.000 PDFs (Verträge, Schriftsätze, Urteile)

Architektur-Highlights:

  • Access Control: Metadata-Filter stellt sicher, dass Anwälte nur auf ihre eigenen Mandate zugreifen können
  • Audit-Trail: Jede Anfrage wird mit Timestamp, User-ID und Quelldokumenten protokolliert
  • Air-Gap: Der Server hat keinen Internet-Zugang — DSGVO-konform by Design
  • Quellenangabe: Jede Antwort enthält Links zu den Quelldokumenten

Weiterführende Ressourcen

RAG-System aufbauen? Holen Sie sich Feedback

In unserer Community teilen Entwickler ihre RAG-Architekturen, Chunking-Strategien und Evaluierungs-Ergebnisse.

Jetzt Community beitreten →

Häufige Fragen zu RAG-Systemen

Was ist RAG und wie funktioniert es?

RAG (Retrieval-Augmented Generation) ist eine Architektur, die ein LLM mit einer externen Wissensbasis kombiniert. Bei jeder Nutzeranfrage werden zuerst relevante Dokumente aus einer Vektordatenbank abgerufen (Retrieval), dann als Kontext an das LLM übergeben (Augmented), das daraus eine Antwort generiert (Generation). So kann das LLM auf aktuelle, unternehmensspezifische Informationen zugreifen, ohne neu trainiert werden zu müssen.

Welche Vektordatenbank ist die beste für On-Premise RAG?

Qdrant ist unsere Empfehlung für die meisten Enterprise-Szenarien: native Rust-Performance, einfaches Deployment, gute Skalierung und aktive Entwicklung. Milvus ist die bessere Wahl für sehr große Datenmengen (>100 Mio. Vektoren) und wenn Kubernetes bereits im Einsatz ist. ChromaDB eignet sich hervorragend für Prototypen und kleine Deployments.

Kann ich RAG komplett On-Premise betreiben — auch die Embeddings?

Ja, absolut. Sie können Open-Source-Embedding-Modelle wie bge-m3, multilingual-e5-large oder nomic-embed-text lokal auf Ihrer GPU betreiben. So verlässt kein einziges Dokument Ihr Netzwerk — weder für die Indexierung noch für die Abfrage. Das ist entscheidend für die DSGVO-Compliance.

Wie viel Hardware brauche ich für ein On-Premise RAG-System?

Ein Basis-RAG-System (LLM + Embedding-Modell + Vektordatenbank) benötigt: 1x GPU mit 24+ GB VRAM (z.B. RTX 4090) für das LLM, optional eine zweite GPU für Embeddings, 64+ GB RAM für die Vektordatenbank, und schnellen NVMe-Storage. Für Enterprise-Produktionssysteme empfehlen wir A100/H100 GPUs. Details in unserem GPU-Server Guide.

Wie groß ist der Unterschied zwischen RAG und Fine-Tuning?

RAG und Fine-Tuning lösen unterschiedliche Probleme. RAG gibt dem LLM Zugriff auf aktuelle, spezifische Informationen — ideal für Wissensabfragen, Dokumentensuche und FAQs. Fine-Tuning verändert das Verhalten des Modells — ideal für spezifische Schreibstile, Tonalität oder domänenspezifische Fachsprache. Die meisten Enterprise-Use-Cases profitieren mehr von RAG, da es einfacher zu aktualisieren ist und keine GPU-intensiven Trainingsprozesse erfordert.

Wie verhindere ich Halluzinationen in meinem RAG-System?

Halluzinationen lassen sich durch mehrere Strategien minimieren: 1) Hochwertige Chunking-Strategie mit überlappenden Segmenten, 2) Re-Ranking der Retrieval-Ergebnisse mit Cross-Encoder-Modellen, 3) Instruction im System-Prompt „Antworte nur basierend auf den bereitgestellten Dokumenten", 4) Confidence-Scoring und Quellenangabe in der Antwort, 5) Regelmäßige Evaluierung mit Ground-Truth-Datensätzen.

Welches Embedding-Modell ist das beste für deutsche Texte?

Für deutsche Texte empfehlen wir BAAI/bge-m3 (multilingual, 1024 Dimensionen) oder intfloat/multilingual-e5-large (1024 Dimensionen). Beide zeigen starke Performance auf deutschen Benchmarks. Für höchste Qualität bei reinen deutschsprachigen Dokumenten ist deutsche-telekom/gbert-large-paraphrase-cosine eine spezialisierte Alternative.

RAG-Architektur Review?

Besprechen Sie Ihre RAG-Pipeline mit erfahrenen Data Engineers in unserer Slack-Community.

Kostenlos austauschen →