Erstellung von für die Produktion geeigneten LLM-Prompts: Ein siebenschichtiges Framework
Erlernen Sie ein strukturiertes, API-geprägtes Framework mit sieben Prompt-Ebenen – Anweisungen, Kontext, Einschränkungen und mehr – zur Entwicklung zuverlässiger, produktionsreifer LLM-Systeme.
21 Tage fortgeschrittener Prompt-Engineering-Techniken
Ein praktischer Leitfaden, der Sie von den Grundlagen des Prompting bis zum Entwurf vollständiger KI-Systeme führt.
Viele Menschen gehen davon aus, dass ein Prompt nichts anderes ist als eine Frage, die man an eine KI übermittelt.
Zum Beispiel:
Classify this customer support ticket.
Und es funktioniert.
Bis es plötzlich nicht mehr funktioniert.
Möglicherweise liefern einige Eingaben genau das, was man erwartet hat. Doch sobald eine leicht abweichende Anfrage kommt, verhält sich das Modell plötzlich so:
- wählt die falsche Kategorie aus,
- fertigt Details an, die in der Eingabe nicht enthalten waren,
- gibt ein Format zurück, um das man nicht gebeten hat,
- schreibt einen Erklärungstext anstelle strukturierter Daten,
- oder verhält sich inkonsistent, nur weil sich die Formulierung geändert hat.
Genau hier wird der Unterschied zwischen einem zufällig getesteten Prompt und einem für die Produktion entwickelten Prompt relevant.
In einem Produktionsystem ist ein Prompt nicht einfach nur eine Frage.
Er fungiert als Bestandteil des Vertrags zwischen Ihrer Anwendung und dem Modell.
Entwickler wissen bereits, wie man APIs mit klar definierten Grenzen entwirft:
Request → Validation → Business Logic → Response
Systeme, die auf Prompts basieren, benötigen dieselbe Disziplin:
Instructions
↓
Context
↓
Constraints
↓
Task
↓
Examples
↓
Output Contract
↓
Validation
Im weiteren Verlauf wird jede dieser Schichten einzeln erläutert und anschließend zu einem funktionierenden Beispiel zusammengefügt.
1. Das Problem mit „Fragt einfach das Modell“
Stellen Sie sich eine künstlich intelligente Funktion für eine Kundenservice-Plattform vor. Jedes eingehende Ticket muss in einen von vier Kategorien eingeordnet werden:
billing
technical
account
general
Ein minimaler Prompt könnte so aussehen:
Classify this customer support ticket:
"I was charged twice for my subscription."
Und das Modell könnte antworten:
Billing
Auf den ersten Blick sieht das in Ordnung aus.
Aber Ihr Backend benötigt in der Regel mehr als nur ein einzelnes Label. Es erwartet wahrscheinlich etwas Strukturiertes, wie zum Beispiel:
{
"category": "billing",
"priority": "high"
}
Hier wird es schwieriger.
Wie wird eigentlich die Priorität festgelegt?
Betrachten Sie ein Ticket, das nur Folgendes besagt:
"Ich kann mich nicht einloggen."
Gehört das unter account, oder handelt es sich tatsächlich um ein technisches Problem?
Was passiert, wenn ein Kunde in derselben Nachricht sowohl ein Problem mit der Rechnung als auch eines mit dem Anmelden anspricht?
Was ist, wenn die Kategorie tatsächlich zweideutig ist?
Welches Rückfallverhalten wird in diesem Fall erwartet?
Keine dieser Fragen kann zuverlässig von einem Modell beantwortet werden, wenn die Anweisung ursprünglich nie die Regeln festlegt.
Deshalb beginnt die Erstellung von Prompts für die Produktion mit der Definition einer Spezifikation, nicht mit der Feinabstimmung der Formulierungen.
2. Die Struktur eines Produktionsqualitäts-Prompts
Ein solider Produktionsprompt lässt sich in sieben unterschiedliche Komponenten aufteilen.
Diese Abschnitte müssen nicht unbedingt buchstäblich als beschriftete Überschriften innerhalb des Prompt-Textes selbst erscheinen.
Wichtig ist, dass man versteht, welche Aufgabe jede Schicht erfüllt.
Lassen Sie uns sie nacheinander durchgehen.
3. Systemanweisungen – Rolle und Verhalten definieren
Die erste Schicht legt den Umfang fest, für den das Modell verantwortlich ist.
Zum Beispiel bei dem Ticket-Klassifizierer:
You are a customer support classification assistant.
Your job is to classify incoming support tickets
according to the provided category definitions.Return only information supported by the ticket.
Do not invent customer information.
Das ist weitaus nützlicher als etwas Allgemeines wie:
You are an intelligent AI assistant.
Warum macht der Unterschied etwas aus?
Denn die Bezeichnung des Modells als „intelligenter KI-Assistent“ legt kein konkretes Verhalten fest.
Die spezifischere Version beschreibt detailliert:
- welche Aufgabe das Modell ausführt
- in welchem Bereich es tätig ist
- auf welche Informationen es Zugriff hat
- welche Verhaltensweisen verboten sind
Man kann die Systemanweisungen als den Verhaltensvertrag für die Interaktion betrachten.
4. Kontext – Geben Sie dem Modell, was es braucht
Die nächste Ebene liefert alle Informationen, die zur tatsächlichen Erledigung der Aufgabe erforderlich sind.
Zum Beispiel:
Available categories:
billing:
Questions about charges, invoices, refunds, or payments.technical:
Problems with product functionality, errors, or system behavior.account:
Login, password, profile, access, or account-management issues.general:
Questions that don't clearly belong to the above categories.
Es folgt anschließend der eigentliche Inhalt des Tickets:
Customer ticket:
"I was charged twice for my subscription this month."
Der Unterschied hier ist es wert, ausdrücklich hervorgehoben zu werden:
Instructions = What to do
Context = Information needed to do it
Falls man den Kontext ändert, während die Anweisungen unverändert bleiben, sollte das Modell dennoch in der Lage sein, die neue Eingabe korrekt zu verarbeiten.
Durch die Trennung dieser Elemente werden Prompt-Vorlagen im Laufe der Zeit viel leichter zu warten.
5. Einschränkungen – Geben Sie dem Modell an, wo es aufhören soll
Einschränkungen sind die Ebene, an der Unklarheiten beseitigt werden.
Im weiteren Beispiel:
Rules:
1. Select exactly one category.
2. Use only the four categories provided.
3. Do not create new categories.
4. Do not infer facts that are not present.
5. If the issue is unclear, use "general".
6. Priority must be one of: low, medium, high.
7. Return only the requested JSON.
Diese Regeln verringern den Raum der möglichen Antworten erheblich.
Ohne sie könnte ein Prompt wie folgt aussehen:
Classify the ticket.
und könnte etwas Ähnliches ergeben:
This appears to be a billing-related issue because
the customer mentions being charged twice.
Das ist eine völlig vernünftige Antwort für einen menschlichen Leser.
Aber Ihre API erwartet wahrscheinlich sauberes JSON, nicht Prosa.
Fügen Sie die Einschränkung explizit hinzu:
Return only the requested JSON.
und das erwartete Verhalten wird eindeutig.
6. Aufgabe – Die genaue Operation definieren
Sobald Anweisungen und Einschränkungen festgelegt sind, müssen Sie die konkrete Operation beschreiben, die ausgeführt werden soll.
Task:
1. Identify the most appropriate category.
2. Determine the priority based on the rules.
3. Provide a short reason.
4. Return the result using the specified JSON structure.
Vergleichen Sie das mit der Übermittlung einer vagen Anweisung wie:
Understand this customer issue.
Wenn eine Aufgabe so präzise formuliert wird, können Sie später überprüfen, ob das Modell tatsächlich das geliefert hat, was angefordert wurde.
Stellen Sie sich ein Pipeline-System in dieser Form vor:
Input
↓
Classify
↓
Determine priority
↓
Generate reason
↓
Return JSON
Ab diesem Punkt ist die Aufgabe keine Vermutung mehr, sondern etwas Messbares und Überprüfbares.
7. Beispiele – Das gewünschte Verhalten zeigen
Anweisungen erklären dem Modell mündlich, was zu tun ist.
Beispiele zeigen dies direkt.
Nehmen wir dieses Beispiel:
Example 1
Example 1Input:
"I was charged twice for the same subscription."Output:
{
"category": "billing",
"priority": "medium",
"reason": "The customer reports a duplicate subscription charge."
}
Ein weiteres Beispiel kann ein völlig anderes Szenario veranschaulichen, wie zum Beispiel einen technischen Fehlerbericht:
Example 2Input:
"The application crashes every time I upload an image."Output:
{
"category": "technical",
"priority": "high",
"reason": "The customer reports a repeatable application failure."
}
Beispiele sind am nützlichsten, wenn das gewünschte Verhalten allein durch Regeln schwer zu bestimmen ist, da sie dem Modell helfen, sich an ein konkretes Muster zu halten.
Trotzdem gibt es einen Aspekt, den man berücksichtigen muss.
Mehr Beispiele ≠ automatisch bessere Anfragen
Das Hinzufügen von Beispielen nacheinander hat tatsächliche Nachteile. Dadurch steigen:
- Die Größe der Anfrage
- Der Tokenverbrauch
- Die Latenzzeit
- Mögliche Widersprüche
Eine klügere Strategie besteht darin, bewusst eine kleine Auswahl auszuwählen.
Bevorzugen Sie Beispiele, die bedeutend unterschiedliche Situationen darstellen, insbesondere solche mit Unklarheiten oder Randfällen.
Eine solche Kombination wie:
Clear billing issue
Clear technical issue
Ambiguous issue
wird in der Regel besser sein als zehn nahezu identische Beispiele, die übereinander gestapelt werden.
8. Ausgabeformat – Behandeln Sie es wie einen API-Vertrag
In einem für die Produktion geeigneten Prompt sind nur wenige Aspekte so wichtig wie diese Schicht.
Falls ein anderes System das von dem Modell zurückgegebene Ergebnis analysieren soll, darf die Struktur dieser Antwort nicht dem Zufall überlassen werden – in Form von freiem Prosa-Text.
Geben Sie stattdessen ein klares Schema an.
Zum Beispiel:
{
"category": "billing | technical | account | general",
"priority": "low | medium | high",
"reason": "string"
}
Sobald dies implementiert ist, hat das Modell ein festes Ziel, auf das es abzielen kann, und der nachgeschaltete Code kann sich auf einen solchen Ablauf verlassen:
LLM
↓
JSON
↓
Parser
↓
Schema validation
↓
Business logic
anstatt auf etwas Weitaus Unübersichtlicherem, wie zum Beispiel:
LLM
↓
Some paragraph
↓
Regex
↓
Hope it works
Die zweite Variante ist eine Qual, wenn es darum geht, sie im Laufe der Zeit wartbar zu halten.
Eine gut definierte, strukturierte Ausgabe zieht eine klare Grenze zwischen dem, was das LLM erzeugt, und dem, was Ihre Anwendung tatsächlich benötigt.
9. Validierung – Das Modell ist nicht Ihr Validierer
Hier ist ein Fehler, der in KI-gestützten Systemen ständig auftritt.
Nehmen wir an, das Modell gibt Folgendes zurück:
{
"category": "billing",
"priority": "urgent",
"reason": "The customer has a billing issue."
}
Syntaktisch ist dieses JSON in Ordnung.
Das Problem liegt hier:
"urgent"
„urgent“ war nie einer der zulässigen Werte.
Es ist die Aufgabe Ihrer Anwendung, diese Abweichung zu erkennen – nicht die des Modells.
So sieht das mit Pydantic aus:
from pydantic import BaseModel
from typing import Literal
class TicketClassification(BaseModel):
category: Literal[
"billing",
"technical",
"account",
"general"
]
priority: Literal[
"low",
"medium",
"high"
]
reason: str
Dann rufen Sie Folgendes auf:
result = TicketClassification.model_validate(llm_response)
Und wenn das Modell etwas wie Folgendes zurückgibt:
{
"category": "billing",
"priority": "urgent",
"reason": "Duplicate charge."
}
sollte der Validierungs Schritt es sofort ablehnen.
Diese Ablehnung ist genau der Zweck.
Lassen Sie niemals den Ausgabeinhalt des Modells unüberprüft durchgehen.
Das führt zu einer Regel, die Sie bei der Gestaltung eines von LLMs gestützten Systems unbedingt befolgen sollten:
Das LLM erzeugt. Ihre Anwendung validiert.
Das Modell kann bei Entscheidungsfindungen helfen, aber alle wirklich unverhandelbaren Anforderungen sollten in deterministischem Anwendungscode enthalten sein, der sie direkt durchsetzt.
10. Der vollständige, produktionsorientierte Prompt
Wenn man alle Schichten zusammenfügt, erhält man etwas wie folgt:
SYSTEM
You are a customer support classification assistant.
Your job is to classify incoming support tickets
according to the provided category definitions.
Return only information supported by the ticket.
Do not invent customer information.
CONTEXT
Available categories:
billing:
Charges, invoices, refunds, or payment-related issues.
technical:
Product functionality, errors, crashes, or system behavior.
account:
Login, password, profile, access, or account-management issues.
general:
Issues that do not clearly belong to another category.
Customer ticket:
{{ticket_text}}
CONSTRAINTS
1. Select exactly one category.
2. Use only the categories provided above.
3. Do not create new categories.
4. Do not infer unsupported facts.
5. If the issue is unclear, use "general".
6. Priority must be "low", "medium", or "high".
7. Return only the requested JSON.
TASK
1. Classify the ticket.
2. Determine the priority.
3. Provide a short reason.
4. Return the result in the required JSON format.
EXAMPLE
Input:
"I was charged twice for the same subscription."
Output:
{
"category": "billing",
"priority": "medium",
"reason": "The customer reports a duplicate subscription charge."
}
OUTPUT FORMAT
{
"category": "billing | technical | account | general",
"priority": "low | medium | high",
"reason": "string"
}
Setzen Sie dies nun neben den Punkt, an dem das gesamte Übungsszenario begann:
Classify this customer support ticket.
Der Unterschied zwischen diesen beiden Prompts liegt nicht wirklich im Wortanzahl.
Was sich geändert hat, ist, wie ausdrücklich alles formuliert wurde.
Jeder Block der längeren Version erfüllt eine bestimmte Aufgabe:
- Der Systemteil legt fest, wie das Modell handeln soll
- Der Kontextteil liefert die Informationen, mit denen es arbeitet
- Der Einschränkungsteil nennt klar, welche Regeln es nicht brechen darf
- Der Aufgabenteil bestimmt genau, was es erreichen muss
11. Die Gestaltung von Prompts ähnelt der API-Design
Für Softwareentwickler macht dieser Vergleich das Erstellen von Prompts in der Produktion fast sofort verständlich.
Stellen Sie sich einen typischen REST-Endpunkt vor.
Man würde etwas wie Folgendes spezifizieren:
POST /tickets/classify
Ein Anfragekörper:
{
"ticket": "I was charged twice."
}
Und ein Antwortkörper:
{
"category": "billing",
"priority": "medium",
"reason": "Duplicate charge reported."
}
Übertragen Sie nun denselben Ansatz auf einen LLM-Prompt.
Der Prompt ist im Grunde die Implementierungslogik, die hinter diesem Endpunkt steht.
API
↓
Input
↓
Prompt Template
↓
LLM
↓
Structured Output
↓
Validation
↓
API Response
Deshalb neigt sich die Prompt-Engineering-Disziplin immer mehr zu einer Softwareengineering-Aufgabe statt zu einem kreativen Textverarbeitungsauftrag.
Man sucht nicht nach der perfekten Formulierung.
Man entwickelt eine zuverlässige Schnittstelle auf Basis eines systems, das probabilistisch funktioniert.
12. Häufige Fehler bei Produktionsanfragen
1. Vage Formulierungen
Analyze the ticket carefully.
Was gilt hier als „sorgfältig“?
Geben Sie das genaue gewünschte Verhalten an, anstatt es der Interpretation zu überlassen.
2. Anfragen nach unnötigen Dingen
Geben Sie an, dass Ihre Anwendung nur Folgendes verarbeitet:
{
"category": "billing"
}
Dann fordern Sie nicht an:
category
reason
summary
sentiment
customer mood
recommended response
next action
es sei denn, Ihre Anwendung verwendet diese Felder tatsächlich weiterverarbeitend.
Jedes zusätzliche Feld, nach dem Sie fragen, ist ein weiterer Punkt, an dem die Ausgabe abweichen oder inkonsistent werden kann.
3. Vollständige Unterbringung der Geschäftslogik in der Anfrage
Ein Beispiel für diesen Fehler:
If the customer has been waiting more than 48 hours,
has contacted support three times, and is a premium customer,
set priority to high...
Regeln wie diese gehören in der Regel in den deterministischen Code Ihrer Anwendung und nicht in die Prompt-Texte.
Eine sauberere Aufteilung sieht so aus:
LLM → classify issue
Application → calculate priority
Durch diese Trennung wird das gesamte System in der Regel viel leichter testbar.
4. Anpassung von Prompts ohne Bewertung
Nehmen wir an, Version 1 funktioniert in der Produktion gut.
Dann ändert jemand:
Classify the ticket.
zu:
Analyze and intelligently classify the ticket.
Es scheint sich um eine triviale Umformulierung zu handeln.
Doch das Verhalten in der Produktion kann sich deutlich verändern.
Deshalb verdienen Prompts genau wie Anwendungscode eine Versionskontrolle sowie Bewertung, gemäß derselben Disziplin.
5. Annahme, dass das Modell immer den Anweisungen folgt
Vergessen Sie nicht, dass LLMs von Natur aus probabilistisch sind.
Auch ein sorgfältig formulierter Prompt kann trotzdem etwas liefern, was Sie nicht angefordert haben.
Deshalb benötigt ein echtes Produktionsystem mehr als nur einen guten Prompt – es braucht:
Prompt
+
Structured output
+
Validation
+
Monitoring
+
Fallback handling
Es ist keine sichere Strategie, sich allein auf die Formulierung des Prompts zu verlassen.
13. Produktionsrelevante Prompt-Generierung erfordert Bewertung
Der wesentliche Unterschied zwischen gelegentlichen Experimenten mit einem LLM und der Einführung einer echten KI-Funktion liegt in der Bewertung.
Stellen Sie sich vor, Sie hätten 1.000 historische Support-Tickets zur Verfügung.
Man könnte daraus ein Testset erstellen, das wie folgt strukturiert ist:
200 billing
200 technical
200 account
200 general
100 ambiguous
100 edge cases
Dann werden verschiedene Prompt-Versionen gegen dieses gleiche Set ausgetestet und die Ergebnisse verglichen.
Zum Beispiel:
Prompt V1 Prompt V2
----------------------------------------
Category accuracy 88% 93%
Schema failures 4% 1%
Invalid values 3% 0.5%
Average latency 1.8s 2.1s
Token usage 650 820
An diesem Punkt wird die Arbeit mit Prompts nicht mehr subjektiv.
Man fragt nicht länger:
"Fühlt sich dieser Prompt besser an?"
Sondern man fragt:
"Erzielt diese Version bessere Ergebnisse in den Fällen, die für unsere Anwendung wirklich wichtig sind?"
Das ist eine weitaus praktischere Frage, die man stellen sollte.
14. Der Kompromiss: Mehr Anweisungen versus mehr Komplexität
Es gibt kein festes Gesetz, das besagt:
"Ein längeres Prompt liefert immer bessere Ergebnisse."
Prompts können durchaus übermäßig komplex gestaltet werden.
Etwas wie:
30 rules
+
20 examples
+
multiple exceptions
+
long explanations
+
repeated instructions
kann sich zu einer Wartungslast statt zu einer Hilfe entwickeln.
Eine nützliche Gewohnheit ist, sich ständig folgende Frage zu stellen:
Behandelt diese Anweisung tatsächlich ein reales Problem, das ich beobachtet habe?
Falls die Antwort nein lautet, sollte diese Anweisung wahrscheinlich nicht enthalten sein.
Der beste Prompt für die Produktion ist nicht unbedingt der mit dem meisten Inhalt.
Dies ist jener Ansatz, der den richtigen Kontext, die richtigen Einschränkungen sowie das richtige erwartete Verhalten bietet und dabei möglichst wenig unnötiges Gewicht mit sich bringt.
15. Ein praktisches mentales Modell
Wenn Sie sich an die Erstellung eines Prompts machen, hilft es, sieben Leitfragen zu durchgehen.
1. Wer ist das Modell in diesem Workflow?
Systemanweisungen
2. Was muss das Modell wissen?
Kontext
3. Was darf es auf keinen Fall tun?
Einschränkungen
4. Was genau muss es erreichen?
Aufgabe
5. Kann ich das erwartete Verhalten zeigen?
Beispiele
6. Wie sollte die Antwort aussehen?
Ausgabeformat
7. Wie wird meine Anwendung erkennen, dass die Antwort akzeptabel ist?
Validierung
Zusammen bilden diese sieben Fragen ein einheitliches Rahmenwerk.
Dieses mentale Modell ist weitaus wertvoller als das Auswendiglernen irgendeines einzelnen Prompt-Vorlagenmusters.
16. Prompt Engineering entwickelt sich in Richtung Systemdesign
Das könnte die wichtigste Idee in der gesamten Diskussion sein.
Zu Beginn reduziert sich die Arbeit mit einem LLM in der Regel auf eine Frage wie:
How can I phrase this question better?
Sobald die Systeme komplexer werden, wandelt sich diese Frage in etwas völlig anderes:
What does the model need to know?
What should it be allowed to do?
What should it return?
How do I validate it?
What happens when it fails?
How do I evaluate changes?
Es handelt sich dabei nicht mehr um Formulierungsfragen – es sind Fragen des Softwareengineering.
Genau deshalb hat das für die Produktion geeignete Prompt Engineering weniger mit der Entdeckung eines „magischen“ Satzes zu tun und viel mehr mit dem Entwerfen einer zuverlässigen Interaktion zwischen Ihrer Anwendung und einem probabilistisch verhaltenden Modell.
Kernpunkte
Mehrere zentrale Ideen sind es wert, aus all dem mitzunehmen:
1. Ein für die Produktion geeigneter Prompt ist mehr als nur eine einzige Frage.
Er legt das Verhalten fest, liefert Kontext, setzt Grenzen, beschreibt die Aufgabe, bietet Beispiele und definiert, wie das Ergebnis aussehen sollte.
2. Halten Sie Anweisungen getrennt von den Daten.
Das Modell sollte auf einen Blick erkennen können, was von ihm erwartet wird und mit welchen Informationen es arbeiten soll.
3. Klare Einschränkungen reduzieren Raten.
Lassen Sie das Modell nicht selbst entscheiden müssen, was passiert, wenn Daten fehlen, unklar sind oder fehlerhaft vorliegen.
4. Beispiele dienen dazu, das Verhalten zu veranschaulichen.
Nutzen Sie sie gezielt, insbesondere bei schwierigen Randfällen.
5. Strukturierte Ausgaben sollten wie ein API-Vertrag behandelt werden.
Jedes Mal, wenn ein nachgelagerter Dienst die Antwort des Modells liest, muss genau beschrieben werden, welche Form diese Antwort haben muss.
6. Lassen Sie den Prompt nicht als Ihre einzige Sicherheitsprüfung dienen.
Echte Validierung findet in Ihrer Anwendung statt, durch Schema-Prüfungen und deterministische Geschäftsregeln.
7. Behandeln Sie Prompts als Code, der bewertet werden muss.
Vergleichen Sie verschiedene Versionen mit repräsentativen Testfällen und verfolgen Sie deren Leistung.
8. Ein längerer Prompt ist nicht automatisch besser.
Jede hinzugefügte Zeile muss ihren Platz rechtfertigen.
Fazit
Beim Erstellen von Prompts für die Produktivumgebung geht es nicht darum, ein LLM dazu zu bringen, intelligenter zu klingen.
Es geht darum, den Austausch vorhersehbarer, transparenter und leichter in ein reales System integrierbar zu machen.
Der Wandel sieht im Allgemeinen so aus:
Simple question
↓
Structured instructions
↓
Clear context
↓
Explicit constraints
↓
Defined task
↓
Useful examples
↓
Structured output
↓
Application validation
↓
Evaluation + monitoring
Sobald diese Denkweise verinnerlicht ist, wirkt Prompt Engineering nicht mehr wie ein versuchsweiser Umgang mit Worten, sondern ähnelt eher dem Entwerfen eines API-Vertrags für eine komponentenbasierte Lösung, die probabilistisch funktioniert.
Dieser Wandel ist von großer Bedeutung, sobald man über Demonstrationen hinausgeht und Systeme entwickelt, die in der Produktion laufen sollen.
Verwandte Literatur
- Ein AI-Agent von Grund auf entwickeln: Muster, ReAct und LangGraph — Erfahren Sie die grundlegenden Konzepte hinter AI-Agenten – Planung, Werkzeugnutzung, Reflexion sowie das ReAct-Muster – und wie LangChain und LangGraph bei der manuellen Entwicklung eines solchen Agenten helfen.