Startseite / Artikel / ReAct-Agenten in LangGraph: Denken, Handeln, Beobachten – Schritt für Schritt

ReAct-Agenten in LangGraph: Denken, Handeln, Beobachten – Schritt für Schritt

Implementieren Sie den ReAct-Loop als explizite Graphenknoten mit typisiertem Zustand, Toolaufrufen sowie Stoppsbedingungen, die Sie testen können.

4143 Wörter

Dieser Leitfaden erstellt erneut einen nutzbaren Ablauf für „ReAct Agents Explained: Eine schrittweise Implementierung mit LangGraph“. Der Fokus liegt auf Verträgen, Überprüfungen sowie Code, den man ohne Rückschluss auf die Absicht in ein Repository einfügen kann. Zur Übersicht sollten vor der Codeänderung Eingaben, Verantwortliche für die jeweiligen Schritte sowie Abbruchkriterien definiert werden. Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bevorzugen Sie kleine, testbare Einheiten vor umfangreichen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema.

Einführung

Zur Einführung sollten vor der Codeänderung die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende führt aus; der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

Was ist ein ReAct-Agent?

Zu „Was ist ein ReAct-Agent?“: Definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Erfassen Sie neben den funktionalen Ergebnissen auch die Dauer und Kosten. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo in gemeinsam genutzte Umgebungen wechselt. Trennen Sie Planung von Tool-Exekution: Der Planer schlägt vor, der Ausführende führt aus und der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

Warum ReAct besser ist als reine Chain-of-Thought-Methoden

Für „Warum ReAct besser ist als reiner Chain-of-Thought“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne die versteckte Zustandsinformation erraten zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode liegen. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort zusammengefasst sein, den Operator:innen überprüfen können, ohne den gesamten Ablaufverlauf durchlesen zu müssen. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende führt aus; der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel. Für „Warum ReAct besser ist als reiner Chain-of-Thought“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne die versteckte Zustandsinformation erraten zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortungsbereich verweisen.

anstatt eines verworrenen Pipelines.

Thought: I don’t know the answer yet. I should search.
Action: Search("Paris weather this week")
Observation: It will rain on Thursday.
Thought: I should suggest indoor activities.
Final Answer: ...

ReAct Prompting

Beim ReAct Prompting sollten die Eingaben, der Verantwortliche für den jeweiligen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Begrenzen Sie die Schemata der Tools streng. Weite Freitextargumente ermöglichen Injection-Angriffe und machen Audits kostspielig.

Zweck von ReAct Prompting

Zur Verwendung von ReAct Prompting sollten Eingaben, der Verantwortliche für einen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten und Kosten sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo-Umgebung in eine gemeinsam genutzte Umgebung wechselt. Tool-Schemata müssen streng begrenzt werden; weit gefasste Argumente im Freitext-Format ermöglichen Angriffe durch Injection und machen Audits kostspielig.

Kernelemente von ReAct Prompting

Zu den Schlüsselelementen des ReAct Promptings: Definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bewahren Sie Konfigurationen außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Operator:innen überprüfen können, ohne den gesamten Ablauf durchzulesen. Begrenzen Sie die Schemata der Tools streng. Weite Freitextargumente begünstigen Injection-Angriffe und erschweren die Überprüfungen. Zu den Schlüsselelementen des ReAct Promptings: Definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

1. Kausales Denken

Bei 1. Kausalem Denken sollten die Eingaben, der Verantwortliche für jede Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Ergebnisdokumente, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Erstellen Sie Checkpoints nach teuren Modellaufrufen, damit ein erneuter Versuch nicht denselben Aufwand nochmals berechnet.

2. Expliziter Handlungsraum

Zu 2. Expliziter Aktionsspielraum: Definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Erfassen Sie die Laufzeiten und Kosten zusammen mit den funktionalen Ergebnissen. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Legen Sie einen Checkpoint nach teuren Modellaufrufen an, damit ein erneuter Versuch nicht denselben Aufwand nochmals berechnet.

3. Integration von Beobachtungen

Zur Integration von Beobachtungen in Punkt 3 sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Betreiber sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode liegen. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den die Betreiber überprüfen können, ohne den gesamten Ablauf durchlesen zu müssen. Es sollte ein Checkpoint nach teuren Modellaufrufen geben, damit ein erneuter Versuch nicht denselben Aufwand nochmals verursacht. Zur Integration von Beobachtungen in Punkt 3 sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Betreiber sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Kleine, testbare Einheiten sind vor umfangreichen Skripten zu bevorzugen. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

4. Iteratives Schleifenverhalten

Für die 4. iterative Schleife sollten die Eingaben, der Verantwortliche für den jeweiligen Schritt sowie die Beendigungskriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Ergebnisdokumente, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende führt aus; der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

5. Erstellung der endgültigen Antwort

Zur Erstellung der endgültigen Antwort 5 sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten und Kosten sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Ablauf von Demonstrationsumgebungen in gemeinsam genutzte Umgebungen wechselt. Planung und Tool-Exekution sollten getrennt werden: Der Planer schlägt vor, der Ausführende führt aus und der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

Kanonische ReAct-Prompt-Struktur

Für die kanonische ReAct-Prompt-Struktur sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Operator:innen überprüfen können, ohne den gesamten Ablauf durchzulesen. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende führt aus; der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel. Für die kanonische ReAct-Prompt-Struktur sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Question: <user question>Thought: <reason about what to do next>

Action: <selected tool>
Action Input: <tool input>
Observation: <tool output>
... (repeat as needed)
Thought: I now know the final answer
Final Answer: <answer to the user>

Zero-Shot ReAct Prompting

Beim Zero-Shot ReAct Prompting sollten die Eingaben, der Verantwortliche für den jeweiligen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Begrenzen Sie die Schemata der Tools streng. Weite Freitextargumente ermöglichen Injection-Angriffe und machen Audits kostspielig.

ReAct Prompting vs ReAct Agents

Für ReAct Prompting im Vergleich zu ReAct Agents sollten Eingaben, der Verantwortliche für einen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten und Kosten sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Tool-Schemata müssen streng begrenzt werden – weit gefasste Argumente im Freitextformat ermöglichen Angriffe durch Injection und machen Audits teuer.

Warum LangGraph für ReAct Agents?

Für „Warum LangGraph für ReAct Agents?“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf den versteckten Zustand schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode gespeichert werden. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Operator:innen überprüfen können, ohne den gesamten Graphen durchlesen zu müssen. Die Schemata der Tools sollten streng begrenzt werden. Weite Freitextargumente fördern Injection-Angriffe und erschweren die Überprüfungen. Für „Warum LangGraph für ReAct Agents?“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf den versteckten Zustand schließen zu müssen. Man sollte kleine, testbare Einheiten vor umfangreichen Skripten bevorzugen. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Das zentrale Problem: ReAct ist eine Zustandsmaschine, kein Prompt

Zu „Das zentrale Problem: ReAct ist eine Zustandsmaschine, kein Prompt“ sollten Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Erstellen Sie Checkpoints nach teuren Modellaufrufen, damit ein Neversuch nicht dieselbe Arbeit erneut berechnet.

Was funktioniert ohne LangGraph

Für Aufgaben, die ohne LangGraph fehlschlagen, sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Erfassen Sie die Laufzeiten und Kosten zusammen mit den funktionalen Ergebnissen. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Legen Sie einen Checkpoint nach teuren Modellaufrufen an, damit ein erneuter Versuch nicht denselben Aufwand nochmals berechnet.

1. Impliziter Ablauffluss

Zu 1. Impliziter Kontrollfluss: Definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Bewahren Sie Konfigurationen außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort gesammelt sein, den Operator:innen überprüfen können, ohne den gesamten Ablauf durchzulesen. Erstellen Sie Checkpoints nach teuren Modellaufrufen, damit ein Neversuch nicht denselben Vorgang erneut verarbeitet. Zu 1. Impliziter Kontrollfluss: Definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

while True:
    llm_output = llm(prompt)
    if "Action:" in llm_output:
        tool_result = call_tool(...)
    else:
        break

2. Brüchige Zustandsverwaltung

Zu Punkt 2: Bei der Verwaltung von fragilen Zuständen sollten Eingaben, der Verantwortliche für den jeweiligen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende führt aus; der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

3. Keine Erstklass-Schleifensemantik

Für Punkt 3: Ohne Semantik für Schleifen erster Klasse sollten Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten und Kosten sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Ablauf von Demonstrationsumgebungen in gemeinsam genutzte Umgebungen wechselt. Planung und Tool-Exekution sollten getrennt werden: Der Planer schlägt vor, der Ausführende ändert die Parameter, und der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

4. Schlechte Bereitschaft für die Produktion

Für Punkt 4: Schlechte Bereitschaft für die Produktion – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes. Die Betreiber sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort gesammelt sein, den die Betreiber überprüfen können, ohne den gesamten Ablauf durchlesen zu müssen. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende führt aus; der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel. Für Punkt 4: Schlechte Bereitschaft für die Produktion – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes. Die Betreiber sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Kernkonzepte in LangGraph (agentenzentrierte Sichtweise)

Zu den Kernkonzepten in LangGraph (agentenzentrierte Sichtweise) gehören die Definition der Eingaben, des Verantwortlichen für einen Schritt sowie der Abbruchkriterien vor dem Ändern des Codes. Die Operatoren sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Begrenzen Sie die Schemata der Tools streng. Weite Freitextargumente ermöglichen Injection-Angriffe und machen Audits kostspielig.

1. Zustand: Das Gedächtnis des Agents

Für Zustand 1: Das Gedächtnis des Agenten – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Erfassen Sie die Laufzeiten und Kosten zusammen mit den funktionalen Ergebnissen. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Begrenzen Sie die Schemata der Tools streng. Weite Argumente im Freitext-Format ermöglichen Angriffe durch Injection und machen Audits teuer.

2. Knoten: Kognitive und operative Einheiten

Für Knoten 2: Kognitive und operative Einheiten – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den die Operator überprüfen können, ohne den gesamten Ablauf durchzulesen. Begrenzen Sie die Schemata der Tools streng. Weite Freitextargumente begünstigen Injection-Angriffe und erschweren die Überprüfungen. Für Knoten 2: Kognitive und operative Einheiten – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

3. Kanten: Expliziter Kontrollfluss

Zu 3. Kanten: Expliziter Kontrollfluss – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, teilweise abgeschlossene Arbeiten ab. Erstellen Sie einen Checkpoint nach teuren Modellaufrufen, damit ein Neversuch nicht denselben Aufwand erneut berechnet.

4. Deterministische Ausführung mit Flexibilität

Für eine deterministische Ausführung mit Flexibilität sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten und Kosten sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo-Umgebung in eine gemeinsam genutzte Umgebung wechselt. Ein Checkpoint nach teuren Modellaufrufen sorgt dafür, dass ein erneuter Versuch nicht denselben Aufwand nochmals berechnet.

ReAct + LangGraph: Eine natürliche Kombination

Für ReAct + LangGraph: Eine natürliche Kombination – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Operator:innen überprüfen können, ohne den gesamten Graphen durchlesen zu müssen. Erstellen Sie einen Checkpoint nach teuren Modellaufrufen, damit ein Neversuch nicht dieselbe Arbeit erneut berechnet. Für ReAct + LangGraph: Eine natürliche Kombination – definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Anwendungsfall: Hotelstornohilfe-Tool (Versicherungspolice + Rückerstattungsrechnung)

Für den Anwendungsfall „Hotelstornohilfe-Tool (Versicherungspolice + Rückerstattungsrechnung)“ sollten vor der Codeänderung die Eingaben, der Verantwortliche für den jeweiligen Schritt sowie die Abbruchkriterien definiert werden. Die Bediener sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Ergebnisdokumente, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende führt aus; der Prüfer überprüft die Ergebnisse im Vergleich zum Ziel.

Problemstellung

Zur Problembeschreibung sollten vor der Codeänderung die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Trennen Sie die Planung von der Tool-Exekution: Der Planer schlägt vor, der Ausführende führt aus und der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

Schritt 1: Abhängigkeiten installieren

Trennen Sie die Planung von der Tool-Exekution: Der Planer schlägt vor, der Ausführende führt aus und der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

pip install -U langgraph langchain langchain-openai
export OPENAI_API_KEY="..."

Schritt 2: Tools definieren (Ihre „Aktionen“)

Beschränken Sie die Tool-Schemata streng. Weite freitextbasierte Argumente begünstigen Angriffe durch Injection und machen Audits kostspielig.

from typing import TypedDict, Annotated
from datetime import datetime
import json

from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langchain_core.messages import (
    BaseMessage,
    HumanMessage,
    ToolMessage,
    SystemMessage
)
from langchain_core.tools import tool
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import tools_condition

@tool
def get_cancellation_policy(rate_plan: str) -> str:
    """
    Returns cancellation policy text for a given rate plan.
    """
    policies = {
        "flexible": "Free cancellation until 24 hours before check-in. After that, first night is charged.",
        "semi-flex": "Free cancellation until 72 hours before check-in. After that, 50% of the stay is charged.",
        "non-refundable": "No refund after booking. Full stay amount is charged on cancellation."
    }
    key = rate_plan.strip().lower()
    return policies.get(key, "Policy not found. Supported: flexible, semi-flex, non-refundable.")
@tool
def calculate_refund(
    rate_plan: str,
    check_in: str,
    cancel_date: str,
    nightly_rate: float,
    nights: int
) -> str:
    """
    Calculates refund amount based on a simplified policy model.
    Dates format: YYYY-MM-DD
    """
    rp = rate_plan.strip().lower()
    ci = datetime.strptime(check_in, "%Y-%m-%d").date()
    cd = datetime.strptime(cancel_date, "%Y-%m-%d").date()
    total = nightly_rate * nights
    days_before = (ci - cd).days
    if rp == "non-refundable":
        refund = 0.0
        charged = total
        rule = "Non-refundable: no refund."
    elif rp == "flexible":
        if days_before >= 1:
            refund = total
            charged = 0.0
            rule = "Flexible: cancelled >= 24h before check-in, full refund."
        else:
            charged = nightly_rate  # 1 night penalty
            refund = max(total - charged, 0.0)
            rule = "Flexible: late cancel, 1 night charged."
    elif rp == "semi-flex":
        if days_before >= 3:
            refund = total
            charged = 0.0
            rule = "Semi-flex: cancelled >= 72h before check-in, full refund."
        else:
            charged = 0.5 * total
            refund = total - charged
            rule = "Semi-flex: late cancel, 50% charged."
    else:
        return "Unsupported rate plan. Use: flexible, semi-flex, non-refundable."
    return (
        f"Rule: {rule}\n"
        f"Days before check-in: {days_before}\n"
        f"Total: ${total:.2f}\n"
        f"Charged: ${charged:.2f}\n"
        f"Refund: ${refund:.2f}"
    )

Schritt 3: Einen ReAct-Zyklus in LangGraph erstellen (Reason → Tool → Reason)

Beschränken Sie die Tool-Schemata streng. Weite freitextbasierte Argumente begünstigen Angriffe durch Injection und machen Audits kostspielig.

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

from langchain_openai import ChatOpenAI
from langchain_core.tools import Tool
from langgraph.prebuilt import ToolNode, tools_condition
# 1) Define state
class AgentState(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]
    booking_id: str
# 2) Define structured Output schema
class RefundDecision(BaseModel):
    booking_id: str
    rate_plan: str
    total_amount: float
    charged_amount: float
    refund_amount: float
    policy_summary: str
    explanation: str
# 2) Choose model and System prompt
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
SYSTEM_PROMPT = SystemMessage(
    content="""
You are a hotel cancellation assistant.
Rules:
- Use tools when needed.
- Never guess policy or refund.
- Final answer MUST be valid JSON with this schema:
{
  "booking_id": "...",
  "rate_plan": "...",
  "total_amount": number,
  "charged_amount": number,
  "refund_amount": number,
  "policy_summary": "...",
  "explanation": "..."
}
"""
)
# 3) Register tools
tools = [get_cancellation_policy, calculate_refund]
def safe_tool_node(state):
    last_msg = state["messages"][-1]
    if not hasattr(last_msg, "tool_calls") or not last_msg.tool_calls:
        return {}
    tool_call = last_msg.tool_calls[0]
    tool_name = tool_call["name"]
    if tool_name not in ALLOWED_TOOLS:
        return {
            "messages": [
                ToolMessage(
                    content=f"Tool '{tool_name}' is not allowed.",
                    tool_call_id=tool_call["id"]
                )
            ]
        }
    for tool in tools:
        if tool.name == tool_name:
            result = tool.invoke(tool_call["args"])
            return {
                "messages": [
                    ToolMessage(
                        content=result,
                        tool_call_id=tool_call["id"]
                    )
                ]
            }
# 4)Before reasoning, check if we already processed this booking.
REFUND_MEMORY = {}
def memory_lookup_node(state):
    booking_id = state["booking_id"]
    if booking_id in REFUND_MEMORY:
        return {
            "messages": [
                HumanMessage(
                    content=f"Cached decision found:\n{REFUND_MEMORY[booking_id]}"
                )
            ]
        }
    return {}
# 5) Reasoning node: LLM decides next action (tool call) or final answer
def agent_node(state: AgentState):
    # Bind tools so the model can produce tool calls
    llm_with_tools = llm.bind_tools(tools)
    response = llm_with_tools.invoke(state["messages"])
    return {"messages": [response]}
# 6) After final decision, store it.
def memory_write_node(state):
    booking_id = state["booking_id"]
    final_answer = state["messages"][-1].content
    REFUND_MEMORY[booking_id] = final_answer
    return {}

Bau und Kompilierung des Graphen

Die Schemata der Tools müssen streng begrenzt werden. Umfangreiche Argumente im Freitextformat fördern Injection-Angriffe und machen Audits teuer.

# 7) Build the graph
builder = StateGraph(AgentState)

# Nodes
builder.add_node("memory_lookup", memory_lookup_node)
builder.add_node("agent", agent_node)
builder.add_node("tools", safe_tool_node)
builder.add_node("memory_write", memory_write_node)
# Flow
builder.add_edge(START, "memory_lookup")
builder.add_edge("memory_lookup", "agent")
builder.add_conditional_edges(
    "agent",
    tools_condition,
    {
        "tools": "tools",   # model wants to act
        END: "memory_write" # model finished reasoning
    }
)
builder.add_edge("tools", "agent")
builder.add_edge("memory_write", END)
graph = builder.compile()

Schritt 4: Ausführung des Agents im Use Case

Die Schemata der Tools müssen streng begrenzt werden. Umfangreiche Argumente im Freitextformat fördern Injection-Angriffe und machen Audits teuer.

query = """
Booking details:
Rate plan: Non-Refundable
Check-in: 2026-01-20
Nights: 2
Nightly rate: 120
Cancelled on: 2026-01-18
"""

result = graph.invoke({
    "booking_id": "BKG-12345",
    "messages": [
        SYSTEM_PROMPT,
        HumanMessage(content=query)
    ]
})
final_output = result["messages"][-1].content
print(final_output)

Ausgabe

Die Schemata der Tools müssen streng begrenzt werden. Umfangreiche Argumente im Freitextformat fördern Injection-Angriffe und machen Audits teuer.

{
  "booking_id": "BKG-12345",
  "rate_plan": "Non-Refundable",
  "total_amount": 240.0,
  "charged_amount": 240.0,
  "refund_amount": 0.0,
  "policy_summary": "Non-refundable bookings do not allow refunds after confirmation.",
  "explanation": "The booking was made under a non-refundable rate plan, which charges the full stay amount regardless of cancellation timing."
}

Was im Inneren passiert (ReAct-Verhalten)

Die Schemata der Tools müssen streng begrenzt werden. Umfangreiche Argumente im Freitextformat fördern Injection-Angriffe und machen Audits teuer.

1) Gedanke (Begründung)

Die Schemata der Tools müssen streng begrenzt werden. Umfangreiche Argumente im Freitextformat fördern Injection-Angriffe und machen Audits teuer.

2) Aktion (Aufruf eines Tools)

Die Schemata der Tools müssen streng begrenzt werden. Umfangreiche Argumente im Freitextformat fördern Injection-Angriffe und machen Audits teuer.

3) Beobachtung (Ausgaben der Tools)

Checkpoint nach teuren Modellaufrufen, damit ein erneuter Versuch nicht denselben Vorgang erneut berechnet.

4) Endgültige Antwort

Checkpoint nach teuren Modellaufrufen, damit ein erneuter Versuch nicht denselben Vorgang erneut berechnet.

Warum dies „ReAct“ ist (nicht nur Tools)

Checkpoint nach teuren Modellaufrufen, damit ein erneuter Versuch nicht denselben Vorgang erneut berechnet.

Fazit

Planung und Tool-Ausführung getrennt halten. Der Planer schlägt vor; der Ausführende modifiziert; der Überprüfer prüft die Ergebnisse gegen das Ziel.

Operative Checkliste

Tool-Schemata streng begrenzen. Weite Argumente im Freitextformat ermöglichen Injection-Angriffe und erschweren Audits.

Bedingte Kanten sollten Geschäftsregeln als benannte Funktionen kodieren, nicht in verstecktem Prompt-Text.

Typen zusammen mit Komponenten platzieren und Eigenschaften begrenzt halten. Weite Eigenschaftensätze führen zu den Problemen, die TypeScript verhindern soll.

Schreiben Sie ein kurzes Handbuch: Wie man Schlüssel rotiert, wie man die Warteschlange leert und wie man die letzte Änderung rückgängig macht.