From 05e69a0d3b9d7f51a911eeb2d5fae7bed75eb525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=B8=D1=8F=20=D0=91=D0=B5=D1=80=D0=B4?= =?UTF-8?q?=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Wed, 27 May 2026 14:15:25 +0000 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=E2=84=963:=20=D0=9F=D0=B0=D0=BC=D1=8F=D1=82?= =?UTF-8?q?=D1=8C=20=D0=B8=20=D0=BF=D0=BE=D0=B4=D1=82=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B5=D0=B9=D1=81?= =?UTF-8?q?=D1=82=D0=B2=D0=B8=D0=B9:=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md | 149 +++++++++--------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/solutions/69a474cdc46fd26feae69896_Практическое_задание__3__Память_и_подтве/README.md b/solutions/69a474cdc46fd26feae69896_Практическое_задание__3__Память_и_подтве/README.md index 1051ab2..93622cc 100644 --- a/solutions/69a474cdc46fd26feae69896_Практическое_задание__3__Память_и_подтве/README.md +++ b/solutions/69a474cdc46fd26feae69896_Практическое_задание__3__Память_и_подтве/README.md @@ -3,121 +3,122 @@ ## Описание проекта В этом задании вы доработаете агента из предыдущих практических работ, добавив: - **Память разговора** – агент будет помнить все сообщения в рамках одного диалога. -- **Механизм подтверждения** – перед выполнением любого инструмента пользователь получает запрос на подтверждение. +- **Механизм подтверждения** перед вызовом любого инструмента – пользователь сможет согласовать действие. -Для красивого вывода в консоли используется библиотека `rich`. +Для более приятного вывода используется библиотека `rich`. ## Структура проекта ``` project/ -├── agent.py # Основной скрипт с реализацией агента -├── tools.py # Пользовательские инструменты -└── README.md # Это файл +├── solution.py # Основной скрипт с реализацией агента +└── README.md # Это файл ``` +--- + ## Установка зависимостей ```bash -# Создайте виртуальное окружение (необязательно, но рекомендуется) +# Создайте виртуальное окружение (рекомендуется) python -m venv .venv -source .venv/bin/activate # Windows: .\.venv\Scripts\activate +source .venv/bin/activate # Windows: .venv\Scripts\activate # Установите все необходимые пакеты -pip install langgraph rich openai # добавьте другие зависимости при необходимости +pip install rich langgraph langchain-openai langchain-core ``` -> **Важно** – `rich` нужен только для вывода, но без него скрипт будет работать. - -## Как запустить каждый файл - -### 1. `tools.py` -Содержит пользовательские инструменты (например, поиск в интернете, вычисления и т.д.). -Запуск не требуется отдельно – он импортируется в `agent.py`. - -### 2. `agent.py` -Главный скрипт, который запускает агента. +> **Важно** +> `langgraph` и `langchain-openai` автоматически подтянут нужные версии OpenAI SDK. +> Если у вас нет ключа API, создайте переменную окружения `OPENAI_API_KEY`. ```bash -python agent.py +export OPENAI_API_KEY="sk-..." ``` -При запуске вы увидите интерактивную сессию: +--- -1. Введите сообщение. -2. Агент сформулирует запрос к инструменту и попросит подтвердить действие. -3. После подтверждения (`yes`/`no`) агент выполнит инструмент или отменит его. +## Запуск скрипта -### 3. Пример запуска в режиме потоковой печати +### 1️⃣ Запустите файл напрямую ```bash -python agent.py --stream +python solution.py ``` -Параметр `--stream` заставляет выводить ответы построчно, как это делает `rich`. +Скрипт откроет интерактивный чат, где вы можете задавать вопросы. При каждом вызове инструмента агент сначала спросит подтверждение. -## Пример использования +> **Пример** +> ``` +> Пользователь: Привет! +> Агент: Здравствуйте! Чем могу помочь? +> Пользователь: Напиши мне список покупок. +> Агент: Вы хотите вызвать инструмент `echo_tool` с аргументом `text="список покупок"`? (y/n) +> y +> Эхо: список покупок +> ``` + +### 2️⃣ Запуск в режиме потоковой передачи + +Если вы хотите видеть ответы по частям, можно запустить скрипт так: + +```bash +python solution.py --stream +``` + +Внутри `solution.py` реализован флаг `--stream`, который переключает режим вывода. + +--- + +## Пример использования кода ```python -# Внутри agent.py (или в интерактивной сессии) -from langgraph.checkpoint.memory import MemorySaver from rich.console import Console -import os +from langgraph.checkpoint.memory import MemorySaver +from langgraph.prebuilt import create_chat_agent +from langchain_openai import ChatOpenAI +# 1. Консоль для красивого вывода console = Console() -# Инициализация памяти и агента +# 2. Создаём LLM +llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) + +# 3. Определяем инструмент +def echo_tool(args: dict) -> str: + return f"Эхо: {args.get('text', '')}" + +# 4. Память и агент с паузой перед инструментом memory = MemorySaver() -agent = create_agent( - model=llm, - tools=[my_tool], - system_prompt="You are a helpful assistant.", +agent = create_chat_agent( + llm=llm, + tools=[echo_tool], + system_prompt="Ты — полезный ассистент, который сначала спрашивает подтверждение перед вызовом инструмента.", checkpointer=memory, - interrupt_before=['tools'] # пауза перед каждым инструментом + interrupt_before=['tools'], # остановка перед каждым инструментом ) -# Конфигурация диалога (thread_id) -config = {"configurable": {"thread_id": "conversation-1"}} - -# Запуск агента с потоковым выводом -for chunk in agent.stream({"messages": [{"role":"user","content":"Расскажи о Python"}]}, config=config): - console.print(chunk, end="") - -# После завершения можно продолжить диалог в том же thread_id +# 5. Запускаем диалог +config = {"configurable": {"thread_id": "разговор-1"}} +for chunk in agent.stream({"messages": [HumanMessage(content="Напиши мне список покупок")]}, config=config): + console.print(chunk) ``` -### Что происходит при запуске +--- -1. **Память**: `MemorySaver` сохраняет все сообщения и состояния агента для конкретного `thread_id`. При повторном вызове с тем же ID агент «видит» историю. -2. **Подтверждение**: Когда агент планирует вызвать инструмент, он выводит запрос вида: - ``` - [Agent] Предлагаю использовать инструмент "search". Подтвердить? (yes/no) - ``` -3. **Пауза** (`interrupt_before=['tools']`): Агент останавливается до подтверждения и ждёт ввода пользователя. +## Что дальше? -## Как добавить новый инструмент +- Добавьте собственные инструменты (например, поиск в интернете, работа с файлами и т.д.). +- Изучите другие параметры `create_chat_agent`, такие как `interrupt_after` или `max_output_tokens`. +- Попробуйте использовать разные модели (`gpt-4o-mini`, `claude-3.5-sonnet` и др.) – просто поменяйте аргумент `model`. -1. Создайте функцию в `tools.py`. -2. Зарегистрируйте её в списке `tools=[...]` при создании агента. -3. При необходимости обновите `system_prompt`, чтобы агент знал о новом инструменте. +--- -## Тестирование +## Полезные ссылки -Для проверки работы можно использовать простые тесты: +| Тема | Ссылка | +|------|--------| +| LangGraph Docs | https://langgraph.org/docs/ | +| LangChain OpenAI | https://python.langchain.com/docs/integrations/providers/openai | +| Rich Library | https://rich.readthedocs.io/en/latest/introduction.html | -```bash -python -m unittest discover tests -``` - -> Убедитесь, что у вас есть файл `tests/` с соответствующими проверками. - -## FAQ - -| Вопрос | Ответ | -|--------|-------| -| Как изменить `thread_id`? | Передайте новый ID в `config = {"configurable": {"thread_id": "новый-id"}}`. | -| Что делать, если инструмент не подтверждается? | Агент просто пропускает вызов и продолжает диалог. | -| Можно ли отключить память? | Уберите `checkpointer=memory` при создании агента – тогда каждый запрос будет независимым. | - -## Лицензия - -MIT © 2026 \ No newline at end of file +--- \ No newline at end of file