Startseite / Artikel

Ein Agent ist eine While-Schleife: Wo LangChain create_agent und LangGraph Fit zum Einsatz kommen.

Ein Werkzeugaufruf-Agent in zwanzig Zeilen, die vier Produktionsprobleme, auf die Schleifen treffen, sowie wann man von LangChain create_agent zu LangGraph State Graphs wechseln sollte.

Verlag: REACTAPP.TOP8 Min. Lesezeit1816 Wörter

Quellen: An Agent Is a While Loop

Der Einsatz von Tools zieht viel Aufmerksamkeit auf sich, doch der entscheidende Teil – nämlich wann ein Tool aufgerufen werden soll, was mit dem Ergebnis gemacht werden muss und wann man aufhören sollte – ist die Schleife, die um das Modell herumgelegt wird. Man bezeichnet diese Schleife als Orchestrierung, ein Begriff, der sie größer erscheinen lässt, als sie tatsächlich ist. Der einfachste Weg, dies zu verstehen, besteht darin, zunächst das Ganze zu betrachten und anschließend zu untersuchen, warum es für die Produktion nicht ausreicht.

Ein kompletter Agent in etwa zwanzig Zeilen

Nehmen Sie den Austausch beim Aufruf von Tools: Das Modell bittet um ein Tool, Ihr Code führt es aus und das Ergebnis kehrt zum Modell zurück – und legen Sie eine while-Schleife darum. Zunächst wird das Gespräch initiiert:

messages = [system_prompt, user_question]

Dann der Schleifenkörper selbst:

while True:
    reply = model(messages, tools=TOOLS)    if not reply.tool_calls:
        return reply.text                    # the model answered; done    for call in reply.tool_calls:
        result = TOOLS[call.name](**call.args)   # your code runs it
        messages.append(tool_result(call.id, result))

Das ist ein echter Agent, kein Cartoon davon. Das Modell wählt aus, welches Tool aufgerufen werden soll. Ihr Code führt dieses Tool aus und fügt das Ergebnis hinzu. Dies wiederholt sich, bis das Modell Text statt einer Tool-Anfrage zurückgibt.

Falls es etwas enttäuschend erscheint, dass das Modell so klein ist, dann ist genau diese Reaktion beabsichtigt. Alles, was ein Framework bereitstellt, muss erst hinzugefügt werden, sobald dieser Loop in der Produktionsumgebung zum Einsatz kommt.

Eine Ausführung, Schritt für Schritt

Betrachten wir einen Notfall-Agenten, der gefragt wird, warum die Synchronisierungen mit den Transportdiensten über Nacht seit der Veröffentlichung im Dezember mit dem Fehler ERR_4412 fehlgeschlagen sind. Er findet eine Antwort in drei Anfragen innerhalb eines einzigen Loops – ohne Einsatz eines Frameworks.

Runde 1. Das Modell antwortet noch nicht. Es sendet eine Anfrage, search_runbooks("ERR_4412"), und der Loop führt diese aus. Drei Ergebnisse kommen zurück, wobei das oberste besagt, dass der Fehler auf einen abgelaufenen Authentifizierungs-Token des Transportdienstes zurückzuführen ist. Dieser Hinweis wird den Nachrichten hinzugefügt.

Schritt 2. Nachdem dies gelesen wurde, ruft das Modell get_release_notes("december") auf. Ein Dokument gibt an: Die Token-Refresh-Intervalle wurden von 24 Stunden auf 12 verkürzt. Dies wird erneut hinzugefügt.

Schritt 3. Mit beiden Ergebnissen antwortet das Modell in reinem Text, ohne weitere Tool-Anfragen. Synchronisierungen, die über Nacht laufen, dauern länger als zwölf Stunden, wodurch das Token mitten in einer Laufzeit abläuft. Da es keine Ausführungsanfrage gibt, verlässt der Loop das Programm.

Das Modell wählte die Tools aus und führte sie aus. Die Nachrichtenliste wuchs um zwei Ergebnisse, ansonsten geschah nichts weiter.

Was bricht nach einer Woche des Betriebs?

In der Produktion treten in der Regel vier Probleme auf, meist in dieser Reihenfolge. Keines betrifft das Modell selbst; alle betreffen den Umfeldbetrieb darum herum.

Der Neustart. In Runde 2 steckt das System wegen eines langsamen Problems acht Minuten lang fest, während der Container recycelt wird. Da die messages nur im Speicher vorhanden waren, verschwinden sie und die Ausführung beginnt erneut von vorne. Die Lösung besteht darin, nach jeder Runde das Gespräch zu speichern und von dieser Speicherung aus fortzufahren.

Das gefährliche Werkzeug. An einem anderen Abend kommt das Modell in Runde 4 zu dem Schluss, dass die Lösung rollback_release("dec-2025") ist. Dass ein Modell so etwas um 3 Uhr morgens allein erledigt, ist nichts, was jemand wollen würde. Der Loop muss gestoppt werden, eine Person um Rat gefragt werden, möglicherweise bis zum Morgen gewartet werden, bevor die Ausführung genau dort fortgesetzt wird, wo sie unterbrochen wurde. Ein einfacher while-Loop kann nicht bis zum Morgen warten.

Die falsche Entscheidung. In Schritt 5 wird eine schlechte Suchanfrage gewählt, und in den Schritten 6 bis 16 wird diese Suche mit geringfügig abgewandelten Formulierungen wiederholt, wobei jeder Versuch extra berechnet wird. Das Anstarren einer Liste mit sechzehn Einträgen zeigt nicht, wo es schiefgelaufen ist. Hilfreich sind eine Obergrenze für die Anzahl der Schritte sowie ein aufgezeichneter Ablauf jeder Schritt, den man nachvollziehen kann.

Welcher Weg ist richtig? Authentifizierungsfehler erfordern eine bestimmte Abfolge von Schritten, Datenfehler wiederum eine andere – und wenn zwei Tools unterschiedliche Ergebnisse liefern, sollte der Fall an einen Menschen weitergeleitet werden. Ein Modell ist gut darin, ein geeignetes Tool auszuwählen, sollte aber den Ablauf nicht bei jedem Lauf anders improvisieren. Die Entscheidungspfade sollten schriftlich festgehalten werden, damit sie jedes Mal gleich funktionieren.

Betrachten Sie die vier Aspekte erneut. Keiner macht einem cleveren oder ungeschickten Modell Vorwürfe. Sie alle führen auf den umgebenden Code zurück – also darauf, was dieser beibehält, wann er anhält, was er protokolliert und wer den Ablauf bestimmt. Orchestrierung ist diese umgebende Schicht; deshalb kann eine Schleife aus zwanzig Zeilen völlig korrekt sein und dennoch ein Punkt sein, an dem man weitermachen muss.

Verwandeln Sie die Schritte in Kästchen

Ziehen Sie den gleichen Ablauf erneut auf, wobei jeder Schritt als Kästchen dargestellt wird, das durch Pfeile miteinander verbunden ist: Klassifizieren, Runbooks durchsuchen, Release-Notes abrufen, eine Lösung vorschlagen, genehmigen und anschließend anwenden oder antworten. Wenn die Schritte als Kästchen dargestellt werden, ergeben sich drei neue Möglichkeiten.

  • Jedes Kästchen beendet den Vorgang mit der Speicherung des Zustands in einer dauerhaften Speicherstelle, sodass nach einem Neustart der Ablauf dort weitergeht, wo er zuletzt beendet wurde, und nicht von vorne.
  • Jedes Kästchen kann den gesamten Ablauf pausieren und so lange auf eine Person warten, wie nötig ist, wobei der Zustand sicher gespeichert bleibt.
  • Weil die Schritte diskret sind, können Sie zu jedem Feld zurückspulen und mit unterschiedlichen Eingaben weiterlaufen, um herauszufinden, wo etwas schiefgelaufen ist.
  • Die Verzweigungen befinden sich im Klassifizierungsfeld – es gibt einen Authentifizierungspfad, einen Datensatzpfad sowie eine Eskalationsmöglichkeit. Sie haben diese drei Pfeile gezeichnet. Das Modell wählt weiterhin Werkzeuge innerhalb eines Pfades aus, doch der Pfad selbst liegt in Ihren Händen.

    Das Modell hat sich nicht geändert. Der Loop erhielt eine Form, die man sehen, speichern und unterbrechen kann.

    Was LangChain ist

    LangChain ist eine Python-Bibliothek mit einer JavaScript-Version, die vorgefertigte Komponenten für LLM-Anwendungen bereitstellt, damit derselbe Aufbau nicht jedes Mal neu geschrieben werden muss. Drei Arten von Komponenten sind wichtig.

    Modell-Wrapper. Eine einzige Schnittstelle für alle Anbieter. ChatAnthropic, ChatOpenAI und ChatGoogleGenerativeAI bieten alle dieselbe Methode .invoke(messages) an, sodass ein Wechsel des Anbieters lediglich durch eine Änderung in einer Zeile erfolgt – ohne dass der Anfragedeckel neu geschrieben werden muss.

    Integrationen. Adapter für alles, was das Modell umgibt: Vektordatenspeicher, Dokumentlader, Abrufmechanismen, Embedding-Modelle sowie mehrere hundert externe Tools. Hier liegt der größte Teil der eingesparten Arbeit, denn sonst müssten Sie für jeden Adapter selbst schreiben und ihn warten.

    Ein paketierter Agent-Loop. Seit der Version 1.0 im Oktober 2025 ist die Eingangsstelle die Funktion create_agent, die wie folgt importiert wird:

    from langchain.agents import create_agent
    

    und so verwendet:

    agent = create_agent(
        model="anthropic:claude-sonnet-4-6",
        tools=[search_runbooks, get_release_notes],
        system_prompt="You are the on-call triage assistant.",
    )
    result = agent.invoke({"messages": [("user", "Why is ERR_4412 failing?")]})
    

    Im Grunde wird der zuvor erwähnte Loop bereits vorgefertigt bereitgestellt. Auch Middleware wird unterstützt: kleine Haken, die bei einem Aufruf eines Modells oder einer Tool-Funktion ausgelöst werden. Die vorhandenen Lösungen umfassen das Anhalten zur manuellen Freigabe vor Ausführung eines Tools, das Entfernen personenbezogener Daten sowie die Zusammenfassung langer Gespräche.

    Was create_agent weglässt, ist die Kontrolle über den Inhalt des Loops: Es gibt keinen Überblick über den Zustand zwischen den Schritten, keine Pause von einem Tag Dauer, und ein abgestürzter Prozess bringt den gesamten Ablauf zum Stillstand.

    Was LangGraph ist

    Hinter create_agent steht LangGraph, eine andere Bibliothek desselben Entwicklers. Während LangChain einen fertigen Loop bereitstellt, liefert LangGraph die Komponenten zum Aufbau Ihres eigenen Loops in der oben dargestellten Graphenform. Sie müssen drei Dinge definieren.

    Zustand. Ein eingegebener Objekt, das durch den Ablauf läuft. Zur Triage enthält es die bisherigen Nachrichten, die Fehlerklassifizierung, den vorgeschlagenen Fix sowie an, ob er bereits genehmigt wurde.

    Knoten. Gewöhnliche Python-Funktionen, die den Zustand erhalten und Aktualisierungen zurückgeben. classify, search_runbooks, propose_fix und ask_human sind jeweils nur Funktionen.

    Kanten. Die Ausführungsreihenfolge. Einfache Kanten sind feste Pfeile, während bedingte Kanten Funktionen sind, die den Zustand lesen und den nächsten Knoten auswählen; dadurch wird die Trennung zwischen Authentifizierung und Daten ausgedrückt.

    Die Importe:

    from langgraph.graph import StateGraph
    

    Und ein Diagramm, das aus diesen Elementen erstellt wurde:

    g = StateGraph(TriageState)
    g.add_node("classify", classify)
    g.add_node("search", search_runbooks)
    g.add_node("propose", propose_fix)
    g.add_node("approve", ask_human)
    g.add_edge("classify", "search")
    g.add_conditional_edges("search", route_by_error_type)
    g.add_edge("propose", "approve")app = g.compile(checkpointer=PostgresSaver(...))
    

    Eine Zeile ganz am Ende trägt die entscheidende Bedeutung: ein Checkpointer, also ein Ort zur Speicherung des Zustands, der bei der Kompilierung des Graphen übergeben wird. Mit ihm wird der Zustand nach jedem Knoten geschrieben. Die Fähigkeit, nach einem Neustart weiterzumachen, interrupt() zur Wartezeit auf eine Person sowie das Zurückspulen zu einem Knoten, um alles von vorn abzuspielen – all das stammt von diesem einen Argument und nicht von handgeschriebenem Code. Ihr Beitrag bestehen aus den Kästchen und Pfeilen.

    Der Kontrast liegt also darin: LangChain bietet einen Loop, in den man nicht hineinschauen kann. LangGraph verlangt von Ihnen, den Loop selbst zu zeichnen, und im Gegenzug können Sie ihn untersuchen, speichern, anhalten und erneut abspielen. Die vier oben genannten Probleme sind die Momente, in denen es nicht mehr akzeptabel ist, nicht hineinschauen zu können.

    Ein Stack, zwei Türen

    Weil create_agent auf einem LangGraph-Graphen basiert, ist die Wahl zwischen LangChain und LangGraph keine Entscheidung bezüglich des Frameworks. Es geht vielmehr darum, welche „Tür“ verwendet wird – und die beiden ergänzen sich. Ein Agent, der mit create_agent erstellt wird, ist selbst ein Graph, was bedeutet, dass er als einzelner Knoten innerhalb eines größeren StateGraph platziert werden kann. Der größere Graph übernimmt Aufgaben wie Klassifizierung, Freigabe und Persistenz, während der innere Agent die Bereiche abdeckt, in denen das Modell entscheiden muss.

    Nutzen Sie create_agent, wenn Sie heute bereits einen funktionsfähigen Agenten benötigen und dessen innere Struktur keine Rolle spielt. Viele Agents benötigen tatsächlich nicht mehr davon. Wenden Sie sich erst an StateGraph, wenn Sie während des Laufs den Zustand überprüfen, auf eine Person warten, von einem Absturz wiederherstellen oder rückgängig machen müssen – das sind dieselben vier Probleme, die bereits zuvor aufgeführt wurden.

    Die SDKs der Anbieter Anthropic und OpenAI befinden sich neben diesem Stack und nicht darin. Sie führen denselben Zyklus aus, der an eine bestimmte Modellfamilie gebunden ist – es entsteht am geringsten Widerstand, wenn man einen einzigen Anbieter verwendet. Der Preis dafür ist die Portabilität.

    Ratschläge für ein Team

    Schreiben Sie zunächst den zwanzig Zeilen umfassenden Zyklus, auch wenn er später weggeworfen wird. Das dauert eine Stunde, und danach ist klar, was jedes Framework im Auftrag des Benutzers tut – das ist die einzige Möglichkeit, es zu debuggen.

    Wechseln Sie erst zum LangGraph, wenn eines dieser vier Probleme wirklich auftaucht – und nicht früher. Ein Chatbot, der drei Tools aufruft und antwortet, kann ohne Graph auskommen. Ein Agent, von dem erwartet wird, dass er länger als ein Neustart überlebt, auf Genehmigungen wartet oder wiederholt wird, kann das nicht – und eine robuste Ausführung, die von Grund auf entwickelt wird, ist an sich bereits ein eigenes Projekt.

    Teams greifen oft schon am ersten Tag zum Graphen, um ein Problem zu lösen, das durch einen einfachen Schleifenalgorithmus bewältigt werden könnte, und verschwenden anschließend ein Viertel der Zeit damit, das Framework zu erlernen – obwohl diese Zeit eigentlich für die Lösung des Problems selbst bestimmt wäre.