# Serializing and Deserializing Agent Team State in MetaGPT: A Complete Guide to Persistence and Recovery

> Learn to serialize and deserialize agent team state in MetaGPT for robust persistence and recovery. This guide details saving and restoring entire team states via JSON for fault tolerance.

- Repository: [FoundationAgents/MetaGPT](https://github.com/FoundationAgents/MetaGPT)
- Tags: how-to-guide
- Published: 2026-03-04

---

**MetaGPT enables fault-tolerant multi-agent workflows by persisting entire team states—including roles, memory, and execution context—to JSON files that can be fully restored later using a polymorphic serialization architecture.**

MetaGPT provides a robust persistence layer that allows long-running AI agent teams to survive interruptions and resume execution without data loss. By separating stateful objects from the execution engine and implementing specialized serialization logic for complex nested structures, the framework supports **serializing and deserializing agent team state** at both the message and team levels.

## How MetaGPT Handles Agent State Persistence

The framework’s persistence capabilities rely on three coordinated components that transform in-memory Pydantic models into portable JSON representations.

### The Core Serialization Architecture

According to the MetaGPT source code, state persistence operates through a hierarchy of serialization utilities:

- **`BaseSerialization`** (in [`metagpt/base/base_serialization.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/base/base_serialization.py)): Provides the foundation by injecting a `__module_class_name` field into every serialized model, enabling safe reconstruction of subclass instances during deserialization.
- **`SerializationMixin`** (in [`metagpt/schema.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/schema.py)): A subclass of `BaseSerialization` that exposes `serialize()`, `deserialize()`, and `get_serialization_path()` methods to any domain model that inherits it, defaulting storage to `<workspace>/storage`.
- **`serialize_message` and `deserialize_message`** (in [`metagpt/utils/serialize.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/serialize.py)): Handle special-case `Message` objects containing dynamically generated `ActionNode` instances through a combination of schema extraction and pickling.

### The SERDESER_PATH Constant

All persisted state files write to a centralized location defined by `SERDESER_PATH` in [`metagpt/const.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/const.py). This constant points to `workspace/storage` and serves as the root directory for team states, role memories, and message histories.

## Serializing and Deserializing Team State

The `Team` class represents the entire multi-agent system—including the environment, roles, and investment parameters—and implements high-level methods for full-state persistence.

### Persisting a Multi-Agent Team

When you call `Team.serialize()`, the method executes a three-step process:

1. Invokes `self.model_dump()` to capture the team's base Pydantic fields.
2. Serializes the attached `Context` object via `self.env.context.serialize()` (which uses `SerializationMixin`).
3. Writes the combined JSON to `<SERDESER_PATH>/team/team.json`.

```python
from metagpt.team import Team
from metagpt.context import Context

# Initialize and run a multi-agent project

team = Team(context=Context())
team.run_project("Build a chatbot")

# Serialize the entire team state to the default storage location

team.serialize()  # Writes to workspace/storage/team/team.json

```

### Recovering Team State from Disk

The `Team.deserialize()` classmethod reverses the process. It reads the JSON from the specified path, reconstructs the `Context` via `Context.deserialize()`, and rebuilds the `Team` object while re-binding the restored environment. All roles, their internal states, and pending messages resume exactly where they left off.

```python
from metagpt.team import Team
from metagpt.const import SERDESER_PATH
from pathlib import Path

# Load from default storage location

team_path = SERDESER_PATH / "team"
recovered_team = Team.deserialize(team_path)

print(recovered_team.idea)  # Output: Build a chatbot

```

## Working with Individual Messages

Individual `Message` objects containing complex `ActionNode` instances require special handling. The `serialize_message` function in [`metagpt/utils/serialize.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/serialize.py) creates a deep copy of the message, replaces the `ActionNode` with a lightweight dictionary containing the class name and value mapping, then pickles the result.

```python
from metagpt.actions import WritePRD
from metagpt.actions.action_node import ActionNode
from metagpt.schema import Message
from metagpt.utils.serialize import serialize_message, deserialize_message

# Build a dynamic ActionNode model

out_mapping = {"title": (str, ...), "features": (list[str], ...)}
NodeCls = ActionNode.create_model_class("PRD", out_mapping)
prd_node = NodeCls(title="My Product", features=["A", "B"])

# Create a message with the ActionNode attached

msg = Message(
    content="Generate PRD",
    instruct_content=prd_node,
    role="user",
    cause_by=WritePRD,
)

# Serialize to bytes

msg_blob = serialize_message(msg)

# Later—restore the message with full ActionNode reconstruction

restored_msg = deserialize_message(msg_blob)
print(restored_msg.instruct_content.title)  # Output: My Product

```

During deserialization, `deserialize_message` unpickles the data, detects the stored `__module_class_name`, dynamically imports the corresponding `ActionNode` class via `import_class`, and rebuilds the Pydantic model from the saved mapping.

## Custom Storage Paths and Configuration

For testing or sandboxed environments, you can override the default storage location by passing a custom `stg_path` parameter to the serialization methods.

```python
from pathlib import Path

# Serialize to a custom directory

custom_path = Path("/tmp/metagpt_demo")
team.serialize(stg_path=custom_path)  # Writes to /tmp/metagpt_demo/team.json

# Load from the custom location

restored = Team.deserialize(custom_path)

```

## Summary

- **MetaGPT** uses a polymorphic serialization system via `BaseSerialization` and `SerializationMixin` to persist Pydantic models with full subclass type information.
- **Team state** serialization captures the entire multi-agent environment, context, and roles through `Team.serialize()`, storing files in `workspace/storage` by default.
- **Message serialization** handles complex nested `ActionNode` objects by extracting schemas, creating type-mappings, and using pickle for binary serialization.
- **Recovery** via `Team.deserialize()` and `deserialize_message()` dynamically reconstructs classes and restores execution state without manual intervention.

## Frequently Asked Questions

### How does MetaGPT serialize complex ActionNode objects within Messages?

MetaGPT's `serialize_message` function in [`metagpt/utils/serialize.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/serialize.py) creates a deep copy of the `Message`, converts the attached `ActionNode` to a compact dictionary containing the class name and field mappings via `actionoutout_schema_to_mapping()`, and then pickles the entire message. This preserves both the data and the type information needed for reconstruction.

### What file path does MetaGPT use for team state persistence by default?

By default, MetaGPT stores team state in [`workspace/storage/team/team.json`](https://github.com/FoundationAgents/MetaGPT/blob/main/workspace/storage/team/team.json), defined by the `SERDESER_PATH` constant in [`metagpt/const.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/const.py). The `SerializationMixin` automatically resolves paths relative to this directory unless overridden.

### Can I customize the storage location for serialized agent teams?

Yes. Both `Team.serialize()` and `Team.deserialize()` accept an optional `stg_path` parameter (a `pathlib.Path` object) that overrides the default `SERDESER_PATH`. This enables sandboxed testing or multiple concurrent team persistence scenarios.

### How does Team deserialization restore the execution environment?

`Team.deserialize()` reads the saved JSON, reconstructs the `Context` using `Context.deserialize()`, then instantiates a new `Team` object while re-binding the restored environment and roles. The process uses the `__module_class_name` field injected by `BaseSerialization` to ensure correct class instantiation for all polymorphic components.