Пример 1. Агент-поисковик с памятью (как в лекции)
Агент с одним инструментом — поиском Tavily. Память (MemorySaver + thread_id) позволяет во втором запросе вспомнить, что пользователь живёт в Берлине.
# ai6_1.py
import os
from dotenv import load_dotenv
from langchain_google_genai import ChatGoogleGenerativeAI
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
load_dotenv()
# Google-библиотека ждёт ключ в GOOGLE_API_KEY; Tavily — в TAVILY_API_KEY
os.environ["GOOGLE_API_KEY"] = os.getenv("GEMINI_API_KEY")
os.environ["TAVILY_API_KEY"] = os.getenv("TAVILY_API_KEY")
llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash") # «мозг» агента
memory = MemorySaver() # память диалога
search = TavilySearchResults(max_results=2) # инструмент: поиск
tools = [search]
# ReAct-агент: модель + инструменты + память
agent_executor = create_react_agent(llm, tools, checkpointer=memory)
# thread_id — ключ диалога, по нему агент находит свою память
config = {"configurable": {"thread_id": "abc123"}}
# 1) Сообщаем о себе — агент запомнит
for step in agent_executor.stream(
{"messages": [HumanMessage(content="hi im bob! and i live in berlin")]},
config, stream_mode="values"):
step["messages"][-1].pretty_print()
# 2) Спрашиваем «погоду там, где я живу» — агент вспомнит Берлин и вызовет поиск
for step in agent_executor.stream(
{"messages": [HumanMessage(content="whats the weather where I live?")]},
config, stream_mode="values"):
step["messages"][-1].pretty_print()
Что видно в выводе.
stream(..., stream_mode="values") печатает каждый шаг: сообщение пользователя → решение модели вызвать инструмент → результат поиска → финальный ответ. Так наглядно виден цикл ReAct.
Пример 2. Свой инструмент: текущая дата (как в лекции)
Добавим к поиску собственный инструмент — функцию, возвращающую дату/время. Агент сам решит вызвать её, когда спросят про сегодняшний день.
# ai6_2.py
import os
from datetime import datetime
from dotenv import load_dotenv
from langchain_core.tools import Tool
from langchain_core.messages import HumanMessage
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.checkpoint.memory import MemorySaver
from langgraph.prebuilt import create_react_agent
load_dotenv()
os.environ["GOOGLE_API_KEY"] = os.getenv("GEMINI_API_KEY")
os.environ["TAVILY_API_KEY"] = os.getenv("TAVILY_API_KEY")
llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash")
memory = MemorySaver()
search = TavilySearchResults(max_results=2)
# Обычная функция, которую превратим в инструмент
def get_current_date(*args, **kwargs):
return datetime.now().isoformat()
# Оборачиваем функцию в Tool. description подсказывает LLM, КОГДА её вызвать
date_tool = Tool(
name="Datetime",
func=get_current_date,
description="Returns current datetime in ISO format.",
)
tools = [search, date_tool] # два инструмента
agent_executor = create_react_agent(llm, tools, checkpointer=memory)
config = {"configurable": {"thread_id": "abc123"}}
for step in agent_executor.stream(
{"messages": [HumanMessage(content="hi im bob! and i live in berlin")]},
config, stream_mode="values"):
step["messages"][-1].pretty_print()
# Вопрос про дату — агент вызовет наш инструмент Datetime, а не поиск
for step in agent_executor.stream(
{"messages": [HumanMessage(content="whats the date for today?")]},
config, stream_mode="values"):
step["messages"][-1].pretty_print()
⚠️ В современных версиях LangChain свой инструмент удобнее объявлять декоратором
@tool над функцией с понятной сигнатурой и docstring — это надёжнее «голого» Tool(func=...). См. Старый vs Новый.