【大模型记忆-Mem0详解-6】核心组件-图形记忆
架构概述
Graph Memory 与 Mem0 的向量存储一起作为并行存储系统运行,自动从对话数据中提取实体和关系并将其存储在图形数据库中。该系统使用 LLM 进行实体提取和关系建立,然后将结构化数据存储在支持的图形数据库中。
系统集成
核心组件
MemoryGraph 类
MemoryGraph
类充当图形作的主要接口,具有针对不同图形数据库的特定于提供商的实现。
实体提取工具
该系统使用结构化的 LLM 工具从自然语言输入中提取实体并建立关系。
工具 | 目的 | 输入 | 输出 |
---|---|---|---|
EXTRACT_ENTITIES_TOOL | 从文本中提取实体和类型 | 自然语言文本 | 具有类型的实体列表 |
RELATIONS_TOOL | 建立实体之间的关系 | 文本和实体列表 | 源-关系-目标三元组列表 |
DELETE_MEMORY_TOOL_GRAPH | 确定要删除的关系 | 现有关系和新文本 | 要删除的关系 |
实体提取和关系管理
提取管道
图存储系统遵循多阶段流水线,将自然语言转换为结构化图数据。
实体解析和嵌入相似性
系统使用嵌入相似性来合并相似的实体并避免重复:
图作
核心业务
MemoryGraph 类提供了四个与主 Memory 类集成的主要作:
添加作
add()
方法处理新的对话数据并更新图表:
# From mem0/memory/graph_memory.py:75-93
def add(self, data, filters):entity_type_map = self._retrieve_nodes_from_data(data, filters)to_be_added = self._establish_nodes_relations_from_data(data, filters, entity_type_map)search_output = self._search_graph_db(node_list=list(entity_type_map.keys()), filters=filters)to_be_deleted = self._get_delete_entities_from_search_output(search_output, data, filters)deleted_entities = self._delete_entities(to_be_deleted, filters)added_entities = self._add_entities(to_be_added, filters, entity_type_map)return {"deleted_entities": deleted_entities, "added_entities": added_entities}
搜索作
search()
方法根据查询实体查找相关的图关系:
# From mem0/memory/graph_memory.py:95-129
def search(self, query, filters, limit=100):entity_type_map = self._retrieve_nodes_from_data(query, filters)search_output = self._search_graph_db(node_list=list(entity_type_map.keys()), filters=filters)# Re-rank results using BM25search_outputs_sequence = [[item["source"], item["relationship"], item["destination"]] for item in search_output]bm25 = BM25Okapi(search_outputs_sequence)tokenized_query = query.split(" ")reranked_results = bm25.get_top_n(tokenized_query, search_outputs_sequence, n=5)
会话和多租户支持
图形内存支持按 user_id
、agent_id
和 run_id
进行筛选,以实现适当的隔离:
滤波器 | 目的 | 用法 |
---|---|---|
user_id | 用户级隔离 | 所有作都需要 |
agent_id | 特定于代理的记忆 | 可选,用于多代理系统 |
run_id | 特定于会话的记忆 | 可选,用于对话会话 |
过滤是通过动态 Cypher 查询构造实现的:
# From mem0/memory/graph_memory.py:132-149
node_props = ["user_id: $user_id"]
if filters.get("agent_id"):node_props.append("agent_id: $agent_id")
if filters.get("run_id"):node_props.append("run_id: $run_id")
node_props_str = ", ".join(node_props)cypher = f"""
MATCH (n {self.node_label} {{{node_props_str}}})
DETACH DELETE n
"""
数据库提供程序集成
支持的图形数据库
Mem0 的 Graph Memory
通过一个通用接口支持多个图数据库提供者:
Neo4j 实现细节
Neo4j 实现使用特定的优化和索引策略:
- 向量相似性 :使用 vector.similarity.cosine() 进行实体匹配
- 索引创建 :创建复合索引以提高性能
- 标签策略 :使用带有可选自定义标签 Entity 基本标签
# From mem0/memory/graph_memory.py:43-56
self.node_label = ":`__Entity__`" if self.config.graph_store.config.base_label else ""if self.config.graph_store.config.base_label:try:self.graph.query(f"CREATE INDEX entity_single IF NOT EXISTS FOR (n {self.node_label}) ON (n.user_id)")except Exception:passtry:self.graph.query(f"CREATE INDEX entity_composite IF NOT EXISTS FOR (n {self.node_label}) ON (n.name, n.user_id)")except Exception:pass
Memgraph 实现细节
Memgraph
实现使用不同的过程和索引:
- 节点相似性 :用途 node_similarity.cosine_pairwise()
- 向量索引 :创建具有余弦度量的 memzero 向量索引
- 实体标签 :所有节点都获得用于向量搜索的实体标签
# From mem0/memory/memgraph_memory.py:60-80
embedding_dims = self.config.embedder.config["embedding_dims"]
index_info = self._fetch_existing_indexes()if not any(idx.get("index_name") == "memzero" for idx in index_info["vector_index_exists"]):self.graph.query(f"CREATE VECTOR INDEX memzero ON :Entity(embedding) WITH CONFIG {{'dimension': {embedding_dims}, 'capacity': 1000, 'metric': 'cos'}};")
配置和集成
内存类集成
Graph Memory
通过条件初始化集成到主 Memory 类中:
# From mem0/memory/main.py:141-149
self.enable_graph = Falseif self.config.graph_store.config:provider = self.config.graph_store.providerself.graph = GraphStoreFactory.create(provider, self.config)self.enable_graph = True
else:self.graph = None
并发处理
图形作与矢量存储作并行运行,以最大程度地减少延迟:
# From mem0/memory/main.py:258-265
with concurrent.futures.ThreadPoolExecutor() as executor:future1 = executor.submit(self._add_to_vector_store, messages, processed_metadata, effective_filters, infer)future2 = executor.submit(self._add_to_graph, messages, effective_filters)concurrent.futures.wait([future1, future2])vector_store_result = future1.result()graph_result = future2.result()
LLM 提供程序配置
图内存可以使用与主内存配置分开的专用 LLM 配置:
# From mem0/memory/graph_memory.py:58-71
self.llm_provider = "openai"
if self.config.llm and self.config.llm.provider:self.llm_provider = self.config.llm.provider
if self.config.graph_store and self.config.graph_store.llm and self.config.graph_store.llm.provider:self.llm_provider = self.config.graph_store.llm.providerllm_config = None
if self.config.graph_store and self.config.graph_store.llm and hasattr(self.config.graph_store.llm, "config"):llm_config = self.config.graph_store.llm.config
elif hasattr(self.config.llm, "config"):llm_config = self.config.llm.config
self.llm = LlmFactory.create(self.llm_provider, llm_config)