MMR: Suchergebnisse diversifizieren mit maximaler marginaler Relevanz
Reduzieren Sie Redundanz in der RAG-Recherche: Verwenden Sie MMR, um Relevanz und Vielfalt auszubalancieren und so die Qualität des Kontexts zu verbessern.
Das Problem der Redundanz
Die standardmäßige Ähnlichkeitssuche liefert ähnliche Dokumente – oft zu ähnlich :
Requête : "Comment fonctionne la photosynthèse ?"
Top 5 résultats :
1. "La photosynthèse convertit la lumière en énergie..."
2. "La photosynthèse est comment les plantes créent de l'énergie..." ← Redondant
3. "Les plantes utilisent la photosynthèse pour créer..." ← Redondant
4. "La chlorophylle permet la photosynthèse..." ← Aspect différent!
5. "La photosynthèse se produit dans les chloroplastes..." ← Aspect différent!
Sie verschwenden Kontext durch Wiederholungen.
Maximal Marginal Relevance (MMR)
MMR balanciert Relevanz zur Anfrage und Diversität im Vergleich zu bereits ausgewählten Dokumenten.
Formule :
MMR = argmax[λ * Sim(Di, Q) - (1-λ) * max Sim(Di, Dj)]
Di ↑ ↑
pertinence requête similarité aux sélectionnés
λ = 0.7 typisch (70% Relevanz, 30% Diversität)
Implementierung
DEVELOPERpythonimport numpy as np from sklearn.metrics.pairwise import cosine_similarity def mmr_search(query_embedding, doc_embeddings, documents, k=10, lambda_param=0.7): """ MMR-Retrieval Args: query_embedding: Abfragevektor doc_embeddings: Alle Dokumentvektoren documents: Originaldokumente k: Anzahl der Ergebnisse lambda_param: Relevanz vs. Diversität (0-1) """ # Ähnlichkeit zur Anfrage berechnen query_sim = cosine_similarity([query_embedding], doc_embeddings)[0] selected_indices = [] remaining_indices = list(range(len(documents))) # Erstes Dokument auswählen (das der Anfrage am ähnlichsten ist) first_idx = np.argmax(query_sim) selected_indices.append(first_idx) remaining_indices.remove(first_idx) # Iterativ k-1 weitere Dokumente auswählen for _ in range(k - 1): mmr_scores = [] for idx in remaining_indices: # Relevanz zur Anfrage relevance = query_sim[idx] # Maximale Ähnlichkeit zu bereits ausgewählten Dokumenten selected_embeddings = doc_embeddings[selected_indices] diversity = max(cosine_similarity([doc_embeddings[idx]], selected_embeddings)[0]) # MMR-Score mmr_score = lambda_param * relevance - (1 - lambda_param) * diversity mmr_scores.append((idx, mmr_score)) # Dokument mit dem höchsten MMR-Score auswählen best_idx = max(mmr_scores, key=lambda x: x[1])[0] selected_indices.append(best_idx) remaining_indices.remove(best_idx) return [documents[i] for i in selected_indices]
MMR in LangChain integriert
DEVELOPERpythonfrom langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings vectorstore = Chroma.from_documents(documents, OpenAIEmbeddings()) # MMR-Suche results = vectorstore.max_marginal_relevance_search( query="photosynthèse", k=5, fetch_k=20, # 20 Kandidaten abrufen, 5 diversifizierte zurückgeben lambda_mult=0.7 # Gewichtung der Relevanz )
Wann MMR verwenden
MMR verwenden, wenn:
- Die Dokumente starke Überschneidungen aufweisen
- Das Kontextfenster begrenzt ist
- Sie eine breite Abdeckung benötigen
- Multi-Aspekt-Anfragen ("erzählen Sie mir von X, Y und Z")
MMR nicht verwenden, wenn:
- Die Dokumente bereits diversifiziert sind
- Geschwindigkeit kritisch ist (MMR ist langsamer)
- Einfache Ein-Aspekt-Anfragen
Lambda-Anpassung
DEVELOPERpython# Tester différentes valeurs de lambda lambdas = [0.3, 0.5, 0.7, 0.9] for lam in lambdas: results = mmr_search(query, embeddings, docs, lambda_param=lam) # Mesurer la diversité diversity = measure_diversity(results) relevance = measure_relevance(results, query) print(f"λ={lam}: Pertinence={relevance:.2f}, Diversité={diversity:.2f}")
Empfehlungen :
- Domäne mit hoher Redundanz : λ = 0.5-0.6
- Allgemeiner Gebrauch : λ = 0.7
- Kritische Präzision : λ = 0.8-0.9
Performance-Optimierung
MMR ist O(k²) – langsam für große k :
DEVELOPERpython# Schneller: Zuerst Kandidaten abrufen def fast_mmr(query, vectordb, k=10, fetch_k=100, lambda_param=0.7): # 1. fetch_k Kandidaten erhalten (schnelle Vektorsuche) candidates = vectordb.search(query, k=fetch_k) # 2. MMR auf eine kleinere Menge anwenden return mmr_search( query_embedding=query, doc_embeddings=[c['embedding'] for c in candidates], documents=[c['doc'] for c in candidates], k=k, lambda_param=lambda_param )
Kombination mit dem Reranking
Pipeline : Retrieval → MMR → Reranking
DEVELOPERpython# 1. Initial retrieval candidates = vector_search(query, k=100) # 2. Mit MMR diversifizieren diverse_docs = mmr_search(query, candidates, k=20) # 3. Reranking für Präzision final_results = cross_encoder_rerank(query, diverse_docs, k=10)
MMR stellt sicher, dass Ihr LLM einen vielfältigen und nicht redundanten Kontext sieht. Wesentlich für ein hochwertiges RAG.
Tags
Verwandte Artikel
Grundlagen des Retrievals: Wie die RAG-Suche funktioniert
Beherrschen Sie die Grundlagen des Retrievals in RAG-Systemen: Embeddings, vector search, chunking und indexing für relevante Ergebnisse.
Erweiterte Retrieval-Strategien für RAG
Über die grundlegende Ähnlichkeitssuche hinaus: hybride Suche, Query Expansion, MMR und mehrstufiges Retrieval für bessere RAG-Ergebnisse.
Hybride RAG-Suche: BM25 + Vektorsuche (2025)
+20–30% RAG-Genauigkeit mit hybrider Suche. Schritt-für-Schritt-Anleitung zum Kombinieren von BM25 und Vektorsuche mit Weaviate, Qdrant oder Pinecone.