✅ Решения

← К оглавлению урока

⚡ Кратко

create_react_agent(llm, tools, checkpointer=MemorySaver()); память — через thread_id; свой инструмент — Tool/@tool.

Часть 1. Ответы

  1. Обычная LLM только генерирует текст по запросу. Агент использует LLM как «мозг», но дополнительно планирует действия, вызывает инструменты и помнит контекст — действует автономно ради цели.
  2. Характеристики: автономность, целенаправленность, реактивность, проактивность. Компоненты: LLM, Tools, Memory, Planning.
  3. ReAct (Reasoning + Acting): агент рассуждает, какой инструмент нужен → вызывает его → получает результат → снова рассуждает, и так до финального ответа.
  4. thread_id — ключ диалога: по нему агент находит «свою» память. Без памяти каждый запрос обрабатывается изолированно — агент «забывает» предыдущие сообщения.
  5. По description LLM решает, когда вызвать инструмент. Нечёткое описание → инструмент вызывается не вовремя или игнорируется.
  6. Например: непредсказуемое поведение (нужно тщательное тестирование) и риски безопасности/этики при доступе к важным данным и действиям.

Часть 2. Эталон кода

Задание 1 + 2 — агент с поиском, памятью и своим инструментом

# agent.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()


date_tool = Tool(name="Datetime", func=get_current_date,
                 description="Returns current datetime in ISO format.")

agent = create_react_agent(llm, [search, date_tool], checkpointer=memory)
config = {"configurable": {"thread_id": "demo-1"}}


def ask(text):
    for step in agent.stream({"messages": [HumanMessage(content=text)]},
                             config, stream_mode="values"):
        step["messages"][-1].pretty_print()


ask("hi, im bob and i live in berlin")   # агент запомнит
ask("whats the date today?")             # вызовет инструмент Datetime
ask("whats the weather where I live?")   # вспомнит Берлин + вызовет поиск

Часть 3. Пример описания агента (ДЗ из лекции)

Идея: «Агент-ревьюер pull request».

  • Цель: по ссылке на PR дать краткое ревью: что изменилось, потенциальные баги, замечания по стилю.
  • Инструменты: (1) GitHub API — получить diff PR; (2) линтер/анализатор кода — найти проблемы; (3) поиск по документации — свериться с лучшими практиками.
  • Как работает: получает diff → разбивает на файлы → по каждому просит LLM оценить риск и стиль (при необходимости вызывает линтер и поиск) → собирает итоговое ревью со списком замечаний.

Часть 4. Со звёздочкой — @tool

# tools_modern.py
from langchain_core.tools import tool
from datetime import datetime

@tool
def get_current_date() -> str:
    """Возвращает текущие дату и время в формате ISO."""
    return datetime.now().isoformat()

# имя ("get_current_date") и описание (docstring) LangChain возьмёт сам
tools = [search, get_current_date]
⚠️ Имена пакетов/классов зависят от версий LangChain/LangGraph. Сверяйтесь с документацией.