Создание агента
В разделе рассматриваются следующие основные понятия:
Языковые модели просто генерируют текст и не могут выполнять действия. Разработка агентов — это один из основных сценариев использования GigaChain.
Агенты — системы, использующие LLM для рассуждений и определения действий, которые нужно предпринять, а также входных данных, которые нужно при этом использовать.
Результаты этих действий затем могут быть переданы обратно агенту, чтобы он определил, нужно ли делать что-то еще или можно закончить работу.
В разделе приведен пример агента, который может взаимодействовать с несколькими инструментами: локальной базой данных и поисковой системой. С агентом можно вести разговор и наблюдать, как он вызывает инструменты.
Пример агента
Пример ниже содержит код работающего агента, который использует модель для определения того, какой инструмент нужно вызвать. Агент подготовлен для работы с поисковым инструментом и обладает разговорной памятью, что позволяет использовать его в роли развитого чат-бота.
Ниже в разделе приводится пошаговый разбор каждого из компонентов агента.
# Импортирование необходимой функциональности
from langchain_community.chat_models.gigachat import GigaChat
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import HumanMessage
from langgraph.checkpoint.memory import MemorySaver
from langgraph.prebuilt import create_react_agent
# Создание агента {#sozdanie-agenta2}
memory = MemorySaver()
model = GigaChat(
credentials="ключ_авторизации",
scope="GIGACHAT_API_PERS",
model="GigaChat-Pro",
verify_ssl_certs=False,
)
search = TavilySearchResults(max_results=2)
tools = [search]
agent_executor = create_react_agent(model, tools, checkpointer=memory)
# Использование агента
config = {"configurable": {"thread_id": "abc100"}}
for chunk in agent_executor.stream(
{"messages": [HumanMessage(content="Привет! Меня зову Вася. Я живу в Москве")]},
config,
):
print(chunk)
print("----")
for chunk in agent_executor.stream(
{"messages": [HumanMessage(content="Узнай погоду в моем городе")]}, config
):
print(chunk)
print("----")
{'agent': {'messages': [AIMessage(content='Здравствуйте, Вася! Рада слышать вас. Расскажите, могу ли я вам чем-нибудь помочь?', response_metadata={'token_usage': Usage(prompt_tokens=97, completion_tokens=29, total_tokens=126), 'model_name': 'GigaChat-Pro:2.2.25.3', 'finish_reason': 'stop'}, id='run-aad23d97-0cb5-4977-8d2e-b1ce06751157-0')]}}
----
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'function_call': {'name': 'tavily_search_results_json', 'arguments': {'query': 'погода в москве'}}}, response_metadata={'token_usage': Usage(prompt_tokens=140, completion_tokens=23, total_tokens=163), 'model_name': 'GigaChat-Pro:2.2.25.3', 'finish_reason': 'function_call'}, id='run-8989a123-6824-4ae2-839b-77e0290aa584-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'погода в москве'}, 'id': 'fb19fd4f-3bc1-4b7f-9cca-e669ab8d96e4', 'type': 'tool_call'}])]}}
----
{'tools': {'messages': [ToolMessage(content='[{"url": "https://www.gismeteo.ru/weather-moscow-4368/now/", "content": "\\u0423\\u0437\\u043d\\u0430\\u0439\\u0442\\u0435 \\u0444\\u0430\\u043a\\u0442\\u0438\\u0447\\u0435\\u0441\\u043a\\u0443\\u044e \\u043f\\u043e\\u0433\\u043e\\u0434\\u0443 \\u0432 \\u041c\\u043e\\u0441\\u043a\\u0432\\u0435 \\u043d\\u0430 \\u0441\\u0435\\u0433\\u043e\\u0434\\u043d\\u044f \\u0438 \\u043d\\u0430 \\u0431\\u043b\\u0438\\u0436\\u0430\\u0439\\u0448\\u0438\\u0435 \\u0434\\u043d\\u0438. \\u0421\\u043c\\u043e\\u0442\\u0440\\u0438\\u0442\\u0435 \\u043a\\u0430\\u0440\\u0442\\u0443 \\u043e\\u0441\\u0430\\u0434\\u043a\\u043e\\u0432, \\u0442\\u0435\\u043c\\u043f\\u0435\\u0440\\u0430\\u0442\\u0443\\u0440\\u044b, \\u0432\\u0435\\u0442\\u0435\\u0440\\u0430 \\u0438 \\u043e\\u0431\\u043b\\u0430\\u0447\\u043d\\u043e\\u0441\\u0442\\u0438, \\u0430 \\u0442\\u0430\\u043a\\u0436\\u0435 \\u043d\\u043e\\u0432\\u043e\\u0441\\u0442\\u0438 \\u0438 \\u043f\\u0440\\u0438\\u043c\\u0435\\u0442\\u044b."}, {"url": "https://yandex.ru/pogoda/moscow", "content": "\\u0423\\u0437\\u043d\\u0430\\u0439\\u0442\\u0435 \\u043f\\u0440\\u043e\\u0433\\u043d\\u043e\\u0437 \\u043f\\u043e\\u0433\\u043e\\u0434\\u044b \\u0432 \\u041c\\u043e\\u0441\\u043a\\u0432\\u0435 \\u043d\\u0430 \\u0441\\u0435\\u0433\\u043e\\u0434\\u043d\\u044f, \\u0437\\u0430\\u0432\\u0442\\u0440\\u0430 \\u0438 \\u0431\\u043b\\u0438\\u0436\\u0430\\u0439\\u0448\\u0438\\u0435 \\u0434\\u043d\\u0438. \\u0421\\u043c\\u043e\\u0442\\u0440\\u0438\\u0442\\u0435 \\u0442\\u0435\\u043c\\u043f\\u0435\\u0440\\u0430\\u0442\\u0443\\u0440\\u0443, \\u0434\\u0430\\u0432\\u043b\\u0435\\u043d\\u0438\\u0435, \\u0432\\u043b\\u0430\\u0436\\u043d\\u043e\\u0441\\u0442\\u044c, \\u0441\\u043a\\u043e\\u0440\\u043e\\u0441\\u0442\\u044c \\u0432\\u0435\\u0442\\u0440\\u0430 \\u0438 \\u043e\\u0441\\u0430\\u0434\\u043a\\u0438 \\u043d\\u0430 \\u043a\\u0430\\u0440\\u0442\\u0435 \\u0438 \\u0432 \\u0442\\u0430\\u0431\\u043b\\u0438\\u0446\\u0435."}]', name='tavily_search_results_json', tool_call_id='fb19fd4f-3bc1-4b7f-9cca-e669ab8d96e4', artifact={'query': 'погода в москве', 'follow_up_questions': None, 'answer': None, 'images': [], 'results': [{'title': 'Погода В Москве Сейчас | Gismeteo', 'url': 'https://www.gismeteo.ru/weather-moscow-4368/now/', 'content': 'Узнайте фактическую погоду в Москве на сегодня и на ближайшие дни. Смотрите карту осадков, температуры, ветера и облачности, а также новости и приметы.', 'score': 0.9981613, 'raw_content': None}, {'title': 'Прогноз погоды в Москве на 10 дней — Яндекс.Погода', 'url': 'https://yandex.ru/pogoda/moscow', 'content': 'Узнайте прогноз погоды в Москве на сегодня, завтра и ближайшие дни. Смотрите температуру, давление, влажность, скорость ветра и осадки на карте и в таблице.', 'score': 0.99698395, 'raw_content': None}], 'response_time': 2.27})]}}
----
{'agent': {'messages': [AIMessage(content='Погода в Москве сейчас облачная и прохладная. Температура воздуха около 15 градусов по Цельсию.', response_metadata={'token_usage': Usage(prompt_tokens=1744, completion_tokens=29, total_tokens=1773), 'model_name': 'GigaChat-Pro:2.2.25.3', 'finish_reason': 'stop'}, id='run-b864e6be-a222-496d-aeab-2da9bea7ad1b-0')]}}
----
Ключ авторизации — строка, полученная в результате кодирования в Base64 клиентского идентификатора (Client ID) и ключа (Client Secret) API. Вы можете использовать готовый ключ из личного кабинета или самостоятельно закодировать Client ID и Client Secret.
Пример ключа авторизации:
MjIzODA0YTktMDU3OC00MTZmLWI4MWYtYzUwNjg3Njk4MzMzOjljMTI2MGQyLTFkNTEtNGRkOS05ZGVhLTBhNjAzZTdjZjQ3Mw==
Ключ авторизации, Client ID и Client Secret вы можете получить после создания проекта GigaChat API:
Подготовка к разработке
Jupyter-блокноты
Это руководство, как и большинство других в документации, использует Jupyter-блокноты. Они отлично подходят для изучения работы с LLM-системами, так как предоставляют интерактивную среду для работы с руководствами и позволяют работать с непредвиденными ситуациями: недоступностью API, нетипичным выводом и другими.
Подробнее об установке Jupyter — в официальной документации.
Установка
Для установки GigaChain выполните команды:
%%capture --no-stderr
%pip install -U langchain-gigachat langgraph langchain-community tavily-python
Подробнее об установке — в разделе Установка.
Tavily
В качестве инструмента в примере используется поисковый движок Tavily. Для работы с ним вам нужно получить и задать ключ API:
export TAVILY_API_KEY="..."
В Jupyter-блокноте ключ можно использовать так:
# Используйте эту ячейку, чтобы задать ключ в блокноте
import getpass
import os
os.environ["TAVILY_API_KEY"] = getpass.getpass()
Определение инструментов
Сначала создайте инструменты, которые будет использовать агент. Основным инструментом в примере выступает поисковый движок Tavily. GigaChain предоставляет интеграцию для простого использования поисковой системы Tavily в качестве инструмента.
from langchain_community.tools.tavily_search import TavilySearchResults
search = TavilySearchResults(max_results=2)
search_results = search.invoke("Узнай на weatherapi погоду в Москве")
print(search_results)
# Если нужно, вы можете создать другие инструменты.
# После создания всех необходимых инструментов
# их можно сохранить в списке, к которому можно обращаться позднее.
tools = [search]
[{'url': 'https://www.weatherapi.com/', 'content': "{'location': {'name': 'Moscow', 'region': 'Moscow City', 'country': 'Russia', 'lat': 55.7522, 'lon': 37.6156, 'tz_id': 'Europe/Moscow', 'localtime_epoch': 1732032969, 'localtime': '2024-11-19 19:16'}, 'current': {'last_updated_epoch': 1732032900, 'last_updated': '2024-11-19 19:15', 'temp_c': 1.1, 'temp_f': 34.0, 'is_day': 0, 'condition': {'text': 'Clear', 'icon': '//cdn.weatherapi.com/weather/64x64/night/113.png', 'code': 1000}, 'wind_mph': 9.6, 'wind_kph': 15.5, 'wind_degree': 245, 'wind_dir': 'WSW', 'pressure_mb': 1007.0, 'pressure_in': 29.74, 'precip_mm': 0.02, 'precip_in': 0.0, 'humidity': 86, 'cloud': 0, 'feelslike_c': -3.2, 'feelslike_f': 26.3, 'windchill_c': -2.4, 'windchill_f': 27.8, 'heatindex_c': 1.7, 'heatindex_f': 35.1, 'dewpoint_c': -0.5, 'dewpoint_f': 31.2, 'vis_km': 10.0, 'vis_miles': 6.0, 'uv': 0.0, 'gust_mph': 13.4, 'gust_kph': 21.6}}"}, {'url': 'https://weather.rambler.ru/v-moskve/19-november/', 'content': '5 ° Реутов. 6 ° Котельники. 4 ° Лыткарино. 4 ° Долгопрудный. Подробный прогноз погоды в Москве на 19 ноября 2024: температура воздуха, ветер, осадки, давление, влажность, а также геомагнитная'}]
Использование языковых моделей
Пример ниже показывает как использовать языковую модель для вызова инструментов. Кроме моделей GigaChat, GigaChain позволяет использовать и другие модели.
# | output: false
# | echo: false
from langchain_gigachat.chat_models import GigaChat
model = GigaChat(
credentials="ключ_авторизации",
scope="GIGACHAT_API_PERS",
model="GigaChat-Pro",
verify_ssl_certs=False,
)
Для вызова модели передайте ей список сообщений.
По умолчанию ответом будет строка content
.
from langchain_core.messages import HumanMessage
response = model.invoke([HumanMessage(content="Привет!")])
response.content
'Привет! Рад тебя видеть. Как твои дела?'
Используйте метод .bind_tools
, чтобы дать модели знать, к каким инструментам она может обращаться.
model_with_tools = model.bind_tools(tools)
Сначала, посмотрите как ответит модель на обычное сообщение.
Ответ модели можно найти в двух полях ContentString
и tool_calls
.
response = model_with_tools.invoke([HumanMessage(content="Привет!")])
print(f"ContentString: {response.content}")
print(f"ToolCalls: {response.tool_calls}")
ContentString: Привет! Рад тебя видеть. Как могу быть полезен?
ToolCalls: []
Теперь попробуйте вызвать модель с помощью запроса, который предполагает использование инструмента.
response = model_with_tools.invoke(
[HumanMessage(content="Используй функцию поиска Tavily, чтобы сделать запрос на weatherapi и рассказать о погоде в Москве")]
)
print(f"ContentString: {response.content}")
print(f"ToolCalls: {response.tool_calls}")
ContentString:
ToolCalls: [{'name': 'tavily_search_results_json', 'args': {'query': 'weatherapi Moscow'}, 'id': 'ac35392b-2b86-4541-bcca-8264c83a1793', 'type': 'tool_call'}]
Поле ContentString теперь пустое, но по содержимому массива ToolCalls видно, что модель хочет, чтобы вы вызвали инструмент поиска Tavily.
Модель не может самостоятельно вызвать инструмент, для этого нужно создать агента.
Создание агента
Для создания агента используйте LangGraph — инструмент, который предоставляет высокоуровневый интерфейс для создания агентов. LangGraph дает доступ к низкоуровневым инструментам, которые дают полный контроль над логикой работы агента. Инициализируйте агент с моделью и набором инструментов.
В агент можно передавать model
, а не model_with_tools
, т.к. метод create_react_agent
самостоятельно вызывает .bind_tools
.
from langgraph.prebuilt import create_react_agent
agent_executor = create_react_agent(model, tools)
Запуск агента
Теперь вы можете проверить работу агента на нескольких запросах.
Сейчас агент не сохраняет информацию о состоянии и не помнит историю взаимодействия с пользователем.
В результате работы агент возвращает итоговое состояние, которое кроме выходных данных также содержит все входные данные. Как получить только выходные данные показано в примерах ниже.
Посмотрите, как агент отвечает, когда не нужно вызывать инструменты:
response = agent_executor.invoke({"messages": [HumanMessage(content="Привет!")]})
response["messages"]
[HumanMessage(content='Привет!', additional_kwargs={}, response_metadata={}, id='23904d42-79c0-4a7a-b057-074af66c0d1e'),
AIMessage(content='Здравствуйте! Чем могу помочь?', additional_kwargs={'functions_state_id': 'c6f3aac4-5e7d-46b9-86cb-7ea0545a4691'}, response_metadata={'token_usage': Usage(prompt_tokens=110, completion_tokens=15, total_tokens=125), 'model_name': 'GigaChat-Pro:1.0.26.15', 'finish_reason': 'stop'}, id='run-3983b6d5-75d8-4056-8595-055f4e733624-0')]
Попробуйте обратиться к агенту с запросом, который предполагает вызов инструмента:
response = agent_executor.invoke(
{"messages": [HumanMessage(content="Используй функцию поиска Tavily, чтобы сделать запрос на weatherapi и рассказать о погоде в Москве")]}
)
response["messages"]
[HumanMessage(content='Используй функцию поиска Tavily, чтобы сделать запрос на weatherapi и рассказать о погоде в Москве', additional_kwargs={}, response_metadata={}, id='38d8b3a9-98c1-4953-a446-753f1a161048'),
AIMessage(content='', additional_kwargs={'function_call': {'name': 'tavily_search_results_json', 'arguments': {'query': 'weatherapi Москва'}}, 'functions_state_id': '73ea62c8-4d63-44d8-90aa-fd3add771cd1'}, response_metadata={'token_usage': Usage(prompt_tokens=128, completion_tokens=34, total_tokens=162), 'model_name': 'GigaChat:1.0.26.15', 'finish_reason': 'function_call'}, id='run-7c17a3f2-1c47-45b9-ab7f-6d19a207ca57-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'weatherapi Москва'}, 'id': 'f0d93f59-f4dc-47e6-9e36-9188d7dfa7f4', 'type': 'tool_call'}]),
ToolMessage(content='[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Moscow\', \'region\': \'Moscow City\', \'country\': \'Russia\', \'lat\': 55.7522, \'lon\': 37.6156, \'tz_id\': \'Europe/Moscow\', \'localtime_epoch\': 1732034130, \'localtime\': \'2024-11-19 19:35\'}, \'current\': {\'last_updated_epoch\': 1732033800, \'last_updated\': \'2024-11-19 19:30\', \'temp_c\': 1.1, \'temp_f\': 34.0, \'is_day\': 0, \'condition\': {\'text\': \'Clear\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/night/113.png\', \'code\': 1000}, \'wind_mph\': 9.6, \'wind_kph\': 15.5, \'wind_degree\': 245, \'wind_dir\': \'WSW\', \'pressure_mb\': 1007.0, \'pressure_in\': 29.74, \'precip_mm\': 0.02, \'precip_in\': 0.0, \'humidity\': 86, \'cloud\': 0, \'feelslike_c\': -3.2, \'feelslike_f\': 26.3, \'windchill_c\': -2.4, \'windchill_f\': 27.8, \'heatindex_c\': 1.7, \'heatindex_f\': 35.1, \'dewpoint_c\': -0.5, \'dewpoint_f\': 31.2, \'vis_km\': 10.0, \'vis_miles\': 6.0, \'uv\': 0.0, \'gust_mph\': 13.4, \'gust_kph\': 21.6}}"}, {"url": "https://www.meteosource.com/weather-api-moscow", "content": "Weather API - Moscow. Real-time, forecast & historical accurate data. At an affordable price, you will receive accurate and reliable data for Moscow (Москва) that you can easily implement into your website or application. We provide weather data globally. Predictions for any GPS or City"}]', name='tavily_search_results_json', id='64f7f6fe-ba3a-423f-b390-971ec0fe602d', tool_call_id='f0d93f59-f4dc-47e6-9e36-9188d7dfa7f4', artifact={'query': 'weatherapi Москва', 'follow_up_questions': None, 'answer': None, 'images': [], 'results': [{'title': 'Weather in Moscow', 'url': 'https://www.weatherapi.com/', 'content': "{'location': {'name': 'Moscow', 'region': 'Moscow City', 'country': 'Russia', 'lat': 55.7522, 'lon': 37.6156, 'tz_id': 'Europe/Moscow', 'localtime_epoch': 1732034130, 'localtime': '2024-11-19 19:35'}, 'current': {'last_updated_epoch': 1732033800, 'last_updated': '2024-11-19 19:30', 'temp_c': 1.1, 'temp_f': 34.0, 'is_day': 0, 'condition': {'text': 'Clear', 'icon': '//cdn.weatherapi.com/weather/64x64/night/113.png', 'code': 1000}, 'wind_mph': 9.6, 'wind_kph': 15.5, 'wind_degree': 245, 'wind_dir': 'WSW', 'pressure_mb': 1007.0, 'pressure_in': 29.74, 'precip_mm': 0.02, 'precip_in': 0.0, 'humidity': 86, 'cloud': 0, 'feelslike_c': -3.2, 'feelslike_f': 26.3, 'windchill_c': -2.4, 'windchill_f': 27.8, 'heatindex_c': 1.7, 'heatindex_f': 35.1, 'dewpoint_c': -0.5, 'dewpoint_f': 31.2, 'vis_km': 10.0, 'vis_miles': 6.0, 'uv': 0.0, 'gust_mph': 13.4, 'gust_kph': 21.6}}", 'score': 0.9982992, 'raw_content': None}, {'title': 'Meteosource - Weather API for Moscow - current weather and forecast data', 'url': 'https://www.meteosource.com/weather-api-moscow', 'content': 'Weather API - Moscow. Real-time, forecast & historical accurate data. At an affordable price, you will receive accurate and reliable data for Moscow (Москва) that you can easily implement into your website or application. We provide weather data globally. Predictions for any GPS or City', 'score': 0.9962638, 'raw_content': None}], 'response_time': 3.98}),
AIMessage(content='Погода в Москве по данным WeatherAPI: сейчас облачно, температура воздуха около 1°C. Ветер слабый, направление западное. Давление 1007 мбар, влажность воздуха 86%.', additional_kwargs={'functions_state_id': '5991fbe9-05f1-4866-a3d1-d371b58b7537'}, response_metadata={'token_usage': Usage(prompt_tokens=823, completion_tokens=53, total_tokens=876), 'model_name': 'GigaChat:1.0.26.15', 'finish_reason': 'stop'}, id='run-8bc71337-ea8c-4049-8a35-d0e8b76d0e22-0')]
Потоковая передача сообщений
В предыдущих примерах агент вызывается с помощью метода .invoke
и возвращает итоговой ответ.
Это может занимать продолжительное время, если агент в процессе работы выполняет множество шагов.
Для демонстрации промежуточных результатов вы можете передавать сообщения по мере их возникновения.
for chunk in agent_executor.stream(
{"messages": [HumanMessage(content="Используй функцию поиска Tavily, чтобы сделать запрос на weatherapi и рассказать о погоде в Москве")]}
):
print(chunk)
print("----")
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'function_call': {'name': 'tavily_search_results_json', 'arguments': {'query': 'weatherapi Москва'}}, 'functions_state_id': 'a45f74c9-10f3-4efd-b94c-df22d1be543c'}, response_metadata={'token_usage': Usage(prompt_tokens=128, completion_tokens=34, total_tokens=162), 'model_name': 'GigaChat:1.0.26.15', 'finish_reason': 'function_call'}, id='run-021c4daa-dff9-448b-b868-90d4c4591dd0-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'weatherapi Москва'}, 'id': 'c0a3aefb-3ce7-4e73-8bc2-4815f1f976e0', 'type': 'tool_call'}])]}}
----
{'tools': {'messages': [ToolMessage(content='[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Moscow\', \'region\': \'Moscow City\', \'country\': \'Russia\', \'lat\': 55.7522, \'lon\': 37.6156, \'tz_id\': \'Europe/Moscow\', \'localtime_epoch\': 1732034130, \'localtime\': \'2024-11-19 19:35\'}, \'current\': {\'last_updated_epoch\': 1732033800, \'last_updated\': \'2024-11-19 19:30\', \'temp_c\': 1.1, \'temp_f\': 34.0, \'is_day\': 0, \'condition\': {\'text\': \'Clear\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/night/113.png\', \'code\': 1000}, \'wind_mph\': 9.6, \'wind_kph\': 15.5, \'wind_degree\': 245, \'wind_dir\': \'WSW\', \'pressure_mb\': 1007.0, \'pressure_in\': 29.74, \'precip_mm\': 0.02, \'precip_in\': 0.0, \'humidity\': 86, \'cloud\': 0, \'feelslike_c\': -3.2, \'feelslike_f\': 26.3, \'windchill_c\': -2.4, \'windchill_f\': 27.8, \'heatindex_c\': 1.7, \'heatindex_f\': 35.1, \'dewpoint_c\': -0.5, \'dewpoint_f\': 31.2, \'vis_km\': 10.0, \'vis_miles\': 6.0, \'uv\': 0.0, \'gust_mph\': 13.4, \'gust_kph\': 21.6}}"}, {"url": "https://open-meteo.com/en/docs", "content": "Weather Forecast APIs with weather models from multiple national weather providers, combining the best models for accurate forecasts worldwide. Explore the API documentation to learn more about the available weather models, their origin countries, resolutions, forecast lengths, and update frequencies. Get detailed JSON hourly weather forecasts for up to 7 or 16 days by specifying the"}]', name='tavily_search_results_json', id='94eeb125-b2d1-4d68-a7c4-84aaaf8f5e0f', tool_call_id='c0a3aefb-3ce7-4e73-8bc2-4815f1f976e0', artifact={'query': 'weatherapi Москва', 'follow_up_questions': None, 'answer': None, 'images': [], 'results': [{'title': 'Weather in Moscow', 'url': 'https://www.weatherapi.com/', 'content': "{'location': {'name': 'Moscow', 'region': 'Moscow City', 'country': 'Russia', 'lat': 55.7522, 'lon': 37.6156, 'tz_id': 'Europe/Moscow', 'localtime_epoch': 1732034130, 'localtime': '2024-11-19 19:35'}, 'current': {'last_updated_epoch': 1732033800, 'last_updated': '2024-11-19 19:30', 'temp_c': 1.1, 'temp_f': 34.0, 'is_day': 0, 'condition': {'text': 'Clear', 'icon': '//cdn.weatherapi.com/weather/64x64/night/113.png', 'code': 1000}, 'wind_mph': 9.6, 'wind_kph': 15.5, 'wind_degree': 245, 'wind_dir': 'WSW', 'pressure_mb': 1007.0, 'pressure_in': 29.74, 'precip_mm': 0.02, 'precip_in': 0.0, 'humidity': 86, 'cloud': 0, 'feelslike_c': -3.2, 'feelslike_f': 26.3, 'windchill_c': -2.4, 'windchill_f': 27.8, 'heatindex_c': 1.7, 'heatindex_f': 35.1, 'dewpoint_c': -0.5, 'dewpoint_f': 31.2, 'vis_km': 10.0, 'vis_miles': 6.0, 'uv': 0.0, 'gust_mph': 13.4, 'gust_kph': 21.6}}", 'score': 0.977252, 'raw_content': None}, {'title': '️ Docs - Open-Meteo.com', 'url': 'https://open-meteo.com/en/docs', 'content': 'Weather Forecast APIs with weather models from multiple national weather providers, combining the best models for accurate forecasts worldwide. Explore the API documentation to learn more about the available weather models, their origin countries, resolutions, forecast lengths, and update frequencies. Get detailed JSON hourly weather forecasts for up to 7 or 16 days by specifying the', 'score': 0.71611935, 'raw_content': None}], 'response_time': 3.9})]}}
----
{'agent': {'messages': [AIMessage(content='Погода в Москве согласно запросу на WeatherAPI показывает следующие данные: сейчас 19:35, температура воздуха составляет 1,1°C, ощущается как -3,2°C. Направление ветра WSW, скорость 9,6 миль в час. Давление 1007 мб, влажность 86%. Ясно, осадков нет.', additional_kwargs={'functions_state_id': '5c2a46a5-b0dc-40db-8842-dcaf36d98006'}, response_metadata={'token_usage': Usage(prompt_tokens=831, completion_tokens=89, total_tokens=920), 'model_name': 'GigaChat:1.0.26.15', 'finish_reason': 'stop'}, id='run-2a4c7f8e-5834-4cf3-8186-9ec7051f2ce5-0')]}}
----
Потоковая передача токенов
Кроме сообщений вы также можете использовать потоковую передачу токенов.
Для этого используйте метод .astream_events
.
Метод .astream_events
работает в версиях Python 3.11 и выше.
async for event in agent_executor.astream_events(
{"messages": [HumanMessage(content="Используй функцию поиска Tavily, чтобы сделать запрос на weatherapi и рассказать о погоде в Москве")]},
version="v1",
):
kind = event["event"]
if kind == "on_chain_start":
if (
event["name"] == "Agent"
): # Назначается при создании агента с помощью метода `.with_config({"run_name": "Agent"})`
print(
f"Starting agent: {event['name']} with input: {event['data'].get('input')}"
)
elif kind == "on_chain_end":
if (
event["name"] == "Agent"
): # Назначается при создании агента с помощью метода `.with_config({"run_name": "Agent"})`
print()
print("--")
print(
f"Done agent: {event['name']} with output: {event['data'].get('output')['output']}"
)
if kind == "on_chat_model_stream":
content = event["data"]["chunk"].content
if content:
print(content, end="|")
elif kind == "on_tool_start":
print("--")
print(
f"Starting tool: {event['name']} with inputs: {event['data'].get('input')}"
)
elif kind == "on_tool_end":
print(f"Done tool: {event['name']}")
print(f"Tool output was: {event['data'].get('output')}")
print("--")
--
Starting tool: tavily_search_results_json with inputs: {'query': 'weatherapi Москва'}
Done tool: tavily_search_results_json
Tool output was: content='[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Moscow\', \'region\': \'Moscow City\', \'country\': \'Russia\', \'lat\': 55.7522, \'lon\': 37.6156, \'tz_id\': \'Europe/Moscow\', \'localtime_epoch\': 1732034130, \'localtime\': \'2024-11-19 19:35\'}, \'current\': {\'last_updated_epoch\': 1732033800, \'last_updated\': \'2024-11-19 19:30\', \'temp_c\': 1.1, \'temp_f\': 34.0, \'is_day\': 0, \'condition\': {\'text\': \'Clear\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/night/113.png\', \'code\': 1000}, \'wind_mph\': 9.6, \'wind_kph\': 15.5, \'wind_degree\': 245, \'wind_dir\': \'WSW\', \'pressure_mb\': 1007.0, \'pressure_in\': 29.74, \'precip_mm\': 0.02, \'precip_in\': 0.0, \'humidity\': 86, \'cloud\': 0, \'feelslike_c\': -3.2, \'feelslike_f\': 26.3, \'windchill_c\': -2.4, \'windchill_f\': 27.8, \'heatindex_c\': 1.7, \'heatindex_f\': 35.1, \'dewpoint_c\': -0.5, \'dewpoint_f\': 31.2, \'vis_km\': 10.0, \'vis_miles\': 6.0, \'uv\': 0.0, \'gust_mph\': 13.4, \'gust_kph\': 21.6}}"}, {"url": "https://www.cnn.com/2024/11/19/europe/ukraine-russia-atacms-biden-strike-intl/index.html", "content": "Updated 10:11 AM EST, Tue November 19, 2024 Link Copied! Follow: Russia See your ... Under the updated doctrine, Moscow will consider aggression from any non-nuclear state - but with the"}]' name='tavily_search_results_json' tool_call_id='a2ec240c-b31a-45d1-a680-2ce2243272d9' artifact={'query': 'weatherapi Москва', 'follow_up_questions': None, 'answer': None, 'images': [], 'results': [{'title': 'Weather in Moscow', 'url': 'https://www.weatherapi.com/', 'content': "{'location': {'name': 'Moscow', 'region': 'Moscow City', 'country': 'Russia', 'lat': 55.7522, 'lon': 37.6156, 'tz_id': 'Europe/Moscow', 'localtime_epoch': 1732034130, 'localtime': '2024-11-19 19:35'}, 'current': {'last_updated_epoch': 1732033800, 'last_updated': '2024-11-19 19:30', 'temp_c': 1.1, 'temp_f': 34.0, 'is_day': 0, 'condition': {'text': 'Clear', 'icon': '//cdn.weatherapi.com/weather/64x64/night/113.png', 'code': 1000}, 'wind_mph': 9.6, 'wind_kph': 15.5, 'wind_degree': 245, 'wind_dir': 'WSW', 'pressure_mb': 1007.0, 'pressure_in': 29.74, 'precip_mm': 0.02, 'precip_in': 0.0, 'humidity': 86, 'cloud': 0, 'feelslike_c': -3.2, 'feelslike_f': 26.3, 'windchill_c': -2.4, 'windchill_f': 27.8, 'heatindex_c': 1.7, 'heatindex_f': 35.1, 'dewpoint_c': -0.5, 'dewpoint_f': 31.2, 'vis_km': 10.0, 'vis_miles': 6.0, 'uv': 0.0, 'gust_mph': 13.4, 'gust_kph': 21.6}}", 'score': 0.7923353, 'raw_content': None}, {'title': 'Ukraine fires US-made longer-range missiles into Russia for the first ...', 'url': 'https://www.cnn.com/2024/11/19/europe/ukraine-russia-atacms-biden-strike-intl/index.html', 'content': 'Updated 10:11 AM EST, Tue November 19, 2024 Link Copied! Follow: Russia See your ... Under the updated doctrine, Moscow will consider aggression from any non-nuclear state - but with the', 'score': 0.23074637, 'raw_content': None}], 'response_time': 3.56}
--
Погода в Москве по данным сервиса Weather API на момент запроса:|
- Город:| Москва
- Страна:| Россия
- Текущее время:| 19:|35 (по московскому времени)
- Температура воздуха:| 1.|1°C (34°F)
- Погодные условия:| Ясно
- Ветер:| 9.|6 миль в час, направление WSW
- Влажность:| 86%
- Давление:| 1007 мб
Для получения более подробного прогноза рекомендую посетить официальный сайт Weather API или воспользоваться другими метеорологическими сервисами.|
Добавление памяти
Для добавления памяти нужно при вызове агента передать ему чекпойнтер и поле thread_id
.
С помощью этого поля агент сможет понять, к какому разговору нужно вернуться.
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
agent_executor = create_react_agent(model, tools, checkpointer=memory)
config = {"configurable": {"thread_id": "abc123"}}
for chunk in agent_executor.stream(
{"messages": [HumanMessage(content="Привет! Меня зовут Вася")]}, config
):
print(chunk)
print("----")
{'agent': {'messages': [AIMessage(content='Привет, Вася! Рад знакомству. Чем могу быть полезен?', additional_kwargs={'functions_state_id': '9bccea4e-7cf2-424d-b6c6-831bc078868a'}, response_metadata={'token_usage': Usage(prompt_tokens=101, completion_tokens=20, total_tokens=121), 'model_name': 'GigaChat-Max:1.0.26.20', 'finish_reason': 'stop'}, id='run-bdd79550-936b-423a-b382-452f0adba5a9-0')]}}
----
for chunk in agent_executor.stream(
{"messages": [HumanMessage(content="Как меня зовут?")]}, config
):
print(chunk)
print("----")
{'agent': {'messages': [AIMessage(content='Тебя зовут Вася.', additional_kwargs={'functions_state_id': 'd2d4af43-04cb-4b0c-8754-6515d54d3011'}, response_metadata={'token_usage': Usage(prompt_tokens=145, completion_tokens=12, total_tokens=157), 'model_name': 'GigaChat-Max:1.0.26.20', 'finish_reason': 'stop'}, id='run-d0e39541-1513-4cf8-9ce2-efeb1f0ef4d5-0')]}}
----
Для начала нового разговора вам достаточно изменить значение thread_id
.
config = {"configurable": {"thread_id": "xyz123"}}
for chunk in agent_executor.stream(
{"messages": [HumanMessage(content="Как меня зовут?")]}, config
):
print(chunk)
print("----")
{'agent': {'messages': [AIMessage(content='К сожалению, я не могу знать вашего имени, если вы его не указали. Если хотите, можете написать свое имя, и я буду обращаться к вам так.', additional_kwargs={'functions_state_id': '9f09c19d-2e39-4590-b4a9-e87ae62a652b'}, response_metadata={'token_usage': Usage(prompt_tokens=98, completion_tokens=37, total_tokens=135), 'model_name': 'GigaChat-Max:1.0.26.20', 'finish_reason': 'stop'}, id='run-df1d3d9c-970e-4d73-a772-8535aa5e95e4-0')]}}
----
Смотрите также
Более подробную информацию о разработке агентов ищите в документации LangGraph.