5. RetrievalExperte

MMR: Suchergebnisse diversifizieren mit maximaler marginaler Relevanz

15. November 2025
9 Minuten Lesezeit
Équipe de Recherche Ailog

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

DEVELOPERpython
import 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

DEVELOPERpython
from 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

mmrrécupérationdiversitéredondance

Verwandte Artikel

Ailog Assistant

Ici pour vous aider

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