Agentic RAG mit LangGraph: Warum naives RAG 2026 ausgedient hat

Agentic RAG mit LangGraph in Python: Reflection-Loop, Multi-Hop-Retrieval und Self-Correction. Live-Code für Production mit Postgres-Checkpointer, RAGAS-Eval und Cost-Control.

2 Juni. 2026 | AI

Inhaltsverzeichnis

Pexon Consulting | 11 Min. Lesezeit | 24.05.2026


TL;DR

Agentic RAG ersetzt die starre Embed-Retrieve-Generate-Kette durch einen Agent, der seine eigene Antwort hinterfragt, fehlende Information nachholt und mehrstufig retrieved. Pexon Consulting baut diese Pipelines mit LangGraph self-hosted, weil Multi-Provider und DSGVO bei DACH-Kunden Pflicht sind. Ergebnis: 30-50% weniger Halluzinationen und messbar höhere Antwortqualität bei komplexen Fragen.

Naives RAG Agentic RAG
Architektur Embed → Retrieve → Generate Plan → Retrieve → Reflect → Retry
Multi-Hop-Fragen scheitert nativ unterstützt
Halluzination bei „weiß nicht“ hoch niedrig (Self-Check)
Latenz 2-4 Sekunden 5-15 Sekunden
Kosten pro Anfrage 0,01-0,03 EUR 0,05-0,15 EUR
Production-Reife 2026 etabliert dominantes Pattern

Warum naives RAG seine Grenzen erreicht

Das klassische RAG-Schema ist drei Jahre alt und stammt aus einer Zeit, in der LLMs primär Reformulierungsmaschinen waren: User stellt Frage, System embeddet die Frage, holt die Top-5-Chunks aus der Vector DB, klebt sie in den Prompt, das LLM antwortet. Funktioniert gut für einstufige Faktenfragen, scheitert systematisch in fast allem anderen.

Drei konkrete Pain-Points sehen wir in fast jedem Production-Projekt, das wir übernehmen. Erstens: Multi-Hop-Fragen, bei denen die Antwort aus zwei oder mehr Dokumenten zusammengesetzt werden muss. „Welche Versicherungssumme gilt für unseren Standort in München, wenn das Schadensereignis nach 22 Uhr eintritt?“ — die Antwort steht in der allgemeinen Police, im Standort-Anhang und in einer Sonderregelung. Naives RAG findet meistens eines der drei und antwortet mit halbem Bild.

Zweitens: Halluzinationen bei fehlender Evidenz. Wenn der Retriever nichts Sinnvolles findet, halluziniert das LLM trotzdem eine Antwort. Wir messen das in Eval-Runs bei klassischem RAG regelmäßig in einer Größenordnung von 15-25% der „weiß nicht“-Cases — das LLM erfindet plausibel klingende Inhalte, statt zuzugeben, dass die Info fehlt.

Drittens: Keine Korrekturschleife. Wenn der erste Retrieval die falschen Chunks zieht, gibt es keinen zweiten Versuch mit anderer Query-Formulierung. Das ist besonders schmerzhaft bei Fachjargon, Akronymen und unscharfen User-Formulierungen.

Agentic RAG löst alle drei Probleme strukturell — nicht durch besseren Retriever, sondern durch eine Schleife. Der Agent plant, holt, prüft die eigene Antwort und entscheidet, ob weiter retrieved werden muss.


Was Agentic RAG strukturell anders macht

Im Kern ist Agentic RAG ein State-Machine-Pattern. Statt einer linearen Pipeline gibt es Nodes (Schritte) und Edges (Übergänge), die der LLM-Agent dynamisch entscheidet. LangGraph ist 2026 das dominante Framework dafür, weil es als einziges der großen Agent-Frameworks durable Execution mit Checkpointing nativ mitbringt — wir können einen Run pausieren, persistieren und Stunden später fortsetzen, ohne State zu verlieren.

Der typische Agentic-RAG-Graph hat fünf Nodes: ein Query-Planner zerlegt komplexe Fragen in Sub-Queries; ein Retriever holt für jede Sub-Query relevante Chunks; ein Grader prüft, ob die Chunks die Frage beantworten; ein Reflection-Step bewertet die generierte Antwort gegen die Quellen; ein Re-Retrieval-Step wird ausgelöst, wenn der Reflection-Score unter einem Threshold liegt.

LangChain hat im April 2026 eine Eval-Studie veröffentlicht, in der Agentic-RAG-Setups auf dem HotpotQA-Benchmark (klassischer Multi-Hop-Test) 78% F1-Score erreichen, naives RAG 52%. Die Lücke ist nicht klein — sie ist der Grund, warum wir bei neuen Projekten praktisch ausschließlich Agentic-Architekturen empfehlen.


LangGraph-Setup für Production

Bevor wir in Code gehen: LangGraph ist Python, model-agnostisch und läuft self-hosted ohne Cloud-Dependency. Wir installieren es bei Mittelstand-Kunden auf AKS oder OpenShift, mit Postgres als Checkpointer und Redis für Caching. Das LLM ist bei DSGVO-kritischen Setups Llama 3.3 70B oder Qwen 2.5 72B via vLLM, bei Standard-Workloads Azure OpenAI in der EU-Region.

# pip install langgraph langchain langchain-openai langchain-qdrant

from typing import TypedDict, List
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.postgres import PostgresSaver
from langchain_openai import AzureChatOpenAI
from langchain_qdrant import QdrantVectorStore

class RAGState(TypedDict):
    question: str
    sub_queries: List[str]
    documents: List[dict]
    answer: str
    grade: str
    iterations: int

llm = AzureChatOpenAI(
    azure_endpoint="https://pexon-aoai-eu.openai.azure.com/",
    azure_deployment="gpt-4o",
    api_version="2026-05-01",
    temperature=0.0,
)

vectorstore = QdrantVectorStore.from_existing_collection(
    embedding=embeddings,
    collection_name="pexon-knowledge",
    url="http://qdrant.pexon.local:6333",
)
retriever = vectorstore.as_retriever(search_kwargs={"k": 8})

Das ist die Basis. Postgres-Checkpointer macht den Graph durable — wenn ein Run nach Node 3 abstürzt, läuft er beim nächsten Aufruf bei Node 4 weiter, mit kompletter State-Historie. Für regulierte Branchen ist das nicht nur Komfort, sondern Audit-Anforderung.


Code 1: Query-Planning und Reflection

Der erste echte Schritt ist das Query-Planning. Wir bitten das LLM, die User-Frage in atomare Sub-Queries zu zerlegen — eine pro Information, die für die Antwort gebraucht wird.

def plan_queries(state: RAGState) -> RAGState:
    prompt = f"""Zerlege die Frage in atomare Sub-Queries.
Eine Sub-Query pro benötigter Information.
Antwort als JSON-Array.

Frage: {state['question']}

Beispiel:
Frage: Welche Versicherungssumme gilt für München nach 22 Uhr?
["Versicherungssumme Standort München",
 "Sonderregelung Schadensereignis nach 22 Uhr",
 "Allgemeine Police Versicherungssumme"]"""
    
    response = llm.invoke(prompt)
    state["sub_queries"] = json.loads(response.content)
    state["iterations"] = 0
    return state

def retrieve(state: RAGState) -> RAGState:
    all_docs = []
    for sq in state["sub_queries"]:
        docs = retriever.invoke(sq)
        all_docs.extend([{"content": d.page_content, "source": d.metadata, "query": sq}
                         for d in docs])
    state["documents"] = all_docs
    return state

Reflection ist der Kern. Nach der Antwort-Generierung prüft ein zweiter LLM-Call, ob die Antwort vollständig auf den Quellen basiert und die Frage tatsächlich beantwortet. Wir nutzen dafür ein Pydantic-Schema, damit der Output strukturiert und maschinenlesbar ist.

from pydantic import BaseModel, Field
from typing import Literal

class GraderOutput(BaseModel):
    grounded: bool = Field(description="Antwort vollständig aus Quellen ableitbar")
    answers_question: bool = Field(description="Frage tatsächlich beantwortet")
    missing_info: List[str] = Field(description="Fehlende Sub-Queries für Re-Retrieval")
    decision: Literal["accept", "retry", "reject"]

grader_llm = llm.with_structured_output(GraderOutput)

def reflect(state: RAGState) -> RAGState:
    sources_text = "nn".join(f"[{i}] {d['content']}" for i, d in enumerate(state["documents"]))
    grade = grader_llm.invoke(f"""Prüfe ob die Antwort die Frage beantwortet und auf den Quellen basiert.

Frage: {state['question']}
Antwort: {state['answer']}
Quellen: {sources_text}

Wenn Antwort nicht vollständig: nenne fehlende Sub-Queries für Re-Retrieval.""")
    
    state["grade"] = grade.decision
    if grade.decision == "retry":
        state["sub_queries"] = grade.missing_info
        state["iterations"] += 1
    return state

Code 2: Self-Correction-Loop mit Iteration-Cap

Der eigentliche Magic-Moment ist die Schleife. Der Graph entscheidet nach dem Grading, ob die Antwort akzeptiert wird, ob neu retrieved werden muss, oder ob die Antwort verworfen wird (zum Beispiel weil die Info nicht im Korpus existiert).

def should_retry(state: RAGState) -> str:
    if state["grade"] == "accept":
        return "end"
    if state["grade"] == "reject":
        return "honest_response"
    if state["iterations"] >= 3:
        return "honest_response"  # Cap für Cost-Control
    return "retrieve"

def honest_response(state: RAGState) -> RAGState:
    state["answer"] = (
        "Ich kann die Frage mit den verfügbaren Quellen nicht "
        "vollständig beantworten. Folgendes ist sicher: ..."
    )
    return state

graph = StateGraph(RAGState)
graph.add_node("plan", plan_queries)
graph.add_node("retrieve", retrieve)
graph.add_node("generate", generate_answer)
graph.add_node("reflect", reflect)
graph.add_node("honest_response", honest_response)

graph.set_entry_point("plan")
graph.add_edge("plan", "retrieve")
graph.add_edge("retrieve", "generate")
graph.add_edge("generate", "reflect")
graph.add_conditional_edges("reflect", should_retry, {
    "retrieve": "retrieve",
    "honest_response": "honest_response",
    "end": END,
})
graph.add_edge("honest_response", END)

# Persistent checkpointer für Production
checkpointer = PostgresSaver.from_conn_string("postgresql://pexon:***@db.pexon.local/rag")
app = graph.compile(checkpointer=checkpointer)

Das Iteration-Cap auf drei ist unsere klare Empfehlung. Ohne Cap kann ein Agent in pathologischen Cases zehnmal retrieven, jeweils mit neuen Sub-Queries, ohne dass die Antwort besser wird — und die Token-Rechnung explodiert. Wir messen die Iteration-Verteilung in Production: über 80% der Anfragen sind nach Iteration 1 fertig, 15% brauchen Iteration 2, der Rest landet im Cap. Das ist ein gesundes Verhältnis.


Code 3: Multi-Hop mit parallelem Sub-Query-Retrieval

Bei komplexen Multi-Hop-Fragen ist sequenzielles Retrieval zu langsam. Wir parallelisieren die Sub-Queries und mergen die Ergebnisse mit einem Re-Ranker, der die kombinierte Relevanz scort.

import asyncio
from langchain_community.cross_encoders import HuggingFaceCrossEncoder

reranker = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-v2-m3")

async def retrieve_parallel(state: RAGState) -> RAGState:
    async def retrieve_one(sq: str):
        docs = await retriever.ainvoke(sq)
        return [{"content": d.page_content, "source": d.metadata, "query": sq}
                for d in docs]
    
    results = await asyncio.gather(*[retrieve_one(sq) for sq in state["sub_queries"]])
    all_docs = [d for sublist in results for d in sublist]
    
    # Dedup + Rerank gegen die Original-Frage
    seen = set()
    unique = [d for d in all_docs if not (d["content"] in seen or seen.add(d["content"]))]
    pairs = [(state["question"], d["content"]) for d in unique]
    scores = reranker.score(pairs)
    
    ranked = sorted(zip(unique, scores), key=lambda x: x[1], reverse=True)
    state["documents"] = [d for d, _ in ranked[:10]]
    return state

Wir raten zu Cross-Encoder-Re-Ranking statt reinem Vector-Score, weil Vector-Embeddings bei mehreren Sub-Queries Relevanz für die Original-Frage nur indirekt abbilden. Der Cross-Encoder bewertet jeden Chunk direkt gegen die User-Frage und filtert die für die finale Antwort wichtigsten zehn aus 40-80 Kandidaten heraus.


Production-Setup: Observability und Eval

Agentic RAG ohne Eval-Pipeline ist genau der Killer-Fehler, den wir in jedem zweiten gescheiterten Projekt sehen. Drift bei Reflection-Logik, schleichende Qualitätsverluste durch Embedding-Model-Updates, neue Halluzinations-Muster nach Modell-Wechsel — all das fällt ohne automatisierten Eval erst auf, wenn der Compliance-Officer den ersten Fehler-Vorfall aufnimmt.

Unser Standard-Setup: LangSmith oder Langfuse für Traces (Langfuse self-hosted bei DSGVO-Pflicht), ein Golden-Set von 200-500 echten User-Fragen mit erwarteten Antworten, RAGAS für automatisierte Metriken (Faithfulness, Answer Relevance, Context Precision/Recall), und ein nightly CI-Job, der Regression triggert.

# Eval-Skeleton mit RAGAS
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision

results = evaluate(
    dataset=golden_set_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision],
    llm=AzureChatOpenAI(...),
)

# Alert wenn Faithfulness <0.85 oder Drift >5% gegen letzten Run

Was bei Agentic RAG regelmäßig schiefgeht

Wir raten ab: Reflection-Loop ohne Iteration-Cap. Das ist Token-Burn auf höchstem Niveau. Cap auf drei, alarmieren wenn mehr als 5% der Anfragen ins Cap laufen — dann ist die Knowledge-Base lückenhaft oder die Query-Planning-Prompt schlecht.

Wir raten ab: Reflection mit demselben LLM, das die Antwort generiert hat. Die Halluzinations-Pattern korrelieren — wenn GPT-4o sich beim Generieren irrt, bestätigt sich GPT-4o beim Reflektieren oft selbst. Wir nehmen für Reflection ein anderes Modell, typischerweise Claude Sonnet als Grader gegen GPT-4o als Generator oder umgekehrt.

Wir raten ab: Naives Routing zwischen Agentic und einfachem RAG. Manche Frameworks empfehlen „einfach immer agentic“. Das ist falsch — 60% der echten User-Fragen sind einstufige Faktenfragen, bei denen Agentic RAG nur Latenz und Kosten addiert. Wir routen mit einem leichtgewichtigen Classifier am Eingang: simple Frage → klassisches RAG, komplexe oder Multi-Hop → Agentic RAG.

Vierter Klassiker: Kein Checkpoint-Persistenz. Wer Agentic RAG ohne Postgres-Checkpointer in Production fährt, kann nach einem Crash nichts nachvollziehen und nichts wieder aufgreifen. Für DORA-Audit ist das ein direktes Compliance-Problem — fehlende Traces für ICT-Operations.


Häufig gestellte Fragen

Was ist Agentic RAG und wann brauche ich es?

Agentic RAG ist RAG mit einem Agent-Layer, der die eigene Antwort prüft, fehlende Informationen nachholt und mehrstufige Fragen in Sub-Queries zerlegt. Sie brauchen es, wenn echte User-Fragen häufig Multi-Hop sind (Kombination aus mehreren Dokumenten), wenn Halluzinationen geschäftskritisch sind, oder wenn die Knowledge-Base sehr unstrukturiert ist. Bei einfachen FAQ-Bots reicht klassisches RAG.

LangGraph oder LangChain — was ist der Unterschied bei Agentic RAG?

LangChain ist die Foundation-Bibliothek mit Komponenten (Retriever, LLM-Wrappers, Chains). LangGraph ist das Orchestrierungs-Framework darauf, das State-Machines mit Checkpointing, Conditional Edges und durable Execution liefert. Für Production-Agentic-RAG nehmen wir LangGraph — die Conditional Edges sind genau das, was für Reflection-Loops gebraucht wird.

Wie hoch sind die Mehrkosten von Agentic RAG gegenüber naivem RAG?

Faktor 3-5 auf Token-Basis, weil Query-Planning, Reflection und mögliches Re-Retrieval zusätzliche LLM-Calls produzieren. In EUR pro Anfrage: naives RAG 0,01-0,03, Agentic RAG 0,05-0,15. Bei Volumen über 10.000 Anfragen am Tag lohnt sich Caching mit Semantic-Threshold ab 0,95, das senkt die Kosten regelmäßig um 30-50%.

Kann ich Agentic RAG ohne LangGraph bauen?

Ja, mit OpenAI Agents SDK, Claude Agent SDK oder eigenem State-Management. LangGraph hat aber die reifste Implementation für genau das Pattern und das größte Production-Ökosystem (Klarna, Uber, LinkedIn nutzen es produktiv). Eigenbau lohnt nur bei Air-Gap-Setups, bei denen LangChain-Lizenz oder Dependency-Audit den Tooling-Stack einschränkt.

Welches LLM eignet sich am besten für Agentic RAG in DACH?

Für Generation: GPT-4o oder Claude Sonnet 4 über Azure OpenAI EU oder Anthropic via Bedrock EU. Für DSGVO-strenge Setups: Llama 3.3 70B oder Qwen 2.5 72B self-hosted via vLLM — der MMLU-Gap zu GPT-4o liegt unter 1%. Für Reflection nehmen wir ein anderes Modell als für Generation, um korrelierte Halluzinationen zu vermeiden.


Nächster Schritt

Wenn Sie gerade RAG in Production haben oder evaluieren: Wir nehmen 50-100 Ihrer echten User-Fragen, lassen sie gegen Ihren aktuellen Stack und einen Agentic-RAG-Prototyp mit LangGraph laufen und vergleichen Faithfulness, Latency und Cost side-by-side. Danach wissen Sie, ob sich der Architektur-Wechsel rechnet.


Verwandte Themen


Microsoft Fabric. Bilder Blogtemplate Whitepaper

Claude Code im Unternehmen

  • Praxis-Guide für IT-Leiter – mit konkreten Einblicken zu Kosten, Sicherheit und Rollout von Claude Code im Unternehmen.

Beratungsgespräch

Sichern Sie sich Ihre kostenfreie Erstberatung

Analyse Ihres individuellen Cloud- oder KI-Bedarfs
Erste Empfehlungen zu Umsetzungsstrategien
Transparente Einblicke in unsere Methoden, Technologien & Referenzen