Abfrageerweiterung: Relevantere Ergebnisse erhalten
Den Recall um 40 % verbessern: erweitern Sie Nutzeranfragen mit Synonymen, Unterabfragen und von LLM generierten Variationen.
Warum Query-Erweiterung ?
Problem : Die Nutzeranfrage ist zu kurz oder verwendet andere Wörter
Beispiel :
- Nutzer : "ML models"
- Relevante Dokumente verwenden : "machine learning algorithms", "neural networks", "deep learning"
Die Query-Erweiterung formuliert Anfragen um, damit sie zu mehr Dokumenten passen.
Methode 1 : Erweiterung durch Synonyme
DEVELOPERpythonfrom nltk.corpus import wordnet def expand_with_synonyms(query): words = query.split() expanded_queries = [query] # Ursprüngliche Anfrage einschließen for word in words: synonyms = [] for syn in wordnet.synsets(word): for lemma in syn.lemmas(): if lemma.name() != word: synonyms.append(lemma.name().replace('_', ' ')) # Synonymvariationen hinzufügen if synonyms: expanded = query.replace(word, synonyms[0]) expanded_queries.append(expanded) return list(set(expanded_queries)) # Beispiel queries = expand_with_synonyms("fast car") # ["fast car", "quick car", "fast automobile", "quick automobile"]
Methode 2 : Reformulierung par LLM
DEVELOPERpythonimport openai def expand_with_llm(query): response = openai.ChatCompletion.create( model="gpt-4-turbo", messages=[{ "role": "system", "content": "Generate 3 alternative phrasings of the user's query. Output as JSON array." }, { "role": "user", "content": query }], response_format={"type": "json_object"} ) variations = json.loads(response.choices[0].message.content) return [query] + variations["alternatives"] # Beispiel queries = expand_with_llm("How to reduce costs?") # [ # "How to reduce costs?", # "What are cost reduction strategies?", # "Ways to lower expenses", # "Best practices for cutting costs" # ]
Methode 3 : Multi-Query Retrieval
Mit allen Varianten suchen, Ergebnisse zusammenführen :
DEVELOPERpythondef multi_query_retrieval(query, vector_db): # Variationen erzeugen queries = expand_with_llm(query) # Für jede abrufen all_results = [] for q in queries: q_emb = embed(q) results = vector_db.search(q_emb, limit=20) all_results.extend(results) # Duplikate entfernen und nach Häufigkeit bewerten doc_scores = {} for doc in all_results: if doc.id not in doc_scores: doc_scores[doc.id] = 0 doc_scores[doc.id] += doc.score # Nach kombiniertem Score sortieren ranked = sorted(doc_scores.items(), key=lambda x: x[1], reverse=True) return ranked[:10]
Methode 4 : HyDE (Hypothetical Document Embeddings)
Eine hypothetische Antwort erzeugen und damit suchen :
DEVELOPERpythondef hyde_retrieval(query): # Eine hypothetische Antwort generieren hypothetical_doc = openai.ChatCompletion.create( model="gpt-4-turbo", messages=[{ "role": "system", "content": "Write a detailed answer to this question as if it were a Wikipedia article." }, { "role": "user", "content": query }] ).choices[0].message.content # Embedding des hypothetischen Dokuments erstellen (nicht der Anfrage!) doc_embedding = embed(hypothetical_doc) # Nach ähnlichen Dokumenten suchen results = vector_db.search(doc_embedding, limit=10) return results
Methode 5 : Step-Back Prompting
Zunächst eine weiter gefasste Frage stellen :
DEVELOPERpythondef step_back_expansion(query): # Eine allgemeinere Frage generieren step_back = openai.ChatCompletion.create( model="gpt-4-turbo", messages=[{ "role": "system", "content": "Given a specific question, generate a broader, more general question." }, { "role": "user", "content": query }] ).choices[0].message.content return [query, step_back] # Beispiel queries = step_back_expansion("What is the capital of France?") # [ # "What is the capital of France?", # "What are capitals of European countries?" # ]
Methode 6 : Zerlegung in Unteranfragen
Komplexe Anfragen in Teile zerlegen :
DEVELOPERpythondef decompose_query(query): response = openai.ChatCompletion.create( model="gpt-4-turbo", messages=[{ "role": "system", "content": "Break this complex question into 2-3 simpler sub-questions. Return JSON array." }, { "role": "user", "content": query }], response_format={"type": "json_object"} ) sub_queries = json.loads(response.choices[0].message.content)["sub_questions"] # Für jede Teilanfrage abrufen all_results = [] for sq in sub_queries: results = vector_db.search(embed(sq), limit=5) all_results.extend(results) return deduplicate(all_results) # Beispiel sub_queries = decompose_query("How does photosynthesis affect climate change?") # [ # "What is photosynthesis?", # "How do plants remove CO2?", # "What is the relationship between CO2 and climate?" # ]
Langchain-Implementierung
DEVELOPERpythonfrom langchain.retrievers.multi_query import MultiQueryRetriever from langchain.llms import OpenAI retriever = MultiQueryRetriever.from_llm( retriever=vector_store.as_retriever(), llm=OpenAI(temperature=0) ) # Automatische Erweiterung der Anfrage docs = retriever.get_relevant_documents("How to train neural networks?")
Evaluation
DEVELOPERpython# Verbesserung des Recalls messen def evaluate_expansion(queries, ground_truth_docs): recall_baseline = [] recall_expanded = [] for query, relevant_docs in zip(queries, ground_truth_docs): # Basislinie base_results = vector_db.search(embed(query), limit=10) base_recall = len(set(base_results) & set(relevant_docs)) / len(relevant_docs) recall_baseline.append(base_recall) # Erweitert expanded_results = multi_query_retrieval(query, vector_db) exp_recall = len(set(expanded_results) & set(relevant_docs)) / len(relevant_docs) recall_expanded.append(exp_recall) print(f"Baseline recall: {np.mean(recall_baseline):.2f}") print(f"Expanded recall: {np.mean(recall_expanded):.2f}")
Die Query-Erweiterung ist kostengünstig und hochwirksam. Erhöhen Sie den Recall sofort um 30–50%.
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.