Human-in-the-Loop через middleware: README.md
This commit is contained in:
@@ -1,109 +1,139 @@
|
|||||||
# Human‑in‑the‑Loop через Middleware
|
# Human‑in‑the‑Loop Agent via Middleware
|
||||||
|
|
||||||
Пример реализации агента на LangGraph с встроенным `HumanInTheLoopMiddleware`.
|
This repository contains a minimal example of an LLM agent that pauses whenever it wants to call a tool and asks the user for approval before proceeding.
|
||||||
При каждом вызове инструмента агент останавливается и выводит в терминал запрос
|
The core idea is to use **`HumanInTheLoopMiddleware`** from LangChain, which intercepts every tool invocation, prints a prompt with the action details, and waits for the user to respond (`approve`, `reject`, or optionally edit the request).
|
||||||
на подтверждение (`approve` / `reject`). После ответа пользователь может
|
|
||||||
продолжить выполнение, а агент продолжит работу.
|
> **Why this matters** – In many real‑world scenarios you want an LLM to ask for human confirmation before performing potentially sensitive actions (e.g., sending emails, accessing databases, calling external APIs).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📦 Установка зависимостей
|
## Table of Contents
|
||||||
|
|
||||||
```bash
|
- [Project Structure](#project-structure)
|
||||||
# Создайте виртуальное окружение (рекомендуется)
|
- [Installation](#installation)
|
||||||
python -m venv .venv
|
- [Running the Agent](#running-the-agent)
|
||||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
- [Interactive Mode](#interactive-mode)
|
||||||
|
- [Scripted Example](#scripted-example)
|
||||||
|
- [Example Usage](#example-usage)
|
||||||
|
- [Extending the Agent](#extending-the-agent)
|
||||||
|
|
||||||
# Установите необходимые пакеты
|
---
|
||||||
pip install langgraph langchain-core langchain-openai openai tqdm
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
├── solution.py # Main script with the agent implementation
|
||||||
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Важно**
|
`solution.py` contains:
|
||||||
> Для работы с OpenAI API понадобится переменная окружения `OPENAI_API_KEY`.
|
|
||||||
> ```bash
|
1. **LLM configuration** – uses `ChatOpenAI`.
|
||||||
> export OPENAI_API_KEY="sk-..."
|
2. **A simple tool** (`get_weather`) that returns a fake weather string.
|
||||||
> ```
|
3. **Memory checkpoint** via `MemorySaver`.
|
||||||
|
4. **Agent creation** with `create_react_agent` and the middleware.
|
||||||
|
5. **Execution loop** that keeps asking for user input until the conversation ends.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📁 Структура проекта
|
## Installation
|
||||||
|
|
||||||
```text
|
1. **Clone the repo**
|
||||||
.
|
|
||||||
├── solution.py # Основной скрипт, реализующий агент
|
```bash
|
||||||
└── README.md # Текущий файл
|
git clone https://github.com/your-username/human-in-the-loop-agent.git
|
||||||
```
|
cd human-in-the-loop-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Create a virtual environment (optional but recommended)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m venv .venv
|
||||||
|
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Install dependencies**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install langchain langgraph openai
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Set your OpenAI API key**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export OPENAI_API_KEY="sk-..."
|
||||||
|
# Windows: setx OPENAI_API_KEY "sk-..."
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ▶️ Запуск
|
## Running the Agent
|
||||||
|
|
||||||
### 1. Запустите скрипт из командной строки
|
### Interactive Mode
|
||||||
|
|
||||||
|
Simply run the script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python solution.py
|
python solution.py
|
||||||
```
|
```
|
||||||
|
|
||||||
> Скрипт автоматически создаст агента, подключит middleware и начнет диалог с пользователем.
|
You will see a prompt like:
|
||||||
|
|
||||||
### 2. Взаимодействие в терминале
|
|
||||||
|
|
||||||
После каждого вызова инструмента вы увидите сообщение вида:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
⚠️ Инструмент: get_weather
|
Agent wants to call tool `get_weather` with arguments:
|
||||||
Запрос: "Какая погода в Москве на 2024‑06‑01?"
|
city = "Moscow"
|
||||||
Нужно подтвердить действие (approve/reject):
|
date = "2025-10-01"
|
||||||
|
|
||||||
|
Please type one of: approve / reject (or edit <new_args>)
|
||||||
|
>
|
||||||
```
|
```
|
||||||
|
|
||||||
- Введите `approve` – инструмент будет выполнен и результат вернётся агенту.
|
Type **`approve`** to let the agent proceed, or **`reject`** to stop it.
|
||||||
- Введите `reject` – вызов инструмента отменяется, агент продолжит работу без него.
|
If you want to modify the arguments before approval, use `edit city=London date=2025-12-25`.
|
||||||
|
|
||||||
|
The conversation continues until the user types `stop` or the agent finishes its plan.
|
||||||
|
|
||||||
|
### Scripted Example
|
||||||
|
|
||||||
|
You can also run a quick demo that automatically approves all calls:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python - <<'PY'
|
||||||
|
from solution import agent, llm, memory
|
||||||
|
# Override middleware to auto‑approve for demonstration
|
||||||
|
agent.middleware[0].interrupt_on = {"get_weather": False}
|
||||||
|
print(agent.run("What's the weather in New York tomorrow?"))
|
||||||
|
PY
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📄 Пример использования
|
## Example Usage
|
||||||
|
|
||||||
```python
|
```bash
|
||||||
from langgraph.prebuilt import create_react_agent
|
$ python solution.py
|
||||||
from langchain.tools import tool
|
User: What's the weather in Paris next Friday?
|
||||||
from langgraph.checkpoint.memory import MemorySaver
|
Agent wants to call tool `get_weather` with arguments:
|
||||||
from langgraph.types import Command
|
city = "Paris"
|
||||||
from langgraph.moderation import HumanInTheLoopMiddleware
|
date = "2025-10-06"
|
||||||
|
|
||||||
# 1. Определяем инструмент
|
Please type one of: approve / reject (or edit <new_args>)
|
||||||
@tool
|
> approve
|
||||||
def get_weather(city: str, date: str) -> str:
|
|
||||||
"""Возвращает погоду в городе на указанную дату."""
|
|
||||||
return f"Погода в {city} на {date}: солнечно 25°C."
|
|
||||||
|
|
||||||
# 2. Создаём агент с middleware
|
Assistant: Погода в Париже на 2025‑10‑06: солнечно 25°C.
|
||||||
memory = MemorySaver()
|
User: Thank you!
|
||||||
agent = create_react_agent(
|
|
||||||
tools=[get_weather],
|
|
||||||
memory=memory,
|
|
||||||
middleware=[HumanInTheLoopMiddleware()],
|
|
||||||
)
|
|
||||||
|
|
||||||
# 3. Запускаем диалог
|
|
||||||
config = {"thread_id": "session-1"}
|
|
||||||
state = agent.invoke({"messages": [{"role": "user", "content": "Какая погода в Москве на 2024‑06‑01?"}]}, config=config)
|
|
||||||
print(state["messages"][-1]["content"])
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> После запуска вы увидите запрос подтверждения и сможете взаимодействовать с агентом, как описано выше.
|
---
|
||||||
|
|
||||||
|
## Extending the Agent
|
||||||
|
|
||||||
|
1. **Add more tools** – decorate any function with `@tool` and add it to the `tools` list in `create_react_agent`.
|
||||||
|
2. **Change the interrupt policy** – modify `interrupt_on` dict (e.g., `{ "get_weather": True, "send_email": False }`).
|
||||||
|
3. **Persist conversation state** – replace `MemorySaver()` with a database checkpoint if you need long‑term memory.
|
||||||
|
4. **Custom prompts** – tweak `system_prompt` or add a custom `description_prefix`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📚 Полезные ссылки
|
Happy hacking! 🚀
|
||||||
|
|
||||||
- [Документация LangChain – Human‑in‑the‑Loop](https://docs.langchain.com/oss/python/langchain/human-in-the-loop)
|
|
||||||
- [LangGraph GitHub репозиторий](https://github.com/run-llama/langgraph)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🤝 Вклад
|
|
||||||
|
|
||||||
Если вы нашли ошибки или хотите добавить новые инструменты, создайте pull request.
|
|
||||||
Пожалуйста, придерживайтесь стиля кода из `solution.py` и добавляйте комментарии.
|
|
||||||
|
|
||||||
---```
|
|
||||||
Reference in New Issue
Block a user