NeuroMem 架构分析报告¶
Date: 2025-01-22\ Author: SAGE Team\ Summary: NeuroMem 作为独立记忆体组件的完整性评估,包括存储、检索、管理等核心功能分析
分析目标:评估 neuromem 作为独立记忆体组件的完整性
📋 执行摘要¶
结论: ✅ neuromem 已实现完整的记忆体设计
neuromem 作为 sage-middleware 的独立组件,已经包含了记忆体系统的所有核心属性:
- ✅ 完整的 store(存储) 操作
- ✅ 完整的 recall(检索) 操作
- ✅ 完整的 记忆数据结构(文本、元数据、向量)
- ✅ 多种后端支持(VDB、KV、Graph)
- ✅ 独立的存储引擎和搜索引擎
没有发现功能分散到其他包的情况。
🏗️ 当前架构¶
1. 包结构¶
packages/sage-middleware/src/sage/middleware/components/sage_mem/
├── neuromem/ # 核心记忆引擎(独立子项目)
│ ├── memory_collection/ # 记忆集合实现
│ │ ├── base_collection.py # 基础记忆集合
│ │ ├── vdb_collection.py # 向量数据库记忆
│ │ ├── kv_collection.py # 键值对记忆
│ │ └── graph_collection.py # 图结构记忆
│ ├── memory_manager.py # 记忆管理器
│ ├── storage_engine/ # 存储引擎
│ │ ├── text_storage.py # 文本存储
│ │ ├── metadata_storage.py # 元数据存储
│ │ ├── vector_storage.py # 向量存储
│ │ └── kv_backend/ # KV 后端抽象
│ ├── search_engine/ # 搜索引擎
│ │ ├── vdb_index/ # 向量索引(FAISS, Chroma 等)
│ │ └── kv_index/ # KV 索引
│ └── utils/ # 工具函数
├── services/ # SAGE 服务层封装
│ ├── neuromem_vdb.py # VDB 服务接口
│ └── neuromem_vdb_service.py # VDB 服务(继承 BaseService)
└── examples/ # 示例代码
2. 层级关系¶
L4 (sage-middleware)
└── components/
└── sage_mem/ # SAGE 记忆管理包装
├── neuromem/ # ✅ 完整的独立记忆引擎
│ ├── [完整的 store 操作]
│ ├── [完整的 recall 操作]
│ ├── [完整的数据结构]
│ └── [独立的存储/搜索引擎]
└── services/ # SAGE 服务层(薄封装)
└── [调用 neuromem 核心功能]
🔍 功能完整性分析¶
✅ Store(存储)操作 - 完整¶
neuromem 提供了多层次的存储接口:
1. 基础存储 (BaseMemoryCollection)¶
def insert(self, raw_text: str, metadata: Optional[Dict[str, Any]] = None) -> str:
"""存储原始文本与可选的元数据"""
stable_id = self._get_stable_id(raw_text)
self.text_storage.store(stable_id, raw_text)
if metadata:
self.metadata_storage.store(stable_id, metadata)
return stable_id
2. 批量存储 (VDBMemoryCollection)¶
def batch_insert_data(self, data: List[str], metadatas: Optional[List[Dict]] = None):
"""批量插入数据到collection中(仅存储,不创建索引)"""
for i, item in enumerate(data):
self.text_storage.store(stable_id, item)
if metadata:
self.metadata_storage.store(stable_id, metadata)
3. 索引化存储 (VDBMemoryCollection)¶
def insert(self, index_name: str, raw_data: str, metadata: Optional[Dict] = None):
"""单条数据插入(必须指定索引插入)"""
# 1. 存储到 text_storage
# 2. 存储到 metadata_storage
# 3. 生成向量并插入索引
4. 持久化 (MemoryManager)¶
评估: ✅ 提供了从基础存储到索引化存储的完整能力,支持持久化。
✅ Recall(检索)操作 - 完整¶
neuromem 提供了多种检索方式:
1. 全量检索 (BaseMemoryCollection)¶
def retrieve(self, with_metadata: bool = False,
metadata_filter_func: Optional[Callable] = None,
**metadata_conditions):
"""根据元数据(条件或函数)检索原始文本"""
all_ids = self.get_all_ids()
matched_ids = self.filter_ids(all_ids, metadata_filter_func, **metadata_conditions)
return [self.text_storage.get(i) for i in matched_ids]
2. 向量检索 (VDBMemoryCollection)¶
def retrieve(self, query_text: str, index_name: str, topk: int = 5,
with_metadata: bool = False,
metadata_filter_func: Optional[Callable] = None,
**metadata_conditions):
"""在指定索引上进行向量检索"""
# 1. 生成查询向量
# 2. 索引中搜索 topk 相似向量
# 3. 可选:元数据过滤
# 4. 返回文本和元数据
3. KV 检索 (KVMemoryCollection)¶
def retrieve(self, query: str, index_name: str = "default_kv_index",
topk: int = 5, with_metadata: bool = False):
"""基于 KV 索引的检索"""
4. 服务层检索 (NeuroMemVDBService)¶
def retrieve(self, query_text: str, topk: int = 5,
collection_name: Optional[str] = None,
with_metadata: bool = False):
"""在所有 online_register_collections 上按照 vdb_collection 方式检索"""
评估: ✅ 提供了从基础过滤到向量检索的完整能力,支持元数据条件过滤。
✅ 记忆数据结构 - 完整¶
neuromem 实现了完整的记忆数据分层存储:
1. 文本存储层 (TextStorage)¶
class TextStorage:
"""原始文本存储"""
def __init__(self, backend: BaseKVBackend = None):
self._store = backend or DictKVBackend() # 支持多种后端
def store(self, item_id: str, text: str)
def get(self, item_id: str) -> str
def store_to_disk(self, path: str)
def load_from_disk(self, path: str)
2. 元数据存储层 (MetadataStorage)¶
class MetadataStorage:
"""元数据存储(支持字段注册和查询)"""
def __init__(self, backend: BaseKVBackend = None):
self._store = backend or DictKVBackend()
self._fields = set() # 注册的字段
def add_field(self, field_name: str)
def store(self, item_id: str, metadata: Dict[str, Any])
def get(self, item_id: str) -> Dict[str, Any]
3. 向量存储层 (VectorStorage)¶
class VectorStorage:
"""向量存储(支持多种向量索引)"""
def __init__(self, backend: BaseKVBackend = None):
self._store = backend or DictKVBackend()
def store(self, hash_id: str, vector: Any)
def get(self, hash_id: str)
def store_to_disk(self, path: str)
4. 索引层 (VDBIndex, KVIndex)¶
class BaseVDBIndex:
"""向量索引抽象"""
def insert(self, vector: np.ndarray, string_id: str)
def search(self, query_vector: np.ndarray, topk: int) -> List[Tuple[str, float]]
def batch_insert(self, vectors: List[np.ndarray], ids: List[str])
def store(self, root_path: str)
def load(self, root_path: str)
# 实现:
# - FAISSIndex (FAISS)
# - ChromaIndex (Chroma)
# - UsearchIndex (Usearch)
5. 集合层 (MemoryCollection)¶
class BaseMemoryCollection:
"""基础记忆集合(文本 + 元数据)"""
def __init__(self, name: str):
self.name = name
self.text_storage = TextStorage()
self.metadata_storage = MetadataStorage()
class VDBMemoryCollection(BaseMemoryCollection):
"""向量数据库记忆集合(文本 + 元数据 + 向量索引)"""
def __init__(self, config: Dict[str, Any]):
super().__init__(config["name"])
self.index_info = {} # 多索引管理
self.embedding_model_factory = {} # 嵌入模型管理
6. 管理层 (MemoryManager)¶
class MemoryManager:
"""内存管理器,管理不同类型的 MemoryCollection 实例"""
def __init__(self, data_dir: Optional[str] = None):
self.collections: Dict[str, BaseMemoryCollection] = {}
self.collection_metadata: Dict[str, Dict[str, Any]] = {}
self.collection_status: Dict[str, str] = {} # "loaded" or "on_disk"
评估: ✅ 完整的六层数据结构,从底层存储到顶层管理,设计清晰合理。
🔗 依赖关系分析¶
neuromem 的依赖(向下)¶
# neuromem 只依赖 L1 (sage-common) 和 L2 (sage-platform)
from sage.common.components.sage_embedding.embedding_api import apply_embedding_model
from sage.common.utils.logging.custom_logger import CustomLogger
from sage.platform.storage import BaseKVBackend, DictKVBackend # ✅ 正确使用 L2
✅ 依赖方向正确:L4 (middleware) → L2 (platform) → L1 (common)
neuromem 的使用者(向上)¶
1. sage_mem 服务层(同包内)¶
# packages/sage-middleware/src/sage/middleware/components/sage_mem/services/
from sage.middleware.components.sage_mem.neuromem.memory_manager import MemoryManager
from sage.middleware.components.sage_mem.neuromem.memory_collection.vdb_collection import VDBMemoryCollection
用途:提供 SAGE 风格的服务接口(NeuroMemVDB, NeuroMemVDBService)
2. sage-middleware 测试¶
# packages/sage-middleware/tests/components/sage_mem/
from sage.middleware.components.sage_mem.neuromem.memory_manager import MemoryManager
✅ 没有发现其他包直接依赖 neuromem,依赖关系清晰。
🎯 功能独立性评估¶
检查点 1: Store 操作是否完整在 neuromem?¶
✅ 是的
TextStorage.store()- 文本存储MetadataStorage.store()- 元数据存储VectorStorage.store()- 向量存储VDBIndex.insert()- 索引插入MemoryManager.store_collection()- 持久化
没有发现在其他包中的 store 操作。
检查点 2: Recall 操作是否完整在 neuromem?¶
✅ 是的
BaseMemoryCollection.retrieve()- 基础检索VDBMemoryCollection.retrieve()- 向量检索KVMemoryCollection.retrieve()- KV 检索VDBIndex.search()- 索引搜索
没有发现在其他包中的 recall 操作。
检查点 3: 数据结构是否完整在 neuromem?¶
✅ 是的
- 所有存储引擎(
storage_engine/)都在 neuromem 内 - 所有搜索引擎(
search_engine/)都在 neuromem 内 - 所有集合类型(
memory_collection/)都在 neuromem 内 - 管理器(
memory_manager.py)在 neuromem 内
没有发现数据结构分散在其他包。
检查点 4: 是否有功能泄漏到 operators?¶
❌ 没有
# 搜索 sage-middleware/operators/ 中的 neuromem 引用
grep -r "neuromem\|MemoryManager\|VDBMemoryCollection" packages/sage-middleware/src/sage/middleware/operators/
# 结果:No matches found
✅ RAG operators 不直接依赖 neuromem,而是通过标准接口与外部向量数据库交互:
ChromaRetriever- 使用chromadb客户端MilvusRetriever- 使用pymilvus客户端Wiki18FAISSRetriever- 使用本地 FAISS 索引
这是正确的设计:operators 是领域算子,neuromem 是独立的记忆体组件。
🏆 设计优势¶
1. 完整性 ✅¶
neuromem 是一个完全自包含的记忆体系统:
- 所有 store 操作
- 所有 recall 操作
- 所有数据结构
- 所有后端支持
2. 独立性 ✅¶
neuromem 本身就是一个独立子项目:
- 有自己的
pyproject.toml - 有自己的
setup.py - 有自己的
.git仓库标记 - 可以独立测试和发布
3. 分层清晰 ✅¶
MemoryManager # 管理层(多集合管理)
↓
MemoryCollection # 集合层(VDB/KV/Graph)
↓
Storage + Search # 引擎层(存储 + 搜索)
↓
Backend # 后端层(Dict/Redis/RocksDB/FAISS/Chroma)
4. 可扩展性 ✅¶
- 新的存储后端:实现
BaseKVBackend - 新的索引后端:实现
BaseVDBIndex - 新的集合类型:继承
BaseMemoryCollection
5. 服务封装 ✅¶
services/ 目录提供了薄封装层:
NeuroMemVDB- 简化的 API(用于快速原型)NeuroMemVDBService- 标准服务(继承BaseService)
这使得 neuromem 可以被两种方式使用:
- 直接使用:
MemoryManager+VDBMemoryCollection - 通过服务:
NeuroMemVDBService(推荐)
💡 改进建议¶
虽然 neuromem 已经很完整,但仍有一些小的改进空间:
1. API 统一性 ⚠️¶
问题:
BaseMemoryCollection.insert()- 不需要指定索引VDBMemoryCollection.insert()- 需要指定索引VDBMemoryCollection.batch_insert_data()- 不需要指定索引
建议:
# 统一为两步操作
collection.insert(text, metadata) # 总是先存储
collection.create_index("index_name") # 可选:创建索引
collection.init_index("index_name") # 可选:索引化现有数据
或者提供参数:
2. 术语一致性 ⚠️¶
问题:
- 有时用
store,有时用insert - 有时用
retrieve,有时用recall(文档中)
建议:
- 统一使用
insert表示存储 - 统一使用
retrieve表示检索 - 或者明确区分:
store(持久化)vsinsert(插入)
3. 文档完善 📝¶
建议添加:
docs/NEUROMEM_USER_GUIDE.md- 用户指南docs/NEUROMEM_API_REFERENCE.md- API 参考docs/NEUROMEM_ARCHITECTURE.md- 架构设计文档
4. 类型提示 🔧¶
建议:
# 当前
def retrieve(self, query_text: str, index_name: str, topk: int = 5, ...):
# 建议:明确返回类型
def retrieve(
self,
query_text: str,
index_name: str,
topk: int = 5,
...
) -> List[Dict[str, Any]]: # 或定义 MemoryResult 类型
5. GraphMemoryCollection 实现 🚧¶
当前状态:
elif "graph" in backend_type:
# TODO: Graph Collection
# Issue URL: https://github.com/intellistream/SAGE/issues/648
new_collection = GraphMemoryCollection(name)
建议:
- 完成 Graph 类型的实现
- 或者明确标记为 experimental
📊 对比分析:neuromem vs RAG Operators¶
neuromem(记忆体组件)¶
- 职责:通用记忆管理系统
- 特点:
- 独立的存储和检索引擎
- 支持多种后端(FAISS, Chroma, Dict, Redis, RocksDB)
- 完整的数据生命周期管理
- 可被多个应用共享
RAG Operators(领域算子)¶
- 职责:RAG 流程中的特定操作
- 特点:
- 继承
MapOperator,符合 SAGE 算子接口 - 直接调用外部服务(Chroma, Milvus)
- 专注于 RAG 特定场景(检索-增强-生成)
- 与 Pipeline 集成
关系¶
RAG Pipeline
↓
RAG Operators (e.g., ChromaRetriever)
↓
External Service (e.g., chromadb)
(独立)
NeuroMem (通用记忆体)
↓
Services (NeuroMemVDBService)
↓
Applications
✅ 这是正确的架构:
- neuromem 是通用基础设施
- RAG operators 是领域特定功能
- 两者互不依赖,各司其职
✅ 最终结论¶
neuromem 作为独立记忆体组件的评估¶
| 维度 | 评分 | 说明 |
|---|---|---|
| 功能完整性 | ⭐⭐⭐⭐⭐ | 包含所有 store/recall 操作和数据结构 |
| 独立性 | ⭐⭐⭐⭐⭐ | 完全自包含,无外部依赖泄漏 |
| 架构清晰度 | ⭐⭐⭐⭐⭐ | 六层架构,职责明确 |
| 可扩展性 | ⭐⭐⭐⭐⭐ | 支持多种后端,易于扩展 |
| 代码质量 | ⭐⭐⭐⭐☆ | 良好,有小的改进空间 |
| 文档完善度 | ⭐⭐⭐☆☆ | 需要补充用户文档和 API 文档 |
| 测试覆盖 | ⭐⭐⭐⭐☆ | 有测试,但可以更全面 |
总评: ⭐⭐⭐⭐⭐ (5/5)
关键发现¶
✅ neuromem 已经是一个完整的记忆体组件:
- 所有 store/recall 操作都在 neuromem 内部实现
- 完整的记忆数据结构(文本、元数据、向量、索引)
- 独立的存储引擎和搜索引擎
- 多种后端支持(VDB、KV、Graph)
- 清晰的服务封装层
✅ 没有功能分散的问题:
- RAG operators 不依赖 neuromem(正确)
- 其他包不直接使用 neuromem 内部实现
- 依赖方向正确(L4 → L2 → L1)
建议¶
短期改进(可选)¶
- 统一 API 命名(insert vs store)
- 完善类型提示
- 添加用户文档
长期改进(建议)¶
- 完成 GraphMemoryCollection 实现
- 增加集成测试
- 性能优化和基准测试
结论¶
neuromem 的设计已经非常优秀,完全符合"独立记忆体组件"的设计目标。不需要进行架构级别的重构或迁移。建议保持当前设计,专注于文档完善和功能增强。
📚 参考资料¶
- neuromem 代码:
packages/sage-middleware/src/sage/middleware/components/sage_mem/neuromem/ - 服务封装:
packages/sage-middleware/src/sage/middleware/components/sage_mem/services/ - 测试代码:
packages/sage-middleware/tests/components/sage_mem/ - 相关文档:
docs-public/docs_src/dev-notes/package-architecture.md