Практическое задание №3: Память и подтверждение действий: README.md
This commit is contained in:
+79
-86
@@ -1,21 +1,13 @@
|
|||||||
# Практическое задание №3 – Память и подтверждение действий
|
# Практическое задание №3: Память и подтверждение действий
|
||||||
|
|
||||||
## Описание проекта
|
## Описание проекта
|
||||||
|
В этом проекте реализован агент на базе LangGraph с поддержкой:
|
||||||
|
- **Памяти разговора** – сохранение истории сообщений в `MemorySaver`.
|
||||||
|
- **Подтверждения действия** – пауза перед вызовом любого инструмента, чтобы пользователь мог подтвердить или отменить действие.
|
||||||
|
|
||||||
В этом проекте реализован чат‑бот, построенный на **LangGraph** и **OpenAI LLM**, с добавленной памятью диалога и механизмом подтверждения каждого вызова инструмента пользователем.
|
Агент использует модель GPT‑4o‑mini и простой инструмент поиска. Вывод осуществляется через библиотеку `rich`, что делает консольный интерфейс более читаемым.
|
||||||
Бот умеет:
|
|
||||||
|
|
||||||
- хранить историю общения в памяти (`MemorySaver`);
|
---
|
||||||
- прерываться перед каждым использованием внешнего инструмента (пауза `interrupt_before=['tools']`);
|
|
||||||
- запрашивать у пользователя подтверждение, прежде чем выполнять инструмент.
|
|
||||||
|
|
||||||
## Структура проекта
|
|
||||||
|
|
||||||
```
|
|
||||||
.
|
|
||||||
├── solution.py # основной скрипт с реализацией агента
|
|
||||||
└── README.md # это файл
|
|
||||||
```
|
|
||||||
|
|
||||||
## Установка зависимостей
|
## Установка зависимостей
|
||||||
|
|
||||||
@@ -25,83 +17,84 @@ python -m venv .venv
|
|||||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||||
|
|
||||||
# Установите все необходимые пакеты
|
# Установите все необходимые пакеты
|
||||||
pip install langgraph langchain openai rich
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Важно** – для работы с OpenAI нужен ключ API.
|
`requirements.txt` содержит:
|
||||||
> Если переменная окружения `OPENAI_API_KEY` не задана, скрипт автоматически создаст «заглушку» LLM, которая возвращает фиктивный ответ.
|
|
||||||
|
|
||||||
## Как запустить
|
```text
|
||||||
|
langchain-openai>=0.2.0
|
||||||
```bash
|
langgraph>=0.1.0
|
||||||
python solution.py
|
rich>=13.0.0
|
||||||
|
python-dotenv # для удобного управления переменными окружения (необязательно)
|
||||||
```
|
```
|
||||||
|
|
||||||
После запуска бот будет ждать ввода пользователя в консоли.
|
> **Важно**: Установите ключ OpenAI в переменной окружения `OPENAI_API_KEY`.
|
||||||
Пример взаимодействия:
|
> Можно создать файл `.env` с содержимым:
|
||||||
|
> ```dotenv
|
||||||
```
|
> OPENAI_API_KEY=sk-...
|
||||||
User: Привет!
|
> ```
|
||||||
Bot: Здравствуйте! Чем могу помочь?
|
|
||||||
User: Сколько стоит 1 кг яблок?
|
|
||||||
Bot (пауза): Вы хотите вызвать инструмент "price_lookup" с аргументами {"item": "яблоки", "quantity_kg": 1}?
|
|
||||||
(Введите `yes` или `no`)
|
|
||||||
User: yes
|
|
||||||
Bot: Цена за 1 кг яблок составляет $3.50.
|
|
||||||
```
|
|
||||||
|
|
||||||
> В реальном запуске бот будет использовать OpenAI GPT‑4o (или другой выбранный LLM) и ваш собственный инструмент, который вы можете добавить в список `tools`.
|
|
||||||
|
|
||||||
## Пример использования
|
|
||||||
|
|
||||||
```python
|
|
||||||
from langgraph.prebuilt import create_agent
|
|
||||||
from langchain.tools import BaseTool
|
|
||||||
from langgraph.checkpoint.memory import MemorySaver
|
|
||||||
from rich.console import Console
|
|
||||||
|
|
||||||
# 1. Создаём LLM (или заглушку)
|
|
||||||
llm = ChatOpenAI(temperature=0)
|
|
||||||
|
|
||||||
# 2. Определяем инструмент
|
|
||||||
class EchoTool(BaseTool):
|
|
||||||
name: str = "echo"
|
|
||||||
description: str = "Возвращает переданный текст."
|
|
||||||
def _run(self, text: str) -> str:
|
|
||||||
return f"Echo: {text}"
|
|
||||||
|
|
||||||
tools = [EchoTool()]
|
|
||||||
|
|
||||||
# 3. Создаём память
|
|
||||||
memory = MemorySaver()
|
|
||||||
|
|
||||||
# 4. Конфигурируем агента с паузой и подтверждением
|
|
||||||
agent = create_agent(
|
|
||||||
model=llm,
|
|
||||||
tools=tools,
|
|
||||||
system_prompt="You are a helpful assistant.",
|
|
||||||
checkpointer=memory, # нужна для памяти и паузы
|
|
||||||
interrupt_before=['tools'], # остановка перед каждым вызовом инструмента
|
|
||||||
)
|
|
||||||
|
|
||||||
# 5. Запускаем диалог
|
|
||||||
console = Console()
|
|
||||||
config = {"configurable": {"thread_id": "demo-thread"}}
|
|
||||||
|
|
||||||
for chunk in agent.stream(
|
|
||||||
{"messages": [{"role": "user", "content": "Привет!"}]},
|
|
||||||
config=config,
|
|
||||||
):
|
|
||||||
console.print(chunk)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Что дальше
|
|
||||||
|
|
||||||
- Добавьте собственные инструменты (например, поиск в интернете, работа с базой данных и т.д.).
|
|
||||||
- Настройте более сложный `system_prompt` для конкретных задач.
|
|
||||||
- Используйте разные `thread_id`, чтобы вести несколько независимых разговоров одновременно.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Автор:** *Ваша команда*
|
## Запуск
|
||||||
**Дата:** 27 мая 2026 г.
|
|
||||||
|
### 1. Основной скрипт (`solution.py`)
|
||||||
|
```bash
|
||||||
|
python solution.py
|
||||||
|
```
|
||||||
|
Скрипт запускает интерактивный чат‑бот, который:
|
||||||
|
|
||||||
|
1. Принимает ввод пользователя.
|
||||||
|
2. Пауза перед каждым вызовом инструмента `search`.
|
||||||
|
3. Показывает пользователю сообщение о предстоящем действии и ожидает подтверждения (`y`/`n`).
|
||||||
|
4. Если пользователь подтверждает – инструмент вызывается; иначе действие отменяется.
|
||||||
|
|
||||||
|
### 2. Тестовый скрипт (если есть)
|
||||||
|
Если в проекте присутствует файл `test_solution.py`, его можно запустить так:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pytest test_solution.py
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Пример использования
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ python solution.py
|
||||||
|
🤖: Здравствуйте! Чем могу помочь?
|
||||||
|
🧑: Какую погоду будет завтра в Москве?
|
||||||
|
|
||||||
|
🤖: Я собираюсь выполнить поиск по запросу "погода завтра Москва". Продолжить? (y/n) y
|
||||||
|
🔍 Выполняю инструмент search...
|
||||||
|
Результаты поиска по запросу 'погода завтра Москва': ...
|
||||||
|
|
||||||
|
🤖: Похоже, завтра в Москве будет облачно с небольшой вероятностью осадков. Есть ли ещё что‑то, чем могу помочь?
|
||||||
|
```
|
||||||
|
|
||||||
|
Если пользователь вводит `n`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
🤖: Я собираюсь выполнить поиск по запросу "погода завтра Москва". Продолжить? (y/n) n
|
||||||
|
🤖: Операция отменена. Чем ещё могу помочь?
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Как это работает
|
||||||
|
|
||||||
|
1. **MemorySaver** сохраняет состояние разговора, позволяя агенту помнить предыдущие сообщения.
|
||||||
|
2. `interrupt_before=['tools']` заставляет агент остановиться перед каждым вызовом инструмента.
|
||||||
|
3. Внутри цикла обработки сообщений пользователь получает запрос на подтверждение и вводит `y`/`n`.
|
||||||
|
4. После подтверждения инструмент вызывается через LangGraph, а результат возвращается в поток.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что можно улучшить
|
||||||
|
|
||||||
|
- Добавить более сложные инструменты (например, API погоды).
|
||||||
|
- Реализовать хранение истории в базе данных вместо памяти в RAM.
|
||||||
|
- Поддержать несколько параллельных разговоров с разными `thread_id`.
|
||||||
|
|
||||||
|
---
|
||||||
Reference in New Issue
Block a user