News

Durchbruch bei der Anfragezerlegung: DecomposeRAG bewältigt komplexe Fragen 50 % besser

5. November 2025
4 Min. Lesezeit
Équipe de Recherche Ailog

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 :

  1. Wo befindet sich der Eiffelturm ? → Frankreich
  2. Was ist die Hauptstadt von Frankreich ? → Paris
  3. 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 :

DEVELOPERpython
def 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 :

DEVELOPERpython
def 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 :

DEVELOPERpython
def 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 :

DatasetRAG BaselineDecomposeRAGAmélioration
HotpotQA45.3%68.7%+51.7%
2WikiMultihopQA38.2%57.9%+51.6%
MuSiQue32.1%49.8%+55.1%
IIRC41.7%62.3%+49.4%

Durchschnittliche Verbesserung : +52%

Vergleich mit anderen Methoden

MéthodeF1 moyCoût (relatif)
RAG Standard39.3%1x
Chain-of-Thought43.8%2x
ReACT48.2%3x
DecomposeRAG59.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 :

SautsBaselineDecomposeRAGGain
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 ?

  1. Zerlegungsfehler (23%) : Falsche Teilfragen
  2. retrieval-Fehler (34%) : Keine relevanten Dokumente für die Teilfrage gefunden
  3. Antwortfehler (28%) : Falsche Zwischenantwort, die sich fortpflanzt
  4. Integrationsfehler (15%) : Schwierigkeit, die Teilantworten zu kombinieren

Am häufigsten : Das retrieval schlägt nach wie vor bei den Teilfragen fehl.

Implementierung

Basisversion

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

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

DEVELOPERpython
class 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 :

  1. Bessere Zerlegung : Feinabstimmung kleinerer Modelle
  2. Adaptive Strategie : Automatische Erkennung, wann zu zerlegen ist
  3. Iterative Verfeinerung : Wiederholen fehlgeschlagener Teilfragen
  4. 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

query optimizationmulti-hopresearchdecomposition

Verwandte Artikel

Ailog Assistant

Ici pour vous aider

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