Strona główna / Artykuły

Budowanie agenta ReAct w LangChain: Executorzy, tablice robocze i ich ograniczenia

Stwórz agenta typu ReAct wykorzystującego narzędzia, zobacz, jak agent i AgentExecutor dzielą pracę, i dowiedz się, dlaczego LangGraph lepiej radzi sobie z przepływem sterowania, cyklami i stanem.

Wydawca: REACTAPP.TOP12 min czytania2719 słów

Źródła: Langchain Part 17 — End to End Agent Building

Czym jest agent

Agent sztucznej inteligencji to system, który bierze od osoby cel o wysokim poziomie abstrakcji, a następnie sam planuje, podejmuje decyzje i działa. Wykonywał sekwencję kroków przy użyciu zewnętrznych narzędzi, API lub źródeł wiedzy, zachowuje kontekst na przestrzeni całego procesu, rozumuje na podstawie kilku kroków, dostosowuje się po pojawieniu się nowych informacji i dąży do osiągnięcia zamierzonego rezultatu.

W uproszczeniu agent to LLM w połączeniu z kilkoma narzędziami. LLM zajmuje się rozumowaniem i podejmowaniem decyzji, natomiast narzędzia odpowiadają za działanie.

Cechy agenta

  • Kierowany celem. Podaje się, czego chce się osiągnąć, a nie jak to zrobić.
  • Planuje samodzielnie. Agent dzieli problem na części i układa zadania bez pomocy.
  • Wykorzystuje narzędzia. Korzysta z API, kalkulatorów, narzędzi wyszukiwania i podobnych. LLM wie, jakie narzędzia istnieją i kiedy należy je użyć.
  • Zdolny do rozumienia kontekstu. Przechowuje informacje z poprzednich kroków, dzięki czemu wcześniejsze wyniki wpływają na późniejsze działania.
  • Adaptacyjny. Gdy coś się zmienia, na przykład gdy API przestaje działać lub brakuje danych, dostosowuje swój plan.

Agent działający w kodzie

Poniższy skrypt tworzy małego agenta wyposażonego w dwa narzędzia: wyszukiwarkę internetową przez DuckDuckGo oraz funkcję sprawdzania pogody, i zadaje mu pytanie składające się z dwóch części. Aby sprawdzić pogodę, potrzebna jest własna klucz API od dostawcy pogody, tutaj przedstawiona jako zamiennik.

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.

Pięć numerowanych kroków w tym skrypcie obejmuje definicje narzędzi, pobieranie standardowego promptu ReAct z huba LangChain, tworzenie agenta, otoczenie go wykonawcą oraz jego uruchomienie. Wydrukowany na końcu zapis pokazuje, że agent najpierw postanawia poszukać stolicy, a następnie sprawdzi pogodę.

ReAct

LangChain wspiera kilka podejść projektowych do agentów. To, które jest tu omówione, to ReAct, skrót od Reasoning plus Acting. Umożliwia on modelowi przechodzenie między wewnętrznym rozumowaniem, czyli procesem myślenia, a działaniami zewnętrznymi, takimi jak wywoływanie narzędzi, w uporządkowanym cyklu obejmującym kilka kroków.

Model nie generuje odpowiedzi za jednym razem. Myśli krok po kroku, decyduje, co robić dalej, i może korzystać z narzędzi takich jak API, kalkulatory lub wyszukiwarki internetowe w celu uzyskania pomocy.

To podejście pasuje do:

  • problemów wymagających kilku kroków;
  • Zadań, które potrzebują narzędzi;
  • przypadki, gdy chcesz, aby rozumowanie było widoczne i poddawalne weryfikacji.

Jako przykład poproś model o informację o populacji stolicy Francji. Najpierw dochodzi do wniosku, że musi zidentyfikować stolicę, sprawdza to, widzi, że odpowiedzią jest Paryż, następnie rozważa, że potrzebuje informacji o populacji Paryża, szuka ponownie i w końcu udziela odpowiedzi.

ReAct składa się z pięciu elementów:

  • Myśl. Prywatne rozumowanie agenta, w którym ocenia obecną sytuację i planuje kolejny krok. Wyjaśnia, dlaczego wybrano określone narzędzie lub co nadal jest nieznane.
  • Działanie. Decyzja o użyciu jednego z dostępnych narzędzi, określona funkcją lub interfejsem API do wywołania.
  • Wartości wejściowe dla działania. Argumenty przekazywane temu narzędziu. Jeśli działaniem jest search, wartością wejściową jest dokładny tekst zapytania, na przykład „pogoda w Delhi”.
  • Obserwacja. Surowe dane, które narzędzie zwraca po uruchomieniu przez wykonawcę. Agent je odczytuje, aby ocenić, czy zadanie zostało zakończone, czy potrzebne są dodatkowe kroki.
  • Odpowiedź końcowa. Ostateczna odpowiedź, tworzona w momencie, gdy agent stwierdza, że ma już wystarczająco informacji; łączy ona wszystkie obserwacje w prostym języku.

Ścieżka szablonu promptu, która napędza ten cykl, wygląda następująco:

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} —

W tym szablonie obserwacja to po prostu informacja, która pojawia się po zakończeniu działania narzędzia.

Notatnik agenta

Notatnik pełni rolę krótkoterminowej pamięci lub dziennika roboczego agenta. Zapisuje on historię bieżącego zadania: wcześniejsze rozważania, podjęte działania, takie jak wywołania narzędzi, oraz informacje o obserwacjach, które zostały uzyskane.

Czytając ten notatnik, agent przypomina sobie, że już ustalił stolicę Francji i teraz musi znaleźć liczbę mieszkańców Paryża. Jest to tymczasowe przechowywanie danych, które aktualizuje się za każdym razem, gdy wykonawca dostarcza nowe informacje. Gdy ostateczna odpowiedź trafia do użytkownika, notatnik zazwyczaj jest usuwany lub archiwizowany, ponieważ jego zadanie w ramach tego zadania zostało zakończone.

Nazwa staje się zrozumiała, gdy przypomnimy sobie, że LLM nie ma stanu. Nie pamięta automatycznie tego, co wydarzyło się kilka sekund temu w pętli kodu. Dlatego LangChain bierze całą historię bieżącej pętli i ponownie wstawia ją do promptu za każdym razem, gdy pyta agenta, co ma robić dalej.

Agent versus AgentExecutor

Te dwa komponenty pełnią odrębne zadania.

Agent to myśliciel, nieco podobny do menedżera projektu. Czyta prośbę, dzieli ją na mniejsze kroki i decyduje, jakie narzędzia są potrzebne. Jego dane wejściowe zawierają zarówno pytanie użytkownika, jak i wszystko, co zostało dotychczas zrobione.

AgentExecutor to wykonawca, bardziej przypominający asystenta. Słucha instrukcji agenta, faktycznie uruchamia kod dla każdego narzędzia i przekazuje wyniki z powrotem.

Inny sposób na to spojrzenie: agent to architekt, który rysuje plan, a wykonawca to ekipa budowlana, która realizuje budowę. Bez agenta nie ma planu, a bez wykonawcy plan nigdy nie opuszcza papieru.

Wykonawca koordynuje cały proces:

  1. Wysyła dane wejściowe oraz wcześniejsze wiadomości do agenta, aby ten znał pytanie i to, co się wydarzyło.
  2. Otrzymuje od agenta kolejną akcję do wykonania.
  3. Uruchamia narzędzie z podanymi danymi wejściowymi.
  4. Dodaje obserwację uzyskaną przez narzędzie do historii.
  5. Wysyła zaktualizowaną historię wraz z pytaniem użytkownika z powrotem do agenta, a proces ten powtarza się, dopóki agent nie poda Odpowiedzi końcowej.

Weźmy prośbę o temperaturę w Delhi pomnożoną przez 10. Agent decyduje, że potrzebny jest narzędzie do przewidywania pogody, wykonawca je wywołuje, otrzymuje wynik obserwacji, agent decyduje, że konieczne jest pomnożenie, wykonawca je przeprowadza, a agent w końcu podaje odpowiedź. Wykonawca realizuje to, co uzna agent za konieczne.

Ograniczenia tego podejścia

Z góry przygotowany wykonawca sprawdza się w prostych przypadkach, ale ma poważne wady, gdy agenci muszą radzić sobie z bardziej złożonymi zadaniami. Poniższe porównanie dotyczy LangGraph, biblioteki opartej na grafach od LangChain. Należy również zauważyć, że nowsze wersje LangChain zachęcają do używania LangGraph dla agentów, dlatego przed korzystaniem ze starszych klas wykonawców sprawdź aktualną dokumentację.

1. Czarna skrzynka

Standardowy AgentExecutor jest już przygotowany. Wystarczy mu dostarczyć narzędzia i instrukcje, a niewidzialna pętla while będzie działać aż do zakończenia zadania. Interwencja jest trudna. Jeśli chcesz, aby agent zawsze pytał człowieka przed wydaniem pieniędzy lub aby postępował według określonej kolejności, na przykład najpierw krok A, potem krok B, executor się temu sprzeciwia, ponieważ został zaprojektowany jako całkowicie autonomiczny.

Rozważmy agenta posiadającego narzędzia search_flights i book_flight. Wewnątrz executora LangChain model LLM decyduje o dalszych krokach w ukrytej pętli. Gdy zostanie poproszony o rezerwację lotu, może natychmiast go wyszukać i zarezerwować bez pytania, być może za cenę dziesięciu tysięcy dolarów, podczas gdy użytkownik chciał najpierw zatwierdzić zakup. Pośrednie kroki, takie jak obowiązkowe zatwierdzenie, nie mogą być ściśle egzekwowane, ponieważ przepływ sterowania jest ukryty i kontrolowany przez model.

W LangGraph proces jest definiowany jako wyraźne kroki lub węzły, takie jak wyszukiwanie lotów, proszenie o zatwierdzenie i dokonywanie rezerwacji. Są one połączone w taki sposób, że system musi najpierw uzyskać zatwierdzenie, zanim będzie mógł dokonać rezerwacji. Dzięki temu uzyskuje się pełną kontrolę i ułatwia się egzekwowanie zasad, dodawanie ludzkich punktów kontrolnych, prób ponownych lub warunkowych gałęzi.

2. Cykle i pętle

Prawdziwe procesy rzadko są liniowe. Obejmują powrót do poprzednich etapów, korygowanie błędów oraz przetwarzanie serii dokumentów w pętlach.

  • Łańcuchy w LangChain są przede wszystkim projektowane jako grafy skierowane acykliczne, więc dane przepływają w jednym kierunku.
  • LangGraph został stworzony do obsługi cykli. Modeluje przepływ jako mapę, w której węzłami są funkcje, a krawędziami ścieżki między nimi.

W zadaniach typu pytanie-odpowiedź dotyczących dokumentów, pipeline LangChain może pobrać dokumenty, napisać odpowiedź i ją zwrócić. Jeśli odpowiedź jest błędna lub niekompletna, nie wraca automatycznie, aby ponownie pobrać dane lub udoskonalić zapytanie bez dodatkowej ręcznej logiki. Gdy już przejdzie do dalszych kroków, nie może łatwo wrócić, aby się poprawić.

LangGraph umożliwia wyraźne tworzenie pętli: pobieranie danych, odpowiadanie, sprawdzanie jakości, a jeśli wynik jest kiepski, udoskonalanie zapytania i ponowne pobieranie danych, powtarzając ten proces aż do uzyskania dobrego rezultatu. System może krążyć między węzłami, dopóki nie zostanie spełniona określona warunek, co nadaje się do zadań wymagających iteracji, korekty i informacji zwrotnej.

3. Stan i trwałość

To ma największe znaczenie dla skalowalności.

Pamięć w LangChain dotyczy głównie kontekstu rozmowy, np. przechowywania wcześniejszych wiadomości, aby model mógł lepiej odpowiadać. Nie jest ściśle powiązana z procesem pracy i nie śledzi postępów w wykonywanej zadaniu. Jeśli nie zostanie wyraźnie zapisana, zazwyczaj ginie po ponownym uruchomieniu systemu, więc zadania trwające długi czas nie są niezawodne.

LangGraph traktuje pamięć jako pełny stan procesu pracy, a nie tylko historię rozmów. Na każdym kroku zapisuje to, co zostało zrobione, jakie wyniki powstały oraz co następuje dalej. Jeśli proces zostanie przerwany w połowie, można go wznowić dokładnie tam, gdzie się zatrzymał. Pozwala również na pauzowanie, sprawdzanie i edycję stanu przy udziale człowieka, a nawet powrót do wcześniejszego kroku, co sprawia, że złożone zadania wieloetapowe są znacznie bardziej odpornie na awarie.

Załóżmy długie zadanie, takie jak przetwarzanie dziesięciu dokumentów po kolei, które zawodzi na 7. kroku. Bez wbudowanej funkcji przechowywania wszystko jest tracione i musimy zaczynać od nowa, bez żadnych informacji o postępach. Dzięki zapisywaniu stanu po każdym kroku możemy wznowić pracę od 7. kroku. Można również wstrzymać proces, pozwolić komuś przejrzeć lub edytować stan, a następnie kontynuować lub wrócić do wcześniejszego kroku – co przypomina podróż w czasie. Długie procesy pracy stają się bardziej niezawodne, można je wznowić, a także łatwiej je debugować lub audytować.

Wniosek jest taki, że podstawowy mechanizm wykonywania zadań utrudnia tworzenie skalowalnych, gotowych do użycia agentów, dlatego istnieją narzędzia oparte na grafach do tego celu.

Literatura pokrewna

  • Self-Healing Kubernetes w praktyce: trzy awarie, sygnały od SigNoz oraz zatwierdzone rozwiązania — Przejrzyj pętlę awarii, zatrzymanie z powodu braku pamięci oraz nagły wzrost liczby tokenów w klastrze Kind, zobacz, co pokazuje SigNoz dla każdego z tych przypadków, oraz co należy wzmocnić przed użyciem agenta naprawczego opartego na sztucznej inteligencji.
  • RAG z LangChain od zera: loaderzy, kawałki danych, embeddingi, ocena — Zbuduj system pytań i odpowiedzi do dokumentów krok po kroku: ładowanie plików, dzielenie na kawałki, tworzenie embeddingów, fazy indeksowania i wyszukiwania oraz sposoby oceny jakości wyników wyszukiwania i odpowiedzi.
  • Tworzenie pierwszego agenta LangChain za pomocą LangGraph w 2026 roku — Buduj agenta LangChain krok po kroku z wykorzystaniem LangGraph, narzędzi do zarządzania pamięcią i śledzenia działań, unikaj czterech najczęstszych błędów i dowiedz się, jak biuro obsługi uczestników bootcampu go wykorzystało.
  • Dlaczego frontend jest trudny po React: stan, efekty, granice i narzędzia AI — React ułatwił budowanie interfejsów, ale nie ich projektowanie. Prawdziwym wyzwaniem w frontendzie są lokalizacja stanu, skomplikowane efekty, granice systemu oraz kod generowany przez AI.
  • Praktyczne notatki: Twój agent AI napotyka przeszkodę w kroku 12. Deep Agents od LangChain — Szczegółowy przewodnik po Praktycznych notatkach: Twój agent AI napotyka przeszkodę w kroku 12. Deep Agents od LangChain: umowy, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów wdrażających ten wzorzec.