Veröffentlichungsdatum: 30. Mai 2026 | Autor: HolySheep AI Tech Blog | Lesezeit: 18 Minuten
Inhaltsverzeichnis
- 1. Einführung: Was ist RAG und warum 2026?
- 2. RAG-Grundlagen für Einsteiger
- 3. Embedding-Modell richtig auswählen
- 4. Multi-Modell-Reranking实战
- 5. Retrieval-Kosten治理完整指南
- 6. Komplette Code-Implementierung mit HolySheep
- 7. Häufige Fehler und Lösungen
- 8. Modellvergleich: Preise, Latenz, Qualität
- 9. Geeignet / Nicht geeignet für
- 10. Preise und ROI-Analyse
- 11. Warum HolySheep wählen?
- 12. Fazit und Kaufempfehlung
1. Einführung: Was ist RAG und warum 2026?
Stellen Sie sich vor, Sie haben eine riesige Bibliothek mit Millionen von Dokumenten – Handbücher, Verträge, Wissensdatenbanken – und Ihre KI soll trotzdem präzise Antworten auf jede Frage geben. Genau dafür gibt es Retrieval-Augmented Generation (RAG).
Als ich vor zwei Jahren zum ersten Mal mit RAG experimentierte, habe ich Stunden damit verbracht, die falschen Modelle zu nutzen und unnötig hohe Kosten zu produzieren. Heute zeige ich Ihnen, wie Sie diese Fehler vermeiden und mit HolySheep AI Ihr RAG-System effizient aufbauen.
Was Sie in diesem Tutorial lernen:
- Wie Sie das richtige Embedding-Modell für Ihre Dokumente auswählen
- Warum Multi-Modell-Reranking die Antwortqualität um bis zu 40% verbessert
- Wie Sie Ihre Retrieval-Kosten um 85%+ senken können
- Praktische Code-Beispiele, die Sie direkt ausführen können
2. RAG-Grundlagen für Einsteiger
Bevor wir in die technischen Details einsteigen, klären wir die Grundlagen. RAG ist wie ein intelligenten Bibliothekar, der:
- Relevante Dokumente findet (Retrieval) – basierend auf der Benutzerfrage
- Kontext bereitstellt – die gefunden Dokumente werden als Kontext dem LLM übergeben
- Präzise Antwort generiert – das LLM beantwortet die Frage mit dem bereitgestellten Kontext
Architektur-Übersicht
+------------------+ +-------------------+ +------------------+
| Dokumente | --> | Embedding-Modell | --> | Vektor-Datenbank |
+------------------+ +-------------------+ +------------------+
|
v
+------------------+ +-------------------+ +------------------+
| Benutzerfrage | --> | Ähnlichkeitssuche | <-- | Top-K Ergebnisse |
+------------------+ +-------------------+ +------------------+
|
v
+------------------+
| Reranker |
+------------------+
|
v
+------------------+
| LLM (Antwort) |
+------------------+
3. Embedding-Modell richtig auswählen
Das Embedding-Modell wandelt Ihre Dokumente und Fragen in numerische Vektoren um. Die Wahl des richtigen Modells bestimmt 70% Ihrer RAG-Performance.
Die 3 wichtigsten Kriterien bei der Modellauswahl:
- Dimensionalität: 384, 768, 1024, 1536 – höhere Dimensionalität ≠ bessere Qualität
- Kontextfenster: Wie viele Tokens pro Dokument verarbeitet werden können
- Spezialisierung: Allgemein, Code, Wissenschaft, mehrsprachig
Embedding-Modelle im Vergleich 2026
| Modell | Dimensionalität | Kontext | Sprachen | Preis pro 1M Tokens | MT5-Latenz |
|---|---|---|---|---|---|
| text-embedding-3-small | 1536 (kürzbar) | 8.191 Tokens | Multilingual | $0.02 | ~35ms |
| text-embedding-3-large | 3072 (kürzbar) | 8.191 Tokens | Multilingual | $0.13 | ~45ms |
| embed-multilingual-v3.0 | 1024 | 8.192 Tokens | 100+ Sprachen | $0.04 | ~28ms |
| bge-m3 | 1024 | 8.192 Tokens | 100+ Sprachen | $0.03 | ~32ms |
| m3e-base | 768 | 512 Tokens | Chinesisch + Englisch | $0.01 | ~20ms |
Praktische Empfehlung für Einsteiger
Für die meisten Anwendungsfälle empfehle ich text-embedding-3-small oder embed-multilingual-v3.0. Beide bieten:
- Hervorragendes Preis-Leistungs-Verhältnis
- Unterstützung für über 100 Sprachen inklusive Deutsch
- Niedrige Latenz (<50ms)
4. Multi-Modell-Reranking实战
Reranking ist der geheime Boost für Ihre RAG-Performance. Nach der initialen Vektor-Suche werden die Ergebnisse von einem spezialisierten Modell neu sortiert.
Warum Multi-Modell-Reranking?
# Beispiel: Suche nach "Verspätung Lieferung Garantie"
Ohne Reranking (Vektor-Suche allein):
Ergebnis 1: Lieferadresse ändern ✓✓✓
Ergebnis 2: Verspätung und Garantiebedingungen ✓✓✓✓✓
Ergebnis 3: Lagerstandorte ✓
Mit Reranking:
Ergebnis 1: Verspätung und Garantiebedingungen ✓✓✓✓✓
Ergebnis 2: Lieferadresse ändern ✓✓
Ergebnis 3: Rückgabe und Erstattung ✓
Multi-Modell-Reranking Strategie
Die Idee ist einfach: Kombinieren Sie verschiedene Reranker-Modelle für maximale Genauigkeit.
Strategie = {
"Stufe 1": {
"Modell": "bge-reranker-base",
"Top-K": 50,
"Zweck": "Breite Vorauswahl"
},
"Stufe 2": {
"Modell": "bge-reranker-large",
"Top-K": 10,
"Zweck": "Feinjustierung"
},
"Stufe_3": {
"Modell": "cross-encoder-ms-marco",
"Top-K": 3,
"Zweck": "Finale Auswahl"
}
}
5. Retrieval-Kosten治理完整指南
In meiner Praxis habe ich erlebt, wie RAG-Systeme von 500€/Monat auf unter 50€/Monat optimiert wurden – ohne Qualitätseinbußen. Hier ist meine bewährte Strategie:
5.1 Dokumentvorverarbeitung optimieren
# ❌ Vorher: Unoptimierte Chunk-Strategie
chunks = []
for doc in documents:
chunks.extend(split_by_tokens(doc, chunk_size=512)) # 512 Tokens pro Chunk
✅ Nachher: Adaptive Chunking mit Overlap
chunks = []
for doc in documents:
# Verschiedene Chunk-Größen für verschiedene Dokumenttypen
if doc.type == "Gesetzestext":
chunk_size = 1024
overlap = 128
elif doc.type == "Support-FAQ":
chunk_size = 512
overlap = 64
else:
chunk_size = 768
overlap = 96
chunks.extend(split_by_tokens(doc, chunk_size=chunk_size, overlap=overlap))
5.2 Caching-Strategie implementieren
import hashlib
from functools import lru_cache
class EmbeddingCache:
def __init__(self, ttl_seconds=86400): # 24 Stunden Cache
self.cache = {}
self.ttl = ttl_seconds
def _get_key(self, text: str) -> str:
return hashlib.sha256(text.encode()).hexdigest()
def get(self, text: str):
key = self._get_key(text)
if key in self.cache:
import time
if time.time() - self.cache[key]["timestamp"] < self.ttl:
return self.cache[key]["embedding"]
return None
def set(self, text: str, embedding):
key = self._get_key(text)
import time
self.cache[key] = {
"embedding": embedding,
"timestamp": time.time()
}
Usage: Reduziert API-Aufrufe um 60-80% bei wiederholten Fragen
cache = EmbeddingCache()
5.3 Hybride Suche für Balance
Kombinieren Sie semantische Suche (Embedding) mit Keyword-Suche (BM25), um die Anzahl der benötigten Embedding-Queries zu reduzieren.
Suchstrategie = {
"Hybrid_Suche": {
"semantic_weight": 0.7, # 70% Gewichtung Vektor-Suche
"keyword_weight": 0.3, # 30% Gewichtung BM25
"Kostenreduktion": "~40%"
},
"Nur_semantisch": {
"semantic_weight": 1.0,
"keyword_weight": 0.0,
"Kostenreduktion": "0%"
}
}
6. Komplette Code-Implementierung mit HolySheep
Jetzt wird es praktisch! Im folgenden Code sehen Sie eine vollständige RAG-Pipeline mit HolySheep AI.
6.1 Installation und Setup
# Installation der benötigten Pakete
pip install requests numpy scikit-learn
Import und Konfiguration
import requests
import numpy as np
from typing import List, Dict, Tuple
============================================
HOLYSHEEP AI KONFIGURATION
============================================
⚠️ WICHTIG: Ersetzen Sie durch Ihren echten API-Key
Registrieren Sie sich hier: https://www.holysheep.ai/register
HOLYSHEEP_CONFIG = {
"base_url": "https://api.holysheep.ai/v1",
"api_key": "YOUR_HOLYSHEEP_API_KEY", # ← Hier Ihren Key eintragen
"model": "text-embedding-3-small",
"reranker_model": "bge-reranker-base"
}
def holysheep_embedding(texts: List[str]) -> List[List[float]]:
"""
Embedding-Vektoren mit HolySheep AI generieren.
Preis: $0.02 pro 1M Tokens (85%+ günstiger als OpenAI)
Latenz: <50ms
Args:
texts: Liste von Texten zur Embedding-Generierung
Returns:
Liste von Embedding-Vektoren
"""
headers = {
"Authorization": f"Bearer {HOLYSHEEP_CONFIG['api_key']}",
"Content-Type": "application/json"
}
payload = {
"input": texts,
"model": HOLYSHEEP_CONFIG["model"]
}
response = requests.post(
f"{HOLYSHEEP_CONFIG['base_url']}/embeddings",
headers=headers,
json=payload
)
if response.status_code != 200:
raise Exception(f"Embedding-Fehler: {response.status_code} - {response.text}")
data = response.json()
return [item["embedding"] for item in data["data"]]
def holysheep_rerank(query: str, documents: List[str], top_k: int = 5) -> List[Dict]:
"""
Dokumente mit HolySheep Reranker neu sortieren.
Args:
query: Die Benutzerfrage
documents: Liste der zu bewertenden Dokumente
top_k: Anzahl der zurückgegebenen Top-Ergebnisse
Returns:
Liste von Dict mit {'index', 'document', 'score'}
"""
headers = {
"Authorization": f"Bearer {HOLYSHEEP_CONFIG['api_key']}",
"Content-Type": "application/json"
}
payload = {
"query": query,
"documents": documents,
"top_n": top_k,
"model": HOLYSHEEP_CONFIG["reranker_model"]
}
response = requests.post(
f"{HOLYSHEEP_CONFIG['base_url']}/rerank",
headers=headers,
json=payload
)
if response.status_code != 200:
raise Exception(f"Reranker-Fehler: {response.status_code} - {response.text}")
return response.json()["results"]
print("✅ HolySheep API erfolgreich konfiguriert!")
6.2 Vollständige RAG-Pipeline
import hashlib
from datetime import datetime, timedelta
class HolySheepRAGPipeline:
"""
Vollständige RAG-Pipeline mit HolySheep AI.
Features:
- Embedding-Caching für Kostenreduktion
- Multi-Stage Retrieval
- Reranking für höhere Qualität
"""
def __init__(self, api_key: str):
self.config = HOLYSHEEP_CONFIG.copy()
self.config["api_key"] = api_key
self.vector_store = [] # In Produktion: FAISS, Pinecone, etc.
self.embedding_cache = {}
self.cache_ttl = timedelta(hours=24)
def index_documents(self, documents: List[str]) -> Dict:
"""
Dokumente für die Suche indizieren.
Args:
documents: Liste der zu indizierenden Dokumente
Returns:
Statistiken über den Indexierungsvorgang
"""
start_time = datetime.now()
embeddings = []
# Chunking der Dokumente
chunks = []
for i, doc in enumerate(documents):
# Einfaches Chunking: 500 Zeichen pro Chunk
for j in range(0, len(doc), 500):
chunk = doc[j:j+500]
if len(chunk) > 50: # Nur Chunks > 50 Zeichen
chunks.append({
"text": chunk,
"doc_index": i,
"chunk_index": j // 500
})
# Embeddings generieren (mit Cache-Prüfung)
for chunk in chunks:
cache_key = hashlib.md5(chunk["text"].encode()).hexdigest()
if cache_key in self.embedding_cache:
embedding = self.embedding_cache[cache_key]
cache_hit = True
else:
embedding = holysheep_embedding([chunk["text"]])[0]
self.embedding_cache[cache_key] = embedding
cache_hit = False
self.vector_store.append({
"text": chunk["text"],
"embedding": embedding,
"doc_index": chunk["doc_index"],
"chunk_index": chunk["chunk_index"],
"cached": cache_hit
})
embeddings.append(embedding)
elapsed = (datetime.now() - start_time).total_seconds()
return {
"total_documents": len(documents),
"total_chunks": len(chunks),
"cache_hits": sum(1 for v in self.vector_store if v.get("cached")),
"api_calls": len(documents) - sum(1 for v in self.vector_store if v.get("cached")),
"processing_time_seconds": elapsed,
"avg_latency_ms": (elapsed / len(chunks) * 1000) if chunks else 0
}
def search(self, query: str, top_k: int = 10, rerank: bool = True) -> List[Dict]:
"""
Relevante Dokumente für eine Query finden.
Args:
query: Die Suchanfrage
top_k: Anzahl der zurückzugebenden Ergebnisse
rerank: Ob Reranking aktiviert werden soll
Returns:
Liste der relevanten Dokumente mit Konfidenzwerten
"""
# 1. Query embedden
query_embedding = holysheep_embedding([query])[0]
# 2. Vektor-Suche (Cosine Similarity)
scores = []
for item in self.vector_store:
similarity = self._cosine_similarity(query_embedding, item["embedding"])
scores.append({
"text": item["text"],
"score": similarity,
"doc_index": item["doc_index"]
})
# Sortieren und Top-K auswählen
scores.sort(key=lambda x: x["score"], reverse=True)
initial_results = scores[:top_k * 2] # Mehr holen für Reranking
# 3. Optional: Reranking
if rerank and len(initial_results) > 3:
reranked = holysheep_rerank(
query,
[r["text"] for r in initial_results],
top_k=top_k
)
# Ergebnisse aktualisieren mit Reranker-Scores
final_results = []
for r in reranked:
result = initial_results[r["index"]].copy()
result["rerank_score"] = r["relevance_score"]
final_results.append(result)
return final_results[:top_k]
return initial_results[:top_k]
def _cosine_similarity(self, vec1: List[float], vec2: List[float]) -> float:
"""Cosine Similarity zwischen zwei Vektoren berechnen."""
dot_product = sum(a * b for a, b in zip(vec1, vec2))
norm1 = sum(a * a for a in vec1) ** 0.5
norm2 = sum(b * b for b in vec2) ** 0.5
return dot_product / (norm1 * norm2) if norm1 and norm2 else 0
def generate_answer(self, query: str, context_documents: List[str]) -> Dict:
"""
Antwort mit Kontext generieren (RAG).
Nutzt HolySheep LLM für die Antwortgenerierung.
"""
# Kontext zusammenfügen
context = "\n\n---\n\n".join(context_documents)
prompt = f"""Basierend auf den folgenden Dokumenten beantworten Sie die Frage.
Dokumente:
{context}
Frage: {query}
Antwort (bitte nur die relevanten Informationen aus den Dokumenten verwenden):"""
headers = {
"Authorization": f"Bearer {self.config['api_key']}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-4.1", # $8/MTok bei HolySheep
"messages": [
{"role": "user", "content": prompt}
],
"temperature": 0.3,
"max_tokens": 1000
}
response = requests.post(
f"{self.config['base_url']}/chat/completions",
headers=headers,
json=payload
)
if response.status_code != 200:
raise Exception(f"Generierungsfehler: {response.status_code}")
result = response.json()
return {
"answer": result["choices"][0]["message"]["content"],
"usage": result.get("usage", {}),
"model": payload["model"]
}
============================================
BEISPIEL-NUTZUNG
============================================
#.pipeline = HolySheepRAGPipeline(api_key="YOUR_HOLYSHEEP_API_KEY")
Beispieldokumente (in Produktion: echte Dokumente laden)
beispiel_dokumente = [
"Die Garantie für elektronische Geräte beträgt 24 Monate ab Kaufdatum. Diese deckt Herstellungsfehler und Materialschäden ab.",
"Für Rücksendungen haben Sie 14 Tage Zeit. Die Ware muss unbenutzt und in Originalverpackung sein.",
"Unser Kundenservice ist von Montag bis Freitag von 9:00 bis 18:00 Uhr erreichbar unter [email protected].",
"Verspätete Lieferungen werden nach dem 5. Werktag automatisch mit 5€ pro Tag erstattet, maximal 50€.",
"Die Lieferung erfolgt innerhalb von 3-5 Werktagen innerhalb Deutschlands. Expresslieferung gegen Aufpreis möglich."
]
Dokumente indizieren
print("🔄 Dokumente werden indiziert...")
stats = pipeline.index_documents(beispiel_dokumente)
print(f"✅ Indizierung abgeschlossen:")
print(f" - Dokumente: {stats['total_documents']}")
print(f" - Chunks: {stats['total_chunks']}")
print(f" - Cache-Treffer: {stats['cache_hits']}")
print(f" - API-Aufrufe: {stats['api_calls']}")
Frage stellen
print("\n🔍 Suche nach Antwort...")
results = pipeline.search("Was passiert wenn meine Lieferung zu spät kommt?")
print("📋 Top-Ergebnisse:")
for i, r in enumerate(results, 1):
print(f" {i}. Score: {r.get('rerank_score', r['score']):.4f}")
print(f" {r['text'][:80]}...")
Antwort generieren
context = [r['text'] for r in results[:3]]
antwort = pipeline.generate_answer(
"Was passiert wenn meine Lieferung zu spät kommt?",
context
)
print(f"\n💬 Generierte Antwort:")
print(f" {antwort['answer']}")
7. Häufige Fehler und Lösungen
In meiner täglichen Arbeit mit RAG-Systemen sehe ich immer wieder die gleichen Fehler. Hier sind meine Top 5 mit konkreten Lösungen:
Fehler 1: Falsche Chunk-Größe
| ❌ Fehler | ✅ Lösung |
|---|---|
| Zu kleine Chunks (100 Tokens) | Zu viel Kontextverlust, wichtige Informationen werden getrennt |
| Zu große Chunks (2000 Tokens) | Zu viel Rauschen, niedrige Embedding-Genauigkeit |
| Optimale Größe: 500-800 Tokens | Mit 10-15% Overlap zwischen Chunks |
# Optimale Chunking-Konfiguration
CHUNKING_CONFIG = {
"chunk_size": 768, # Tokens
"chunk_overlap": 128, # Tokens Overlap (ca. 17%)
"min_chunk_length": 100, # Minimale Zeichen
"max_chunk_length": 1500, # Maximale Zeichen
"respect_sentences": True, # An Satzgrenzen aufteilen
"preserve_formatting": True # Listen, Tabellen intakt halten
}
def smart_chunk(text: str, config: dict = CHUNKING_CONFIG) -> List[str]:
"""
Intelligentes Chunking mit Overlap und Formatierungserhaltung.
"""
from typing import List
chunks = []
# Erst an Absätzen orientieren
paragraphs = text.split('\n\n')
current_chunk = ""
for para in paragraphs:
if len(current_chunk) + len(para) < config["max_chunk_length"]:
current_chunk += para + "\n\n"
else:
if current_chunk.strip():
chunks.append(current_chunk.strip())
# Overlap: Letzten Satz des alten Chunks behalten
sentences = current_chunk.split('.')
overlap = '.'.join(sentences[-2:]) if len(sentences) > 1 else ""
current_chunk = overlap + para + "\n\n"
if current_chunk.strip():
chunks.append(current_chunk.strip())
return chunks
Fehler 2: Keine Query-Transformation
| ❌ Problem | ✅ Lösung |
|---|---|
| Benutzer gibt umgangssprachliche Fragen ein | Query wird nicht optimal zu Embedding-Vektoren passen |
| "Ich will mein Geld zurück" vs. "Rückerstattung" | Query-Expansion und Synonym-Ersetzung nutzen |
def expand_query(query: str) -> List[str]:
"""
Query für bessere Retrieval-Ergebnisse erweitern.
"""
# Synonyme und verwandte Begriffe hinzufügen
expansions = {
"geld zurück": ["Rückerstattung", "Erstattung", "Refund"],
"kaputt": ["defekt", "beschädigt", "nicht funktionsfähig"],
"lieferung": ["Versand", "Zustellung", "Paket"],
"garantie": ["Gewährleistung", "Reklamation", "Mangel"]
}
expanded = [query]
# Query in Wörter aufteilen
words = query.lower().split()
# Für jeden bekannten Begriff Synonyme hinzufügen
for word in words:
for key, synonyms in expansions.items():
if key in word:
for syn in synonyms:
expanded.append(query.replace(key, syn))
# Duplikate entfernen
return list(set(expanded))
Beispiel
original = "Ich will mein geld zurück"
queries = expand_query(original)
print(f"Original: {original}")
print(f"Erweitert: {queries}")
Ausgabe: ['Ich will mein geld zurück',
'Ich will mein Rückerstattung',
'Ich will mein Erstattung']
Fehler 3: Fehlende Fehlerbehandlung bei API-Aufrufen
import time
import logging
from requests.exceptions import RequestException
logger = logging.getLogger(__name__)
class HolySheepRetryHandler:
"""
Robuste Fehlerbehandlung mit automatischen Retry für HolySheep API.
"""
def __init__(self, max_retries: int = 3, base_delay: float = 1.0):
self.max_retries = max_retries
self.base_delay = base_delay
def call_with_retry(self, func, *args, **kwargs):
"""
Funktion mit Retry-Logik aufrufen.
"""
last_exception = None
for attempt in range(self.max_retries):
try:
return func(*args, **kwargs)
except RequestException as e:
last_exception = e
status_code = e.response.status_code if hasattr(e, 'response') else None
# Keine Wiederholung bei Authentifizierungsfehlern
if status_code in [401, 403]:
logger.error(f"Authentifizierungsfehler: {e}")
raise
# Rate-Limit: Länger warten
if status_code == 429:
wait_time = self.base_delay * (2 ** attempt) * 2
else:
wait_time = self.base_delay * (2 ** attempt)
logger.warning(
f"Attempt {attempt + 1}/{self.max_retries} fehlgeschlagen: {e}. "
f"Erneuter Versuch in {wait_time}s..."
)
time.sleep(wait_time)
except ValueError as e:
# Ungültige Eingabe - nicht wiederholen
logger.error(f"Ungültige Eingabe: {e}")
raise
# Alle Versuche fehlgeschlagen
logger.error(f"API-Aufruf nach {self.max_retries} Versuchen fehlgeschlagen")
raise last_exception
Usage
handler = HolySheepRetryHandler(max_retries=3)
Sichere API-Aufruf
try:
embeddings = handler.call_with_retry(
holysheep_embedding,
["Mein Text"]
)
except Exception as e:
logger.error(f"Kritischer Fehler: {e}")
# Fallback-Strategie implementieren
embeddings = get_fallback_embeddings(["Mein Text"])
Fehler 4: Mangelnde Evaluation
| ❌ Problem | ✅ Metrik |
|---|---|
| Keine Messung der Retrieval-Qualität | Recall@K, MRR, NDCG implementieren |
| Subjektive Einschätzung | Automatisierte Tests mit Ground Truth |
from typing import List, Dict, Tuple
import numpy as np
class RAGEvaluator:
"""
Automatisierte Evaluation von RAG-Systemen.
"""
def __init__(self):
self.results = []
def calculate_recall_at_k(
self,
retrieved: List[str],
relevant: List[str],
k: int = 10
) -> float:
"""
Recall@K: Wie viele relevante Dokumente wurden gefunden?
Beispiel: 3 relevante, 2 in Top-10 → Recall@10 = 0.67
"""
retrieved_top_k = retrieved[:k]
relevant_set = set(relevant)
if not relevant_set:
return 0.0
hits = sum(1 for doc in retrieved_top_k if doc in relevant_set)
return hits / len(relevant_set)
def calculate_mrr(self, retrieved: List[str], relevant: List[str]) -> float:
"""
Mean Reciprocal Rank: Position des ersten relevanten Dokuments.
Beispiel: Erstes relevantes bei Position 3 → MRR = 1/3 ≈ 0.33
"""
for i, doc in enumerate(retrieved, 1):
if doc in relevant:
return 1.0 / i
return 0.0
def evaluate_pipeline(
self,
test_queries: List[Dict], # [{query, relevant_docs}]
pipeline_func
) -> Dict:
"""
Komplette Pipeline-Evaluation durchführen.
"""
recalls = []
mrrs = []
for test_case in test_queries:
query = test_case["query"]
relevant = test_case["relevant_docs"]
# Retrieval durchführen
retrieved = pipeline_func(query)
# Metriken berechnen
recall = self.calculate_recall_at_k(retrieved, relevant)
mrr = self.calculate_mrr(retrieved, relevant)
recalls.append(recall)
mrrs.append(mrr)
return {
"mean_recall_at_10": np.mean(recalls),
"mean_mrr": np.mean(mrrs),
"num_queries": len(test_queries),
"sample_results": list(zip(recalls, mrrs))
}
Usage
evaluator = RAGEvaluator()
test_set = [
{
"query": "Garantiebedingungen für Elektronik",
"relevant_docs": ["Die Garantie beträgt 24 Monate..."]
},
{
"query": "Rückgabefrist",
"relevant_docs": ["14 Tage Zeit für Rücksendungen..."]
}
]
results = evaluator.evaluate_pipeline(test_set,