Startseite / Artikel

LangGraph bedingte Arbeitsabläufe: Zweigbildung ohne promptbedingtes Chaos

Codieren Sie das LangGraph-if-else-Routing als benannte bedingte Kanten mit klaren Zustandsvereinbarungen und wiederherstellbaren Fehlern, anstatt Verzweigungen in Prompts zu packen.

Verlag: REACTAPP.TOP10 Min. Lesezeit2192 Wörter

Quellen: Conditional Workflows in LangGraph: The If-Else of Agentic AI

Dieser Leitfaden erstellt erneut einen funktionsfähigen Ablauf für: Bedingte Workflows in LangGraph – das If-Else der agierenden KI. 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 Sie vor dem Ändern des Codes die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien definieren. 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. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Notfallweg gemeinsam. Wiederholungsversuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen.

Was ist eigentlich ein bedingter Workflow?

Für was genau dient ein bedingter Workflow? 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 Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Pipeline-System. Begrenzen Sie die Schemata der Tools streng – weit gefasste Argumente im Freitextformat ermöglichen Angriffe durch Dateninjektionen und machen Audits kostspielig.

Workflow #1: Lösen einer quadratischen Gleichung

Für Workflow #1: Lösen einer quadratischen Gleichung – 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 versteckten 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. Begrenzen Sie die Schemata der Tools streng. Weite Freitextargumente ermöglichen Injection-Angriffe und machen Audits kostspielig.

Die Workflow-Struktur

Für die Workflow-Struktur sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den 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. 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 Freitexte ermöglichen Angriffe durch Injection und machen Audits teuer. Für die Workflow-Struktur sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den 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. Der „happy path“ sowie der Wiederherstellungsweg sollten gemeinsam dokumentiert werden. Versuche, menschliche Kontrollen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen.

Aufbau des Zustands

Zur Erstellung des Systems sollten vor der Änderung 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 verborgenen Zuständen 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. Führen Sie Checkpoints nach teuren Modellaufrufen durch, damit ein erneuter Versuch nicht dieselbe Arbeit mehrfach ausführt.

class QuadState(TypedDict):
    a: float
    b: float
    c: float
    equation: str
    discriminant: float
    result: str

Die Knoten

Für die Knoten sollten vor der Änderung 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. 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. Erstellen Sie einen Checkpoint nach teuren Modellaufrufen, damit ein erneuter Versuch nicht denselben Aufwand nochmals berechnet.

def show_equation(state: QuadState):
    equation = f"{state['a']}x² + {state['b']}x + {state['c']}"
    return {"equation": equation}

def calculate_discriminant(state: QuadState):
    discriminant = (state['b'] ** 2) - (4 * state['a'] * state['c'])
    return {"discriminant": discriminant}

def real_roots(state: QuadState):
    r1 = (-state['b'] + state['discriminant'] ** 0.5) / (2 * state['a'])
    r2 = (-state['b'] - state['discriminant'] ** 0.5) / (2 * state['a'])
    result = f"The roots are {r1} and {r2}"
    return {"result": result}

def repeated_root(state: QuadState):
    root = -state['b'] / (2 * state['a'])
    result = f"Only repeating root is {root}"
    return {"result": result}

def no_real_roots(state: QuadState):
    return {"result": "No real roots"}

Die Routenfunktion – das ist der entscheidende Teil

Für die Routierungsfunktion – das ist der entscheidende Teil: Definieren Sie vor dem Ändern des Codes die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien. Die Bediener 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. Erfassen Sie die Laufzeiten und Kosten zusammen mit den funktionalen Ergebnissen. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Pfad von einer Demo-Umgebung in eine gemeinsam genutzte Umgebung wechselt. Legen Sie einen Checkpoint nach teuren Modellaufrufen an, damit ein erneuter Versuch nicht denselben Aufwand nochmals berechnet. Für die Routierungsfunktion – das ist der entscheidende Teil: Definieren Sie vor dem Ändern des Codes die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien. Die Bediener 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. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholte Versuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen.

def check_condition(state: QuadState):
    if state['discriminant'] > 0:
        return "real_roots"
    elif state['discriminant'] == 0:
        return "repeated_root"
    else:
        return "no_real_roots"

Zusammenfügen

Zur Verknüpfung der Komponenten 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. Vorzuziehen sind kleine, testbare Einheiten statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Trennen Sie die Planung von der Ausführung durch Tools: Der Planer schlägt vor, der Ausführende ändert die Daten, der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

graph = StateGraph(QuadState)

graph.add_node("show_equation", show_equation)
graph.add_node("calculate_discriminant", calculate_discriminant)
graph.add_node("real_roots", real_roots)
graph.add_node("repeated_root", repeated_root)
graph.add_node("no_real_roots", no_real_roots)

graph.add_edge(START, "show_equation")
graph.add_edge("show_equation", "calculate_discriminant")

# This is the magic line
graph.add_conditional_edges("calculate_discriminant", check_condition)

graph.add_edge("real_roots", END)
graph.add_edge("repeated_root", END)
graph.add_edge("no_real_roots", END)

workflow = graph.compile()

Workflow #2: Kundenbewertungsverarbeiter (basierend auf LLM)

Für Workflow #2: Customer Review Handler (basierend auf LLM), 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 Abläufe ab. Trennen Sie Planung von Tool-Exekution. Der Planer schlägt vor; der Ausführende ändert die Daten; der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

Das Szenario

Für das Szenario 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 die versteckte Zustandsinformation erraten 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. Planung und Tool-Exekution sollten getrennt bleiben: Der Planer schlägt vor, der Ausführende führt aus und der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel. Für das Szenario 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 die versteckte Zustandsinformation erraten zu müssen. Der „happy path“ sowie der „recovery path“ sollten gemeinsam dokumentiert werden. Wiederholungsversuche, menschliche Kontrollen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen.

Gestrukturierte Ausgabeschemata

Für strukturierte Ausgabeschemata 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 versteckten Zuständen 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 Pipeline-System. Begrenzen Sie die Schemata der Tools streng. Weite Argumente im Freitextformat ermöglichen Angriffe durch Dateninjektionen und machen Audits kostspielig.

from pydantic import BaseModel
from typing import Literal

class SentimentSchema(BaseModel):
    sentiment: Literal["positive", "negative"]

class DiagnosisSchema(BaseModel):
    issue_type: Literal["UI", "performance", "bug", "support", "other"]
    tone: Literal["frustrated", "angry", "disappointed", "neutral"]
    urgency: Literal["low", "medium", "high"]
from langchain_openai import ChatOpenAI

model = ChatOpenAI(model="gpt-4o-mini")
structured_model_sentiment = model.with_structured_output(SentimentSchema)
structured_model_diagnosis = model.with_structured_output(DiagnosisSchema)

Der Zustand

Für den Staat 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 verborgenen Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, 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.

class ReviewState(TypedDict):
    review: str
    sentiment: Literal["positive", "negative"]
    diagnosis: dict
    response: str

Die Knoten

Für The Nodes 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. Erhalten Sie Zeitenangaben und Kosten zusammen mit den funktionalen Ergebnissen. Frühzeitige Sichtbarkeit verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo in gemeinsame Umgebungen wechselt. Begrenzen Sie die Schemata der Tools streng. Weite Freitextargumente ermöglichen Injection-Angriffe und machen Audits teuer. Für The Nodes 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. Dokumentieren Sie den erfolgreichen Ablauf sowie den Notfallweg gemeinsam. Wiederholungsversuche, menschliche Kontrollen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen.

def find_sentiment(state: ReviewState):
    prompt = f"For the following review, find out the sentiment:\n{state['review']}"
    result = structured_model_sentiment.invoke(prompt)
    return {"sentiment": result.sentiment}
def positive_response(state: ReviewState):
    prompt = f"""Write a warm thank you message in response to this review:
    {state['review']}
    Also kindly ask the user to leave feedback on our website."""

    result = model.invoke(prompt)
    return {"response": result.content}
def run_diagnosis(state: ReviewState):
    prompt = f"""Diagnose this negative review:
    {state['review']}
    Return issue type, tone, and urgency."""

    result = structured_model_diagnosis.invoke(prompt)
    return {"diagnosis": result.model_dump()}
def negative_response(state: ReviewState):
    diagnosis = state['diagnosis']
    prompt = f"""You are a support assistant. The user had a {diagnosis['issue_type']} issue,
    sounded {diagnosis['tone']}, and marked urgency as {diagnosis['urgency']}.
    Write an empathetic, helpful resolution message."""

    result = model.invoke(prompt)
    return {"response": result.content}
def check_sentiment(state: ReviewState):
    if state['sentiment'] == "positive":
        return "positive_response"
    else:
        return "run_diagnosis"

Das Graphenmodell

Für The Graph sollten die Eingaben, der Eigentümer des Schritts 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. 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 ein verworrenes Pipeline-System. Führen Sie Checkpoints nach teuren Modellaufrufen durch, damit ein erneuter Versuch nicht denselben Aufwand nochmals berechnet.

graph = StateGraph(ReviewState)

graph.add_node("find_sentiment", find_sentiment)
graph.add_node("positive_response", positive_response)
graph.add_node("run_diagnosis", run_diagnosis)
graph.add_node("negative_response", negative_response)

graph.add_edge(START, "find_sentiment")
graph.add_conditional_edges("find_sentiment", check_sentiment)
graph.add_edge("positive_response", END)
graph.add_edge("run_diagnosis", "negative_response")
graph.add_edge("negative_response", END)

workflow = graph.compile()

Testen

Zur Überprüfung sollten Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definieren. 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. Erstellen Sie einen Checkpoint nach teuren Modellaufrufen, damit ein erneuter Versuch nicht denselben Aufwand nochmals berechnet.

Das grundlegende Denkmodell

Für das Kern-Mental-Modell 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 verborgene 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 in gemeinsam genutzte Umgebungen wechselt. Es sollte ein Checkpoint nach teuren Modellaufrufen geben, damit ein Neversuch nicht denselben Aufwand erneut berechnet. Für das Kern-Mental-Modell 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 verborgene Zustände schließen zu müssen. Der erfolgreiche Ablauf sowie der Notfallablauf sollten gemeinsam dokumentiert werden. Neversuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen.

Was kommt als Nächstes

Für den nächsten Schritt sollten Sie die Eingabedaten, den Verantwortlichen für die jeweilige Aufgabe sowie die Abbruchkriterien vor dem Ändern des Codes definieren. 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 Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema. Trennen Sie Planung von Tool-Exekution: Der Planer schlägt vor, der Ausführende ändert die Daten, der Überprüfer prüft die Ergebnisse im Vergleich zum Ziel.

Gestütztes Lernen jenseits von Blogs

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

Kurse

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

Operative Checkliste

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

Halten Sie den Graphenzustand einfach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Störungen beim Wiederaufnehmen nach Unterbrechungen.

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.