Praktyczne notatki: Langchain Część 17 — Budowa agenta od początku do końca
Praktyczne wskazówki: Langchain Część 17 — Budowa agenta od początku do końca: umowy, sprawdzania oraz miejsca na kod dostępne dla zespołów wdrażających ten wzorzec.
To przewodnik pokazuje, jak odtworzyć proces od surowców do gotowego systemu w ramach: Langchain Część 17 — Budowa agenta od początku do końca. Skupiamy się na krokach realizowalnych w praktyce, wyraźnych sprawdzeniach oraz kodzie, który można bez problemu dodać do repozytorium, nie musząc zgadywać intencji. Na etapie przeglądu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Konfigurację należy trzymać oddzielnie od kodu aplikacji. Pliki środowiskowe, magazyny tajemnic oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić, nie musząc czytać całej struktury.
Cechy agenta AI
Gdy przechodzisz przez etap charakterystyk sztucznej inteligencji, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez człowieka oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Utwórz punkt kontrolny po kosztownych krokach. Program powinien unikać ponownego pobierania opłat za tę samą funkcję LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.
KOD:
Gdy przechodzisz przez etap CODE, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolij małe, testowalne jednostki od rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustalaj punkty kontrolne po kosztownych krokach. System powinien unikać ponownego pobierania opłat za tę samą funkcję LLM, gdy operator próbuje ponownie wykonać późniejszy element.
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.
ReAct
Gdy przechodzisz przez etap ReAct, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Ustaw punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie modelu LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Gdy przechodzisz przez etap ReAct, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury.
Przykład:
Etap Przykład działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Zdokumentuj zarówno pomyślny, jak i awaryjny scenariusz działania. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione bloki ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji po przerwach.
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} —
Dlaczego nazywa się to „Scratchpad”?
Najlepiej funkcjonuje podejście oparte na koncepcji „dlaczego” wtedy, gdy traktuje się je jako mierzalną powierzchnię do analizy. Zapisz jeden udany przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wtórne struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, co utrudnia kontynuację pracy po przerwach.
Różnica między Agent a AgentExecutor
Różnica pomiędzy agentem a etapem funkcjonuje najlepiej, gdy jest traktowana jako mierzalna struktura. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej typowości. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, co powoduje przerwanie kontynuacji po przerwach. Różnica pomiędzy agentem a etapem funkcjonuje najlepiej, gdy jest traktowana jako mierzalna struktura. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Utrzymuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całego grafu.
Przykład: Chcemy poznać temperaturę w Delhi i chcemy, aby została pomnożona przez 10
Dla przykładu, który chcemy zaprezentować, należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżki naprawcze. Próby ponownego wykonania, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później. Konieczne jest uzyskanie zatwierdzenia człowieka w przypadkach, gdy dochodzi do wydawania pieniędzy lub modyfikacji danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się kompletności rozwiązania biznesowego.
Przepływ pracy między Agent Executor a Agentem
Dla procesu pracy pomiędzy etapem Agent Executor należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanej punktacji kontrolnej, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Konieczne jest ludzkie zatwierdzenie w tych przypadkach, gdy dochodzi do wydatków lub zmian w danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się kompletności biznesowej.
Ograniczenia Langchain
Dla etapu Limitation of Langchain należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Wprowadź ludzką aprobatę w przypadkach, gdy dochodzi do wydawania pieniędzy lub zmiany danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności biznesowej.
1. Problem „czarnej skrzynki”
Dla etapu 1 „The Black Box” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy odnotować czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Konieczne jest ludzkie zatwierdzenie dla operacji, które generują wydatki lub zmieniają dane produkcyjne. Podłączenia realizowane w czasie kompilacji nie gwarantują pełnej kompletności biznesowej.
Przykład:
W fazie Przykład należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Konfigurację należy przechowywać poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zastosuj zatwierdzenie przez człowieka do operacji, które wiążą się z wydatkami lub zmianą danych produkcyjnych. Połączenia skompilowane w czasie kompilacji nie równają się pełności funkcjonalności biznesowej.
2. Cykle i pętle (część „Grafu”)
W fazie 2 Cykli i Pętli należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później. Konieczna jest ludzka akceptacja w przypadku operacji, które powodują wydatki lub zmieniają dane produkcyjne. Połączenia realizowane w czasie kompilacji nie równają się kompletności rozwiązania biznesowego.
Przykład:
W fazie Przykład należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki nad rozbudowanymi skryptami. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Konieczne jest ludzkie zatwierdzenie w przypadkach, gdy dochodzi do wydatków lub zmian w danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się kompletności rozwiązania biznesowego.
3. Zarządzanie stanem (część „Trwałość”)
W fazie zarządzania 3 stanami należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań. Zapewnij ludzką aprobatę w przypadkach, gdy dochodzi do wydawania pieniędzy lub zmiany danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności procesu biznesowego. W fazie zarządzania 3 stanami należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury.
Przykład:
Podczas prace nad etapem Przykładu najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później. Ustal punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłaty za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.
Lista kontrolna operacyjna
Etap Lista kontrolna operacyjna działa najlepiej, gdy jest traktowany jako mierzalna powierzchnia do analizy. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy.
Zapisuj czasy wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przejście od wersji demonstracyjnej do środowisk współdzielonych zmienia warunki działania.
Zachowuj prostą i typowaną strukturę stanu grafu. Wkładane błotka ukrywają informację o tym, który węzeł zapisał dane do którego pola, i utrudniają kontynuację pracy po przerwach.
Gdy budżet na to pozwala, dodaj test sprawdzający kluczową ścieżkę w procesie CI przy użyciu fixitów, a nie rzeczywistych, płatnych API.
Konfigurację trzymaj poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności przeglądania całego grafu.
Zachowuj prostą i typowaną strukturę stanu grafu. Wkładane błotka ukrywają informację o tym, który węzeł zapisał dane do którego pola, i utrudniają kontynuację pracy po przerwach.
Zanim wdrożysz nową architekturę, zamroź wersje oprogramowania, utwórz dokładny zapis działania kluczowej ścieżki oraz potwierdź kroki konieczne do cofnięcia zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji przynależności oraz jasno określonego właściciela odpowiedzialnego za rotację tajnych danych. Wolij nudną niezawodność od pomysłowych, jednorazowych demonstracji.
Uwagi dotyczące wersji 261dc94d9d46: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj transkrypcje obok plików testowych, aby późniejsze zmiany modeli pozostały porównywalne.