MemCube
MemCube is your memory container that manages three types of memories: textual memory, activation memory, and parametric memory. It provides a simple interface for loading, saving, and operating on multiple memory modules, making it easy to build, save, and share memory-augmented applications.What is MemCube?
MemCube contains three major types of memory:
- Textual Memory: Stores text knowledge, supporting semantic search and knowledge management.
- Activation Memory: Stores intermediate reasoning results, accelerating LLM responses.
- Parametric Memory: Stores model adaptation weights, used for personalization.
Each memory type can be independently configured and flexibly combined based on application needs.
Structure
MemCube is defined by a configuration (see GeneralMemCubeConfig), which specifies the backend and settings for each memory type. The typical structure is:
MemCube
├── user_id
├── cube_id
├── text_mem: TextualMemory
├── act_mem: ActivationMemory
└── para_mem: ParametricMemory
All memory modules are accessible via the MemCube interface:
mem_cube.text_memmem_cube.act_memmem_cube.para_mem
View Architecture
Starting from MemOS 2.0, runtime operations (add/search) should go through the View architecture:
SingleCubeView
Use this to manage a single MemCube. When you only need one memory space.
from memos.multi_mem_cube.single_cube import SingleCubeView
view = SingleCubeView(
cube_id="my_cube",
naive_mem_cube=naive_mem_cube,
mem_reader=mem_reader,
mem_scheduler=mem_scheduler,
logger=logger,
searcher=searcher,
feedback_server=feedback_server, # Optional
)
# Add memories
view.add_memories(add_request)
# Search memories
view.search_memories(search_request)
CompositeCubeView
Use this to manage multiple MemCubes. When you need unified operations across multiple memory spaces.
from memos.multi_mem_cube.composite_cube import CompositeCubeView
# Create multiple SingleCubeViews
view1 = SingleCubeView(cube_id="cube_1", ...)
view2 = SingleCubeView(cube_id="cube_2", ...)
# Composite view for multi-cube operations
composite = CompositeCubeView(cube_views=[view1, view2], logger=logger)
# Search across all cubes
results = composite.search_memories(search_request)
# Results contain cube_id field to identify source
API Request Fields
When using the View architecture for add/search operations, specify these parameters:
| Field | Type | Description |
|---|---|---|
writable_cube_ids | list[str] | Target cubes for add operations. Can specify multiple; the system will write to all targets in parallel. |
readable_cube_ids | list[str] | Target cubes for search operations. Can search across multiple cubes; results include source information. |
async_mode | str | Execution mode: "sync" for synchronous processing (wait for results), "async" for asynchronous processing (push to background queue, return task ID immediately). |
Core Methods (GeneralMemCube)
GeneralMemCube is the standard implementation of MemCube, managing all system memories through a unified interface. Here are the main methods to complete memory lifecycle management.
Initialization
from memos.mem_cube.general import GeneralMemCube
mem_cube = GeneralMemCube(config)
Static Data Operations
| Method | Description |
|---|---|
init_from_dir(dir) | Load a MemCube from a local directory |
init_from_remote_repo(repo, base_url) | Load a MemCube from a remote repository (e.g., Hugging Face) |
load(dir) | Load all memories from a directory into the existing instance |
dump(dir) | Save all memories to a directory for persistence |
File Structure
A MemCube directory contains the following files, with each file corresponding to a memory type:
config.json(MemCube configuration)textual_memory.json(textual memory)activation_memory.pickle(activation memory)parametric_memory.adapter(parametric memory)
Usage Examples
Export Example (dump_cube.py)
import json
import os
import shutil
from memos.api.handlers import init_server
from memos.api.product_models import APIADDRequest
from memos.log import get_logger
from memos.multi_mem_cube.single_cube import SingleCubeView
logger = get_logger(__name__)
EXAMPLE_CUBE_ID = "example_dump_cube"
EXAMPLE_USER_ID = "example_user"
# 1. Initialize server
components = init_server()
naive = components["naive_mem_cube"]
# 2. Create SingleCubeView
view = SingleCubeView(
cube_id=EXAMPLE_CUBE_ID,
naive_mem_cube=naive,
mem_reader=components["mem_reader"],
mem_scheduler=components["mem_scheduler"],
logger=logger,
searcher=components["searcher"],
feedback_server=components["feedback_server"],
)
# 3. Add memories via View
result = view.add_memories(APIADDRequest(
user_id=EXAMPLE_USER_ID,
writable_cube_ids=[EXAMPLE_CUBE_ID],
messages=[
{"role": "user", "content": "This is a test memory"},
{"role": "user", "content": "Another memory to persist"},
],
async_mode="sync", # Use sync mode to ensure immediate completion
))
print(f"✓ Added {len(result)} memories")
# 4. Export data for the specific cube_id
output_dir = "tmp/mem_cube_dump"
if os.path.exists(output_dir):
shutil.rmtree(output_dir)
os.makedirs(output_dir, exist_ok=True)
# Export graph data (only data for the current cube_id)
json_data = naive.text_mem.graph_store.export_graph(
include_embedding=True, # Include embeddings to support semantic search
user_name=EXAMPLE_CUBE_ID, # Filter by cube_id
)
# Fix embedding format: parse string to list for import compatibility
import contextlib
for node in json_data.get("nodes", []):
metadata = node.get("metadata", {})
if "embedding" in metadata and isinstance(metadata["embedding"], str):
with contextlib.suppress(json.JSONDecodeError):
metadata["embedding"] = json.loads(metadata["embedding"])
print(f"✓ Exported {len(json_data.get('nodes', []))} nodes")
# Save to file
memory_file = os.path.join(output_dir, "textual_memory.json")
with open(memory_file, "w", encoding="utf-8") as f:
json.dump(json_data, f, indent=2, ensure_ascii=False)
print(f"✓ Saved to: {memory_file}")
Import and Search Example (load_cube.py)
Embedding Compatibility Note: The sample data uses the bge-m3 model with 1024 dimensions. If your environment uses a different embedding model or dimension, semantic search after import may be inaccurate or fail. Ensure your
.envconfiguration matches the embedding settings used during export.
import json
import os
from memos.api.handlers import init_server
from memos.api.product_models import APISearchRequest
from memos.log import get_logger
from memos.multi_mem_cube.single_cube import SingleCubeView
logger = get_logger(__name__)
EXAMPLE_CUBE_ID = "example_dump_cube"
EXAMPLE_USER_ID = "example_user"
# 1. Initialize server
components = init_server()
naive = components["naive_mem_cube"]
# 2. Create SingleCubeView
view = SingleCubeView(
cube_id=EXAMPLE_CUBE_ID,
naive_mem_cube=naive,
mem_reader=components["mem_reader"],
mem_scheduler=components["mem_scheduler"],
logger=logger,
searcher=components["searcher"],
feedback_server=components["feedback_server"],
)
# 3. Load data from file into graph_store
load_dir = "examples/data/mem_cube_tree"
memory_file = os.path.join(load_dir, "textual_memory.json")
with open(memory_file, encoding="utf-8") as f:
json_data = json.load(f)
naive.text_mem.graph_store.import_graph(json_data, user_name=EXAMPLE_CUBE_ID)
nodes = json_data.get("nodes", [])
print(f"✓ Imported {len(nodes)} nodes")
# 4. Display loaded data
print(f"\nLoaded {len(nodes)} memories:")
for i, node in enumerate(nodes[:3], 1): # Show first 3
metadata = node.get("metadata", {})
memory_text = node.get("memory", "N/A")
mem_type = metadata.get("memory_type", "unknown")
print(f" [{i}] Type: {mem_type}")
print(f" Content: {memory_text[:60]}...")
# 5. Semantic search verification
query = "test memory dump persistence demonstration"
print(f'\nSearching: "{query}"')
search_result = view.search_memories(
APISearchRequest(
user_id=EXAMPLE_USER_ID,
readable_cube_ids=[EXAMPLE_CUBE_ID],
query=query,
)
)
text_mem_results = search_result.get("text_mem", [])
memories = []
for group in text_mem_results:
memories.extend(group.get("memories", []))
print(f"✓ Found {len(memories)} relevant memories")
for i, mem in enumerate(memories[:2], 1): # Show first 2
print(f" [{i}] {mem.get('memory', 'N/A')[:60]}...")
Complete Examples
See examples in the code repository:
MemOS/examples/mem_cube/dump_cube.py- Export MemCube data (add + export)MemOS/examples/mem_cube/load_cube.py- Import MemCube data and perform semantic search (import + search)
Legacy API Notes
The old approach of directly calling mem_cube.text_mem.get_all() is deprecated. Please use the View architecture. Legacy examples have been moved to MemOS/examples/mem_cube/_deprecated/.
Developer Notes
- MemCube enforces schema consistency to ensure safe loading and dumping
- Each memory type can be independently configured, tested, and extended
- See
/tests/mem_cube/for integration tests and usage examples
API Development Guide
MemOS v2.0 adopts a more modular and decoupled architecture. The legacy MOS class is deprecated; Components + Handlers is now recommended for development.
MemReader
MemReader is your "memory translator". It translates messy user inputs (chat, documents, images) into structured memory fragments the system can understand.