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:
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) 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
- Privater KI-Assistent — Pilotumfang und Abnahmekriterien
- Ollama Enterprise Setup Guide — LLM-Server für RAG
- vLLM vs. Ollama — Welche Engine für RAG?
- Open-Source LLM Vergleich — Das richtige Modell für RAG
- GPU-Server Kaufguide — Hardware für RAG-Systeme
- LLM für Kanzleien — Branchenspezifischer Guide
- DSGVO & KI — Compliance für RAG-Systeme
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?
Beschreiben Sie Ihren Anwendungsfall, Ihre Datenquellen und Ihren Schutzbedarf für eine konkrete Ersteinschätzung.
Kostenlos austauschen →