Content
# Tool List
## Overview
The ZpAgent project is a ReAct intelligent agent built using **LangChain 1.2 + LangGraph + FastAPI + Vue 3**. It supports SSE streaming output, dynamic tool selection, multi-round conversation memory, and human-in-the-loop tool approval.
## Features
- **ReAct Reasoning Loop**: Think → Act → Observe → Reconsider, fully demonstrating the Agent decision-making process
- **SSE Streaming Output**: Real-time token-by-token push, presenting the answer with a typewriter effect
- **Dynamic Tool Selection**: Front-end selectable enable/disable tools, supporting built-in tools + MCP external tools
- **Human-in-the-Loop**: Sensitive tools require user approval before execution, supporting approval/editing/rejection/self-reply
- **Multi-Round Conversation Memory**: Two-layer storage architecture (metadata + conversation state), supporting InMemory/MySQL back-end switching
- **MCP Tool Extension**: Load external MCP tool services through `mcp_servers.json` configuration
## Interface Preview
- Chat Interface

- Support for Built-in Tools and MCP

- Support for Human-in-the-Loop

## Project Architecture
```
ZpAgent-Python/
├── zpagent.sh # One-click start/stop/restart script
├── back/ # Back-end (Python + FastAPI + LangChain + LangGraph)
│ ├── main.py # FastAPI application entry
│ ├── config.py # Configuration management (pydantic-settings)
│ ├── .env # Environment variables (API Key, etc., not submitted to Git)
│ ├── mcp_servers.json # MCP external tool service configuration
│ ├── agent/
│ │ ├── __init__.py # ReAct Agent orchestration layer (streaming events + HITL + session management)
│ │ └── graph.py # LangGraph Agent graph factory (create_agent)
│ ├── llm/
│ │ └── __init__.py # LLM client (ChatOpenAI)
│ ├── tools/
│ │ ├── __init__.py # Tool export
│ │ ├── builtin_tools.py # Built-in tools (location/time/weather)
│ │ ├── mcp_loader.py # MCP tool loader
│ │ └── registry.py # Tool registry (HITL strategy management)
│ ├── conversation/ # Conversation metadata storage (strategy pattern)
│ │ ├── __init__.py # Factory function + export
│ │ ├── base.py # Abstract base class
│ │ ├── memory_store.py # InMemory implementation
│ │ └── mysql_store.py # MySQL implementation
│ ├── checkpoint/ # Conversation state storage (strategy pattern)
│ │ ├── __init__.py # Factory function + export
│ │ ├── base.py # Abstract base class
│ │ ├── memory_store.py # InMemory implementation
│ │ └── mysql_store.py # MySQL implementation
│ ├── models/
│ │ └── __init__.py # Pydantic data model
│ ├── routers/
│ │ └── api.py # Unified API routing (chat + HITL + session + tool)
│ └── requirements.txt # Python dependencies
│
└── front/ # Front-end (Vue 3 + Vite)
├── package.json
├── vite.config.js # Vite configuration (including SSE proxy)
├── index.html
└── src/
├── main.js
├── App.vue # Root component (global state management)
├── style.css # Global style
├── api/
│ └── index.js # API encapsulation (REST + SSE streaming)
├── views/
│ └── ChatView.vue # Chat main view
├── utils/
│ └── index.js # Utility functions + tool Chinese name mapping
└── components/
├── ChatMessage.vue # Message component (including ReAct thinking process)
├── ConversationList.vue # Side-bar conversation list
├── ToolSelector.vue # Tool multi-select bar
└── ApprovalPanel.vue # HITL tool approval panel
```
## Technology Stack
| Level | Technology | Version | Description |
|------|------------|---------|-------------|
| Back-end framework | FastAPI | 0.115+ | High-performance asynchronous web framework |
| AI framework | LangChain | 1.2+ | LLM call + tool binding + astream_events streaming |
| Agent engine | LangGraph | 1.2+ | ReAct state graph + checkpointer + HITL |
| LLM API | OpenAI compatible | — | DeepSeek / 智谱 / Moonshot / OpenAI, etc. |
| Streaming transmission | SSE | — | Server-Sent Events real-time token-by-token output |
| Front-end framework | Vue 3 + Vite | 3.5+ / 5.4+ | Composition API + fast hot update |
| Conversation memory | Two-layer storage | — | Metadata (conversation) + conversation state (checkpoint), supporting InMemory/MySQL |
## Quick Start (Recommended)
The project provides a `zpagent.sh` one-click management script, which automatically handles virtual environment detection, dependency installation, and service management.
### Preconditions
1. Edit `back/.env` and configure your LLM API key:
```bash
cd back
cp .env.example .env # If there is no .env, copy from the template
# Edit .env, change API_KEY=your-api-key-here to your actual key
```
2. Create a Python virtual environment (only once) before first use:
```bash
cd back
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
### One-click Start
```bash
# Grant execution permission (first time)
chmod +x zpagent.sh
# Start all services (back-end + front-end)
./zpagent.sh start
```
After successful startup, output:
```
==============================
ZpAgent Started
==============================
[INFO] Starting back-end service...
[OK] Back-end service started (PID: 12345)
[INFO] API documentation: http://localhost:8000/docs
[INFO] Starting front-end service...
[OK] Front-end service started (PID: 12346)
[INFO] Front-end address: http://localhost:5173
==============================
ZpAgent services all started
Back-end: http://localhost:8000
Front-end: http://localhost:5173
API: http://localhost:8000/docs
==============================
```
### Script Command Overview
```bash
./zpagent.sh {start|stop|restart|status} [backend|frontend|all]
```
| Command | Description | Example |
|------|------------|------|
| `start` | Start service | `./zpagent.sh start` — Start back-end and front-end |
| `stop` | Stop service | `./zpagent.sh stop` — Stop all services |
| `restart` | Restart service | `./zpagent.sh restart` — Restart all services |
| `status` | View status | `./zpagent.sh status` — View running status and health check |
The second parameter is optional, defaulting to `all`:
```bash
./zpagent.sh start backend # Start back-end only
./zpagent.sh start frontend # Start front-end only
./zpagent.sh stop frontend # Stop front-end only
./zpagent.sh restart backend # Restart back-end only
./zpagent.sh status # View all service status + API health check
```
### Service Addresses
| Service | Address | Description |
|------|--------|------------|
| Front-end | http://localhost:5173 | User interface |
| Back-end | http://localhost:8000 | API service |
| API documentation | http://localhost:8000/docs | Swagger UI |
| Health check | http://localhost:8000/api/health | Back-end health status |
### Log Files
| Service | Log path |
|------|----------|
| Back-end | `log/backend.log` |
| Front-end | `log/frontend.log` |
## Manual Start
If you don't want to use the script, you can start manually:
### Step 1: Start Back-end
```bash
cd back
# 1. Create a Python virtual environment (only once)
python3 -m venv venv
# 2. Activate virtual environment
source venv/bin/activate # macOS / Linux
# venv\Scripts\activate # Windows
# 3. Install Python dependencies (only once)
pip install -r requirements.txt
# 4. Configure environment variables (only once)
# Edit back/.env, change API_KEY=your-api-key-here to your actual key
# 5. Start back-end service
python main.py
```
> Back-end runs on **http://localhost:8000**
> API documentation (Swagger UI): **http://localhost:8000/docs**
### Step 2: Start Front-end
```bash
cd front
# 1. Install front-end dependencies (only once)
npm install
# 2. Start development server
npm run dev
```
> Front-end runs on **http://localhost:5173**
> Vite has configured `/api` proxy to back-end port 8000, no additional configuration needed
## Usage Instructions
1. Open **http://localhost:5173** in your browser
2. Input a message in the bottom input box and press Enter to send
3. Select tools to enable through the tool bar (default 3 built-in tools)
4. Observe the Agent's ReAct reasoning process (tool calls → observation results → final answer)
5. When the Agent calls a tool that requires approval, the approval panel will pop up, and you can choose to approve/edit/reject/self-reply
## Environment Variable Description
Configure in `back/.env`:
| Variable | Description | Default value |
|------|------------|--------------|
| `API_KEY` | LLM API key (required) | — |
| `BASE_URL` | API base address | `https://api.deepseek.com` |
| `MODEL_NAME` | Model name | `deepseek-v4-flash` |
| `TEMPERATURE` | Generation temperature (0~2) | `0.7` |
| `MAX_COMPLETION_TOKENS` | Maximum generated tokens | `2048` |
| `REQUEST_TIMEOUT` | LLM request timeout (seconds) | `60` |
| `MAX_RETRIES` | LLM request retry times | `2` |
| `MAX_ITERATIONS` | ReAct maximum iterations | `10` |
| `HOST` | Service listening address | `0.0.0.0` |
| `PORT` | Service port | `8000` |
| `CONVERSATION_BACKEND` | Conversation metadata storage back-end | `memory` |
| `CHECKPOINT_BACKEND` | Conversation state storage back-end | `memory` |
| `MYSQL_HOST` | MySQL host address | `localhost` |
| `MYSQL_PORT` | MySQL port | `3306` |
| `MYSQL_USER` | MySQL username | `root` |
| `MYSQL_PASSWORD` | MySQL password | — |
| `MYSQL_DATABASE` | MySQL database name | `zpagent` |
## Conversation Memory Mechanism
The project adopts a **two-layer storage architecture** (strategy pattern), with each layer independently switchable:
```
┌──────────────────────────────────────────────────────────────┐
│ Conversation memory = two-layer collaboration │
├─────────────────────────┬────────────────────────────────────┤
│ conversation/ │ checkpoint/ │
│ ───────────────────── │ ──────────────────────── │
│ Application layer: conversation metadata │ Framework layer: conversation state management │
│ - Conversation list/create/delete │ - Associated with thread_id conversation │
│ - Title management │ - Automatically stitch historical context to LLM │
│ - Support Memory / MySQL │ - Support Memory / MySQL │
│ │ - Support human-in-the-loop │
└─────────────────────────┴────────────────────────────────────┘
```
Switch storage back-end through `.env` variables `CONVERSATION_BACKEND` and `CHECKPOINT_BACKEND`, no code changes needed.
## ReAct Loop Principle
```
User input
│
▼
┌──────────────────────────────────────────────────────┐
│ LangGraph Agent(create_agent + checkpointer) │
│ checkpointer automatically loads conversation history through thread_id │
│ LLM reasoning (astream_events v2 streaming) │
│ Token-by-token output + tool_calls detection │
└──────────────┬───────────────────────────────────────┘
│
┌─────────┴──────────────────────┐
│ │
Has tool_calls No tool_calls
│ │
▼ ▼
Approval required? ── Yes ──→ interrupt() Final answer output
│ Pause waiting │
│ No │ ▼
▼ ▼ checkpointer save state
ToolNode execution User approval decision
│ (approve/reject/edit)
▼ │
Observation result ────────────┘
│
▼
Back to LLM continue reasoning
```
## Built-in Tools
| Tool identifier | Function description |
|----------|----------|
| `get_datetime` | Query current date, time, week |
Additional MCP external tools can be loaded through `back/mcp_servers.json` configuration.
## Extension Guide
### Add New Tools
Define in `back/tools/builtin_tools.py` with `@tool` decorator:
```python
from langchain.tools import tool
@tool
def my_new_tool(param: str) -> str:
"""Tool description (LangChain automatically extracts as description).
Args:
param: Parameter description (automatically generates JSON Schema)
"""
return "Execution result"
```
Then add `my_new_tool` to the `BUILTIN_TOOLS` list at the bottom of the file, and the front-end will automatically identify it.
If you need to add a Chinese display name in `front/src/utils/index.js` in `TOOL_NAME_MAP`.
### Add New Storage Back-end
1. Create a new file in `conversation/` or `checkpoint/`, inherit the abstract base class
2. Implement all abstract methods
3. Add a branch in the factory function in `__init__.py`
4. Add related configuration items in `config.py`
## API Interface Overview
| Method | Path | Description |
|------|------|------|
| `POST` | `/api/chat` | Chat (SSE streaming output) |
| `POST` | `/api/chat/decide` | HITL approval decision (approve/reject/edit/self-reply) |
| `GET` | `/api/messages/{id}` | Get conversation message history |
| `GET` | `/api/conversations` | Get all conversation lists |
| `GET` | `/api/conversations/{id}` | Get conversation details |
| `DELETE` | `/api/conversations/{id}` | Delete conversation |
| `DELETE` | `/api/conversations/{id}/messages` | Clear conversation messages |
| `GET` | `/api/tools` | Get available tool list |
| `POST` | `/api/tools/reload` | Reload tools (including MCP) |
| `GET` | `/api/health` | Health check |
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available