LangGraph Praxis-Guide 2026: KI-Agenten als zustandsbehaftete Workflows orchestrieren

Praxisnaher Guide zu LangGraph 2026: Lernen Sie, wie Sie KI-Agenten als graphbasierte Workflows orchestrieren – mit Code-Beispielen für ReAct-Agenten, Human-in-the-Loop, Multi-Agenten-Supervisor und Produktions-Best-Practices.

Einleitung: Warum KI-Agenten-Orchestrierung 2026 unverzichtbar ist

Wir schreiben das Jahr 2026, und mal ehrlich: Einfache Prompt-Ketten haben ausgedient. Die Zeiten, in denen ein Large Language Model (LLM) eine einzelne Anfrage entgegennahm und brav eine Antwort ausspuckte, sind vorbei. Moderne Unternehmensanwendungen brauchen mehr — sie brauchen autonome Agenten, die Werkzeuge nutzen, eigenständig Entscheidungen treffen und dabei einen konsistenten Zustand über mehrere Schritte hinweg beibehalten.

Das Problem mit klassischen LLM-Ketten? Sie sind linear. Eingabe rein, Verarbeitung, Ausgabe raus. Klingt simpel, ist es auch. Aber was passiert, wenn ein Agent ein Werkzeug aufrufen muss, das Ergebnis bewerten und dann entscheiden soll, ob er noch ein Werkzeug braucht oder direkt antworten kann? Was, wenn er bei einem Fehler einen alternativen Pfad einschlagen oder auf menschliche Freigabe warten muss?

Lineare Ketten versagen hier komplett. Keine Schleifen, keine bedingten Verzweigungen, kein persistentes Zustandsmanagement.

Genau hier kommt LangGraph ins Spiel. Als graphbasiertes Framework ermöglicht es die Modellierung komplexer Agenten-Workflows als gerichtete Graphen — mit Knoten für Verarbeitungsschritte, Kanten für den Kontrollfluss und bedingten Verzweigungen für dynamische Entscheidungen. Der entscheidende Unterschied zu herkömmlichen DAGs (Directed Acyclic Graphs): LangGraph unterstützt explizit zyklische Graphen, was iterative Schleifen wie den klassischen ReAct-Zyklus (Reasoning, Acting, Observing) erst möglich macht.

Die Zahlen sprechen eine deutliche Sprache: Über 14.000 GitHub-Sterne, mehr als 4,2 Millionen monatliche Downloads. Unternehmen wie Elastic, Replit und zahlreiche Fortune-500-Firmen setzen auf LangGraph für ihre produktionsreifen Multi-Agenten-Systeme. In diesem Artikel zeige ich Ihnen praxisnah, wie Sie LangGraph einsetzen — von den Grundkonzepten über konkrete Code-Beispiele bis hin zu fortgeschrittenen Mustern für den Produktionseinsatz.

Was ist LangGraph? Grundkonzepte verstehen

LangGraph ist ein Framework innerhalb des LangChain-Ökosystems, das speziell für zustandsbehaftete, graphbasierte Workflows gebaut wurde. Während LangChain sich um die Komposition von LLM-Aufrufen, Prompts und Werkzeugen kümmert, liefert LangGraph die Infrastruktur für den Kontrollfluss: Wann wird welcher Schritt ausgeführt? Wie fließt der Zustand zwischen Knoten? Wann wird eine Schleife beendet?

Die vier Kernkonzepte

Um LangGraph wirklich zu verstehen, sollten Sie vier zentrale Bausteine kennen:

  • StateGraph: Der zentrale Container für den gesamten Workflow. Ein StateGraph wird mit einem Zustandstyp (typischerweise ein TypedDict) parametrisiert und enthält alle Knoten und Kanten des Graphen.
  • Nodes (Knoten): Jeder Knoten ist im Grunde eine Python-Funktion, die den aktuellen Zustand entgegennimmt, etwas damit macht und einen aktualisierten Zustand zurückgibt. Das können LLM-Aufrufe sein, Werkzeugausführungen, Datenbankanfragen — eigentlich alles.
  • Edges (Kanten): Einfache Kanten verbinden zwei Knoten und definieren den sequenziellen Kontrollfluss. Nach Knoten A kommt immer Knoten B. Simpel.
  • Conditional Edges (Bedingte Kanten): Hier wird es spannend. Eine Routing-Funktion analysiert den aktuellen Zustand und bestimmt, welcher Knoten als nächstes drankommt. Das ist der Schlüssel für verzweigte und zyklische Workflows.

DAGs versus zyklische Graphen

Die meisten Workflow-Engines — von Apache Airflow bis zu klassischen ML-Pipelines — basieren auf DAGs, also gerichteten azyklischen Graphen. Der Kontrollfluss geht immer nur vorwärts, Schleifen sind tabu. Für viele ETL- und Datenpipelines reicht das völlig aus.

Für KI-Agenten allerdings sind Zyklen unverzichtbar. Nehmen wir den ReAct-Zyklus: Ein Agent bekommt eine Aufgabe, überlegt sich einen nächsten Schritt (Reason), führt eine Aktion aus (Act), beobachtet das Ergebnis (Observe) und entscheidet dann — weitermachen oder fertig? Diese Schleife kann drei, fünf oder auch zehn Durchläufe brauchen, und genau dafür benötigt man einen zyklischen Graphen. LangGraph unterstützt das nativ und stellt dabei sicher, dass der Zustand bei jedem Durchlauf korrekt aktualisiert und persistent gespeichert wird.

Zustandsmanagement mit TypedDict

Der Zustand eines LangGraph-Workflows wird typischerweise als Python-TypedDict definiert. Jeder Schlüssel repräsentiert einen Teil des Zustands, der zwischen Knoten geteilt wird. Durch Annotated-Typen können Sie sogenannte Reducer-Funktionen definieren, die festlegen, wie neue Werte mit bestehenden zusammengeführt werden — zum Beispiel das Anhängen neuer Nachrichten an eine bestehende Liste.

Erste Schritte: Ein einfacher ReAct-Agent mit LangGraph

Genug Theorie — jetzt wird gebaut. Wir erstellen einen funktionierenden ReAct-Agenten, der Fragen beantworten und dabei ein einfaches Rechenwerkzeug nutzen kann. Los geht's mit der Installation:

pip install langgraph langchain-openai langchain-core

Und hier der vollständige Code für unseren ersten LangGraph-Agenten:

from typing import Annotated, TypedDict
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, BaseMessage
from langchain_core.tools import tool
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode


# State definition with message reducer
class AgentState(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]


# Define a simple calculator tool
@tool
def rechner(ausdruck: str) -> str:
    """Evaluate a mathematical expression and return the result."""
    try:
        result = eval(ausdruck)
        return f"Result: {result}"
    except Exception as e:
        return f"Error: {str(e)}"


# Initialize the LLM with tool binding
tools = [rechner]
llm = ChatOpenAI(model="gpt-4o", temperature=0)
llm_with_tools = llm.bind_tools(tools)


# Node: Call the LLM
def call_llm(state: AgentState) -> dict:
    response = llm_with_tools.invoke(state["messages"])
    return {"messages": [response]}


# Routing function: Should we continue or end?
def should_continue(state: AgentState) -> str:
    last_message = state["messages"][-1]
    if last_message.tool_calls:
        return "tools"
    return END


# Build the graph
graph = StateGraph(AgentState)

# Add nodes
graph.add_node("agent", call_llm)
graph.add_node("tools", ToolNode(tools))

# Set the entry point
graph.set_entry_point("agent")

# Add conditional edge from agent node
graph.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END})

# After tool execution, always return to agent
graph.add_edge("tools", "agent")

# Compile the graph
app = graph.compile()

# Run the agent
result = app.invoke({
    "messages": [HumanMessage(content="Was ist 42 * 17 + 389?")]
})

print(result["messages"][-1].content)

Schauen wir uns an, was hier passiert:

  1. Zustandsdefinition (AgentState): Wir definieren unseren Zustand mit einem einzigen Schlüssel messages, annotiert mit dem add_messages-Reducer. Der sorgt dafür, dass neue Nachrichten an die bestehende Liste angehängt werden, anstatt sie zu überschreiben.
  2. Werkzeugdefinition: Der @tool-Dekorator macht unsere Python-Funktion für das LLM sichtbar. Das LLM bekommt die Funktionssignatur und Beschreibung und entscheidet selbst, wann es das Werkzeug einsetzt.
  3. LLM-Knoten: Die Funktion call_llm ruft das LLM mit dem aktuellen Nachrichtenverlauf auf. Das LLM entscheidet autonom, ob es ein Werkzeug aufruft oder direkt antwortet.
  4. Routing-Funktion: should_continue prüft, ob die letzte Nachricht Werkzeugaufrufe enthält. Falls ja, geht's zum Werkzeug-Knoten; andernfalls ist der Workflow fertig.
  5. Graph-Aufbau: Wir fügen die Knoten hinzu, definieren den Einstiegspunkt und verbinden alles mit Kanten. Die bedingte Kante nach dem Agent-Knoten ermöglicht die dynamische Entscheidung, und die feste Kante von tools zurück zu agent erzeugt den gewünschten Zyklus.

Das Ergebnis? Der Agent erkennt die mathematische Aufgabe, ruft das Rechenwerkzeug mit 42 * 17 + 389 auf, bekommt das Ergebnis (1103) und formuliert eine natürlichsprachliche Antwort. Ziemlich elegant für ein paar Zeilen Code.

Zustandsmanagement und Checkpointing

Das Zustandsmanagement ist ehrlich gesagt das Herzstück von LangGraph — und das, was es fundamental von einfachen Ketten-Frameworks unterscheidet. Jeder Knoten im Graphen erhält den vollständigen aktuellen Zustand, kann ihn lesen und einen aktualisierten Zustand zurückgeben. Die Aktualisierung erfolgt dabei nicht durch stumpfes Überschreiben, sondern durch intelligente Reducer-Funktionen.

Zustandsfluss und Reducer

Wenn ein Knoten ein Dictionary zurückgibt, wird dieses nicht einfach als neuer Zustand gesetzt. Stattdessen wird für jeden Schlüssel die zugehörige Reducer-Funktion aufgerufen. Der add_messages-Reducer zum Beispiel fügt neue Nachrichten zur bestehenden Liste hinzu und sorgt dafür, dass Nachrichten mit gleicher ID aktualisiert statt dupliziert werden. Sie können eigene Reducer definieren — etwa um Zähler zu inkrementieren, Listen zu filtern oder Dictionaries zusammenzuführen:

from typing import Annotated, TypedDict
from operator import add


def overwrite_value(existing, new):
    """Simple reducer that always takes the newest value."""
    return new


def merge_dicts(existing: dict, new: dict) -> dict:
    """Reducer that merges dictionaries."""
    merged = existing.copy()
    merged.update(new)
    return merged


class WorkflowState(TypedDict):
    messages: Annotated[list, add_messages]
    step_count: Annotated[int, add]          # Accumulates with addition
    metadata: Annotated[dict, merge_dicts]    # Merges dictionaries
    current_task: Annotated[str, overwrite_value]  # Always overwrites

Persistenz mit Checkpointern

Für die Entwicklung bietet LangGraph den MemorySaver, der Zustände im Arbeitsspeicher hält. Für den Produktionseinsatz stehen persistente Checkpointer zur Verfügung:

from langgraph.checkpoint.memory import MemorySaver
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.checkpoint.postgres import PostgresSaver

# Development: In-memory checkpointing
memory_saver = MemorySaver()
app_dev = graph.compile(checkpointer=memory_saver)

# Production: SQLite for single-server deployments
sqlite_saver = SqliteSaver.from_conn_string("checkpoints.db")
app_staging = graph.compile(checkpointer=sqlite_saver)

# Production: PostgreSQL for distributed systems
postgres_saver = PostgresSaver.from_conn_string(
    "postgresql://user:password@localhost:5432/langgraph_db"
)
app_prod = graph.compile(checkpointer=postgres_saver)

# Every invocation requires a thread_id for state persistence
config = {"configurable": {"thread_id": "user-session-42"}}
result = app_prod.invoke(
    {"messages": [HumanMessage(content="Analysiere den Quartalsbericht.")]},
    config=config
)

Die thread_id ist der zentrale Mechanismus für die Zuordnung von Zuständen zu Konversationen oder Benutzersitzungen. Jeder Thread bekommt seinen eigenen isolierten Zustandsverlauf — sauber getrennt.

Zeitreise-Debugging

Ein Feature, das ich besonders schätze: die Zeitreise (Time Travel). Da bei jedem Schritt ein Checkpoint erstellt wird, können Sie zu jedem beliebigen Punkt in der Ausführungshistorie zurückspringen, den Zustand inspizieren und den Workflow von dort aus mit veränderten Eingaben neu starten. Das ist unglaublich hilfreich beim Debugging komplexer Agenten-Interaktionen, bei denen ein Fehler vielleicht erst nach mehreren Zyklen sichtbar wird.

Über die get_state_history-Methode können Sie den gesamten Zustandsverlauf eines Threads abrufen und gezielt einzelne Checkpoints untersuchen. In Kombination mit LangSmith erhalten Sie so eine vollständige Transparenz über jeden einzelnen Schritt Ihres Agenten.

Bedingte Verzweigungen und dynamische Workflows

In der echten Welt brauchen Anwendungen häufig komplexere Routing-Logik als nur die Unterscheidung zwischen „Werkzeug aufrufen“ und „Antwort liefern“. LangGraph unterstützt beliebig komplexe bedingte Verzweigungen basierend auf dem aktuellen Zustand.

Mehrpfad-Routing am Beispiel eines Support-Agenten

Das folgende Beispiel zeigt einen Kundenservice-Agenten, der eingehende Anfragen analysiert und an spezialisierte Knoten weiterleitet. Ich finde dieses Pattern besonders praxisnah, weil es so gut wie in jedem Unternehmen vorkommt:

from typing import Annotated, TypedDict, Literal
from langchain_core.messages import BaseMessage, HumanMessage
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages


class SupportState(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]
    category: str
    priority: str
    resolution: str


def classify_request(state: SupportState) -> dict:
    """Classify the incoming request into a category."""
    message = state["messages"][-1].content.lower()
    if any(word in message for word in ["rechnung", "zahlung", "preis", "kosten"]):
        return {"category": "billing", "priority": "medium"}
    elif any(word in message for word in ["fehler", "bug", "absturz", "funktioniert nicht"]):
        return {"category": "technical", "priority": "high"}
    elif any(word in message for word in ["kuendigen", "abmelden", "loeschen"]):
        return {"category": "retention", "priority": "critical"}
    else:
        return {"category": "general", "priority": "low"}


def route_to_specialist(state: SupportState) -> str:
    """Route to the appropriate specialist node based on category."""
    category = state.get("category", "general")
    routing_map = {
        "billing": "billing_agent",
        "technical": "technical_agent",
        "retention": "retention_agent",
        "general": "general_agent",
    }
    return routing_map.get(category, "general_agent")


def billing_agent(state: SupportState) -> dict:
    return {"resolution": "Billing inquiry processed. Invoice details sent."}


def technical_agent(state: SupportState) -> dict:
    return {"resolution": "Technical issue logged. Engineering team notified."}


def retention_agent(state: SupportState) -> dict:
    return {"resolution": "Retention offer presented. Discount code generated."}


def general_agent(state: SupportState) -> dict:
    return {"resolution": "General inquiry answered from knowledge base."}


def compose_response(state: SupportState) -> dict:
    """Compose a final response message based on the resolution."""
    from langchain_core.messages import AIMessage
    response = f"[{state['priority'].upper()}] {state['resolution']}"
    return {"messages": [AIMessage(content=response)]}


# Build the multi-path graph
graph = StateGraph(SupportState)

graph.add_node("classifier", classify_request)
graph.add_node("billing_agent", billing_agent)
graph.add_node("technical_agent", technical_agent)
graph.add_node("retention_agent", retention_agent)
graph.add_node("general_agent", general_agent)
graph.add_node("responder", compose_response)

graph.set_entry_point("classifier")

# Conditional routing based on classification
graph.add_conditional_edges(
    "classifier",
    route_to_specialist,
    {
        "billing_agent": "billing_agent",
        "technical_agent": "technical_agent",
        "retention_agent": "retention_agent",
        "general_agent": "general_agent",
    }
)

# All specialists converge at the responder
for agent_name in ["billing_agent", "technical_agent", "retention_agent", "general_agent"]:
    graph.add_edge(agent_name, "responder")

graph.add_edge("responder", END)

app = graph.compile()

# Test with a billing inquiry
result = app.invoke({
    "messages": [HumanMessage(content="Ich habe eine Frage zu meiner Rechnung vom letzten Monat.")]
})
print(result["resolution"])
print(result["messages"][-1].content)

Dieses Muster begegnet Ihnen in der Praxis ständig: Eine Klassifikationsstufe analysiert die Eingabe, basierend auf dem Ergebnis wird an spezialisierte Verarbeitungsknoten delegiert, und alle Pfade laufen am Ende in einem gemeinsamen Antwort-Knoten zusammen. Die Stärke von LangGraph dabei? Die Routing-Logik ist vollständig transparent und testbar — keine versteckten Prompts, keine impliziten Entscheidungen.

Dynamische Knotenerstellung zur Laufzeit

Für besonders flexible Systeme unterstützt LangGraph auch die dynamische Erstellung von Knoten zur Laufzeit. Mithilfe von Send-Objekten können Sie Aufgaben dynamisch an Knoten delegieren, die zur Kompilierungszeit noch gar nicht feststehen. Das ist besonders nützlich für Map-Reduce-Muster, bei denen eine variable Anzahl von Dokumenten parallel verarbeitet werden soll.

Human-in-the-Loop: Menschliche Kontrolle einbauen

In produktiven KI-Systemen ist menschliche Kontrolle nicht nur nice-to-have — in vielen Branchen ist sie regulatorisch vorgeschrieben. LangGraph bietet mit der interrupt()-Funktion einen eleganten Mechanismus, um die Ausführung eines Agenten an definierten Stellen zu pausieren und auf menschliche Eingabe zu warten.

Warum menschliche Aufsicht unverzichtbar ist

Auch die besten LLMs machen Fehler. Halluzinationen, fehlgeleitete Werkzeugaufrufe, unangemessene Antworten — all das passiert. In sensiblen Bereichen wie Finanzdienstleistungen, Gesundheitswesen oder Rechtsberatung kann ein unkontrollierter Agent erheblichen Schaden anrichten. Human-in-the-Loop-Muster stellen sicher, dass kritische Aktionen vor ihrer Ausführung von einem Menschen geprüft werden.

Die interrupt()-Funktion in der Praxis

from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
from typing import Annotated, TypedDict


class ApprovalState(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]
    pending_action: str
    approved: bool


def plan_action(state: ApprovalState) -> dict:
    """Agent plans an action that requires human approval."""
    user_query = state["messages"][-1].content
    # In a real system, the LLM would determine the action
    planned = f"Execute database query based on: {user_query}"
    return {"pending_action": planned}


def human_review(state: ApprovalState) -> dict:
    """Pause execution and wait for human approval."""
    action = state["pending_action"]
    # This will pause the graph and return control to the caller
    decision = interrupt({
        "action": action,
        "question": "Do you approve this action? (approve/reject)"
    })
    return {"approved": decision == "approve"}


def execute_action(state: ApprovalState) -> dict:
    """Execute the approved action."""
    if state["approved"]:
        return {"messages": [AIMessage(content=f"Aktion ausgefuehrt: {state['pending_action']}")]}
    return {"messages": [AIMessage(content="Aktion wurde vom Benutzer abgelehnt.")]}


def route_after_review(state: ApprovalState) -> str:
    return "execute" if state.get("approved", False) else "execute"


# Build graph with human-in-the-loop
graph = StateGraph(ApprovalState)
graph.add_node("planner", plan_action)
graph.add_node("review", human_review)
graph.add_node("execute", execute_action)

graph.set_entry_point("planner")
graph.add_edge("planner", "review")
graph.add_edge("review", "execute")
graph.add_edge("execute", END)

# Compile with checkpointer (required for interrupt)
checkpointer = MemorySaver()
app = graph.compile(checkpointer=checkpointer)

config = {"configurable": {"thread_id": "approval-demo"}}

# First invocation: will pause at interrupt()
result = app.invoke(
    {"messages": [HumanMessage(content="Loesche alle inaktiven Benutzerkonten.")]},
    config=config
)
# At this point, the graph is paused, waiting for human input

# Resume with approval
result = app.invoke(
    Command(resume="approve"),
    config=config
)
print(result["messages"][-1].content)

Der entscheidende Punkt: Wenn interrupt() aufgerufen wird, speichert LangGraph den vollständigen Zustand im Checkpointer und gibt die Kontrolle an den Aufrufer zurück. Das ist typischerweise eine Web-API oder ein Chat-Interface, das dem Benutzer die geplante Aktion zeigt und auf seine Entscheidung wartet. Sobald die Entscheidung vorliegt, wird der Graph mit Command(resume=...) fortgesetzt — nahtlos, als wäre nichts gewesen.

Gängige Human-in-the-Loop-Muster

  • Genehmigen/Ablehnen: Der Agent schlägt eine Aktion vor, der Mensch genehmigt oder lehnt ab. Das einfachste und häufigste Muster.
  • Bearbeiten vor Senden: Der Agent entwirft eine E-Mail oder ein Dokument, der Mensch kann den Entwurf vor dem Versand bearbeiten.
  • Prüfen vor Ausführung: Der Agent zeigt einen Ausführungsplan an, und der Mensch kann einzelne Schritte modifizieren oder entfernen, bevor es losgeht.
  • Eskalation: Der Agent merkt, dass eine Anfrage seine Fähigkeiten übersteigt, und eskaliert automatisch an einen menschlichen Mitarbeiter.

Multi-Agenten-Systeme mit dem Supervisor-Muster

Einzelne Agenten stoßen schnell an ihre Grenzen, wenn Aufgaben unterschiedliche Spezialisierungen erfordern. Das kennen Sie vermutlich aus Ihrem eigenen Team: Niemand kann alles gleich gut. Multi-Agenten-Systeme lösen genau dieses Problem, indem sie mehrere spezialisierte Agenten unter der Koordination eines übergeordneten Agenten zusammenarbeiten lassen.

Das Supervisor-Muster erklärt

Beim Supervisor-Muster gibt es einen zentralen Koordinator (den Supervisor), der eingehende Aufgaben analysiert und an spezialisierte Arbeiter-Agenten delegiert. Er entscheidet, welcher Agent als nächstes aktiv wird, sammelt die Ergebnisse ein und stellt die finale Antwort zusammen. Der große Vorteil: Jeder Agent kann mit eigenen Werkzeugen, Prompts und sogar unterschiedlichen Modellen konfiguriert werden, während der Supervisor die Kontrolle über den Gesamtworkflow behält.

Implementierung mit langgraph-supervisor

from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from langgraph_supervisor import create_supervisor


# Define specialized tools for each agent
@tool
def web_search(query: str) -> str:
    """Search the web for current information."""
    # In production, integrate with a real search API
    return f"Search results for: {query} - [simulated results]"


@tool
def calculate(expression: str) -> str:
    """Evaluate a mathematical expression."""
    try:
        return str(eval(expression))
    except Exception as e:
        return f"Calculation error: {e}"


@tool
def analyze_data(dataset: str) -> str:
    """Analyze a dataset and return key statistics."""
    return f"Analysis of {dataset}: mean=42.5, median=40, std=12.3"


# Create specialized worker agents
llm = ChatOpenAI(model="gpt-4o", temperature=0)

research_agent = create_react_agent(
    model=llm,
    tools=[web_search],
    name="research_agent",
    prompt="You are a research specialist. Find accurate, up-to-date information."
)

math_agent = create_react_agent(
    model=llm,
    tools=[calculate, analyze_data],
    name="math_agent",
    prompt="You are a math and data analysis specialist. Perform calculations accurately."
)

# Create the supervisor that coordinates the agents
supervisor = create_supervisor(
    model=llm,
    agents=[research_agent, math_agent],
    prompt=(
        "You are a team supervisor coordinating research and analysis tasks. "
        "Delegate research questions to the research_agent and mathematical "
        "or analytical tasks to the math_agent. Synthesize their outputs "
        "into a comprehensive final answer."
    )
)

# Compile and run the multi-agent system
app = supervisor.compile()

result = app.invoke({
    "messages": [{
        "role": "user",
        "content": "Recherchiere die aktuellen BIP-Zahlen Deutschlands und berechne die prozentuale Veraenderung zum Vorjahr."
    }]
})

print(result["messages"][-1].content)

In diesem Beispiel erstellt der Supervisor zwei spezialisierte Agenten: einen Recherche-Agenten mit Zugang zu einer Websuche und einen Mathematik-Agenten mit Rechen- und Analysefähigkeiten. Der Supervisor analysiert die Benutzeranfrage, delegiert die Recherche an den research_agent, leitet die Ergebnisse an den math_agent zur Berechnung weiter und fasst alles in einer kohärenten Antwort zusammen.

Supervisor versus Swarm: Wann welches Muster?

Neben dem Supervisor-Muster gibt es auch das Swarm-Muster, bei dem Agenten sich direkt untereinander die Kontrolle übergeben — ohne zentralen Koordinator. Die Entscheidung hängt vom Anwendungsfall ab:

  • Supervisor: Ideal bei zentraler Kontrolle, klaren Verantwortlichkeiten und nachvollziehbaren Entscheidungsketten. Für die meisten Unternehmensanwendungen die bessere Wahl.
  • Swarm: Geeignet für dynamische Szenarien, in denen die Aufgabenverteilung nicht vorhersehbar ist und Agenten autonom entscheiden sollen, wann sie die Kontrolle abgeben. Eher was für explorative oder kreative Workflows.

Fehlerbehandlung und Retry-Strategien für Produktionssysteme

Produktive KI-Systeme müssen robust mit Fehlern umgehen. LLM-APIs können Timeouts liefern, Werkzeuge können fehlschlagen, und Agenten können sich in Endlosschleifen verirren. LangGraph verfolgt dabei eine Philosophie, die ich sehr begrüße: Fehler werden sofort sichtbar gemacht, nicht still verschluckt.

RetryPolicy pro Knoten

LangGraph ermöglicht Retry-Richtlinien auf Knotenebene. Sie legen fest, wie oft ein Knoten bei einem Fehler wiederholt wird, welche Verzögerung dazwischenliegt und welche Fehlertypen einen Retry auslösen:

from langgraph.pregel import RetryPolicy
from langgraph.graph import StateGraph, END
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
from langchain_core.messages import BaseMessage


class RobustState(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]
    error_count: int
    last_error: str


# Configure retry policy with exponential backoff
retry_policy = RetryPolicy(
    max_attempts=3,
    initial_interval=1.0,    # 1 second initial delay
    backoff_factor=2.0,      # Double the delay each retry
    max_interval=10.0,       # Maximum 10 seconds between retries
    retry_on=(TimeoutError, ConnectionError),  # Only retry on these errors
)


def unreliable_api_call(state: RobustState) -> dict:
    """A node that calls an unreliable external API."""
    try:
        # Simulate an API call that might fail
        import random
        if random.random() < 0.3:
            raise ConnectionError("API temporarily unavailable")
        return {"messages": [], "error_count": 0, "last_error": ""}
    except Exception as e:
        return {
            "error_count": state.get("error_count", 0) + 1,
            "last_error": str(e)
        }


def fallback_handler(state: RobustState) -> dict:
    """Handle the case when all retries are exhausted."""
    from langchain_core.messages import AIMessage
    return {
        "messages": [AIMessage(
            content="Der Dienst ist voruebergehend nicht verfuegbar. "
                    "Bitte versuchen Sie es spaeter erneut."
        )]
    }


def check_error(state: RobustState) -> str:
    if state.get("error_count", 0) >= 3:
        return "fallback"
    return END


# Build graph with retry policy on the unreliable node
graph = StateGraph(RobustState)
graph.add_node("api_call", unreliable_api_call, retry=retry_policy)
graph.add_node("fallback", fallback_handler)

graph.set_entry_point("api_call")
graph.add_conditional_edges("api_call", check_error, {"fallback": "fallback", END: END})
graph.add_edge("fallback", END)

app = graph.compile()

Mehrstufige Fehlerbehandlung

Für produktive Systeme empfiehlt sich eine mehrstufige Strategie:

  1. Knotenebene: RetryPolicy für transiente Fehler wie Netzwerk-Timeouts oder API-Ratenlimits.
  2. Graph-Ebene: Bedingte Kanten, die bei wiederholtem Versagen auf Fallback-Knoten umleiten.
  3. Anwendungsebene: Try-Catch-Blöcke um den gesamten Graph-Aufruf, um unerwartete Fehler abzufangen und dem Benutzer eine hilfreiche Fehlermeldung anzuzeigen.

Circuit Breaker und Schritt-Limits

Ein häufiges Problem bei zyklischen Agenten-Graphen: Endlosschleifen. Der Agent ruft immer wieder Werkzeuge auf, ohne zu einem Ergebnis zu kommen. LangGraph bietet den recursion_limit-Parameter als Notbremse:

# Limit the maximum number of steps to prevent infinite loops
result = app.invoke(
    {"messages": [HumanMessage(content="Komplexe Aufgabe...")]},
    config={"recursion_limit": 25}  # Maximum 25 steps
)

Mein Tipp: Setzen Sie den recursion_limit immer. Ein Wert zwischen 15 und 50 passt für die meisten Anwendungsfälle. Zusätzlich können Sie im Zustand einen eigenen Schrittzähler implementieren und in der Routing-Funktion prüfen, ob ein Maximum erreicht wurde — das gibt Ihnen feinere Kontrolle als der globale Limit.

Graceful Degradation

Produktive Systeme sollten bei Fehlern nicht einfach abstürzen, sondern eine reduzierte, aber nützliche Antwort liefern. Bewährte Strategien:

  • Rückfall auf ein einfacheres Modell (z.B. von GPT-4o auf GPT-4o-mini), wenn das primäre Modell nicht verfügbar ist.
  • Verwendung gecachter Ergebnisse, wenn eine API nicht erreichbar ist.
  • Transparente Kommunikation mit dem Benutzer über eingeschränkte Funktionalität.
  • Automatische Eskalation an menschliche Mitarbeiter bei wiederholtem Versagen.

Integration mit MCP und A2A-Protokollen

2026 hat zwei wichtige Protokollstandards für KI-Agenten hervorgebracht, die LangGraph nahtlos integriert: das Model Context Protocol (MCP) und das Agent-to-Agent Protocol (A2A).

MCP: Einheitliche Werkzeugintegration

Das Model Context Protocol, ursprünglich von Anthropic initiiert, definiert einen standardisierten Weg für LLMs, auf externe Werkzeuge und Datenquellen zuzugreifen. Statt für jedes Werkzeug eine eigene Integration zu bauen (was schnell mühsam wird), verbinden Sie sich einfach mit einem MCP-Server, der die verfügbaren Werkzeuge beschreibt und deren Ausführung übernimmt.

LangGraph bietet seit Version 0.3 erstklassige MCP-Unterstützung. Sie können MCP-Server als Werkzeugquellen registrieren und die bereitgestellten Werkzeuge direkt in Ihren Agenten-Graphen nutzen. Das Schöne daran: Ein einziger MCP-Server für Datenbankzugriff kann von beliebig vielen LangGraph-Agenten genutzt werden, ohne dass die Werkzeuglogik in jedem Agenten neu implementiert werden muss.

A2A: Agenten übergreifend kommunizieren

Während MCP die Kommunikation zwischen Agenten und Werkzeugen standardisiert, adressiert A2A (Agent-to-Agent) die Kommunikation zwischen Agenten verschiedener Frameworks. Ein LangGraph-Agent kann mit einem CrewAI-Agenten oder einem AutoGen-Agenten zusammenarbeiten — ohne dass die Frameworks etwas voneinander wissen müssen. Das ist, wenn man so will, die Lingua Franca der Agentenwelt.

Das A2A-Protokoll basiert auf Agent Cards — JSON-Beschreibungen, die die Fähigkeiten eines Agenten maschinenlesbar dokumentieren. Diese werden typischerweise unter .well-known/agent-card.json bereitgestellt:

# Example agent card structure (as JSON served via HTTP)
agent_card = {
    "name": "Finanzanalyse-Agent",
    "description": "Analysiert Finanzdaten und erstellt Berichte",
    "url": "https://agents.example.com/finance",
    "version": "2.0",
    "capabilities": {
        "streaming": True,
        "pushNotifications": False,
        "stateTransitionHistory": True,
    },
    "skills": [
        {
            "id": "quarterly-report",
            "name": "Quartalsbericht",
            "description": "Erstellt einen detaillierten Quartalsbericht",
            "inputModes": ["text/plain", "application/json"],
            "outputModes": ["text/markdown", "application/pdf"]
        }
    ],
    "authentication": {
        "schemes": ["OAuth2"]
    }
}

In der Praxis ermöglicht die Kombination von MCP und A2A den Aufbau verteilter Multi-Agenten-Systeme, die über Framework- und Organisationsgrenzen hinweg zusammenarbeiten. Ein LangGraph-Supervisor könnte etwa Aufgaben an externe A2A-kompatible Agenten delegieren, die wiederum über MCP auf spezialisierte Werkzeuge zugreifen.

LangGraph vs. CrewAI vs. AutoGen: Wann welches Framework?

Die Wahl des richtigen Agenten-Frameworks hängt von den Anforderungen Ihres Projekts ab. Hier ein Vergleich der drei führenden Frameworks 2026 — und ja, ich habe mit allen dreien gearbeitet:

Kriterium LangGraph CrewAI AutoGen
Architekturansatz Graphbasierte Zustandsmaschine Rollenbasierte Agenten-Teams Konversationsbasierte Zusammenarbeit
Kontrollfluss Explizit, vollständig steuerbar Halbautomatisch, prozessdefiniert Konversationsgesteuert, dynamisch
Zustandsmanagement Umfassend, persistent, versioniert Grundlegend, aufgabenbasiert Konversationsbasiert
Lernkurve Mittel bis steil Flach, intuitiv Mittel
Produktionsreife Hoch (Enterprise-getestet) Mittel (rasch aufholend) Mittel
Human-in-the-Loop Erstklassig (interrupt/resume) Grundlegend Gut (native Unterstützung)
Streaming Vollständig (Token und Event) Begrenzt Begrenzt
Debugging Exzellent (LangSmith, Zeitreise) Grundlegend Gut (AutoGen Studio)
Skalierbarkeit Horizontal (LangGraph Platform) Vertikal Vertikal
MCP/A2A-Unterstützung Erstklassig MCP ja, A2A experimentell Grundlegend

Entscheidungshilfe

Wählen Sie LangGraph, wenn:

  • Sie maximale Kontrolle über jeden Schritt des Agenten-Workflows brauchen.
  • Persistentes Zustandsmanagement und Checkpointing essentiell sind.
  • Sie produktionsreife Systeme mit Human-in-the-Loop, Fehlerbehandlung und Observability bauen.
  • Ihre Anwendung komplexe, zyklische Workflows mit bedingten Verzweigungen erfordert.
  • Auditierbarkeit und Nachvollziehbarkeit im Unternehmensumfeld gefragt sind.

Wählen Sie CrewAI, wenn:

  • Sie schnell einen Prototyp mit rollenbasierten Agenten-Teams zusammenstecken möchten.
  • Der Workflow durch klar definierte Aufgaben und Rollen beschrieben werden kann.
  • Sie eine intuitive API mit flacher Lernkurve bevorzugen.
  • Komplexe Zustandsverwaltung kein Thema ist.

Wählen Sie AutoGen, wenn:

  • Ihr Anwendungsfall auf iterativer Verfeinerung durch Agenten-Konversation basiert.
  • Sie flexible, dynamische Interaktionsmuster brauchen, die schwer vorherzusagen sind.
  • Code-Generierung und -Ausführung ein zentraler Bestandteil des Workflows ist.
  • Sie vom Microsoft-Ökosystem profitieren möchten.

Best Practices für den Produktionseinsatz

Der Weg vom funktionierenden Prototyp zum produktiven LangGraph-System erfordert sorgfältige Planung. Die folgenden Best Practices stammen aus den Erfahrungen zahlreicher Unternehmen, die LangGraph im großen Maßstab betreiben — und aus ein paar eigenen schmerzhaften Lektionen.

1. Persistente Checkpointer verwenden

Der MemorySaver ist ausschließlich für die Entwicklung gedacht. Punkt. In Produktionsumgebungen brauchen Sie einen persistenten Checkpointer, der Daten über Neustarts und Skalierungsereignisse hinweg erhält. Für Einzelserver-Deployments eignet sich SqliteSaver, für verteilte Systeme PostgresSaver. Wenn Sie die LangGraph Platform nutzen, wird das Checkpointing automatisch verwaltet.

2. Begrenzte Retries und Circuit Breaker implementieren

Konfigurieren Sie für jeden Knoten, der externe Dienste aufruft, eine angemessene RetryPolicy. Setzen Sie immer einen recursion_limit und implementieren Sie zusätzlich anwendungsspezifische Abbruchbedingungen im Zustand. Ein Agent, der nach 20 Werkzeugaufrufen keine Lösung gefunden hat, sollte das offen kommunizieren — anstatt stur weiterzumachen.

3. Observability mit LangSmith

LangSmith, die Beobachtungsplattform des LangChain-Ökosystems, bietet tiefe Integration mit LangGraph. Jeder Knotenaufruf, jede Zustandsänderung und jeder LLM-Aufruf wird automatisch protokolliert. Für Produktionssysteme ist das unverzichtbar:

  • Aktivieren Sie LangSmith-Tracing für alle Produktions-Workflows.
  • Definieren Sie Alarme für ungewöhnlich lange Ausführungszeiten oder hohe Fehlerraten.
  • Nutzen Sie die Zeitreise-Funktion, um fehlerhafte Ausführungen Schritt für Schritt zu analysieren.
  • Erstellen Sie Dashboards für Durchsatz, Latenz, Fehlerrate und Kosten pro Ausführung.

4. Inhaltsfilterung und Ratenbegrenzung

Für Unternehmensanwendungen sind Sicherheitsmaßnahmen Pflicht:

  • Eingabefilterung: Prüfen Sie Benutzereingaben auf Prompt-Injection-Versuche und schädliche Inhalte, bevor sie den Agenten erreichen.
  • Ausgabefilterung: Validieren Sie Agentenantworten auf sensible Daten (PII), unerwünschte Inhalte und Konsistenz.
  • Ratenbegrenzung: Begrenzen Sie die Anzahl der Agenten-Ausführungen pro Benutzer und Zeiteinheit. Sonst explodieren die Kosten.
  • Kostenbudgets: Setzen Sie maximale Token-Budgets pro Ausführung, um kostenexplosive Endlosschleifen zu verhindern.

5. Teststrategien für graphbasierte Workflows

Das Testen von LangGraph-Workflows erfordert einen mehrschichtigen Ansatz:

  • Unit-Tests für einzelne Knoten: Testen Sie jede Knotenfunktion isoliert mit definierten Eingabezuständen. Mocken Sie LLM-Aufrufe und externe Dienste.
  • Integrationstests für Sub-Graphen: Testen Sie Teilabschnitte des Graphen mit realistischen Zuständen, um die korrekte Zusammenarbeit von Knoten und Routing-Logik zu prüfen.
  • End-to-End-Tests: Führen Sie den vollständigen Graphen mit vordefinierten Szenarien aus und prüfen Sie sowohl das Endergebnis als auch den Zustandsverlauf.
  • Chaos-Tests: Simulieren Sie Fehler in einzelnen Knoten, um die Robustheit der Fehlerbehandlung zu verifizieren.
  • LLM-Evaluierungen: Nutzen Sie LangSmith-Evaluierungen, um die Qualität der Agentantworten systematisch zu messen und Regressionen früh zu erkennen.

6. Monitoring und Trace-Visualisierung

In Produktionsumgebungen müssen Sie den Zustand Ihrer Agenten-Systeme kontinuierlich überwachen. Definieren Sie KPIs, die für Ihren Anwendungsfall relevant sind:

  • Ausführungsdauer: Wie lange braucht ein durchschnittlicher Workflow von der Eingabe bis zur finalen Antwort?
  • Schrittanzahl: Wie viele Knoten durchläuft ein typischer Workflow? Steigt diese Zahl unerwartet an?
  • Werkzeugnutzung: Wie häufig und in welcher Kombination werden Werkzeuge aufgerufen?
  • Fehlerrate: Wie viele Workflows enden mit einem Fehler? Welche Knoten sind besonders anfällig?
  • Kosten pro Workflow: Wie viele Token werden pro Ausführung verbraucht? Gibt es Ausreißer?

LangGraph bietet mit der stream-Methode die Möglichkeit, jeden Schritt eines Workflows in Echtzeit zu verfolgen. In Kombination mit Trace-Visualisierung können Sie den vollständigen Ausführungspfad grafisch darstellen — inklusive Verzweigungen, Schleifen und Zustandsänderungen. Das ist nicht nur beim Debugging Gold wert, sondern auch bei der Kommunikation mit nichttechnischen Stakeholdern, die verstehen wollen, wie ein KI-Agent zu seiner Entscheidung gekommen ist.

7. Versionierung und schrittweises Rollout

Behandeln Sie Ihre LangGraph-Workflows wie Software-Artefakte: Versionieren, in Staging testen und schrittweise (Canary-Deployment) ausrollen. Gerade bei Änderungen an Routing-Logik oder Prompts können unerwartete Verhaltensänderungen auftreten, die nur unter realen Bedingungen sichtbar werden. Die LangGraph Platform bietet hierzu integrierte Unterstützung für A/B-Tests und schrittweises Rollout.

Fazit und Ausblick

LangGraph hat sich 2026 als Industriestandard für die Orchestrierung von KI-Agenten etabliert. Die Kombination aus graphbasiertem Kontrollfluss, persistentem Zustandsmanagement, erstklassiger Human-in-the-Loop-Unterstützung und nahtloser LangChain-Integration macht es zur ersten Wahl für produktionsreife Agenten-Systeme.

Was LangGraph wirklich ausmacht, ist die Philosophie der expliziten Kontrolle: Jeder Schritt, jede Entscheidung, jede Zustandsänderung ist nachvollziehbar, testbar und debuggbar. In einer Welt, in der KI-Agenten zunehmend autonome Entscheidungen treffen, ist das nicht nur ein technischer Vorteil — es ist eine Notwendigkeit für verantwortungsvolle KI-Entwicklung.

Erwartete Entwicklungen

Für die kommenden Monate zeichnen sich einige spannende Trends ab:

  • Verbesserte Typsicherheit: Das LangGraph-Team arbeitet an strikterer Typvalidierung zur Kompilierungszeit, um Laufzeitfehler frühzeitig zu verhindern.
  • Cloud-verwaltetes Checkpointing: Die LangGraph Platform wird verwaltete Checkpointing-Dienste anbieten, die Skalierung, Backup und Wiederherstellung automatisieren. Das wird den operativen Aufwand erheblich reduzieren.
  • Tiefere MCP/A2A-Integration: Die Standardisierung von Werkzeug- und Agentenprotokollen wird die Interoperabilität weiter verbessern. LangGraph dürfte als eines der ersten Frameworks vollständige A2A-Konformität erreichen.
  • Visuelle Entwicklungsumgebungen: Grafische Editoren werden die Erstellung und Visualisierung von Workflows erleichtern, ohne die Flexibilität des programmatischen Zugangs einzuschränken.
  • Erweiterte Evaluierungswerkzeuge: LangSmith und andere Plattformen werden spezialisierte Metriken für Multi-Agenten-Systeme anbieten — über reine Antwortqualität hinaus, inklusive Effizienz, Kosten und Kooperationsqualität.

Der Blick auf den Markt

Analysten prognostizieren, dass bis Ende 2027 mehr als 30 Prozent aller neuen Unternehmensanwendungen Multi-Agenten-Systeme nutzen werden. Diese werden nicht mehr als Experimente betrachtet, sondern als strategische Infrastrukturkomponenten.

LangGraph ist für diese Zukunft hervorragend positioniert. Graphen statt Ketten, explizite Zustandsmaschinen statt impliziter Konversationen, persistentes Checkpointing statt flüchtigem Speicher — diese architektonischen Entscheidungen erweisen sich als die richtigen Grundlagen für skalierbare, zuverlässige und wartbare KI-Systeme.

Ihr nächster Schritt

Wenn Sie bis hierhin gelesen haben, haben Sie ein solides Verständnis der Konzepte, Muster und Best Practices für LangGraph aufgebaut. Der beste nächste Schritt? Die Code-Beispiele aus diesem Artikel in Ihrer eigenen Entwicklungsumgebung ausprobieren. Beginnen Sie mit dem einfachen ReAct-Agenten, fügen Sie Checkpointing und Human-in-the-Loop hinzu, und bauen Sie dann ein Multi-Agenten-System mit dem Supervisor-Muster.

Die offizielle LangGraph-Dokumentation unter langchain-ai.github.io/langgraph bietet weitere Tutorials und Referenzen. Die wachsende Community auf GitHub und Discord ist eine wertvolle Ressource für Fragen und Erfahrungsaustausch. Und letztlich gilt: Der beste Weg, ein Framework zu lernen, ist ein echtes Projekt. Finden Sie einen konkreten Anwendungsfall in Ihrem Unternehmen und legen Sie los.

Über den Autor Editorial Team

Our team of expert writers and editors.