Startseite / Artikel / Praktische Hinweise: Erstellung eines LEPA-Support-Agenten mit LangGraph

Praktische Hinweise: Erstellung eines LEPA-Support-Agenten mit LangGraph

Schritt-für-Schritt-Anleitung zu den Praktischen Hinweisen: Erstellung eines LEPA-Support-Agenten mit LangGraph – Verträge, Überprüfungen sowie Code-Slots für Teams, die dieses Muster einsetzen.

2082 Wörter

Nutzen Sie dies als für Operator zugängliche Neuformulierung der Ideen aus „Building LEPA Support Agent with LangGraph“: klare Phasen, geordnete Codeabschnitte sowie Wiederherstellungshinweise, die auch bei Übergaben erhalten bleiben. Die Überblicksphase funktioniert am besten, wenn sie als messbarer Rahmen betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein optimales Transkript, einen Fehlerfall sowie die Notizen zur Rücksetzung. 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 einen verworrenen Ablaufprozess.

Was Sie vom ersten Graphen erwartet haben

Für die gewünschte Phase sollten Sie vor dem Ändern des Codes die Eingaben, den Verantwortlichen für den jeweiligen 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. 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. Setzen Sie menschliche Freigabe bei Schritten ein, die Geld kosten oder Produktionsdaten ändern. Eine Kompilierzeit-Verkabelung entspricht nicht der Geschäftsabschlussfähigkeit.

User message
     ↓
Notice who is speaking (teacher / admin / unknown)
     ↓
Classify the topic (grades, login, …)
     ↓
Too vague? Ask a clarifying question
     ↓
Otherwise continue toward docs + an answer

Projekteinrichtung (bewusst langweilig gehalten)

Zur gezielten Projektkonfiguration sollten Eingaben, der Verantwortliche für einen Schritt sowie die Abbruchkriterien vor dem Codeändern 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 sowie Kosten für Token oder Abfragen sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von einer Demo-Umgebung in gemeinsam genutzte Umgebungen übergeht. Bei Schritten, die Geld kosten oder Produktionsdaten ändern, sollte eine menschliche Freigabe erforderlich sein. Eine Verkabelung zur Kompilierzeit bedeutet nicht automatisch vollständige Geschäftsabdeckung.

PRJ-02/
├── app/
│   ├── state.py      # SupportState
│   ├── graph.py      # StateGraph wiring
│   ├── agents/       # intake, knowledge, support
│   ├── nodes/        # classify, ask_clarification
│   └── tools/        # search_knowledge (next article)
├── knowledge/        # LEPA support Markdown
├── api/              # FastAPI (later article)
└── tests/

Zustand: Das Objekt, das durch das Diagramm wandert

Für den Zustand des jeweiligen Stadiums sollten Eingaben, der Verantwortliche für die Schrittausführung sowie die Abbruchkriterien vor dem Codeändern definiert werden. Operator:innen 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. 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. Setzen Sie menschliche Freigabe für Kanten voraus, die Geld ausgeben oder Produktionsdaten ändern. Eine Verkabelung zur Kompilierzeit bedeutet nicht automatisch vollständige Geschäftsabdeckung. Für den Zustand des jeweiligen Stadiums sollten Eingaben, der Verantwortliche für die Schrittausführung sowie die Abbruchkriterien vor dem Codeändern definiert werden. Operator:innen 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. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortungsbereich verweisen und nicht auf einen verworrenen Ablauf.

e.

messages                 # conversation turns (add_messages reducer)
user_role                # teacher / admin / unknown
issue_category           # grades, authentication, …
clarification_needed     # should we ask for more detail?
clarification_question   # what we ask
retrieved_documents      # doc snippets (later step)
final_answer             # what we return to the user
conversation_summary     # reserved for later — unused in v1
messages: Annotated[list, add_messages]
{"user_role": "teacher"}
{"issue_category": "grades", "clarification_needed": False}

Node: jeweils eine Aufgabe

Wenn Sie die Nodes mit jeweils einer Aufgabe pro Phase bearbeiten, notieren Sie zunächst den Vertrag: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweiser Fehlermeldung. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab. Erstellen Sie nach aufwändigen Schritten einen Checkpoint. Die Wiederaufnahme sollte keine doppelte Abrechnung für denselben LLM-Aufruf vornehmen, wenn ein Operator einen späteren Node erneut ausführt.

(state) → partial update

Eingang

Während der Eingabephase sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikator sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Notieren Sie die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von einer Demo-Umgebung in gemeinsam genutzte Umgebungen übergeht. Legen Sie nach teuren Schritten einen Kontrollpunkt an. Das Wiederaufnehmen des Prozesses sollte keine erneute Gebühr für denselben LLM-Aufruf veranlassen, wenn ein Operator einen späteren Knoten erneut ausführt.

Klassifizieren

Beim Arbeiten in der Klassifizierungsphase sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreuer ohne das Durchlesen des gesamten Systems überprüfen können. Erstellen Sie Zwischenchecks nach aufwändigen Schritten. Das Wiederaufnehmen des Vorgangs sollte keine doppelte Abrechnung für denselben LLM-Aufruf verursachen, wenn ein Betreuer einen späteren Knoten erneut ausführt. Beim Arbeiten in der Klassifizierungsphase sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. 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 Pipeline-System.

Fragen zur Klärung stellen

Die Klärungsphase funktioniert am besten, wenn sie als messbarer Rahmen betrachtet wird. Erfassen Sie ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Halten Sie den Zustand der Graphen flach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen der Verarbeitung.

Wissen + Support

Die Wissensunterstützungsphase funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie vor Erweiterung des Umfangs ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Erfassen Sie außerdem die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo in gemeinsame Umgebungen wechselt. Halten Sie den Zustand der Graphen flach und typisiert – verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen der Verarbeitung.

Kanten: Wie sich die Steuerung bewegt

Die Steuerung der Bewegungen auf der Bühne funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Notizen zur Rücksetzung, bevor Sie den Umfang erweitern. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreuer ohne das Durchlesen des gesamten Graphen überprüfen können. Halten Sie den Zustand des Graphen flach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Wiederaufnehmen der Ausführung.

Normale Kanten

Die Normal-Edges-Ebene funktioniert am besten, wenn sie als messbare Oberfläche behandelt wird. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Rollback-Anmerkung, bevor Sie den Umfang erweitern. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf und den Wiederherstellungsprozess. Wiederholversuche, menschliche Kontrollen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Halten Sie den Graphenzustand strukturiert und typisiert – verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen des Ablaufs.

graph.add_edge(START, "intake")
graph.add_edge("intake", "classify")
graph.add_edge("knowledge", "support")
graph.add_edge("support", END)
When this node finishes, always go there next.

Bedingte Kanten

Die Phase der bedingten Kanten funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Ziehen Sie kleine, testbare Einheiten vor umfangreichen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf. Halten Sie den Zustand des Graphen flach und typisiert. Verschachtelte Strukturen verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen der Ausführung.

def route_after_classify(state: SupportState) -> Literal["clarify", "continue"]:
    if state.get("clarification_needed"):
        return "clarify"
    return "continue"
graph.add_conditional_edges(
    "classify",
    route_after_classify,
    {
        "clarify": "ask_clarification",
        "continue": "knowledge",
    },
)
"help"  → clarify → ask_clarification → END
"How do I enter grades?" → continue → knowledge → support → END

START und END

Die START- und END-Phase funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie ein gelungenes Beispiel, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. 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. Halten Sie den Zustand des Graphen flach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen der Verarbeitung.

START = where the runtime begins
END   = where this run stops
START → intake → classify → …
…
ask_clarification → END
support → END

Die vollständige Topologie (wie implementiert)

Die vollständige Topologie als Schritt funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie ein „goldenes“ Transkript, einen Fehlerfall sowie die Rollback-Anmerkung, bevor Sie den Umfang erweitern. Notieren Sie die Zeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von einer Demo in gemeinsame Umgebungen übergeht. Halten Sie den Zustand des Graphen flach und typisiert – eingebettete Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen des Vorgangs.

START
  → intake
  → classify
  → conditional
        ├─ clarify  → ask_clarification → END
        └─ continue → knowledge → support → END

Wie eine Anfrage durch den Graphen gelangt

Die Funktionsweise von „How a request moves stage“ funktioniert am besten, wenn sie als messbarer Ansatz betrachtet wird. Erfassen Sie ein gelungenes Beispiel, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreuer ohne das Durchlesen des gesamten Graphen überprüfen können. Halten Sie den Zustand des Graphen flach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen der Verarbeitung.

Klare Frage

Die Phase der klaren Fragestellung funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie einen erfolgreichen Fallbeispiel, einen Fehlerfall sowie die Notizen zur Rücksetzung, bevor Sie den Umfang erweitern. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Wiederherstellungsprozess. Wiederholversuche, menschliche Kontrollen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen. Halten Sie den Zustand der Graphen einfach und typisiert – verschachtelte Strukturen verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen des Ablaufs.

User: "Why aren't grades showing?"
        ↓
intake        → user_role = unknown (unless they said teacher/admin)
        ↓
classify      → issue_category = grades, clarification_needed = False
        ↓
route         → "continue"
        ↓
knowledge     → search docs (next article)
        ↓
support       → final_answer
        ↓
END

Vage Frage

User: "help"
        ↓
intake
        ↓
classify      → unknown + clarification_needed = True
        ↓
route         → "clarify"
        ↓
ask_clarification → asks which LEPA area
        ↓
END

compile() und invoke(): Der Laufzeitmoment

return graph.compile(checkpointer=checkpointer)
from langchain_core.messages import HumanMessage
from app.graph import app_graph
result = app_graph.invoke(
    {"messages": [HumanMessage(content="How do I enter grades?")]}
)
print(result["final_answer"])

Was Sie absichtlich aufgeschoben haben

Fazit

Links

Operative Kontrollliste