123 lines
5.3 KiB
Markdown
123 lines
5.3 KiB
Markdown
# Human‑in‑the‑Loop через Middleware
|
||
|
||
## Описание проекта
|
||
В этом проекте реализован агент на базе LangChain, который использует **HumanInTheLoopMiddleware** для ручного подтверждения вызовов инструментов. Каждый раз, когда агент планирует использовать инструмент (например, `get_weather`), он останавливается и выводит в терминал сообщение с просьбой подтвердить действие. Пользователь вводит одно из решений (`approve`, `reject` или `edit`) и только после этого выполнение возобновляется.
|
||
|
||
> **Преимущество**: Middleware сам формирует запрос на подтверждение, обрабатывает ответ и управляет переходом к следующему шагу через `Command(resume={…})`. Это упрощает интеграцию Human‑in‑the‑Loop по сравнению с ручным использованием `interrupt_before=['tools']`.
|
||
|
||
## Структура проекта
|
||
```
|
||
├── solution.py # Основной скрипт, реализующий агента
|
||
└── README.md # Текущий файл
|
||
```
|
||
|
||
---
|
||
|
||
## Установка зависимостей
|
||
|
||
```bash
|
||
# Создайте виртуальное окружение (рекомендуется)
|
||
python -m venv .venv
|
||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||
|
||
# Установите необходимые библиотеки
|
||
pip install langchain langgraph langchain-community openai
|
||
```
|
||
|
||
> **Важно**
|
||
> * Если у вас нет ключа OpenAI, замените `OpenAI` на любой другой LLM (например, `DummyLLM`, который возвращает фиксированный ответ).
|
||
> * Для работы с `HumanInTheLoopMiddleware` требуется версия LangChain ≥ 0.2 и LangGraph ≥ 0.1.
|
||
|
||
---
|
||
|
||
## Запуск проекта
|
||
|
||
```bash
|
||
python solution.py
|
||
```
|
||
|
||
### Что происходит при запуске?
|
||
|
||
1. Инициализируется LLM (по умолчанию OpenAI).
|
||
2. Создаётся инструмент `get_weather`.
|
||
3. Агент создаётся с Middleware, который перехватывает вызовы инструмента и запрашивает подтверждение у пользователя.
|
||
4. В терминале выводятся сообщения вида:
|
||
|
||
```
|
||
[HumanInTheLoop] Подтвердите вызов инструмента:
|
||
- get_weather
|
||
Введите решение (approve/reject/edit):
|
||
```
|
||
|
||
5. После ввода решения агент продолжает работу.
|
||
|
||
---
|
||
|
||
## Пример использования
|
||
|
||
```bash
|
||
$ python solution.py
|
||
> Какую погоду в Москве сегодня?
|
||
|
||
[HumanInTheLoop] Подтвердите вызов инструмента:
|
||
- get_weather
|
||
Введите решение (approve/reject/edit): approve
|
||
|
||
Ответ агента: Сегодня в Москве солнечно, температура 22°C.
|
||
```
|
||
|
||
Если пользователь введёт `reject`, агент отменит вызов и попытается найти другой способ ответа. В случае `edit` можно изменить параметры запроса к инструменту.
|
||
|
||
---
|
||
|
||
## Как добавить собственный инструмент
|
||
|
||
1. Определите функцию‑инструмент:
|
||
|
||
```python
|
||
def get_time(location: str) -> str:
|
||
# Возвращает текущее время в указанном месте
|
||
```
|
||
|
||
2. Добавьте её в список `tools` при создании агента и настройте Middleware:
|
||
|
||
```python
|
||
agent = create_agent(
|
||
model=llm,
|
||
tools=[get_weather, get_time],
|
||
middleware=[
|
||
HumanInTheLoopMiddleware(
|
||
interrupt_on={"get_time": True},
|
||
description_prefix="Подтвердите вызов инструмента",
|
||
),
|
||
],
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## Тестирование
|
||
|
||
Для быстрой проверки можно использовать `DummyLLM`, который всегда возвращает один и тот же ответ. Это удобно, если у вас нет доступа к OpenAI.
|
||
|
||
```python
|
||
class DummyLLM:
|
||
def __call__(self, *args, **kwargs):
|
||
return "dummy response"
|
||
```
|
||
|
||
---
|
||
|
||
## FAQ
|
||
|
||
| Вопрос | Ответ |
|
||
|--------|-------|
|
||
| Как отключить Human‑in‑the‑Loop? | Удалите Middleware из списка `middleware` при создании агента. |
|
||
| Можно ли задать только `approve` и `reject`, без `edit`? | Да, передайте в `interrupt_on`: `{"get_weather": {"allowed_decisions": ["approve", "reject"]}}`. |
|
||
| Что делать, если агент не сохраняет состояние после паузы? | Убедитесь, что вы передали `checkpointer=MemorySaver()` при создании агента. |
|
||
|
||
---
|
||
|
||
## Лицензия
|
||
|
||
MIT © 2026 |