5. Retrieval

Dense Retrieval: Semantische Suche mit Embeddings

5. März 2026
Équipe Ailog

Beherrschen Sie Dense Retrieval für eine leistungsfähige semantische Suche. Embeddings, Modelle, vektorielle Indexierung und fortgeschrittene Optimierungen.

Dense Retrieval: Semantische Suche mit Embeddings

Dense Retrieval revolutioniert die Informationssuche, indem es die tiefere Bedeutung von Anfragen und Dokumenten erfasst. Im Gegensatz zur lexikalischen Suche, die Wörter vergleicht, vergleicht Dense Retrieval Konzepte. Dieser Leitfaden vertieft die Mechanismen, Modelle und Techniken zur Implementierung einer leistungsstarken semantischen Suche in Ihren RAG-Systemen.

Was ist Dense Retrieval?

Dense Retrieval stellt jeden Text als einen dichten Vektor reeller Zahlen dar, typischerweise mit 384 bis 4096 Dimensionen. Diese Vektoren, genannt Embeddings, erfassen die Semantik des Textes in einem mathematischen Raum, in dem ähnliche Konzepte nahe beieinander liegen.

Unterschied zum Sparse Retrieval

EigenschaftDense RetrievalSparse Retrieval
DarstellungDichte Vektoren (384-4096 Dim.)Sparse-Vektoren (Vokabular)
ZuordnungSemantischLexikalisch
"Auto" = "Automobil"JaNein
Seltene BegriffeWeniger leistungsfähigHervorragend
Tippfehler und VariantenRobustEmpfindlich

Dense Retrieval ist besonders stark, wenn der Nutzer seine Anfrage anders formuliert als der Quellinhalt. "Wie storniere ich meine Bestellung" findet "Verfahren zur Kaufrückabwicklung", selbst ohne gemeinsame Wörter.

Architektur eines Dense-Retrieval-Systems

┌──────────────────────────────────────────────────────────────┐
│                    Pipeline Dense Retrieval                   │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   Documents          Modèle           Base Vectorielle       │
│   ┌─────────┐       Embedding         ┌──────────────┐      │
│   │ Doc 1   │──┐    ┌───────┐    ┌───│   Qdrant     │      │
│   │ Doc 2   │──┼───▶│ E5    │────┼───│   Pinecone   │      │
│   │ Doc 3   │──┘    │ BGE   │    │   │   Weaviate   │      │
│   └─────────┘       └───────┘    │   └──────────────┘      │
│                                   │          │              │
│   Query                          │          │ ANN Search   │
│   ┌─────────┐                    │          ▼              │
│   │"Comment │────────────────────┘   ┌──────────────┐      │
│   │annuler" │                        │ Top-K docs   │      │
│   └─────────┘                        └──────────────┘      │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Embedding-Modelle: Der Vergleich 2024

Die Wahl des Embedding-Modells wirkt sich direkt auf die Qualität Ihres Retrieval aus. Hier sind die aktuellen Optionen, geordnet nach Performance in den MTEB-Benchmarks.

Open-Source-Modelle

DEVELOPERpython
from sentence_transformers import SentenceTransformer # BGE-M3 : Meilleur rapport qualité/performance multilingue model_bge = SentenceTransformer('BAAI/bge-m3') # E5-Large : Excellent pour le français model_e5 = SentenceTransformer('intfloat/multilingual-e5-large') # GTE-Large : Alternative performante model_gte = SentenceTransformer('thenlper/gte-large')
ModellDimensionenMTEB FRGeschwindigkeitEinsatz
BGE-M3102462.3MittelMehrsprachige Produktion
E5-Large-v2102461.8MittelFranzösisch-Priorität
GTE-Large102460.2SchnellHohes Volumen
All-MiniLM38452.1Sehr schnellPrototyping

Proprietäre Modelle

DEVELOPERpython
import openai # OpenAI text-embedding-3 client = openai.OpenAI() response = client.embeddings.create( model="text-embedding-3-large", input="Comment annuler ma commande ?", dimensions=1536 # Configurable jusqu'à 3072 ) embedding = response.data[0].embedding # Cohere Embed v4 import cohere co = cohere.Client() response = co.embed( texts=["Comment annuler ma commande ?"], model="embed-v4.0", input_type="search_query" )
ModellDimensionenPerformanceKosten/1M Tokens
text-embedding-3-large3072Hervorragend$0,13
text-embedding-3-small1536Sehr gut$0,02
Cohere embed-v41536Hervorragend$0,12
Voyage-3.51024State of the Art$0,06

(API-Preise: Juli 2026)

Qualität der Embeddings optimieren

Query-/Passage-Präfixe

Einige Modelle erfordern Präfixe, um Anfragen von Dokumenten zu unterscheiden:

DEVELOPERpython
from sentence_transformers import SentenceTransformer model = SentenceTransformer('intfloat/multilingual-e5-large') # IMPORTANT : Préfixer correctement query = "query: Comment fonctionne la garantie ?" passages = [ "passage: La garantie couvre les défauts pendant 2 ans.", "passage: Contactez le SAV pour toute réclamation." ] query_embedding = model.encode(query) passage_embeddings = model.encode(passages)

Ohne diese Präfixe kann die Performance in Benchmarks um 5 bis 15 Punkte sinken.

Normalisierung der Embeddings

Um das Skalarprodukt anstelle der Kosinusähnlichkeit zu verwenden (schneller):

DEVELOPERpython
import numpy as np def normalize(embeddings): norms = np.linalg.norm(embeddings, axis=1, keepdims=True) return embeddings / norms # Embeddings normalisés embeddings_norm = normalize(embeddings) # Maintenant dot product = cosine similarity similarity = np.dot(query_norm, doc_norm.T)

Matryoshka Embeddings

Neuere Modelle unterstützen "Matryoshka Embeddings": Embeddings, bei denen die ersten Dimensionen am informativsten sind.

DEVELOPERpython
# Avec text-embedding-3, vous pouvez réduire les dimensions response = client.embeddings.create( model="text-embedding-3-large", input=texts, dimensions=512 # Au lieu de 3072, avec perte minime ) # Recherche rapide avec dimensions réduites # puis reranking avec dimensions complètes

Dies ermöglicht einen konfigurierbaren Kompromiss zwischen Geschwindigkeit und Präzision.

Fortgeschrittene Vektorindexierung

ANN-Algorithmen (Approximate Nearest Neighbor)

Die exakte Suche (Brute Force) hat O(n). ANN-Algorithmen reduzieren auf O(log n) mit einem geringen Präzisionsverlust.

HNSW (Hierarchical Navigable Small Worlds)

Am häufigsten verwendet. Hervorragender Kompromiss zwischen Geschwindigkeit und Präzision.

DEVELOPERpython
from qdrant_client import QdrantClient from qdrant_client.models import VectorParams, HnswConfigDiff client = QdrantClient("localhost", port=6333) # Configuration HNSW optimisée client.create_collection( collection_name="documents", vectors_config=VectorParams( size=1024, distance="Cosine" ), hnsw_config=HnswConfigDiff( m=16, # Connexions par nœud (16-64) ef_construct=100, # Qualité de construction ) ) # À la recherche, ajuster ef pour précision/vitesse results = client.search( collection_name="documents", query_vector=query_embedding, limit=10, search_params={"ef": 128} # Plus haut = plus précis, plus lent )

IVF (Inverted File Index)

Teilt den Raum in Cluster. Schneller, aber weniger präzise.

DEVELOPERpython
# Avec FAISS import faiss # Créer l'index IVF dimension = 1024 nlist = 100 # Nombre de clusters quantizer = faiss.IndexFlatL2(dimension) index = faiss.IndexIVFFlat(quantizer, dimension, nlist) # Entraîner sur les données index.train(embeddings) index.add(embeddings) # Recherche avec nprobe clusters index.nprobe = 10 # Plus haut = plus précis distances, indices = index.search(query_embedding, k=10)

Quantisierung zur Speicherreduzierung

Vektorgröße um 75% reduzieren bei minimalem Verlust:

DEVELOPERpython
# Quantification scalaire (int8) from qdrant_client.models import QuantizationConfig, ScalarQuantization client.create_collection( collection_name="documents_quantized", vectors_config=VectorParams(size=1024, distance="Cosine"), quantization_config=QuantizationConfig( scalar=ScalarQuantization( type="int8", quantile=0.99, always_ram=True ) ) ) # 1M vecteurs 1024d : 4GB → 1GB # Perte de recall : ~1-2%

Bewertung des Dense Retrieval

Wesentliche Metriken

DEVELOPERpython
def evaluate_retrieval(queries, ground_truth, retriever, k_values=[1, 5, 10]): metrics = {} for k in k_values: recalls = [] precisions = [] for query, relevant_docs in zip(queries, ground_truth): retrieved = retriever.search(query, top_k=k) retrieved_ids = [doc.id for doc in retrieved] # Recall@k hits = len(set(retrieved_ids) & set(relevant_docs)) recall = hits / len(relevant_docs) recalls.append(recall) # Precision@k precision = hits / k precisions.append(precision) metrics[f"recall@{k}"] = np.mean(recalls) metrics[f"precision@{k}"] = np.mean(precisions) # MRR mrr_scores = [] for query, relevant_docs in zip(queries, ground_truth): retrieved = retriever.search(query, top_k=100) for i, doc in enumerate(retrieved): if doc.id in relevant_docs: mrr_scores.append(1 / (i + 1)) break else: mrr_scores.append(0) metrics["mrr"] = np.mean(mrr_scores) return metrics

Empfohlene Benchmarks

  • BEIR: Multi-Domain-Benchmark für Retrieval
  • MTEB: Massive Text Embedding Benchmark
  • MS MARCO: Web-basierter Frage-Antwort-Benchmark

Häufige Fallstricke und Lösungen

1. Domain Shift

Generische Modelle zeigen bei spezialisiertem Vokabular eine schwache Performance.

Lösung: Kontrastives Fine-Tuning

DEVELOPERpython
from sentence_transformers import SentenceTransformer, InputExample, losses model = SentenceTransformer('BAAI/bge-m3') # Données d'entraînement : paires (query, positive_doc) train_examples = [ InputExample(texts=["Symptômes COVID", "Fièvre, toux sèche, fatigue"]), InputExample(texts=["Traitement grippe", "Repos, hydratation, paracétamol"]), ] # Loss contrastive train_loss = losses.MultipleNegativesRankingLoss(model) # Fine-tuning model.fit( train_objectives=[(train_dataloader, train_loss)], epochs=3, warmup_steps=100 )

2. Kurze Anfragen

Anfragen mit 1-2 Wörtern erzeugen wenig unterscheidungskräftige Embeddings.

Lösung: Query Expansion

DEVELOPERpython
def expand_query(query: str, llm) -> str: if len(query.split()) <= 3: expansion = llm.complete( f"Reformule cette recherche en une phrase complète: {query}" ) return f"{query} {expansion}" return query

3. Lange Dokumente

Embeddings von zu langen Dokumenten verlieren an Präzision.

Lösung: Late Interaction oder Chunking mit Aggregation

DEVELOPERpython
def embed_long_document(doc: str, model, chunk_size=512): chunks = split_into_chunks(doc, chunk_size) chunk_embeddings = model.encode(chunks) # Agrégation : moyenne pondérée par position weights = np.exp(-np.arange(len(chunks)) * 0.1) weights /= weights.sum() return np.average(chunk_embeddings, axis=0, weights=weights)

Integration in eine RAG-Pipeline

DEVELOPERpython
class DenseRetriever: def __init__(self, model_name: str, collection: str): self.model = SentenceTransformer(model_name) self.client = QdrantClient("localhost", port=6333) self.collection = collection def index(self, documents: list[dict]): embeddings = self.model.encode( [doc["content"] for doc in documents], show_progress_bar=True ) points = [ PointStruct( id=doc["id"], vector=emb.tolist(), payload={"content": doc["content"], **doc.get("metadata", {})} ) for doc, emb in zip(documents, embeddings) ] self.client.upsert(collection_name=self.collection, points=points) def search(self, query: str, top_k: int = 5, filters: dict = None): query_embedding = self.model.encode(f"query: {query}") filter_conditions = self._build_filters(filters) if filters else None results = self.client.search( collection_name=self.collection, query_vector=query_embedding.tolist(), query_filter=filter_conditions, limit=top_k ) return [ {"content": hit.payload["content"], "score": hit.score} for hit in results ]

Nächste Schritte

Dense Retrieval ist leistungsstark, aber nicht universell einsetzbar. In bestimmten Fällen bleibt die lexikalische Suche überlegen. Erfahren Sie mehr in unseren verwandten Leitfäden:

FAQ

Die Stichwortsuche (BM25) vergleicht exakte Begriffe zwischen Anfrage und Dokumenten. Dense Retrieval kodiert Anfrage und Dokumente in dichte Vektoren, die die semantische Bedeutung erfassen. So findet "Wie storniere ich meine Bestellung" auch "Verfahren zur Kaufrückabwicklung", selbst ohne gemeinsame Wörter. Dense Retrieval ist hervorragend für Umformulierungen, Sparse für exakte Übereinstimmungen (Codes, Referenzen).
Für Französisch bieten BGE-M3 und E5-Large-v2 die beste Performance in den MTEB-Benchmarks. BGE-M3 (1024 Dimensionen) ist die beste mehrsprachige Wahl für die Produktion. Bei Geschwindigkeitsanforderungen ist All-MiniLM (384 Dimensionen) 3x schneller bei akzeptablem Qualitätsverlust. Proprietäre Modelle (OpenAI, Cohere) sind hervorragend, bringen aber API-Kosten und Souveränitätsüberlegungen mit sich.
Einige Modelle (E5, BGE) werden mit unterschiedlichen Präfixen für Anfragen und Dokumente trainiert. Ohne diese Präfixe kann die Performance in Benchmarks um 5-15% sinken. Der Präfix zeigt dem Modell die Rolle des Textes an: eine kurze Anfrage, die Informationen sucht, vs. ein Dokumentenabschnitt, der Informationen enthält. Überprüfen Sie immer die Dokumentation des verwendeten Modells.
Drei Haupttechniken: Die skalare Quantisierung (int8) reduziert die Größe um 75% bei einem Recall-Verlust von 1-2%. Matryoshka Embeddings ermöglichen die Reduzierung der Dimensionen (z.B. von 3072 auf 512) bei minimalem Verlust. Der IVF-Algorithmus teilt den Raum in Cluster, um die Suche zu beschleunigen. Die Kombination von Quantisierung und reduzierten Dimensionen ermöglicht die Speicherung von 10x mehr Vektoren im gleichen Speicher.
Für allgemeines Vokabular reichen vortrainierte Modelle aus. Fine-Tuning wird für spezialisierte Bereiche (Medizin, Recht, Technik) notwendig, wo sich das Vokabular erheblich vom Trainingscorpus unterscheidet. Kontrastives Fine-Tuning mit einigen hundert Paaren (Anfrage, relevantes Dokument) kann den Recall um 10-20% in Ihrem spezifischen Bereich verbessern. ---

Starten Sie mit Dense Retrieval mit Ailog

Die Implementierung eines leistungsstarken Dense-Retrieval-Systems erfordert Expertise und Infrastruktur. Mit Ailog profitieren Sie von:

  • Optimierten Embedding-Modellen für Französisch (BGE-M3, E5-Large)
  • Automatischer HNSW-Indexierung mit Qdrant
  • Intelligenter Quantisierung zur Optimierung von Kosten und Performance
  • Unterstütztem Fine-Tuning auf Ihr Fachvokabular

Kostenlos testen und Ihre semantische Suche in Minuten bereitstellen.

Tags

ragretrievalembeddingsdense retrievalsemantische Suche

Verwandte Artikel

Ailog Assistant

Ici pour vous aider

Salut ! Pose-moi des questions sur Ailog et comment intégrer votre RAG dans vos projets !