Durchbruch bei der Anfragezerlegung: DecomposeRAG bewältigt komplexe Fragen 50 % besser
Die Forscher von UC Berkeley stellen DecomposeRAG vor, ein automatisiertes Framework zur Anfragezerlegung, das die Antworten auf Multi-Hop-Fragen deutlich verbessert.
Forschungsüberblick
Das NLP-Labor der UC Berkeley hat DecomposeRAG veröffentlicht, ein Framework, das komplexe Anfragen automatisch in einfachere Teilanfragen zerlegt und state-of-the-art-Ergebnisse auf Multi-Hop-QA-Benchmarks erzielt.
Problemstellung
Komplexe Fragen erfordern Multi-Hop-Reasoning:
Beispiel : "Wie groß ist die Bevölkerung der Hauptstadt des Landes, in dem sich der Eiffelturm befindet ?"
Erfordert :
- Wo befindet sich der Eiffelturm ? → Frankreich
- Was ist die Hauptstadt von Frankreich ? → Paris
- Wie groß ist die Bevölkerung von Paris ? → 2,1 Millionen
Der traditionelle RAG holt Kontext für die vollständige Frage und verpasst dabei oft die Zwischenschritte.
DecomposeRAG-Ansatz
Automatische Zerlegung
Verwendet GPT-4, um Anfragen in Teilfragen zu zerlegen :
DEVELOPERpythondef decompose_query(complex_query): prompt = f"""Break this question into simple sub-questions that must be answered in order. Question: {complex_query} Sub-questions (in order): 1.""" response = gpt4.generate(prompt) sub_questions = parse_questions(response) return sub_questions
Sequenzielle retrieval
Beantworte die Teilfragen der Reihe nach und verwende die vorherigen Antworten als Kontext :
DEVELOPERpythondef sequential_rag(sub_questions): context = "" for i, sub_q in enumerate(sub_questions): # Retrieve for this sub-question docs = retrieve(sub_q + " " + context, k=5) # Generate answer answer = llm.generate( query=sub_q, context=docs, previous_answers=context ) # Add to cumulative context context += f"\nQ{i+1}: {sub_q}\nA{i+1}: {answer}\n" return answer # Answer to final sub-question
Validierung der Antworten
Validiert jede Zwischenantwort, bevor fortgefahren wird :
DEVELOPERpythondef validate_answer(question, answer, retrieved_docs): prompt = f"""Is this answer supported by the documents? Question: {question} Answer: {answer} Documents: {retrieved_docs} Supported? (yes/no):""" validation = llm.generate(prompt) return "yes" in validation.lower()
Wenn die Validierung fehlschlägt, erneut versuchen mit mehr Kontext oder einer alternativen retrieval-Strategie.
Benchmark-Ergebnisse
Getestet auf vier Multi-Hop-QA-Datasets :
| Dataset | RAG Baseline | DecomposeRAG | Amélioration |
|---|---|---|---|
| HotpotQA | 45.3% | 68.7% | +51.7% |
| 2WikiMultihopQA | 38.2% | 57.9% | +51.6% |
| MuSiQue | 32.1% | 49.8% | +55.1% |
| IIRC | 41.7% | 62.3% | +49.4% |
Durchschnittliche Verbesserung : +52%
Vergleich mit anderen Methoden
| Méthode | F1 moy | Coût (relatif) |
|---|---|---|
| RAG Standard | 39.3% | 1x |
| Chain-of-Thought | 43.8% | 2x |
| ReACT | 48.2% | 3x |
| DecomposeRAG | 59.7% | 2.5x |
DecomposeRAG erreicht die höchste Genauigkeit bei moderaten Kosten.
Wichtige Erkenntnisse
Wann die Zerlegung hilft
Die Wirksamkeit variiert mit der Komplexität der Anfrage :
| Sauts | Baseline | DecomposeRAG | Gain |
|---|---|---|---|
| 1 (simple) | 68.2% | 69.1% | +1.3% |
| 2 (moyen) | 51.3% | 67.4% | +31.4% |
| 3 (complexe) | 28.7% | 52.3% | +82.2% |
| 4+ (très complexe) | 15.2% | 38.9% | +156.3% |
Fazit : Mehr Sprünge = größere Verbesserungen durch Zerlegung.
Qualität der Zerlegung
Analyse der Qualität der vom LLM erzeugten Zerlegungen :
- Korrekte Zerlegung : 87.3%
- Fehlende Schritte : 8.2%
- Falsche Reihenfolge : 3.1%
- Zirkuläre Logik : 1.4%
Auch unvollkommene Zerlegungen verbessern die Ergebnisse.
Fehleranalyse
Woran DecomposeRAG scheitert ?
- Zerlegungsfehler (23%) : Falsche Teilfragen
- retrieval-Fehler (34%) : Keine relevanten Dokumente für die Teilfrage gefunden
- Antwortfehler (28%) : Falsche Zwischenantwort, die sich fortpflanzt
- Integrationsfehler (15%) : Schwierigkeit, die Teilantworten zu kombinieren
Am häufigsten : Das retrieval schlägt nach wie vor bei den Teilfragen fehl.
Implementierung
Basisversion
DEVELOPERpythonclass DecomposeRAG: def __init__(self, retriever, llm): self.retriever = retriever self.llm = llm async def query(self, complex_question): # Step 1: Decompose sub_questions = await self.decompose(complex_question) # Step 2: Sequential RAG context = "" for sub_q in sub_questions: # Retrieve docs = await self.retriever.retrieve( sub_q + " " + context, k=5 ) # Generate answer = await self.llm.generate( query=sub_q, context=docs, previous=context ) context += f"\n{sub_q} -> {answer}" # Return final answer return answer async def decompose(self, query): # Use LLM to decompose return await self.llm.decompose(query)
Fortgeschritten : Mit Validierung
DEVELOPERpythonclass ValidatedDecomposeRAG(DecomposeRAG): async def query(self, complex_question, max_retries=2): sub_questions = await self.decompose(complex_question) context = "" for sub_q in sub_questions: for attempt in range(max_retries): docs = await self.retriever.retrieve(sub_q + " " + context) answer = await self.llm.generate(sub_q, docs, context) # Validate if await self.validate(sub_q, answer, docs): context += f"\n{sub_q} -> {answer}" break elif attempt == max_retries - 1: # Failed validation, use best-effort answer context += f"\n{sub_q} -> {answer} (unverified)" return answer
Optimierungen
Parallele Teilfragen
Wenn die Teilfragen unabhängig sind :
DEVELOPERpython# Identify independent sub-questions dependencies = analyze_dependencies(sub_questions) # Group independent questions independent_groups = group_by_dependencies(sub_questions, dependencies) # Process groups in parallel for group in independent_groups: # Parallel retrieval for group results = await asyncio.gather(*[ self.retrieve_and_answer(q, context) for q in group ]) # Add all to context for q, answer in zip(group, results): context += f"\n{q} -> {answer}"
Cache für Zwischenergebnisse
DEVELOPERpythonclass CachedDecomposeRAG(DecomposeRAG): def __init__(self, retriever, llm): super().__init__(retriever, llm) self.cache = {} async def retrieve_and_answer(self, sub_q, context): cache_key = hash(sub_q + context) if cache_key in self.cache: return self.cache[cache_key] result = await super().retrieve_and_answer(sub_q, context) self.cache[cache_key] = result return result
Praktische Überlegungen
Latenz
DecomposeRAG ist 2–3x langsamer :
- Anfrage mit 2 Sprüngen : +2–3 Sekunden
- Anfrage mit 3 Sprüngen : +4–6 Sekunden
- Anfrage mit 4 Sprüngen : +6–10 Sekunden
Abmilderung :
- Parallele Teilfragen, wenn möglich
- Cache für häufige Zerlegungen
- Schnellere LLMs für Zwischenschritte verwenden
Kosten
Mehr LLM-Aufrufe = höhere Kosten :
- Zerlegung : 1 LLM-Aufruf
- Jede Teilfrage : 1 LLM-Aufruf
- Validierung (optional) : 1 Aufruf pro Teilfrage
Beispiel :
- 3 Teilfragen + Validierung = 7 LLM-Aufrufe
- vs. 1 Aufruf beim Standard-RAG
Kostenmultiplikator : 2–5x je nach Komplexität
Wann zu verwenden
DecomposeRAG verwenden, wenn :
- Die Fragen komplex sind (Multi-Hop)
- Genauigkeit wichtiger ist als Geschwindigkeit
- Das Budget höhere Kosten erlaubt
Standard-RAG verwenden, wenn :
- Einfache Abfragen
- Geschwindigkeit kritisch ist
- Kosten sensibel sind
Zukünftige Richtungen
Geplante Verbesserungen :
- Bessere Zerlegung : Feinabstimmung kleinerer Modelle
- Adaptive Strategie : Automatische Erkennung, wann zu zerlegen ist
- Iterative Verfeinerung : Wiederholen fehlgeschlagener Teilfragen
- Multimodal : Zerlegung über Modalitäten hinweg
Ressourcen
- Artikel : "DecomposeRAG: Automatic Query Decomposition for Multi-Hop Question Answering"
- Code : github.com/berkeley-nlp/decomposerag
- Démo : decomposerag.demo.berkeley.edu
Fazit
DecomposeRAG zeigt, dass eine explizite Zerlegung von Anfragen die Antworten auf Multi-Hop-Fragen deutlich verbessert. Obwohl teurer und langsamer als der Standard-RAG, rechtfertigen die Genauigkeitsgewinne die Mehrkosten für komplexe Anfragen, bei denen Präzision entscheidend ist.
Tags
Verwandte Artikel
BEIR Benchmark 2.0 – Rangliste 2025: Vollständige NDCG@10-Scores & Platzierungen
Vollständige BEIR 2.0-Rangliste mit NDCG@10-Scores für alle Top-Modelle. Vergleichen Sie Voyage, Cohere, BGE, OpenAI im neuesten Benchmark.
Neue Forschung: Der Reranking Cross-Encoder verbessert die RAG-Genauigkeit um 40 %
Eine Studie des MIT zeigt, dass zweistufiges Retrieval mit Reranking Cross-Encoder die einfache Vektorsuche deutlich übertrifft.
CLaRa: Ein neuer Ansatz für RAG mit Continuous Latent Reasoning
CLaRa führt Continuous Latent Reasoning ein, um retrieval und generation zu vereinheitlichen und erzielt state-of-the-art-Leistungen auf QA-Benchmarks.