From c727e0ba55775a857964bfba027d2d0b68aab85e 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 10:34:11 +0000 Subject: [PATCH] =?UTF-8?q?Human-in-the-Loop=20=D1=87=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B7=20middleware:=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md | 199 ++++++++++-------- 1 file changed, 113 insertions(+), 86 deletions(-) diff --git a/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md b/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md index 6d139cb..cbc45b6 100644 --- a/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md +++ b/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md @@ -1,96 +1,123 @@ -# Human‑in‑the‑Loop via Middleware +# Human‑in‑the‑Loop через Middleware -## 📖 Описание -В этом проекте реализован агент на базе LangChain, который при каждом вызове инструмента останавливается и запрашивает подтверждение пользователя. -* **HumanInTheLoopMiddleware** автоматически формирует запрос к пользователю (в терминале) с описанием того, что планирует сделать агент. -* Пользователь вводит одно из решений: `approve`, `reject` или `edit`. После этого выполнение возобновляется через команду `Command(resume={"decisions": [...]})`. +## Описание проекта +В этом проекте реализован агент на базе LangChain, который использует **HumanInTheLoopMiddleware** для ручного подтверждения вызовов инструментов. Каждый раз, когда агент планирует использовать инструмент (например, `get_weather`), он останавливается и выводит в терминал сообщение с просьбой подтвердить действие. Пользователь вводит одно из решений (`approve`, `reject` или `edit`) и только после этого выполнение возобновляется. -Таким образом, пользователь всегда контролирует действия агента и может корректировать их в реальном времени. +> **Преимущество**: Middleware сам формирует запрос на подтверждение, обрабатывает ответ и управляет переходом к следующему шагу через `Command(resume={…})`. Это упрощает интеграцию Human‑in‑the‑Loop по сравнению с ручным использованием `interrupt_before=['tools']`. -## 📦 Установка зависимостей -```bash -# Создайте виртуальное окружение (рекомендовано) -python -m venv .venv -source .venv/bin/activate # Windows: .venv\Scripts\activate - -# Установите зависимости из requirements.txt -pip install -r requirements.txt +## Структура проекта ``` - -`requirements.txt` -```txt -langchain==0.2.* -langgraph==0.1.* -openai==1.* -python-dotenv==1.* +├── solution.py # Основной скрипт, реализующий агента +└── README.md # Текущий файл ``` -> **Важно**: -> * `checkpointer=MemorySaver()` нужен для сохранения состояния паузы, иначе агент не сможет возобновиться после подтверждения. -> * Убедитесь, что переменная окружения `OPENAI_API_KEY` установлена (или используйте `.env` файл). - -## 🚀 Запуск файлов - -| Файл | Что делает | Как запустить | -|------|------------|---------------| -| `agent.py` | Создаёт агента с middleware и инструментом `get_weather`. | `python agent.py` | -| `run_agent.py` | Демонстрирует взаимодействие: задаётся вопрос, агент вызывает инструмент, пользователь подтверждает. | `python run_agent.py` | - -### Пример запуска -```bash -# 1️⃣ Запустите агента -python agent.py - -# 2️⃣ В другом терминале запустите сценарий взаимодействия -python run_agent.py -``` - -## 🧪 Пример использования - -```python -from langchain.agents import create_agent -from langgraph.checkpoint.memory import MemorySaver -from langchain.agents.middleware import HumanInTheLoopMiddleware - -# Инициализация памяти для сохранения состояния паузы -memory = MemorySaver() - -agent = create_agent( - model=llm, - tools=[get_weather], - system_prompt="Ты полезный ассистент", - middleware=[ - HumanInTheLoopMiddleware( - interrupt_on={ - "get_weather": True, # разрешаем все решения: approve, edit, reject - }, - description_prefix="Подтвердите вызов инструмента", - ), - ], - checkpointer=memory, -) - -# Запрос к агенту -response = agent.run("Какая погода в Москве?") -print(response) -``` - -При выполнении агента вы увидите в терминале запрос вида: - -``` -[HumanInTheLoop] Подтвердите вызов инструмента: -Agent wants to call tool 'get_weather' with arguments: {"location": "Moscow"} -Enter decision (approve/reject/edit): -``` - -Введите `approve`, и агент продолжит работу, возвращая результат. -Если ввести `reject` – запрос будет отменён, а если `edit` – можно изменить аргументы перед повторным вызовом. - --- -## 📚 Дополнительные ресурсы +## Установка зависимостей -* [Документация Human‑in‑the‑Loop — LangChain](https://docs.langchain.com/oss/python/langchain/human-in-the-loop) -* [LangGraph Checkpointing](https://langgraph.org/docs/checkpoints) +```bash +# Создайте виртуальное окружение (рекомендуется) +python -m venv .venv +source .venv/bin/activate # Windows: .venv\Scripts\activate ---- \ No newline at end of file +# Установите необходимые библиотеки +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 \ No newline at end of file