Blogs / Migration von LangChain zu LangGraph, CrewAI, Pydantic AI

Migration von LangChain zu LangGraph, CrewAI, Pydantic AI

Veröffentlicht
10. September 2026
Autor
Faizan Nadeem
Tags
LangChain LangGraph AI Agents Python
Abstrakter Netzwerkgraph aus verbundenen Knoten, der eine LangGraph-Multi-Agent-State-Machine darstellt

Das Suchinteresse erzählt gerade eine ziemlich eindeutige Geschichte: LangChain rutscht ab, während LangGraph, CrewAI und Pydantic AI steigen. Das ist weder ein Branding-Problem noch ein Hype-Zyklus, dem die Luft ausgeht — so sieht es aus, wenn die Kernabstraktion eines Frameworks nicht mehr zu dem Problem passt, das Entwickler tatsächlich haben. LangChain hat die erste Welle des LLM-App-Booms gewonnen, indem es „ein Modell aufrufen, ein paar Schritte verketten, vielleicht einen Vector Store durchsuchen" trivial gemacht hat. Agenten in Produktion sind ein anderes Problem: State, der einen Absturz überleben muss, mehrere Agenten, die Arbeit aneinander übergeben müssen, und eine Debugging-Session, die dir exakt zeigen muss, welcher Schritt schiefgelaufen ist und warum. Genau um diese Lücke geht es bei diesem Umbruch.

Der übliche Fehler in der Berichterstattung darüber ist, das Ganze als Beliebtheitswettbewerb zu rahmen — LangGraph „gewinnt", LangChain „verliert". Das ist nicht die nützliche Perspektive. Die nützliche Perspektive ist architektonisch: Was nimmt jedes Framework darüber an, wie dein Agent läuft, und hält diese Annahme noch, sobald du über das Demo hinaus bist und in einem System steckst, auf das sich andere verlassen. Dieser Post geht genau das durch — aus der Praxis, in der man auf beiden Stacks tatsächlich gebaut hat, nicht aus dem Trend-Hinterherlaufen.

Das lernst du:

  • Was LangChain richtig gemacht hat und warum es überhaupt zum Standard-Agent-Framework wurde
  • Die konkreten LangChain-Produktionsprobleme — State-Management, undurchsichtiges Debugging, Multi-Agent-Koordination — die Teams zur Migration treiben
  • Was LangGraph strukturell tatsächlich ändert: State Graphs, Checkpointer und wiederaufnehmbare Runs
  • Wie sich AgentExecutor und ein LangGraph-StateGraph auf Code-Ebene direkt nebeneinander unterscheiden
  • Wo CrewAI und Pydantic AI in denselben Umbruch passen und warum sie nicht mit LangGraph austauschbar sind
  • Wann LangChain weiterhin die richtige Wahl ist und wann sich eine LangGraph-Migration als Rewrite lohnt
  • Wie man schrittweise von LangChain zu LangGraph migriert, statt alles auf einmal

Inhaltsverzeichnis

  1. Was LangChain richtig gemacht hat und warum es zum Standard wurde
  2. Wo LangChain in Produktion wehtut: State, Debugging und Churn
  3. Was LangGraph tatsächlich ändert: State Graphs und Checkpoints
  4. AgentExecutor vs. LangGraph StateGraph: der Code nebeneinander
  5. CrewAI vs. LangGraph vs. Pydantic AI: was jedes davon löst
  6. Die drei Schmerzpunkte hinter der LangChain-Migration
  7. Wann LangChain weiterhin die richtige Wahl ist
  8. Wann sich die Migration zu LangGraph als Rewrite lohnt
  9. Wie man schrittweise von LangChain zu LangGraph migriert

Was LangChain richtig gemacht hat und warum es zum Standard wurde

Es lohnt sich, ehrlich darüber zu sein, warum LangChain zum Standard-Agent-Framework wurde, denn die Migrationsgeschichte ergibt nur im Kontrast dazu Sinn. Vor LangChain schrieb jedes Team, das auf einer LLM-API aufbaute, denselben Boilerplate von Grund auf neu: Prompt-Templating, Retry-Logik rund um Rate Limits, einen dünnen Wrapper um einen Vector Store, irgendeine Ad-hoc-Methode, den abgerufenen Kontext in einen Prompt zu stopfen. LangChain hat all das in komponierbare Bausteine verpackt — LLMChain, Retriever, Document Loader, Output Parser — und Integrationen für praktisch jeden Modellanbieter und jede Vektordatenbank mitgeliefert, die es gab. Für die erste Welle von RAG-Chatbots und einfachen Tool-nutzenden Agenten war das genau der richtige Trade-off: Du musstest nicht über Architektur nachdenken, du musstest bis Freitag ein funktionierendes Demo ausliefern, und LangChain hat dich dorthin gebracht.

Die AgentExecutor-Abstraktion hat dieselbe Idee auf Agenten ausgeweitet: Gib dem Modell eine Liste von Tools, lass es in einer Schleife schlussfolgern, parse seine Ausgabe, rufe das Tool auf, füttere das Ergebnis zurück. Für einen einzelnen Agenten, der eine Handvoll Tool-Calls in einer weitgehend linearen Abfolge macht, funktioniert das gut — und tut es immer noch. Eine riesige Menge legitimen Produktionsverkehrs hat exakt diese Form, und es gibt keinen Grund, ein System zu migrieren, das dazu passt.

Wo LangChain in Produktion wehtut: State, Debugging und Churn

Der Ärger zeigt sich, sobald das System aufhört, eine gerade Linie zu sein — und es ist derselbe Ärger, der aus einer RAG-Pipeline, die im Demo funktioniert, eine macht, die in Produktion scheitert. Die AgentExecutor-Schleife ist eine Black Box: Du übergibst ihr einen Prompt und eine Tool-Liste, und sie verwaltet intern die Reasoning-Schleife, die Zwischenschritte und den Abbruchzeitpunkt. Das ist bequem — genau bis um 2 Uhr nachts etwas schiefgeht und du wissen musst, welchen Tool-Call der Agent gemacht hat, mit welchen Argumenten, auf Basis welcher Zwischenüberlegung, und warum er sich für einen vierten Call entschieden hat, statt nach dem dritten aufzuhören. LangChains Callback-System kann das sichtbar machen, aber es ist nachträglich drangeschraubt — du rekonstruierst eine Geschichte aus Logzeilen, statt sie von einer expliziten State Machine abzulesen.

State ist der zweite, schärfere Schmerzpunkt. LangChains Memory-Abstraktionen wurden um Chat-Verläufe herum gebaut — eine Liste von Nachrichten, die wächst. Das ist nicht dasselbe Problem wie Agent-State: welche Teilaufgaben erledigt sind, was ein Sub-Agent zurückgegeben hat, wie der Plan aussieht, nachdem Schritt drei fehlgeschlagen ist und mit anderen Parametern wiederholt werden musste. Es ist auch nicht dasselbe Problem wie dauerhaftes Gedächtnis, das über Agent-Sessions hinweg bestehen bleibt — das ist noch mal eine dritte Sache. Teams schrauben am Ende eine Datenbank, einen Redis-Hash oder ein handgebautes State-Dict seitlich an die Chain, um das zu verfolgen. Das heißt: Der tatsächliche State eines Agent-Runs lebt teils in LangChains Objekten und teils in Code, den du geschrieben hast, um auszugleichen, was LangChain nicht verfolgt. In genau dieser Trennung wohnen die Bugs.

Multi-Agent-Koordination ist der dritte Druckpunkt, und es ist der, den die Suchdaten am deutlichsten widerspiegeln. In dem Moment, in dem zwei oder mehr Agenten Arbeit übergeben müssen — ein Planner, der an einen Researcher delegiert, ein Researcher, der geprüfte Ergebnisse an einen Writer weitergibt — hat AgentExecutor dafür kein natives Konzept. Du schreibst wieder deine eigene Orchestrierungsschicht auf einem Framework, dessen gesamtes Wertversprechen eigentlich lautete: „Das musst du nicht schreiben."

Es gibt einen leiseren vierten Schmerzpunkt, der die anderen drei verstärkt: LangChains eigenen Churn. Die Bibliothek hat genug Breaking-Umbauten durchlaufen — verschobene Modulpfade, Chain-Subklassen, die zugunsten von LCEL (LangChain Expression Language) deprecated wurden, und dann LCEL selbst, das etwas unbeholfen neben den neueren Agent-APIs steht — dass Teams mit einem Produktionssystem auf einer älteren Version vor einer echten Wahl stehen: durch mehrere Breaking Changes hochziehen oder unbefristet gepinnt bleiben. Ein Framework, das seine eigenen Kernabstraktionen noch aktiv umgestaltet, ist eine härtere Grundlage für ein stabiles Produktionssystem als eines, das sich gesetzt hat. Diese Instabilität ist für manche Teams selbst der Grund, warum eine Migration auf einen neueren, stabiler wirkenden Stack weniger Risiko bedeutet, als LangChains Versions-Tretmühle weiter mitzufahren.

Was LangGraph tatsächlich ändert: State Graphs und Checkpoints

LangGraphs Pitch ist nicht „LangChain, aber neuer". Es ist eine strukturell andere Idee: Dein Agent ist ein State Graph, keine undurchsichtige Schleife. Du definierst Nodes — Arbeitseinheiten, die ein LLM-Call, ein Tool-Call oder beliebiges Python sein können — und Edges dazwischen, einschließlich bedingter Edges, die anhand des aktuellen State routen. Der State selbst ist ein explizites, typisiertes Objekt, das durch den Graph fließt und an jedem Node aktualisiert wird. Diese eine Änderung löst die beiden größten LangChain-Schmerzpunkte auf einen Schlag.

Debugging wird besser, weil der Graph von Natur aus inspizierbar ist. Du kannst einen Run Node für Node nachverfolgen und den exakten State an jedem Punkt sehen, statt ihn aus Callback-Logs zu rekonstruieren. LangGraphs Checkpointer geht noch weiter: Er persistiert den State nach jedem Node, was bedeutet, dass ein abgestürzter Run von seinem letzten Checkpoint aus weiterlaufen kann, statt von vorn zu beginnen — und du kannst die State-Übergänge eines vergangenen Runs buchstäblich abspielen, um zu sehen, was passiert ist. Das ist der Unterschied zwischen „Logging hinzufügen und hoffen, dass es reicht" und „das Framework wurde unter der Annahme gebaut, dass du das inspizieren musst".

Multi-Agent-Koordination hört auf, etwas Angeschraubtes zu sein, denn ein Graph eignet sich von Natur aus dafür: Jeder Agent ist ein Subgraph oder ein Node, und das gemeinsame State-Objekt ist der Übergabemechanismus. Ein Planner-Node schreibt einen Plan in den State; ein Researcher-Node liest ihn, macht seine Arbeit und schreibt Ergebnisse zurück; eine Router-Edge entscheidet anhand des State, wer als Nächstes läuft. Das ist der tatsächliche Mechanismus, keine Marketingbeschreibung — und deshalb taucht LangGraph als Standardantwort auf, wenn Leute fragen, wie man ein Multi-Agent-System auf dem LangChain-Ökosystem baut.

Der Trade-off ist allerdings real: LangGraph ist expliziter, was für einen einfachen Fall mehr Code im Vorfeld bedeutet. Ein Single-Agent-Chatbot, der Fragen über einer Wissensbasis beantwortet, braucht keinen State Graph. Einen dafür zu schreiben ist Over-Engineering, keine Architektur.

AgentExecutor vs. LangGraph StateGraph: der Code nebeneinander

Den tatsächlichen Unterschied sieht man leichter, als man ihn beschreibt. Eine LangChain-Agent-Schleife ist ein einzelner Aufruf, der die Reasoning-Schritte im Executor versteckt:

from langchain.agents import AgentExecutor, create_tool_calling_agent

agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": "Find the latest invoice and flag anomalies"})

Alles zwischen „input" und „result" — wie viele Tool-Calls passiert sind, in welcher Reihenfolge, auf welcher Zwischenüberlegung — lebt in den Interna des Executors. verbose=True gibt dir einen Log-Stream, keinen abfragbaren State.

Eine LangGraph-Variante macht diese Reasoning-Schleife zu einem Graph, den du selbst definierst:

from langgraph.graph import StateGraph, END

def call_model(state: AgentState) -> AgentState:
    response = llm.invoke(state["messages"])
    return {"messages": [response]}

def route(state: AgentState) -> str:
    last = state["messages"][-1]
    return "tools" if last.tool_calls else END

graph = StateGraph(AgentState)
graph.add_node("agent", call_model)
graph.add_node("tools", tool_node)
graph.add_conditional_edges("agent", route, {"tools": "tools", END: END})
graph.add_edge("tools", "agent")
app = graph.compile(checkpointer=checkpointer)

Hier ist nichts versteckt. state ist ein typisiertes Objekt, das du definiert hast, jeder Node ist eine schlichte Funktion, die du isoliert unit-testen kannst, und route ist exakt die Entscheidungslogik, die früher in der Black Box des Executors lag. Das checkpointer-Argument ist das, was Wiederaufnahmefähigkeit erkauft: app.compile(checkpointer=checkpointer) persistiert state nach jedem Node-Durchlauf, sodass app.invoke einen abgestürzten Run ab dem letzten abgeschlossenen Node wieder aufnehmen kann, statt alles neu zu rechnen. Das ist der strukturelle Unterschied, den der Rest dieses Posts beschreibt — kein neues Feature, das ans alte Modell geschraubt wurde, sondern ein anderes Modell.

Der explizite Graph ist auch der Ort, an dem operative Kontrollen endlich einen Platz haben. Sobald Routing eine Funktion und State ein Objekt ist, werden ein Kill Switch für den Agenten und eng gefasste Tool-Berechtigungen zu einem Node und einer Edge — statt zu einem Wrapper, von dem du hoffst, dass er alles umschließt.

CrewAI vs. LangGraph vs. Pydantic AI: was jedes davon löst

CrewAI und Pydantic AI steigen in denselben Suchdaten, aber sie lösen angrenzende Probleme, nicht dasselbe — und sie mit LangGraph zu verwechseln ist ein verbreiteter Fehler.

CrewAI sitzt eine Ebene über LangGraph. Statt dass du Nodes und Edges definierst, definierst du Rollen — einen „Researcher"-Agenten, einen „Writer"-Agenten, einen „Editor"-Agenten — jeweils mit einem Ziel und einer Backstory, und CrewAI übernimmt die Delegation und Reihenfolge zwischen ihnen. Es ist das richtige Werkzeug, wenn dein Multi-Agent-System sich natürlich auf eine Team-Metapher abbilden lässt und du willst, dass diese Orchestrierung für dich erledigt wird. Der Preis ist derselbe, den LangChains AgentExecutor hatte: weniger Einblick darin, wie die Delegation genau abläuft, weil CrewAI diese Logik intern besitzt.

Pydantic AI ist eine andere Art von Reaktion auf dieselbe Grundbeschwerde. Es geht überhaupt nicht um Orchestrierung — es geht um Typsicherheit und darum, Magie zu minimieren. Wo LangChain und selbst LangGraph dich lose typisierte Dicts durch deine Pipeline reichen lassen, stützt sich Pydantic AI an jeder Grenze auf Pydantic-Modelle für strukturierte Ein- und Ausgaben: Die Ausgabe des Agenten ist ein validiertes Modell, kein String, von dem du hoffst, dass er JSON ist. Für Backend-Entwickler, die ohnehin in Schemas denken und ein Agent-Framework wollen, das sich wie der Rest ihrer typisierten Codebasis verhält, statt eine parallele untypisierte Welt einzuführen, ist genau das der eigentliche Reiz — keine konkurrierende Orchestrierungsgeschichte, sondern eine konkurrierende Philosophie darüber, wie viel das Framework ableiten und wie viel du deklarieren solltest.

Erwähnenswert: Keines dieser drei besitzt die Tool-Ebene so, wie es die Orchestrierung besitzt. Tools kommen zunehmend über MCP, das Model Context Protocol, das alle drei konsumieren können — „welches Framework" und „welche Tools" sind also getrennte Entscheidungen, und die eine legt die andere nicht fest.

Die drei Schmerzpunkte hinter der LangChain-Migration

Ohne Framework-Namen betrachtet, treiben drei konkrete Produktionsprobleme diesen ganzen Umbruch. Erstens undurchsichtiges Debugging: Wenn im Reasoning eines Agenten etwas schiefgeht, wie lange brauchst du, um herauszufinden warum, und gibt dir das Framework einen State-Trace oder einen Haufen Logzeilen, die du von Hand rekonstruieren musst. Zweitens Wiederaufnahmefähigkeit: Wenn ein langlaufender Agent-Prozess mitten in der Aufgabe stirbt, startet er von vorn oder dort, wo er aufgehört hat — und kannst du diese Frage überhaupt beantworten, ohne Framework-Interna zu lesen. Drittens Koordination: Wenn du mehr als einen Agenten brauchst, gibt dir das Framework ein echtes Primitiv für die State-Übergabe, oder schreibst du diese Schicht selbst, auf einer Abstraktion, die die ganze Zeit von einem einzigen Agenten ausgegangen ist.

Jedes Team, das von LangChain zu LangGraph, CrewAI oder Pydantic AI migriert, beantwortet eine dieser drei Fragen mit „der alte Stack hat das schwerer gemacht, als es sein musste". Das ist das eigentliche Signal in den Suchdaten — kein Hype, sondern eine reale Anhäufung von Produktionsreibung, die eine neue Architektur direkt adressiert.

Wann LangChain weiterhin die richtige Wahl ist

Schreib kein System um, das keine Schmerzen hat. Wenn du einen einzelnen Agenten durch eine weitgehend lineare Schrittfolge laufen lässt — abrufen, schlussfolgern, antworten, vielleicht ein oder zwei Tools aufrufen — erledigt AgentExecutor diese Aufgabe weiterhin gut, und LangChains Integrationsfläche (jeder Vector Store, jeder Modellanbieter, jeder Document Loader, der dir einfällt) ist immer noch der schnellste Weg, das zu verdrahten. Wenn dein Team bereits eine stabile, gepinnte LangChain-Version in Produktion hat, mit Testabdeckung drumherum, muss die Migrationskosten eines Rewrites eine echte Hürde nehmen, nicht bloß einen Trend. Ein funktionierendes System ohne Debugging-Schmerz, ohne Multi-Agent-Anforderung und ohne Wiederaufnahme-Anforderung ist kein System, das LangGraph braucht. Ausliefern, warten, weitermachen.

Wann sich die Migration zu LangGraph als Rewrite lohnt

Das Signal zum Migrieren ist nicht „LangGraph ist neuer". Es ist eine konkrete Symptomliste, und es lohnt sich, die eigene Codebasis ehrlich dagegen zu prüfen, bevor man einen Rewrite beginnt:

  • Du debuggst undurchsichtige Agent-Fehler häufiger als einmal pro Woche und bekommst dabei keinen klaren State-Trace — du liest Logs, um zu raten, was passiert ist, statt zu inspizieren, was passiert ist.
  • Du brauchst zwei oder mehr Agenten, die Arbeit übergeben, und schreibst bereits eigenen Orchestrierungscode — ein gemeinsames Dict, eine Message Queue, einen handgebauten Router — um das auf einem Framework hinzubekommen, das die ganze Zeit von einem Agenten ausgegangen ist.
  • Deine Agent-Runs sind lang genug oder wichtig genug, dass ein Absturz mitten in der Aufgabe ohne Wiederaufnahme ein echter Incident ist und keine Lästigkeit, die jemand von Hand neu startet.
  • Dein Kontrollfluss hat so viele bedingte Verzweigungen und Retry-Schleifen bekommen, dass du gegen das Single-Loop-Modell von AgentExecutor kämpfst, statt es zu nutzen — und die Workarounds fangen an, wie eine schlechtere Version eines State Graph auszusehen.

Wenn zwei oder mehr davon zutreffen, zahlt sich der Rewrite meist schon innerhalb von ein paar Incidents aus, die du sonst blind debuggt hättest. Wenn keines zutrifft, hast du kein Framework-Problem — du hast ein funktionierendes System, und der Suchtrend ist kein Grund, es anzufassen.

Wie man schrittweise von LangChain zu LangGraph migriert

Die Abbildung von LangChain-Konzepten auf LangGraph ist mechanischer, als „kompletter Rewrite" nahelegt. Eine Chain wird zu einer linearen Folge von Nodes. Memory wird zum State-Objekt plus Checkpointer. Die Tool-Schleife von AgentExecutor wird zu einem expliziten Node, der Tools aufruft, und einer bedingten Edge, die entscheidet, ob nochmal geschleift oder weitergegangen wird. Du musst nicht alles auf einmal migrieren — die eigentliche Agent-Schleife in einen LangGraph-Subgraph zu isolieren und dabei Retriever, Loader und andere LangChain-Integrationen stehen zu lassen (LangGraph ist darauf ausgelegt, mit ihnen zusammenzuarbeiten, nicht sie pauschal zu ersetzen), ist ein realistischer inkrementeller Pfad — und dort fangen Teams meistens an.

Wähle den Checkpointer passend dazu, wie lange deine Runs tatsächlich leben. Ein In-Memory-Checkpointer reicht für Tests, aber ein Run, der sich über Minuten zieht und ein Deployment überlebt, braucht ein dauerhaftes Backend, was in der Praxis Postgres oder Redis heißt — dieselbe Dauerhaftigkeitsfrage, die jede Background-Job-Queue dir stellt, nur in einem neuen Kostüm.

Bei alldem geht es nicht wirklich darum, welches Framework einen Beliebtheitswettbewerb gewinnt. Es ist dieselbe Architekturfrage, die Backend-Entwickler seit jeher zu jedem System stellen: Passt die Abstraktion, die du benutzt, zur Form des Problems, das du tatsächlich hast — oder schreibst du Code drumherum, um die Fehlanpassung auszugleichen. LangChain passte gut zur ersten Form von LLM-Apps. Produktions-Agenten sind aus dieser Form herausgewachsen. Triff die Entscheidung für deine eigene Codebasis auf dieser Grundlage, bevor die Debugging-Sessions und das angeschraubte State-Management sie für dich treffen.

Siehe auch: Sobald dein Graph läuft, eignen sich die Routing-Knoten für ein kleines, typisiertes Entscheidungsmodell. Mehr dazu in Jev von TypeSafe.

Faizan Nadeem
Autor
Faizan Nadeem

AI/GenAI engineer specialising in agentic RAG, LangGraph, and production LLM systems with Python and FastAPI. 2 years building AI agents, RAG pipelines, and the backends behind them.

Weitere Artikel