Human-in-the-Loop через middleware: README.md

This commit is contained in:
2026-05-28 05:48:01 +00:00
parent 1a6ccc4678
commit 6f46f73dcd
@@ -1,140 +1,86 @@
# HumanintheLoop Agent via Middleware (LangGraph)
# HumanintheLoop Agent with LangGraph
This repository contains a minimal example of a **HumanintheLoop** agent built on top of LangGraph.
The agent pauses whenever it needs to call an external tool, prints the tool request and waits for a user decision (`approve` or `reject`). After the decision is supplied, execution resumes automatically.
This repository contains a minimal example of a **HumanintheLoop** (HITL) agent built on top of [LangGraph](https://github.com/langchain-ai/langgraph).
The agent pauses whenever it needs to call an external tool, presents the tool output to the user and waits for a decision (`approve` or `reject`). After the decision is made the conversation continues automatically.
> ⚠️ The example uses OpenAIs API (or any compatible LLM). Make sure you have an API key set in the environment variable `OPENAI_API_KEY`.
> **⚠️ Prerequisites** The example uses OpenAIcompatible APIs.
> Make sure you have an API key set in the environment variable `OPENAI_API_KEY`.
---
## Table of Contents
- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Running the Agent](#running-the-agent)
- [Interactive Demo (`solution.py`)](#interactive-demo-solutionpy)
- [Unit Tests (`tests/test_solution.py`)](#unit-tests-test_solutionpy)
- [Example Usage](#example-usage)
- [License](#license)
---
## Features
| Feature | Description |
|---------|-------------|
| **HumanintheLoop** | Agent stops before calling any tool, prints the request and waits for user input. |
| **Interrupts via `interrupt_before=["tools"]`** | Configurable interruption point in LangGraph. |
| **Tool Example** | Simple `get_weather(city, date)` function that returns a mock weather string. |
| **Checkpointing** | Uses an inmemory checkpoint (`MemorySaver`) to preserve state across interruptions. |
---
## Prerequisites
- Python 3.10+
- An OpenAI API key (or any compatible LLM endpoint)
## 📦 Installation
```bash
export OPENAI_API_KEY="sk-..."
```
# 1️⃣ Clone the repo (or copy solution.py into a new folder)
git clone https://github.com/your-username/hitl-langgraph.git
cd hitl-langgraph
---
## Installation
1. **Clone the repository**
```bash
git clone https://github.com/yourusername/human-in-loop-langgraph.git
cd human-in-loop-langgraph
```
2. **Create a virtual environment (optional but recommended)**
```bash
# 2️⃣ Create and activate a virtual environment (optional but recommended)
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
source .venv/bin/activate # Windows: .\.venv\Scripts\activate
# 3️⃣ Install dependencies
pip install --upgrade pip
pip install langchain-openai langgraph langchain-tools
```
3. **Install dependencies**
```bash
pip install -r requirements.txt
```
*If you dont have a `requirements.txt`, create one with the following content:*
```text
langchain-openai>=0.2.0
langgraph>=0.1.0
```
> **Tip** If you want to use a different LLM (e.g., Anthropic, Gemini), replace the `ChatOpenAI` import with the appropriate wrapper and adjust the model name.
---
## Running the Agent
## 🚀 Running the Agent
### Interactive Demo (`solution.py`)
The main script demonstrates how to start the agent and handle interruptions.
The main logic is in `solution.py`.
Run it directly:
```bash
python solution.py
```
**What happens:**
### What Happens?
1. The user enters a prompt (e.g., “Whats the weather in Paris on 20241201?”).
2. The agent processes the request, decides it needs to call `get_weather`, and pauses.
3. The tool request is printed:
```
Tool requested: get_weather
Arguments: {'city': 'Paris', 'date': '2024-12-01'}
```
4. You are prompted to type `approve` or `reject`.
5. After your decision, the agent resumes and prints the final answer.
1. The agent starts a conversation.
2. When it decides to call the `get_weather` tool, the execution pauses.
3. The tool output (e.g., `"Погода в Москва на 2024-05-28: солнечно 25°C."`) is printed to the console.
4. You are prompted to type **approve** or **reject**:
- `approve`: the agent resumes with the tool result as normal input.
- `reject`: the agent receives a `ToolMessage` indicating rejection and can decide what to do next.
---
### Unit Tests (`tests/test_solution.py`)
## 🔧 Example Interaction
Run the test suite to verify that the interruption logic works as expected:
```bash
pytest tests/test_solution.py
```text
$ python solution.py
Agent: Какую погоду вы хотите узнать?
User: Москва на 2024-05-28
Agent (calling tool): get_weather(city='Москва', date='2024-05-28')
Tool output: Погода в Москва на 2024-05-28: солнечно 25°C.
Please type 'approve' or 'reject': approve
Agent: Спасибо! Как ещё могу помочь?
```
The tests simulate a user approving the tool call automatically and check that the final output contains the weather string.
If you type `reject`, the agent will receive a rejection message and can, for example, ask for clarification.
---
## Example Usage
## 📁 Project Structure
Below is a quick snippet you can paste into a Python REPL or another script to see the agent in action:
```python
from solution import agent, memory # assuming solution.py defines them
# Start a new thread/session
config = {"configurable": {"thread_id": "demo-session"}}
# Invoke with a user message
response = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in Tokyo on 2025-01-15?"}]},
config=config,
)
print("\nFinal response:")
print(response["messages"][-1]["content"])
```
When you run this, youll see the same interruption prompt as described above.
| File | Purpose |
|------|---------|
| `solution.py` | Full implementation of the HITL agent. |
| `README.md` | This documentation file. |
---
## License
## 🛠️ Customization
MIT © 2026. Feel free to fork and adapt for your own projects.
- **Add more tools** Decorate any function with `@tool` and add it to the `tools=[...]` list.
- **Change prompt** Edit `system_prompt` in `create_react_agent`.
- **Persist memory** Replace `MemorySaver()` with a filebased or database checkpoint if you need persistence across runs.
---
## 📜 License
MIT © 2026. Feel free to fork and adapt for your own projects!