Практическое задание №3: Память и подтверждение действий: README.md
This commit is contained in:
+75
-74
@@ -3,121 +3,122 @@
|
|||||||
## Описание проекта
|
## Описание проекта
|
||||||
В этом задании вы доработаете агента из предыдущих практических работ, добавив:
|
В этом задании вы доработаете агента из предыдущих практических работ, добавив:
|
||||||
- **Память разговора** – агент будет помнить все сообщения в рамках одного диалога.
|
- **Память разговора** – агент будет помнить все сообщения в рамках одного диалога.
|
||||||
- **Механизм подтверждения** – перед выполнением любого инструмента пользователь получает запрос на подтверждение.
|
- **Механизм подтверждения** перед вызовом любого инструмента – пользователь сможет согласовать действие.
|
||||||
|
|
||||||
Для красивого вывода в консоли используется библиотека `rich`.
|
Для более приятного вывода используется библиотека `rich`.
|
||||||
|
|
||||||
## Структура проекта
|
## Структура проекта
|
||||||
```
|
```
|
||||||
project/
|
project/
|
||||||
├── agent.py # Основной скрипт с реализацией агента
|
├── solution.py # Основной скрипт с реализацией агента
|
||||||
├── tools.py # Пользовательские инструменты
|
└── README.md # Это файл
|
||||||
└── README.md # Это файл
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Установка зависимостей
|
## Установка зависимостей
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Создайте виртуальное окружение (необязательно, но рекомендуется)
|
# Создайте виртуальное окружение (рекомендуется)
|
||||||
python -m venv .venv
|
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` нужен только для вывода, но без него скрипт будет работать.
|
> **Важно**
|
||||||
|
> `langgraph` и `langchain-openai` автоматически подтянут нужные версии OpenAI SDK.
|
||||||
## Как запустить каждый файл
|
> Если у вас нет ключа API, создайте переменную окружения `OPENAI_API_KEY`.
|
||||||
|
|
||||||
### 1. `tools.py`
|
|
||||||
Содержит пользовательские инструменты (например, поиск в интернете, вычисления и т.д.).
|
|
||||||
Запуск не требуется отдельно – он импортируется в `agent.py`.
|
|
||||||
|
|
||||||
### 2. `agent.py`
|
|
||||||
Главный скрипт, который запускает агента.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python agent.py
|
export OPENAI_API_KEY="sk-..."
|
||||||
```
|
```
|
||||||
|
|
||||||
При запуске вы увидите интерактивную сессию:
|
---
|
||||||
|
|
||||||
1. Введите сообщение.
|
## Запуск скрипта
|
||||||
2. Агент сформулирует запрос к инструменту и попросит подтвердить действие.
|
|
||||||
3. После подтверждения (`yes`/`no`) агент выполнит инструмент или отменит его.
|
|
||||||
|
|
||||||
### 3. Пример запуска в режиме потоковой печати
|
### 1️⃣ Запустите файл напрямую
|
||||||
|
|
||||||
```bash
|
```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
|
```python
|
||||||
# Внутри agent.py (или в интерактивной сессии)
|
|
||||||
from langgraph.checkpoint.memory import MemorySaver
|
|
||||||
from rich.console import Console
|
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()
|
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()
|
memory = MemorySaver()
|
||||||
agent = create_agent(
|
agent = create_chat_agent(
|
||||||
model=llm,
|
llm=llm,
|
||||||
tools=[my_tool],
|
tools=[echo_tool],
|
||||||
system_prompt="You are a helpful assistant.",
|
system_prompt="Ты — полезный ассистент, который сначала спрашивает подтверждение перед вызовом инструмента.",
|
||||||
checkpointer=memory,
|
checkpointer=memory,
|
||||||
interrupt_before=['tools'] # пауза перед каждым инструментом
|
interrupt_before=['tools'], # остановка перед каждым инструментом
|
||||||
)
|
)
|
||||||
|
|
||||||
# Конфигурация диалога (thread_id)
|
# 5. Запускаем диалог
|
||||||
config = {"configurable": {"thread_id": "conversation-1"}}
|
config = {"configurable": {"thread_id": "разговор-1"}}
|
||||||
|
for chunk in agent.stream({"messages": [HumanMessage(content="Напиши мне список покупок")]}, config=config):
|
||||||
# Запуск агента с потоковым выводом
|
console.print(chunk)
|
||||||
for chunk in agent.stream({"messages": [{"role":"user","content":"Расскажи о Python"}]}, config=config):
|
|
||||||
console.print(chunk, end="")
|
|
||||||
|
|
||||||
# После завершения можно продолжить диалог в том же thread_id
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Что происходит при запуске
|
---
|
||||||
|
|
||||||
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
|
|
||||||
Reference in New Issue
Block a user