How to Implement Persistent User Memory Across Agent Sessions
You implement persistent user memory across agent sessions by configuring a PostgreSQL-backed PostgresMemoryStore, initializing the MemoryFactory singleton with a MemoryConfig, and accessing the cached instance via MemoryFactory.instance() to ensure user data survives process restarts.
Maintaining continuity across conversations is critical for AI agents that need to remember user preferences and context. The bojieli/ai-agent-book repository provides a modular memory subsystem that supports both ephemeral and durable storage backends. This guide explains how to implement persistent user memory across agent sessions using the MemoryFactory pattern and PostgreSQL integration.
Understanding the Memory Architecture
The memory system centers on the MemoryFactory singleton defined in aworld/memory/main.py. This factory manages the lifecycle of concrete MemoryBase implementations, caching instances in a module-level MEMORY_HOLDER dictionary to ensure global access to the same storage backend throughout the application lifecycle.
The MemoryFactory Singleton Pattern
The MemoryFactory class implements a singleton pattern that guarantees a single source of truth for memory storage. When you call MemoryFactory.init() at lines 158-166 of aworld/memory/main.py, the factory registers your chosen storage implementation—either ephemeral or persistent—in the global MEMORY_HOLDER dict. Subsequent calls to MemoryFactory.instance() (lines 174-182) retrieve this cached instance, ensuring all agent components access the same memory store regardless of when or where they initialize.
Storage Backends: Ephemeral vs Persistent
The repository provides two primary storage implementations:
InMemoryMemoryStore(lines 55-79 ofaworld/memory/main.py): Stores items in a Python list that disappears when the process terminates. Ideal for testing and stateless deployments.PostgresMemoryStore(lines 224-229 ofaworld/memory/db/postgres.py): Persists memory items to PostgreSQL using SQLAlchemy models (MemoryItemModelandMemoryHistoryModel), writing to theaworld_memory_itemstable.
Configuring Persistent Storage with PostgreSQL
To achieve durability across agent sessions, you must configure the PostgresMemoryStore and bind it to the factory.
Setting up PostgresMemoryStore
The PostgresMemoryStore class requires a database connection string and uses SQLAlchemy ORM models to manage data persistence. According to the source code in aworld/memory/db/postgres.py, this store handles serialization of MemoryItem objects to relational rows, ensuring your user data survives process restarts and system reboots.
The MemoryConfig Object
The MemoryConfig class (defined in aworld/memory/models.py) encapsulates configuration settings including the provider type ("aworld", "mem0", or custom), embedding model settings, and vector store configurations. When initializing persistent storage, you instantiate this config alongside your concrete store implementation.
Initializing the Memory Factory
The initialization process follows a strict three-step pattern to ensure the singleton is properly configured before any agent logic executes.
First, create your concrete store and configuration:
from aworld.memory.main import MemoryFactory, MemoryConfig
from aworld.memory.db.postgres import PostgresMemoryStore
# Configure PostgreSQL connection
postgres_store = PostgresMemoryStore(
db_url="postgresql://user:pwd@host/db"
)
config = MemoryConfig(
provider="aworld",
embedding_config=..., # Your embedding model
vector_store_config=..., # Vector DB (e.g., FAISS, Milvus)
)
Second, initialize the factory with your custom store:
# Register the persistent store in the global singleton
MemoryFactory.init(
custom_memory_store=postgres_store,
config=config
)
Third, retrieve the instance anywhere in your codebase:
memory = MemoryFactory.instance() # Returns the same PostgresMemoryStore
Accessing and Manipulating User Memory
Once initialized, agents interact with memory through the uniform MemoryBase API, agnostic of the underlying storage mechanism.
The MemoryBase API
Both storage implementations expose methods defined in MemoryBase: add(), get(), get_all(), delete(), and history(). This abstraction allows you to switch between in-memory and persistent storage without modifying agent code.
Cross-Session Memory Retrieval
To maintain continuity, agents store user-specific data with metadata identifiers, then retrieve them in subsequent sessions:
from aworld.memory.models import MemoryHumanMessage, MessageMetadata
# Store user preference in session 1
memory.add(
MemoryHumanMessage(
content="My favorite color is blue",
metadata=MessageMetadata(
user_id="user_123",
session_id="sess_001"
)
)
)
# Retrieve in session 2 (different process/instance)
memory = MemoryFactory.instance() # Same PostgreSQL store
prev = memory.get_first(
filters={"user_id": "user_123"}
)
print(prev.content) # Output: "My favorite color is blue"
Implementation in Agent Workflows
Real-world agents in the repository access this memory system through the factory pattern. In aworld/agents/llm_agent.py, agents call MemoryFactory.instance() to read historical context and write new observations, ensuring user context persists across multiple interaction cycles.
The pattern guarantees that when an agent finishes a session, the serialized memory state remains in PostgreSQL. When the next session begins, MemoryFactory.instance() reconnects to the same database, retrieves the prior snapshot, and restores the conversation context.
Summary
- Use
MemoryFactoryas the central singleton to manage memory store lifecycle across your application. - Choose
PostgresMemoryStore(defined inaworld/memory/db/postgres.py) for durability, orInMemoryMemoryStorefor ephemeral testing. - Initialize once using
MemoryFactory.init()with aMemoryConfigand custom store, then access globally viaMemoryFactory.instance(). - Leverage the
MemoryBaseAPI (add,get,get_all) to remain storage-agnostic in your agent logic. - Persist across sessions by storing user data with identifiers (
user_id,session_id) and retrieving via filters in subsequent agent instantiations.
Frequently Asked Questions
What is the difference between InMemoryMemoryStore and PostgresMemoryStore?
The InMemoryMemoryStore (lines 55-79 of aworld/memory/main.py) maintains items in a Python list that is destroyed when the process exits, making it suitable for testing or single-session deployments. The PostgresMemoryStore (lines 224-229 of aworld/memory/db/postgres.py) uses SQLAlchemy models to write memory items to a PostgreSQL database, ensuring data survives process restarts and enabling cross-session persistence for production agents.
How does MemoryFactory ensure the same store instance is returned across different parts of the code?
MemoryFactory implements a singleton pattern that caches the initialized store in a module-level MEMORY_HOLDER dictionary. When you call MemoryFactory.init() (lines 158-166), it stores the instance globally. All subsequent calls to MemoryFactory.instance() (lines 174-182) retrieve this cached object, guaranteeing that every component—from agents to middleware—accesses the same underlying storage connection.
Can I use a different database backend instead of PostgreSQL?
Yes. While the repository provides PostgresMemoryStore as the reference persistent implementation in aworld/memory/db/postgres.py, you can implement the MemoryBase abstract class to create custom backends for MongoDB, Redis, or other databases. Pass your custom implementation to MemoryFactory.init(custom_memory_store=your_store) to integrate alternative storage solutions.
How do I migrate from in-memory storage to persistent storage in existing agents?
Migration requires changing the initialization call from using the default in-memory store to explicitly providing a PostgresMemoryStore. Update your bootstrap code to instantiate PostgresMemoryStore with your database URL, pass it to MemoryFactory.init(), and ensure your MemoryConfig specifies the appropriate provider. No changes are required to agent logic since both stores implement the same MemoryBase interface.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →