Human‑in‑the‑Loop Agent via Middleware
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).
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
Project Structure
├── solution.py # Main script with the agent implementation
└── README.md # This file
solution.py contains:
- LLM configuration – uses
ChatOpenAI. - A simple tool (
get_weather) that returns a fake weather string. - Memory checkpoint via
MemorySaver. - Agent creation with
create_react_agentand the middleware. - Execution loop that keeps asking for user input until the conversation ends.
Installation
-
Clone the repo
git clone https://github.com/your-username/human-in-the-loop-agent.git cd human-in-the-loop-agent -
Create a virtual environment (optional but recommended)
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate -
Install dependencies
pip install --upgrade pip pip install langchain langgraph openai -
Set your OpenAI API key
export OPENAI_API_KEY="sk-..." # Windows: setx OPENAI_API_KEY "sk-..."
Running the Agent
Interactive Mode
Simply run the script:
python solution.py
You will see a prompt like:
Agent wants to call tool `get_weather` with arguments:
city = "Moscow"
date = "2025-10-01"
Please type one of: approve / reject (or edit <new_args>)
>
Type approve to let the agent proceed, or reject to stop it.
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:
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 solution.py
User: What's the weather in Paris next Friday?
Agent wants to call tool `get_weather` with arguments:
city = "Paris"
date = "2025-10-06"
Please type one of: approve / reject (or edit <new_args>)
> approve
Assistant: Погода в Париже на 2025‑10‑06: солнечно 25°C.
User: Thank you!
Extending the Agent
- Add more tools – decorate any function with
@tooland add it to thetoolslist increate_react_agent. - Change the interrupt policy – modify
interrupt_ondict (e.g.,{ "get_weather": True, "send_email": False }). - Persist conversation state – replace
MemorySaver()with a database checkpoint if you need long‑term memory. - Custom prompts – tweak
system_promptor add a customdescription_prefix.
Happy hacking! 🚀