MemCube
MemCube 是你的“记忆收纳箱”,统一管理三种类型的记忆:明文记忆、激活记忆和参数化记忆。它提供简洁的接口,方便加载、保存和操作多个记忆模块,让开发者轻松构建、保存和共享记忆增强应用。
什么是 MemCube?
MemCube 是一个容器,包含了三种主要类型的记忆:
- 明文记忆 (例如,
GeneralTextMemory、TreeTextMemory): 用于存储和检索非结构化或结构化文本知识。 - 激活记忆 (例如,
KVCacheMemory): 用于存储键值缓存以加速 LLM 推理和上下文重用。 - 参数化记忆 (例如,
LoRAMemory): 用于存储模型适应参数(如 LoRA 权重)。
每种记忆都可以独立配置,根据应用需求灵活组合。
结构
MemCube 由配置定义(参见 GeneralMemCubeConfig),该配置为每种记忆类型指定后端和配置。典型结构是:
MemCube
├── user_id
├── cube_id
├── text_mem: TextualMemory
├── act_mem: ActivationMemory
└── para_mem: ParametricMemory
所有记忆模块都可通过 MemCube 接口访问:
mem_cube.text_memmem_cube.act_memmem_cube.para_mem
View 架构
从 MemOS 2.0 开始,运行时操作(add/search)应通过 View 架构:
SingleCubeView
用于管理单个 MemCube。当系统只需要一个记忆空间时使用。
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, # 可选
)
# 添加记忆
view.add_memories(add_request)
# 搜索记忆
view.search_memories(search_request)
CompositeCubeView
用于管理多个 MemCube。当需要跨多个记忆空间进行统一操作时使用。
from memos.multi_mem_cube.composite_cube import CompositeCubeView
# 创建多个 SingleCubeView
view1 = SingleCubeView(cube_id="cube_1", ...)
view2 = SingleCubeView(cube_id="cube_2", ...)
# 用于多 cube 操作的组合视图
composite = CompositeCubeView(cube_views=[view1, view2], logger=logger)
# 跨所有 cube 搜索
results = composite.search_memories(search_request)
# 结果包含 cube_id 字段以标识来源
API 请求字段
添加记忆(add模式)
| 字段 | 描述 |
|---|---|
writable_cube_ids | add 操作的目标 cube |
async_mode | "async"(启用 scheduler 后台处理)或 "sync"(禁用 scheduler 同步处理) |
搜索记忆(search模式)
| 字段 | 描述 |
|---|---|
readable_cube_ids | search 操作的目标 cube |
async_mode | "async"(启用 scheduler 后台处理)或 "sync"(禁用 scheduler 同步处理) |
核心方法(GeneralMemCube)
GeneralMemCube 是 MemCube 的标准实现,通过统一的接口管理系统的所有记忆。GeneralMemCube 提供以下核心方法来管理记忆数据的生命周期。
初始化
from memos.mem_cube.general import GeneralMemCube
mem_cube = GeneralMemCube(config)
静态数据操作
| 方法 | 描述 |
|---|---|
init_from_dir(dir) | 从本地目录加载 MemCube |
init_from_remote_repo(repo, base_url) | 从远程仓库加载 MemCube(如 Hugging Face) |
load(dir) | 从目录加载所有记忆到现有实例 |
dump(dir) | 将所有记忆保存到目录以持久化 |
文件存储
MemCube 保存后的目录包含以下文件,每个文件对应一种记忆类型:
config.json(MemCube 配置)textual_memory.json(明文记忆)activation_memory.pickle(激活记忆)parametric_memory.adapter(参数化记忆)
使用示例
导出示例 (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. 初始化服务
components = init_server()
naive = components["naive_mem_cube"]
# 2. 创建 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. 通过 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", # 使用同步模式确保立即完成
))
print(f"✓ Added {len(result)} memories")
# 4. 导出特定 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)
# 导出图数据(仅导出当前 cube_id 的数据)
json_data = naive.text_mem.graph_store.export_graph(
include_embedding=True, # 包含 embedding 以支持语义搜索
user_name=EXAMPLE_CUBE_ID, # 按 cube_id 过滤
)
# 修复 embedding 格式:将字符串解析为列表以兼容导入
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")
# 保存到文件
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}")
导入与搜索示例 (load_cube.py)
Embedding 兼容性说明:示例数据使用 bge-m3 模型,维度为 1024。如果您的环境使用不同的 embedding 模型或维度,导入后的语义搜索可能不准确或失败。请确保您的
.env配置与导出时的 embedding 配置一致。
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. 初始化服务
components = init_server()
naive = components["naive_mem_cube"]
# 2. 创建 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. 从文件加载数据到 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. 显示加载的数据
print(f"\nLoaded {len(nodes)} memories:")
for i, node in enumerate(nodes[:3], 1): # 显示前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. 语义搜索验证
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): # 显示前2条
print(f" [{i}] {mem.get('memory', 'N/A')[:60]}...")
完整示例
参见代码仓库中的示例:
MemOS/examples/mem_cube/dump_cube.py- 导出 MemCube 数据(add + export)MemOS/examples/mem_cube/load_cube.py- 导入 MemCube 数据并进行语义搜索(import + search)
旧 API 说明
早期版本中直接调用 mem_cube.text_mem.get_all() 的方式已废弃,请使用 View 架构。旧示例已移至 MemOS/examples/mem_cube/_deprecated/。
开发者说明
- MemCube 强制执行模式一致性,确保安全的加载/转储
- 每种记忆类型都是可插拔的,支持独立测试
- 参见
/tests/mem_cube/了解集成测试和使用模式