# How to Manage Conversation History in Qwen-Agent: A Complete Technical Guide

> Master conversation history management in Qwen-Agent. Learn to store, persist, and retrieve chat data using provided functions for seamless application development.

- Repository: [Qwen/Qwen-Agent](https://github.com/qwenlm/Qwen-Agent)
- Tags: how-to-guide
- Published: 2026-03-09

---

**Qwen-Agent stores conversation history as a list of tuples `[(user_text, assistant_reply), ...]` in memory, persists it as JSON to `<workspace>/history/<url>.json` after each assistant turn, and exposes `add_text()`, `bot()`, `save_history()`, and `read_history()` functions to manage the full lifecycle.**

Managing conversation history in Qwen-Agent is essential for building stateful AI applications that maintain context across multiple interactions. The QwenLM/Qwen-Agent repository implements a lightweight yet robust history management system that stores dialogue turns as structured Python tuples while providing durable JSON persistence. This guide examines the core implementation files, key functions, and practical patterns for managing conversation history in Qwen-Agent.

## Understanding the Conversation History Format

Qwen-Agent represents conversation history as a **Python list of tuples**, where each tuple contains exactly two elements: the user message and the assistant reply.

The structure follows this pattern:

```python
history = [
    ("Hello, can you help me?", "Of course! What do you need?"),
    ("What's the weather like?", "I can check that for you...")
]

```

When the assistant has not yet replied to the latest user message, the tuple contains `None` as the second element: `("Latest user message", None)`. This format is deliberately simple to ensure compatibility with other agents in the ecosystem, such as the `memo_assistant` that truncates long dialogues, and UI helpers like `convert_history_to_chatbot` in [`qwen_agent/gui/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_agent/gui/utils.py).

## Core Methods for Managing Conversation History

The primary interface for managing conversation history in Qwen-Agent resides in [`qwen_server/workstation_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/workstation_server.py) and [`qwen_server/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/utils.py). These functions handle the complete lifecycle from adding messages to persistent storage.

### Adding User Messages with `add_text`

The `add_text()` function appends a new user message to the history list with a `None` placeholder for the assistant's response.

Located at line 73 in [`qwen_server/workstation_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/workstation_server.py), the function signature is:

```python
def add_text(history, text):
    # Appends (text, None) to history and returns updated history

    pass

```

This function is typically called before invoking the language model to ensure the user input is recorded in the conversation state.

### Generating Responses with `bot`

The `bot()` function (line 245 in [`qwen_server/workstation_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/workstation_server.py)) processes the conversation history, sends the latest user message to the LLM, and updates the history with the assistant's reply.

Key characteristics of this implementation:

- It yields the updated history after each token or chunk for streaming UI updates
- It automatically calls `save_history()` after the complete response is generated
- It handles tool selection via the `chosen_plug` parameter

```python
def bot(history, chosen_plug):
    # Generator that yields updated history tuples

    # Automatically persists to disk after completion

    pass

```

### Persisting Conversations with `save_history`

The `save_history()` function in [`qwen_server/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/utils.py) (line 85) handles durable storage of conversation history.

Implementation details:

- Serializes the history list as JSON
- Stores files at `<history_dir>/<url>.json` where `url` is the conversation identifier
- Creates parent directories if they do not exist

```python
def save_history(history, url, history_dir):
    # Persists history to JSON file

    pass

```

### Restoring Previous Sessions with `read_history`

The `read_history()` function (line 94 in [`qwen_server/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/utils.py)) loads previously saved conversations.

Behavior:

- Returns the history list if the JSON file exists
- Returns an empty list `[]` if no history file is found for the given URL
- Deserializes the JSON back into the tuple list format

```python
def read_history(url, history_dir):
    # Loads history from JSON or returns empty list

    pass

```

### Clearing History

To delete or clear a conversation history, Qwen-Agent uses `save_history()` with `None` as the history parameter. This pattern appears in [`qwen_server/database_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/database_server.py) (line 100) and effectively overwrites the stored JSON with an empty state.

```python

# Clears the conversation by saving None

save_history(None, url, history_dir)

```

## File Structure and Implementation Details

The conversation history management system spans several key files in the Qwen-Agent repository:

| File | Role | Key Functions |
|------|------|---------------|
| [`qwen_server/workstation_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/workstation_server.py) | UI-side endpoint for browser-based interactions | `add_text`, `pure_add_text`, `rm_text`, `bot`, `pure_bot` |
| [`qwen_server/assistant_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/assistant_server.py) | Server-side counterpart for API/headless sessions | `add_text`, `rm_text`, `bot`, `save_history`, `read_history` |
| [`qwen_server/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/utils.py) | Low-level persistence utilities | `save_history`, `read_history`, `save_browsing_meta_data` |
| [`qwen_agent/gui/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_agent/gui/utils.py) | UI conversion helpers for Gradio | `convert_history_to_chatbot` |
| [`qwen_server/database_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/database_server.py) | Database operations including history deletion | Calls `save_history(None, url, ...)` |

## Practical Code Examples

### Complete Workflow: Starting, Continuing, and Saving a Session

```python
from qwen_server.workstation_server import add_text, bot
from qwen_server.utils import save_history, read_history

# Configuration

session_id = "user-session-001"
history_dir = "./workspace/history"

# 1. Restore existing session or start fresh

history = read_history(session_id, history_dir) or []

# 2. Add user message

user_input = "Explain quantum computing in simple terms"
history, _ = add_text(history, user_input)

# 3. Generate assistant response (streaming)

for updated_history in bot(history, chosen_plug=None):
    current_history = updated_history
    # In a real UI, you would display the partial response here

# The history is now automatically persisted, but you can manually save:

save_history(current_history, session_id, history_dir)

```

### Managing Multiple Conversations

```python
from qwen_server.utils import save_history, read_history

history_dir = "./workspace/history"

# List all active conversations by scanning the history directory

import os
active_sessions = [f.replace('.json', '') for f in os.listdir(history_dir) if f.endswith('.json')]

# Load a specific conversation

target_session = "project-alpha"
history = read_history(target_session, history_dir)

# Delete a conversation (clear history)

save_history(None, target_session, history_dir)

```

## Summary

- **Qwen-Agent stores conversation history as a list of tuples** `[(user_text, assistant_reply), ...]` in memory, using `None` as a placeholder for pending assistant responses.
- **The `add_text()` function** in [`qwen_server/workstation_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/workstation_server.py) appends user messages, while the **`bot()` generator** processes LLM responses and automatically triggers persistence.
- **Persistence is handled by `save_history()` and `read_history()`** in [`qwen_server/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/utils.py), which serialize the history to JSON files at `<workspace>/history/<url>.json`.
- **History deletion** is performed by calling `save_history(None, url, history_dir)`, effectively clearing the stored conversation state.

## Frequently Asked Questions

### What is the default format of conversation history in Qwen-Agent?

Qwen-Agent uses a **Python list of tuples** where each tuple contains exactly two elements: the user message string and the assistant reply string. When the assistant has not yet responded, the second element is `None`. This format is implemented in [`qwen_server/workstation_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/workstation_server.py) and is designed to be simple enough for other agents like `memo_assistant` to process and truncate when conversations grow too long.

### How does Qwen-Agent persist conversation history between sessions?

After each complete assistant response, the `bot()` function in [`qwen_server/workstation_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/workstation_server.py) automatically calls `save_history()` from [`qwen_server/utils.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/utils.py). This function serializes the history list as JSON and writes it to `<history_dir>/<url>.json`, where `url` is a unique conversation identifier. When a session starts, `read_history()` loads this JSON file back into memory, returning an empty list if no prior history exists.

### Can I manually edit the conversation history JSON files?

Yes, because Qwen-Agent stores history as **plain JSON files** in the `<workspace>/history/` directory, you can manually edit, copy, or version-control these files. The schema is a simple array of arrays (tuples serialized as lists), such as `[["Hello", "Hi there"], ["How are you?", "I'm doing well"]]`. However, manual edits should respect the two-element structure to avoid errors when `read_history()` attempts to parse the file back into Python tuples.

### How do I clear or delete a conversation history in Qwen-Agent?

To delete a conversation, call `save_history(None, url, history_dir)` where `url` is the conversation identifier and `history_dir` is your configured storage path. This pattern is used in [`qwen_server/database_server.py`](https://github.com/QwenLM/Qwen-Agent/blob/main/qwen_server/database_server.py) (line 100) to reset workspaces. Passing `None` as the history parameter overwrites the stored JSON with an empty state, effectively clearing the conversation without requiring direct file system manipulation.