From 4b56939f0f8988f15896dccc1417f36a10bd39e0 Mon Sep 17 00:00:00 2001 From: lonpatovaadelina Date: Wed, 27 May 2026 12:05:05 +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 | 187 +++++++----------- 1 file changed, 75 insertions(+), 112 deletions(-) diff --git a/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md b/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md index 7efe35c..71e74d9 100644 --- a/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md +++ b/solutions/69a86305c46fd26feae6bcaa_Human-in-the-Loop_через_middleware/README.md @@ -1,51 +1,53 @@ -# Human‑in‑the‑Loop Middleware +# Human‑in‑the‑Loop Middleware Demo -Human‑in‑the‑Loop (HITL) middleware is a lightweight Python framework that lets you build conversational agents on top of **Qdrant** vector store and **Ollama** LLMs. -The project demonstrates how to: +A minimal Python project that demonstrates how to add a **Human‑in‑the‑Loop (HITL)** experience to a LangChain agent using the built‑in `HumanInTheLoopMiddleware`. +When the agent is about to invoke an external tool, it pauses and asks for user approval (`approve` or `reject`) before continuing. -* Store and retrieve documents with Qdrant. -* Embed text using the `nomic-embed-text` model from Ollama. -* Generate responses with the `llama3` chat model via LangChain. -* Wrap everything in a simple HTTP client that can be used by external services or UI front‑ends. - -The core logic lives in two files: - -| File | Purpose | -|------|---------| -| **agent.py** | Implements the LangChain pipeline: embedding → vector search → LLM generation. | -| **client.py** | Exposes a minimal FastAPI server that accepts user queries and returns responses from `agent.py`. | +> **Why use middleware?** +> Unlike the older `interrupt_before=['tools']` approach, the middleware automatically builds the confirmation prompt, handles the response, and resumes execution via a `Command(resume={…})`. This keeps your agent logic clean and declarative. --- -## 📦 Prerequisites +## 📦 Project Structure + +``` +├── agent.py # Agent definition + HITL middleware +├── client.py # Simple CLI that runs the agent +├── requirements.txt +└── README.md +``` + +- `agent.py` – creates a LangChain agent with a single tool (`get_weather`) and attaches the HITL middleware. +- `client.py` – launches the agent in an interactive loop. + +--- + +## ⚙️ Prerequisites | Component | Minimum Version | Notes | |-----------|-----------------|-------| -| Python | 3.10+ | Tested on 3.12 | -| pip | – | Use the system package manager or `pipx` | -| **Ollama** | Latest | Install from https://ollama.ai/ | -| **Qdrant** | 1.7+ | Run locally (`docker run -p 6333:6333 qdrant/qdrant`) or use a managed instance | +| Python | 3.11+ | Tested on 3.12 | +| Ollama | latest | Local LLM (e.g., `llama3`) | +| LangChain | 0.2.x or newer | Provides agents & middleware | +| LangGraph | 0.1.x or newer | For checkpointing (optional) | -> **Important:** -> * The Ollama image must expose the `llama3` and `nomic-embed-text` models. -> ```bash -> ollama pull llama3 -> ollama pull nomic-embed-text -> ``` -> * Qdrant should be reachable at `http://localhost:6333` (or set via the `QDRANT_URL` env var). +> **Ollama** must be running locally and the model (`llama3` in this repo) should be pulled beforehand: +> ```bash +> ollama pull llama3 +> ``` --- -## ⚙️ Installation +## 📦 Installation ```bash -# Clone the repo -git clone https://github.com/your-org/hitl-middleware.git -cd hitl-middleware +# Clone the repository +git clone https://github.com/your-username/hitl-middleware-demo.git +cd hitl-middleware-demo -# Create a virtual environment (optional but recommended) +# Create a virtual environment (recommended) python -m venv .venv -source .venv/bin/activate # Windows: .venv\Scripts\activate +source .venv/bin/activate # On Windows: .venv\Scripts\activate # Install dependencies pip install -r requirements.txt @@ -55,115 +57,76 @@ pip install -r requirements.txt ```text langchain==0.2.* -langchain-ollama==0.1.* -langchain-qdrant==0.1.* -fastapi==0.* # for client.py -uvicorn==0.* # ASGI server -python-dotenv==1.* +langgraph==0.1.* +langchain-ollama==0.2.* ``` --- ## 🚀 Running the Project -### 1️⃣ Start Qdrant (if not already running) +### 1️⃣ Start the Agent (CLI) ```bash -docker run -d --name qdrant \ - -p 6333:6333 \ - qdrant/qdrant +python client.py ``` -> Make sure the container is healthy before proceeding. - -### 2️⃣ Run the Agent - -The agent can be executed as a script or imported into other code. -It will automatically load embeddings, connect to Qdrant, and expose a `process_query` function. - -```bash -python agent.py -``` - -> The script prints a simple “Agent ready” message and waits for input if run directly. - -### 3️⃣ Run the Client (FastAPI) - -The client exposes an HTTP endpoint `/query`. -It forwards incoming requests to the agent and returns the LLM response. - -```bash -uvicorn client:app --host 0.0.0.0 --port 8000 -``` - -You should see: +You will see a prompt like: ``` -INFO: Started server process [12345] +Agent: What would you like to know? +> Tell me the weather in Paris tomorrow. ... -INFO: Application startup complete. +[HITL] The agent wants to call tool `get_weather` with arguments: +{ + "city": "Paris", + "date": "2024-06-01" +} +Approve? (approve/reject): ``` -Now you can send requests to `http://localhost:8000/query`. +Type **`approve`** or **`reject`** and press Enter. +If approved, the tool runs; if rejected, the agent will re‑think. ---- +### 2️⃣ Run a Single File Directly -## 📄 Example Usage - -### Using the HTTP API +You can also run each file individually: ```bash -curl -X POST http://localhost:8000/query \ - -H "Content-Type: application/json" \ - -d '{"question": "What is the capital of France?"}' -``` +# Agent definition (no output) +python agent.py -**Response** - -```json -{ - "answer": "The capital of France is Paris." -} -``` - -### Using the Agent Directly (Python) - -```python -from agent import process_query - -response = process_query("Explain quantum computing in simple terms.") -print(response) -# Output: "Quantum computing uses qubits..." +# Client that uses the agent +python client.py ``` --- -## 🔧 Configuration +## 🔍 Example Interaction -All configuration values can be overridden via environment variables or a `.env` file placed at the project root. - -| Variable | Default | Description | -|----------|---------|-------------| -| `QDRANT_URL` | `http://localhost:6333` | Qdrant endpoint | -| `OLLAMA_HOST` | `http://localhost:11434` | Ollama API host | -| `LLM_MODEL` | `llama3` | Chat model name | -| `EMBEDDING_MODEL` | `nomic-embed-text` | Embedding model name | - -Example `.env`: - -```dotenv -QDRANT_URL=http://qdrant:6333 -OLLAMA_HOST=http://ollama:11434 -LLM_MODEL=llama3 -EMBEDDING_MODEL=nomic-embed-text ``` +Agent: Tell me the weather in Tokyo tomorrow. +[HITL] The agent wants to call tool `get_weather` with arguments: +{ + "city": "Tokyo", + "date": "2024-06-01" +} +Approve? (approve/reject): approve +Tool output: "Tomorrow in Tokyo, expect a high of 28°C and light showers." +Agent: The weather in Tokyo tomorrow will be around 28°C with light showers. +``` + +If you type `reject`, the agent will ask for clarification or try a different approach. --- ## 📚 Further Reading -* [LangChain Docs](https://langchain.com/) -* [Ollama Quickstart](https://github.com/ollama/ollama) -* [Qdrant Documentation](https://qdrant.tech/documentation/) +- [Human‑in‑the‑Loop — LangChain](https://docs.langchain.com/docs/middleware/human_in_the_loop) +- [LangGraph Checkpoints](https://langgraph.org/docs/checkpointing) -Feel free to extend the middleware with custom prompts, retrieval strategies, or additional LLMs. Happy hacking! \ No newline at end of file +Feel free to extend the toolset or replace `ChatOllama` with an OpenAI model by swapping imports. + +--- + +Happy hacking! 🚀 \ No newline at end of file