# 记忆子网 — 训练目标与训练计划 ## 概述 记忆子网类比人脑的**海马体与皮层**,负责记忆的存储、检索和管理。采用**三层记忆架构**:**文本记忆**(短对话临时工作区)、**向量记忆**(语义检索)、**图记忆**(结构化知识)。 > 图数据库记忆设计参考了 [TrulyMEM-TrueHumanMEM](https://jianfgit.xyz:220/jianf/TrulyMEM-TrueHumanMEM.git) 项目。 ### 架构定位 记忆子网是整个 NextAgent 架构中**唯一与记忆内容交互的模块**。Core 不自作主张处理记忆——只负责将查询张量和新信息张量传递过来,**如何更新、删除、修改**由记忆子网自行完成。 ``` Core 传过来的两样东西 │ ┌─────────┴────────────┐ │ │ 查询张量 新信息张量 (含意图/种子实体) (含本轮标签/结果) │ │ └─────────┬────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────┐ │ 记忆子网(自治) │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ 记忆管理器 (Memory Manager) │ │ │ │ 自行决定: │ │ │ │ → 如何解析查询 → 走文本/向量/图记忆 │ │ │ │ → 如何写入新信息 → 先入文本记忆再处理 │ │ │ │ → 如何更新 → 冲突合并/覆盖/增量 │ │ │ │ → 如何删除 → 软删除/硬删除/归档 │ │ │ │ → 如何关联 → 链路推理/图谱推理 │ │ │ └──────┬─────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ 文本记忆(临时工作区) │ │ │ │ 近期对话内容,按时间顺序追加,容量有限 │ │ │ └─────────────────────┬────────────────────────────┘ │ │ │ 定期扫描 (每 N 轮/定时) │ │ ▼ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ 记忆处理流水线 │ │ │ │ │ │ │ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐│ │ │ │ │ 拆解 │────→│冲突合并│────→│相似合并│────→│分路写入││ │ │ │ └──────┘ └──────┘ └──────┘ └──┬───┘│ │ │ │ │ │ │ │ └───────────────────────────────────────────────┼────┘ │ │ │ │ │ ┌──────────────────────────────────┼──┐ │ │ ▼ ▼ │ │ ┌─────────────────────┐ ┌─────────────────────────┐ │ │ │ 图记忆 │ │ 向量记忆 │ │ │ │ (结构化知识) │ │ (语义向量) │ │ │ │ Entity / RELATES │ │ 索引 + 相似度搜索 │ │ │ │ Cypher 查询 │ │ │ │ │ └─────────────────────┘ └─────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ 张量编/解码层 │ │ │ │ 输入:查询张量 + 新信息张量(来自 Core) │ │ │ │ 输出:记忆结果张量(返回给 Core) │ │ │ └────────────────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────┘ ``` ## 三层记忆 ### 第一层:文本记忆(Text Memory)— 临时工作区 类似人脑工作记忆,保存近期对话内容,按时间顺序追加。容量有限,保证短对话内的上下文连续性。由记忆子网定期处理(拆解/冲突合并/相似合并/分路写入)。 | 项目 | 说明 | |------|------| | 存储内容 | 近期对话原始文本 | | 管理方式 | 按时间顺序追加,溢出时丢弃最旧内容 | | 处理时机 | 每 N 轮对话或定时触发 | | 用途 | 短期对话连续性,记忆处理源 | ### 第二层:向量记忆(Vector Memory)— 语义检索 存储经过嵌入的语义向量,支持语义相似度检索。长对话连续性关键组件之一。 | 项目 | 说明 | |------|------| | 索引类型 | IVF_FLAT / HNSW | | 向量维度 | 768 (匹配标准张量维度) | | 度量方式 | Cosine Similarity | | 分片策略 | 按时间桶 + 会话 ID 分片 | ### 第三层:图记忆(Graph Memory)— 结构化知识 实体-关系图,存储用户偏好、知识图谱等结构化信息。长对话连续性关键组件之二。 **参考 TrulyMEM 的图数据库设计:** #### 节点 (Entity) 类型 | 节点类型 | Node Label | 属性 | 说明 | |----------|-----------|------|------| | 人设节点 | PersonaNode | name, type, created_at | AI 角色、性格、语气 | | 任务节点 | TaskNode | task_id, description, state, created_at | 任务概述与状态 | | 状态节点 | StateNode | name, value, timestamp | 任务或实体的状态 | | 信息节点 | InfoNode | name, content, source, confidence | 具体信息 | | 实体节点 | EntityNode | name, type, mention_count, updated_at | 通用实体 | #### 边 (RELATES) 类型 | 边类型 | 说明 | 示例 | |--------|------|------| | `HAS_PERSONA` | 人设关联 | AI → PersonaNode | | `NEXT_TASK` | 任务时间链 | TaskNode → TaskNode | | `HAS_STATE` | 状态关联 | TaskNode → StateNode | | `CONTAINS_INFO` | 信息包含 | TaskNode → InfoNode | | `RELATES_TO` | 通用关联 | EntityNode → EntityNode | #### 索引设计 ```cypher // 实体约束 CREATE CONSTRAINT entity_name_constraint IF NOT EXISTS FOR (e:Entity) REQUIRE e.name IS UNIQUE CREATE CONSTRAINT session_id_constraint IF NOT EXISTS FOR (s:Session) REQUIRE s.session_id IS UNIQUE // 关系索引 CREATE INDEX rel_created_at IF NOT EXISTS FOR ()-[r:RELATES]-() ON r.created_at CREATE INDEX rel_type IF NOT EXISTS FOR ()-[r:RELATES]-() ON r.type CREATE INDEX rel_status IF NOT EXISTS FOR ()-[r:RELATES]-() ON r.status CREATE INDEX rel_date_bucket IF NOT EXISTS FOR ()-[r:RELATES]-() ON r.date_bucket // 实体索引 CREATE INDEX entity_type IF NOT EXISTS FOR (e:Entity) ON e.type CREATE INDEX entity_mention_count IF NOT EXISTS FOR (e:Entity) ON e.mention_count ``` #### 检索示例 ```cypher -- 关键字检索 MATCH (e:Entity)-[r:RELATES]->(t:Entity) WHERE r.status = 'active' AND (toLower(e.name) CONTAINS '关键词' OR toLower(t.name) CONTAINS '关键词') RETURN e, r, t ORDER BY r.created_at DESC LIMIT 30 -- 会话隔离检索 MATCH (e:Entity)-[r:RELATES]->(t:Entity) WHERE r.session_id = $session_id AND r.status = 'active' RETURN e, r, t -- 热点实体查询 MATCH (e:Entity) RETURN e.name, e.mention_count, e.type ORDER BY e.mention_count DESC LIMIT 10 ``` ## 输入/输出 | 项目 | 说明 | |------|------| | **输入1** | 查询张量,fmt_id=2,来自 Core(编码后的查询意图、种子实体) | | **输入2** | 新信息张量,fmt_id=3,来自 Core(编码后的本轮更新数据;**不含具体写入指令**) | | **输出** | 记忆结果张量,fmt_id=1,编码检索到的实体/关系向量 | | **自治** | 记忆子网自行决定如何写入、更新、删除、修改记忆 | ## 训练目标 ### 目标 1:图数据库检索准确率 | 指标 | 目标值 | 说明 | |------|--------|------| | 检索召回率 (Recall@10) | ≥ 90% | 对于已知关系的检索 | | 检索精确率 (Precision@10) | ≥ 85% | 检索结果的相关性 | | 关系推理准确率 | ≥ 80% | 通过图路径推理发现隐含关系 | ### 目标 2:向量检索能力 | 指标 | 目标值 | 说明 | |------|--------|------| | 语义检索 Recall@10 | ≥ 85% | 向量相似度检索 | | 跨模态检索准确率 | ≥ 80% | 文本→图像/语音的跨模态检索 | | 索引构建时间 | ≤ 100ms/1000条 | 向量索引增量更新 | ### 目标 3:记忆关联发现 | 指标 | 目标值 | 说明 | |------|--------|------| | 关联发现 F1 | ≥ 75% | 自动发现实体间的隐含关系 | | 记忆合并准确率 | ≥ 90% | 重复实体的合并不引入错误 | | 因果链路发现 | ≥ 70% | 从事件序列中发现因果关系 | ### 目标 4:工作记忆管理 | 指标 | 目标值 | 说明 | |------|--------|------| | 上下文切换延迟 | ≤ 10ms | 工作记忆的热区缓存命中率 | | 工作记忆容量 | 4096 tokens | 每轮有效上下文 | | 缓存命中率 | ≥ 80% | 热区缓存有效减少冷区访问 | ## 训练计划 ### 阶段 1:图数据库操作基座(无训练) **目标**:构建 Neo4j 图数据库操作层,建立基础检索和写入能力 **实现**: - 实现 Cypher 查询模板系统 - 实现 MERGE / CREATE 写入逻辑 - 实现会话隔离和索引管理 - 实现软删除和归档机制 参考 TrulyMEM 的 `graph_client.py` 实现: ```python class Neo4jGraph: def recall(self, query_intent, seed_entities, depth=2): """检索记忆 - Cypher 驱动""" # 关键词解析 → 构造 WHERE 子句 # 支持深度扩展(depth 参数) # 返回实体列表 + 关系列表 def commit(self, triplets, entity_types, temporal_tag): """写入记忆 - MERGE + CREATE""" # 逐条写入三元组 # 自动维护 mention_count # 记录会话和轮次信息 def purge(self, criteria, mode="soft", new_relation=None): """删除/修正记忆""" # soft: 标记 status='deleted' # supersede: 标记旧关系 + 创建新关系 ``` ### 阶段 2:图神经网络关联学习 **目标**:训练 GNN 模型进行知识关联推理 **技术路线**: - 模型:R-GCN (Relational Graph Convolutional Network) 或 CompGCN - 或 使用 GraphSAGE + 关系注意力 **训练步骤**: 1. 构建知识图谱训练集:从现有图数据库中采样子图 2. 链接预测任务 (Link Prediction):预测两个实体之间是否存在关系 3. 实体分类任务 (Entity Classification):预测实体类型 4. 损失函数:交叉熵 + 对比损失 (margin-based ranking loss) 5. 训练 200 epochs,使用 Adam 优化器,learning rate 1e-3 6. 评估:在验证集上计算 Hits@K 和 MRR ### 阶段 3:Memory-Augmented Neural Networks (MANN) **目标**:训练记忆增强网络,实现高效的读写操作 **技术路线**: - 模型:Differentiable Neural Computer (DNC) 或 Neural Turing Machine (NTM) - 外部记忆矩阵 + 读写头 **训练步骤**: 1. 合成任务训练:copy task, repeat copy, associative recall 2. 问答任务训练:bAbI 数据集,测试记忆存取能力 3. 长序列建模:训练在长上下文中准确索引信息 4. 添加注意力读写机制 5. 损失函数:任务损失 + 记忆使用正则化 ### 阶段 4:引用-拉取策略训练 **目标**:训练决定何时拉取(从冷区)、何时缓存的策略 **技术路线**: - 强化学习:基于记忆访问模式的 RL - 状态:当前任务类型、历史访问模式、缓存状态 - 动作:拉取/缓存/不操作 - 奖励:访问延迟降低 + 缓存命中率 **训练步骤**: 1. 构建模拟环境:包含热区缓存、图数据库、向量数据库 2. 收集真实交互日志作为训练数据 3. 训练策略网络(Policy Network) 4. 使用 PPO 算法优化策略 5. 评估:缓存命中率、平均访问延迟 ### 阶段 5:端到端联合训练 **目标**:将以上阶段整合,与路由子网、逻辑子网联合训练 **训练步骤**: 1. 固定路由子网的输出作为记忆子网的查询输入 2. 使用多任务训练:图检索 + 向量检索 + 关联发现 3. 损失函数:L = L_retrieval + α * L_link + β * L_cache + γ * L_reg 4. 与 Core 的启发式调度策略联合优化 ## 评估指标体系 ### 离线评估 | 指标 | 计算方法 | 目标 | |------|----------|------| | 图检索 Recall@10 | 检索结果中包含正确答案的比例 | ≥ 90% | | 向量检索 Recall@10 | 按语义相似度排序的召回率 | ≥ 85% | | 关联推理 MRR | Mean Reciprocal Rank | ≥ 0.7 | | 记忆写入一致性 | 写入后检索与原始一致 | ≥ 99% | | 缓存命中率 | 热区缓存直接命中的比例 | ≥ 80% | ### 在线评估 | 指标 | 说明 | |------|------| | 记忆检索延迟 | Core 发出查询到收到结果的时间 | | 记忆更新延迟 | Core 发出更新到写入完成的时间 | | 信息一致性 | 同一信息多次检索结果是否一致 | | 记忆容量 | 在不显著降低性能前提下的最大存储量 | ## 新信息张量格式 Core 传递给记忆子网的**新信息张量**遵循统一通信张量协议: ### 协议定义 ``` 格式: 统一通信张量 (纯数值张量) prefix[0] = fmt_id = 3 (memory_update) prefix[1] = parser_id = 3 (memory_update_parser) payload: 编码后的记忆更新数据 实体编码: [entity_ids..., entity_embeddings...] 关系编码: [relation_ids..., relation_embeddings...] 会话标识: [session_tag, turn_tag, ...] ``` 实体、关系、会话信息通过子网内部的编解码适配器转为张量表示。 ### 记忆子网内部格式(私有) 记忆子网内部维护以下私有数据结构,但**对外通信时始终通过统一协议编解码为纯张量**: ```python # 内部数据模型(子网私有,不对外暴露) @Entity default_graph = { "entities": [ {"name": "用户_张三", "type": "PersonaNode", "preference": "摇滚音乐"}, {"name": "项目_NextAgent", "type": "EntityNode"} ], "relations": [ {"subject": "用户_张三", "relation": "HAS_PERSONA", "object": "喜欢_摇滚", "confidence": 0.95}, {"subject": "用户_张三", "relation": "RELATES_TO", "object": "项目_NextAgent", "confidence": 0.9} ] } # 编码适配器将内部数据 → 统一通信张量 # 解码适配器将统一通信张量 → 内部查询结构 def encode_memory_update(entities, relations, session_id, turn_id) -> Tensor: """内部格式 → 统一通信张量 1. 将实体名/关系名编码为 embedding 向量 2. 拼接会话标识和时间戳 3. 编码适配器: 查表 fmt_id=3, 拼接前缀 """ entity_embeds = embed_entity_names(entities) # [n_entities, 768] relation_embeds = encode_relations(relations) # [n_relations, 768] meta = tensor([session_hash, turn_id]) # [2] return codec.encode(fmt_id=3, parser_id=3, data=concat(entity_embeds, relation_embeds, meta)) def decode_memory_query(comm_tensor: Tensor) -> QueryIntent: """统一通信张量 → 内部查询意图 1. codec.decode(comm_tensor) 剥离前缀 2. 将 payload 张量解码为查询条件 3. 返回: 图DB检索参数 / 向量检索参数 """ payload = codec.decode(comm_tensor) # 剥离 fmt_id=2 query_embed = payload[:768] return self.query_embed_to_params(query_embed) ```