Erstellung eines ReAct-Agenten in LangChain: Executor, Scratchpads und ihre Grenzen
Erstellen Sie einen ReAct-Agenten, der Werkzeuge verwendet, beobachten Sie, wie der Agent und AgentExecutor die Arbeit aufteilen, und erfahren Sie, warum LangGraph den Kontrollfluss, Schleifen und den Zustand besser handhabt.
Was ein Agent ist
Ein KI-Agent ist ein System, das ein von einer Person gestecktes übergeordnetes Ziel übernimmt und anschließend eigenständig plant, entscheidet und handelt. Es führt eine Abfolge von Schritten unter Verwendung externer Tools, APIs oder Wissensquellen aus, behält den Kontext bei, argumentiert über mehrere Schritte hinweg, passt sich an, wenn neue Informationen eintreffen, und arbeitet auf das gewünschte Ergebnis hin.
Einfach ausgedrückt ist ein Agent ein LLM zusammen mit einigen Tools. Das LLM übernimmt das Argumentieren und Entscheiden, während die Tools für die Handlungen sorgen.
Eigenschaften eines Agents
- zielorientiert. Man gibt an, was man will, nicht wie man es erreichen soll.
- plant selbstständig. Der Agent teilt das Problem auf und ordnet die Aufgaben ohne Hilfe.
- nutzt Tools. Er ruft APIs, Rechner, Suchfunktionen und Ähnliches auf. Das LLM kennt die vorhandenen Tools sowie den Zeitpunkt, an dem jeder von ihnen eingesetzt werden sollte.
Ein funktionierender Agent in Code
Das untenstehende Skript erstellt einen kleinen Agenten mit zwei Werkzeugen: einer Websuche über DuckDuckGo und einer Wetterabfrage. An diesen Agenten wird anschließend eine zweiteilige Frage gestellt. Für die Wetterabfrage benötigt man eine eigene API-Schlüssel vom Wetterdienstleister, die hier als Platzhalter dargestellt wird.
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
import requests
from langchain_community.tools import DuckDuckGoSearchRun
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub # It is a place from where we can get many type of prompts, so if we want any predefined prompt, we can get it from here
# Step 1: Creating tool definitions
search_tool = DuckDuckGoSearchRun()
@tool
def get_weather_data(city: str) -> str:
"""
This function fetches the current weather data for a given city
"""
url = f'https://api.weatherstack.com/current?access_key=4d1d8ae207a8c845a52df8a67bf3623e&query={city}'
response = requests.get(url)
return response.json()
llm = ChatOpenAI()
# Step 2: Pull the ReAct prompt from LangChain Hub
prompt = hub.pull("hwchase17/react") # pulls the standard ReAct agent prompt
# The agent which we are gonna make is a ReAct agent (reasoning + action = ReAct)
# ReAct is a design pattern
# Step 3: Create the ReAct agent manually with the pulled prompt
agent = create_react_agent(
llm=llm,
tools=[search_tool, get_weather_data],
prompt=prompt
)
# Step 4: Wrap it with AgentExecutor
agent_executor = AgentExecutor(
agent=agent,
tools=[search_tool, get_weather_data],
verbose=True # whatever the agent thinks, it will be visible to us
)
# Step 5: Invoke
response = agent_executor.invoke({"input": "Find the capital of Madhya Pradesh, then find it's current weather condition"})
print(response)
'''
Entering new AgentExecutor chain...
I should first find out the capital of Madhya Pradesh and then check the current weather condition for that city.
Action: duckduckgo_search
Action Input: "capital of Madhya Pradesh" Madhya Pradesh, state of India that is situated in the heart of the country. It has no coastline and no international frontier. Its physiography is characterized by low hills, extensive plateaus, and river valleys. The capital is Bhopal, in the west-central part of the state. Bhopal, city, capital of Madhya Pradesh state, central India. Situated in the fertile plain of the Malwa Plateau, the city lies just north of the Vindhya Range, along the slopes of a sandstone ridge. It is a major rail junction and has an airport. Pop. (2001) 1,437,354; (2011) 1,798,218. Bhopal was Indore (/ ɪ n ˈ d ɔːr / ⓘ; ISO: Indaura, Hindi: [ɪn̪d̪ɔːr]) is the largest and most populous city in the Indian state of Madhya Pradesh. [15] It is the commercial hub of Madhya Pradesh. It is consistently ranked as the cleanest city in India. [16] It serves as the headquarters of both the Indore District and the Indore Division.It is also considered the state education hub and ... In 1956, Bhopal became part of the state of Madhya Pradesh. Bhopal district was carved out on October 2, 1972, and is one of the 45 districts in the state. 4. Why is Bhopal famous? Bhopal is the capital city of the Indian state of Madhya Pradesh. It is known as the City of Lakes due to the presence of various natural and artificial lakes. In 1948, Madhya Bharat was created, with Indore designated as its summer capital and Gwalior as its winter capital. This arrangement highlights Indore's significance even then. However, Madhya Bharat was a temporary entity, and the map of central India was soon to be redrawn. The Creation of Madhya PradeshNow that I know the capital of Madhya Pradesh is Bhopal, I can use the get_weather_data function to check its current weather condition.
Action: get_weather_data
Action Input: Bhopal {'request': {'type': 'City', 'query': 'Bhopal, India', 'language': 'en', 'unit': 'm'}, 'location': {'name': 'Bhopal', 'country': 'India', 'region': 'Madhya Pradesh', 'lat': '23.267', 'lon': '77.400', 'timezone_id': 'Asia/Kolkata', 'localtime': '2025-05-01 17:52', 'localtime_epoch': 1746121920, 'utc_offset': '5.50'}, 'current': {'observation_time': '12:22 PM', 'temperature': 40, 'weather_code': 116, 'weather_icons': ['https://cdn.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png'], 'weather_descriptions': ['Partly Cloudy '], 'astro': {'sunrise': '05:47 AM', 'sunset': '06:48 PM', 'moonrise': '08:38 AM', 'moonset': '11:01 PM', 'moon_phase': 'Waxing Crescent', 'moon_illumination': 15}, 'air_quality': {'co': '510.6', 'no2': '1.665', 'o3': '180', 'so2': '10.175', 'pm2_5': '29.045', 'pm10': '68.635', 'us-epa-index': '2', 'gb-defra-index': '2'}, 'wind_speed': 12, 'wind_degree': 302, 'wind_dir': 'WNW', 'pressure': 1005, 'precip': 0, 'humidity': 7, 'cloudcover': 25, 'feelslike': 40, 'uv_index': 1, 'visibility': 6, 'is_day': 'yes'}}The current weather condition in Bhopal, Madhya Pradesh is partly cloudy with a temperature of 40°C.
Final Answer: The capital of Madhya Pradesh is Bhopal, and the current weather condition in Bhopal is partly cloudy with a temperature of 40°C.
> Finished chain.
{'input': "Find the capital of Madhya Pradesh, then find it's current weather condition", 'output': 'The capital of Madhya Pradesh is Bhopal, and the current weather condition in Bhopal is partly cloudy with a temperature of 40°C.'}
'''
response['output']
# The capital of Madhya Pradesh is Bhopal, and the current weather condition in Bhopal is partly cloudy with a temperature of 40°C.
Die fünf nummerierten Schritte im Skript umfassen die Definitionen der Tools, das Herunterladen des standardmäßigen ReAct-Prompts aus dem LangChain-Hub, die Erstellung des Agenten, das Einhüllen desselben in einen Executor sowie dessen Aufruf. Die am Ende angezeigte Ausgabe zeigt, dass der Agent zunächst beschließt, die Hauptstadt zu suchen, und danach das Wetter überprüft.
ReAct
LangChain unterstützt mehrere Konzepte für die Gestaltung von Agenten. Das hier vorgestellte Konzept ist ReAct, abgekürzt für Reasoning plus Acting. Es ermöglicht es einem Modell, zwischen internem Denken, also dem „Thought“, und externen Aktionen wie dem Aufruf von Tools in einem strukturierten, mehrschrittigen Prozess abzuwechseln.
Das Modell gibt seine Antwort nicht auf einmal heraus. Es denkt Schritt für Schritt, entscheidet, was als Nächstes getan werden soll, und kann dazu Tools wie APIs, Rechner oder Websuchmaschinen nutzen.
Dieses Muster eignet sich für:
- Probleme, die mehrere Schritte erfordern;
- Aufgaben, bei denen Tools benötigt werden;
- Fälle, in denen die Herleitung sichtbar und überprüfbar sein soll.
Als Beispiel: Fordern Sie vom Modell die Einwohnerzahl der Hauptstadt Frankreichs an. Zunächst überlegt es, dass es die Hauptstadt identifizieren muss, sucht nach ihr, stellt fest, dass die Antwort Paris ist, überlegt anschließend, dass es die Einwohnerzahl von Paris benötigt, sucht erneut und gibt schließlich die Antwort.
ReAct besteht aus fünf Komponenten:
- Gedanke. Die private Herleitung des Agents, bei der er den aktuellen Zustand bewertet und den nächsten Schritt plant. Dabei wird erklärt, warum ein bestimmtes Werkzeug gewählt wurde oder was noch unbekannt ist.
- Aktion. Die Entscheidung, ein Werkzeug aus dem verfügbaren Werkzeugkasten zu verwenden, das durch die zu aufrufende Funktion oder API benannt wird.
- Aktionseingabe. Die Argumente, die an dieses Werkzeug übergeben werden. Wenn die Aktion
searchist, ist die Eingabe der genaue Abfragesatz, zum Beispiel „Wetter in Delhi“. - Beobachtung. Die Rohdaten, die das Tool zurückgibt, sobald der Ausführende es gestartet hat. Der Agent liest sie, um zu beurteilen, ob die Aufgabe abgeschlossen ist oder weitere Schritte erforderlich sind.
- Endgültige Antwort. Die abschließende Antwort, die erstellt wird, wenn der Agent feststellt, dass er genug Informationen hat, und die alle Beobachtungen in alltäglicher Sprache zusammenfasst.
Das Prompt-Muster, das diesen Zyklus antreibt, sieht wie folgt aus:
Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action …
(this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad} —
In diesem Template ist eine Beobachtung einfach das, was nach dem Ausführen eines Tools zurückkommt.
Das Notizbuch des Agenten
Das Notizbuch fungiert als kurzfristiges Gedächtnis oder Arbeitsnotizbuch des Agenten. Es speichert die Historie der aktuellen Aufgabe: frühere Überlegungen, ausgeführte Aktionen wie Toolaufrufe sowie die zurückgekehrten Beobachtungen.
Indem der Agent das Notizbuch liest, erinnert er sich daran, dass er bereits die Hauptstadt Frankreichs ermittelt hat und nun die Bevölkerungszahl von Paris finden muss. Es handelt sich um eine temporäre Speicherung, die jedes Mal aktualisiert wird, wenn der Ausführende neue Informationen liefert. Sobald die endgültige Antwort an den Benutzer gesendet wird, wird das Notizbuch in der Regel gelöscht oder archiviert, da seine Aufgabe für diese Aufgabe erledigt ist.
Der Name ergibt Sinn, wenn man bedenkt, dass ein LLM zustandslos ist. Es erinnert sich nicht von selbst daran, was vor ein paar Sekunden in einer Code-Schleife passiert ist. LangChain nimmt daher die gesamte Historie der aktuellen Schleife und fügt sie jedes Mal wieder in die Anfrage ein, wenn es den Agenten fragt, was als Nächstes zu tun ist.
Agent versus AgentExecutor
Die beiden Komponenten haben unterschiedliche Aufgaben.
Der Agent ist der Denker, ähnlich wie ein Projektmanager. Er liest die Anfrage, teilt sie in kleinere Schritte auf und entscheidet, welche Tools benötigt werden. Seine Eingabe enthält sowohl die Frage des Benutzers als auch alles, was bisher erledigt wurde.
Der AgentExecutor ist der Ausführende, eher wie ein Assistent. Er befolgt die Anweisungen des Agents, führt tatsächlich den Code für jedes Tool aus und gibt die Ergebnisse zurück.
Eine andere Sichtweise: Der Agent ist der Architekt, der den Entwurf zeichnet, und der Ausführende ist das Bauteam, das das Gebäude errichtet. Ohne den Agenten gibt es keinen Plan, und ohne den Ausführenden bleibt der Plan auf dem Papier.
Der Ausführende koordiniert den gesamten Ablauf:
- Er sendet die Eingaben sowie vorherige Nachrichten an den Agenten, damit dieser die Frage sowie das Geschehene kennt.
- Er erhält die nächste Aktion vom Agenten.
- Er führt das Tool mit den bereitgestellten Eingaben aus.
- Er fügt die Beobachtung des Tools der Historie hinzu.
- Er sendet die aktualisierte Historie zusammen mit der Frage des Benutzers zurück an den Agenten, und dieser Vorgang wiederholt sich, bis der Agent „Endgültige Antwort“ angibt.
Nehmen Sie eine Anfrage nach der Temperatur in Delhi und multiplizieren Sie sie mit 10. Der Agent entscheidet, dass ein Wetterwerkzeug benötigt wird, der Ausführende ruft dieses auf, es erfolgt eine Messung, der Agent entscheidet, dass eine Multiplikation nötig ist, der Ausführende führt diese durch und der Agent gibt schließlich die Antwort. Der Ausführende führt alles aus, was der Agent für notwendig hält.
Beschränkungen dieses Ansatzes
Der vorgefertigte Ausführende funktioniert bei einfachen Fällen, weist aber erhebliche Schwächen auf, sobald die Agenten komplexere Aufgaben bewältigen müssen. Der untenstehende Vergleich bezieht sich auf LangGraph, die grafenbasierte Bibliothek von LangChain. Beachten Sie außerdem, dass neuere Versionen von LangChain die Nutzer dazu ermutigen, für Agenten LangGraph zu verwenden; prüfen Sie daher die aktuelle Dokumentation, bevor Sie auf älteren Ausführungsklassen aufbauen.
1. Die Black Box
Der Standard‑AgentExecutor ist bereits vorgefertigt. Geben Sie ihm Werkzeuge und eine Anweisung, und ein unsichtbarer while-Schleifenlauf setzt sich fort, bis die Aufgabe abgeschlossen ist. Eingreifen ist schwierig. Wenn Sie möchten, dass der Agent vor dem Ausgeben von Geld immer einen Menschen um Erlaubnis bittet oder einer festen Reihenfolge wie Schritt A dann Schritt B folgt, wehrt sich der Executor, denn er ist dafür konzipiert, vollständig autonom zu arbeiten.
Betrachten Sie einen Agenten mit den Werkzeugen search_flights und book_flight. Im Executor von LangChain entscheidet das LLM in einem versteckten Schleifenlauf, was als Nächstes geschieht. Wenn es aufgefordert wird, einen Flug zu buchen, könnte es sofort suchen und buchen, ohne zu fragen – vielleicht für eine Flugkosten von zehntausend Dollar, obwohl der Benutzer zunächst jede Kaufentscheidung genehmigen wollte. Zwischenschritte wie eine obligatorische Genehmigung können nicht streng durchgesetzt werden, da der Steuerfluss implizit ist und vom Modell gesteuert wird.
In LangGraph wird der Workflow als explizite Schritte oder Knoten definiert, wie zum Beispiel das Suchen nach Flügen, das Beantragen einer Genehmigung und die Buchung. Sie sind miteinander verbunden, sodass das System vor der Buchung eine Genehmigung einholen muss. Dadurch wird eine vollständige Kontrolle gewährleistet und es fällt leicht, Regeln durchzusetzen, menschliche Kontrollpunkte hinzuzufügen, Wiederholungen vorzunehmen oder bedingte Pfade einzubauen.
2. Zyklen und Schleifen
Reale Workflows sind selten linear. Sie beinhalten das Zurückgehen, das Beheben von Fehlern sowie das Wiederholen von Vorgängen bei bestimmten Dokumentensätzen.
- Die Chains von LangChain sind hauptsächlich als gerichtete azyklische Graphen konzipiert, sodass die Daten in eine Richtung fließen.
- LangGraph ist dafür ausgelegt, Zyklen zu verarbeiten. Er modelliert den Ablauf als eine Karte, bei der die Knoten Funktionen darstellen und die Kanten die Pfade zwischen ihnen sind.
Bei einer Dokument-Frage-Antwort-Aufgabe kann ein LangChain-Pipeline Dokumente abrufen, eine Antwort schreiben und diese zurückgeben. Ist die Antwort falsch oder unvollständig, kehrt das System ohne zusätzliche, manuell geschriebene Logik nicht automatisch zurück, um erneut zu suchen oder die Abfrage zu verfeinern. Sobald es vorangekommen ist, ist es nicht einfach, wieder umzukehren, um sich selbst zu verbessern.
LangGraph ermöglicht es, Schleifen explizit zu erstellen: Dokumente abrufen, antworten, die Qualität überprüfen und bei schlechten Ergebnissen die Abfrage verfeinern und erneut suchen, bis das Ergebnis gut ist. Das System kann zwischen Knoten wechseln, bis eine Bedingung erfüllt ist, was Aufgaben geeignet macht, die Iteration, Korrektur und Rückmeldung erfordern.
3. Zustand und Persistenz
Das ist insbesondere für die Skalierbarkeit wichtig.
LangChain konzentriert sich hauptsächlich auf den Gesprächskontext – beispielsweise das Merken früherer Chatnachrichten, damit das Modell besser antworten kann. Es ist nicht eng mit dem Arbeitsablauf verbunden und verfolgt keinen Fortschritt bei einer Aufgabe. Sofern es nicht explizit gespeichert wird, geht es in der Regel verloren, wenn das System neu gestartet wird, wodurch lang andauernde Aufgaben nicht zuverlässig sind.
LangGraph betrachtet den Speicher als den vollständigen Zustand des Arbeitsablaufs und nicht nur als Chatgeschichte. In jedem Schritt wird aufgezeichnet, was erledigt wurde, welche Ausgaben erzeugt wurden und was als Nächstes kommt. Wenn der Prozess unterbrochen wird, kann er genau dort fortgesetzt werden, wo er aufgehört hat. Zudem ermöglicht es das Pausieren, Überprüfen und Bearbeiten des Zustands mit menschlicher Beteiligung oder sogar das Zurückkehren zu einem früheren Schritt, wodurch komplexe, mehrschrittige Aufgaben viel robuster werden.
Stellen Sie sich eine lange Aufgabe vor, wie beispielsweise die Bearbeitung von zehn Dokumenten nacheinander, die in Schritt 7 abstürzt. Ohne eingebaute Persistenz geht alles verloren und man muss von vorne anfangen, wobei standardmäßig keine Aufzeichnungen über den Fortschritt vorhanden sind. Mit gespeichertem Zustand nach jedem Schritt kann man bei Schritt 7 weitermachen. Man kann auch pausieren, einer Person die Möglichkeit geben, den Zustand zu überprüfen oder zu ändern, anschließend fortzufahren oder zu einem früheren Schritt zurückzukehren – eine Art Zeitreise. Lange Arbeitsabläufe werden dadurch zuverlässiger, können fortgesetzt werden und sind einfacher zu debuggen oder zu prüfen.
Die Schlussfolgerung ist, dass der grundlegende Ausführer es schwierig macht, skalierbare, produktionsreife Agenten zu entwickeln, weshalb es für diese Aufgabe grafenbasierte Werkzeuge gibt.
Verwandte Literatur
- Agent-Memory-Snaps, Fähigkeiten, Zerfall und branchenspezifische Speicherung — Vier Erweiterungen für eine eingebettete Vektor-Datenbank-Speicherschicht für Programmieragenten: portable Snapshots mit Zusammenführungsfunktion, Aktivierung von Fähigkeiten, Zerfall mit Konfliktprüfungen sowie speicherung, die auf bestimmten Branchen beschränkt ist.
- Ihr erster LangGraph-Agent: Ein Fußball-Assistent mit Tools und Routing — Schritt-für-Schritt-Tutorial zu LangGraph: gemeinsamer Zustand, Tools, ein Planungsknoten, bedingte Kanten sowie eine Zusammenfassung im Markdown-Format, entwickelt um einen simulierten Fußball-Statistik-Assistenten herum.