记忆系统 (Memory System) - GraphRAG
PeroCore 的记忆系统是一个增强型的 GraphRAG(基于图的检索增强生成) 数据库。它在传统向量检索的基础上,引入了 加权图遍历 (Weighted Graph Traversal) 机制,让 AI 能够通过逻辑关联检索信息,而不仅仅是关键词匹配。
1. 核心架构 (Core Architecture)
记忆系统采用 Python + Rust 的混合架构,兼顾了业务逻辑的灵活性和计算的高性能。
Python 层负责存储和业务逻辑,Rust 层作为计算引擎处理向量搜索和图谱遍历。
用户输入
向量化
(SQLModel)
读写
记忆服务
向量查询↓
激活节点
意图引擎 (SIMD)
初始能量→
认知图谱 (扩散激活)
2. 核心组件 (Core Components)
2.1. 图遍历引擎 (Graph Traversal Engine)
位于 backend/rust_core,这是记忆系统的核心。它维护了一个内存中的动态图结构。
PEDSA 算法 (Parallel Energy-Decay Spreading Activation): 这是我们核心的加权图遍历算法。当一个记忆节点被检索命中(例如通过语义搜索或关键词锚点),搜索算法会沿着关联边(Edges)向四周进行加权传播。
- 动态剪枝 (Dynamic Pruning): 每层传播会限制激活节点数量(默认 10000),通过
select_nth_unstable_by快速选取 Top-K 能量节点,防止大规模图谱下的计算爆炸。 - 并行计算 (Parallelism): 利用 Rust 的 Rayon 库实现多线程并行能量扩散,通过
fold和reduce模式高效汇总节点增量。 - 负向抑制 (Inhibitory Signals): 支持“抑制边”(EdgeType 255),传播负向能量,用于模拟矛盾关系或降低不相关分支的权重。
- 权重衰减 (Decay): 能量随传播深度指数级衰减,确保只有紧密相关的上下文被激活。
- 动态剪枝 (Dynamic Pruning): 每层传播会限制激活节点数量(默认 10000),通过
Simulated CSR (Compressed Sparse Row): 为了极致的内存效率,我们在 Rust 中使用
SmallVec实现了一种动态的邻接表结构,模拟 CSR 的紧凑性,同时支持动态更新。这使得我们能够在有限的内存中存储数百万级的关联关系。
2.2. 向量检索引擎 (Vector Search Engine)
同样位于 backend/rust_core。
- SIMD 加速: 利用 AVX2 (x86) 或 NEON (ARM) 指令集加速向量点积运算(Cosine Similarity)。
- 功能: 负责将用户的自然语言输入转化为高维空间中的坐标,并快速定位图谱中的"入口节点"。
2.3. 存储层 (Storage Layer)
位于 backend/models.py 和 backend/services/memory_service.py。
- Memory Table: 存储记忆的具体内容、Embedding 向量和重要性权重。
- MemoryRelation Table: 存储记忆之间的关联(Edges),定义了图谱的拓扑结构。
- EntityCooccurrence Table: 统计 Entity 节点在同一批对话中共同出现的次数,用于检索时的共现增益计算。由 GraphGardener 在图谱构建时自动维护,无需人工干预。
- ConversationLog: 对话日志(Conversation Log),用于暂存短期对话流。
3. 记忆动力学 (Memory Dynamics)
PeroCore 的记忆不是静态存储的,而是具有动态权重,随时间推移和访问频率而变化。
3.1. 权重计算公式 (Weight Calculation)
检索时的最终得分(Retrieval Score)采用 混合加权机制:
- GraphScore (扩散分): 由 Rust 引擎 PEDSA 扩散计算得到的能量值。
- VectorScore (向量分): 语义检索得到的原始 Cosine Similarity。
- Importance (重要性权重): 0-10 的离散值,由 Scorer 评估或通过访问频率(Access Count)强化。
- Logarithmic Decay (对数时间衰减): 相比指数衰减,对数衰减能更好地保留“虽然久远但极度重要”的核心记忆。
3.2. 记忆强化机制 (Reinforcement Learning)
PeroCore 实现了类似神经元突触强化的机制:
- 访问计数 (Access Count): 每次记忆被成功检索,其
access_count加 1。 - 重要性强化: 每次被激活时,其
base_importance会获得微小提升,从而在未来的检索中拥有更高的竞争力,实现“常用的知识更深刻”。 - 思维簇 (Thinking Clusters):
ReflectionService会定期将记忆归类为“计划”、“社交”、“创造”、“知识”等簇,增强特定语境下的检索专注度。
4. 时序与上下文 (Temporal Context)
为了解决 RAG 系统常见的"碎片化"问题(即只检索到孤立的片段,丢失了前因后果),我们引入了双向链表结构。
- prev_id / next_id: 每个记忆节点都存储了其前驱和后继节点的 ID。
- 上下文注入: 在 Rust 图遍历过程中,除了语义关联,搜索也会沿着时间轴(Prev/Next)进行。
- 叙事重构: 当检索到一个关键事件时,系统会自动拉取其前后的节点,重组为一个完整的"情景记忆 (Episodic Memory)"片段,让 AI 理解事情的来龙去脉。
5. 后台维护服务 (Background Services)
记忆系统的健康运行依赖于一系列后台异步服务(Workers):
5.1. ScorerService (评分器)
- 职责: 实时监听
ConversationLog。 - 动作: 当一段对话结束,Scorer 会调用 LLM 分析对话内容,提取关键信息(Fact/Event),计算情感(Sentiment)和重要性,并生成新的记忆节点。
- 去噪: 自动过滤掉"Thinking"过程和无意义的寒暄,只保留核心交互。
5.2. ReflectionService (整合服务)
- 职责: 周期性维护长期记忆的质量。
- Consolidation (记忆整合): 扫描那些陈旧(>3天)且重要性较低(Importance < 4)的碎片记忆。
- 压缩: 调用 LLM 将这些碎片合并为一条更概括的"陈述性记忆"(例如将"周一吃了苹果"、"周二吃了香蕉"合并为"用户喜欢吃水果"),然后删除原始碎片。这极大地节省了存储空间并提高了检索质量。
6. 检索全流程详解 (Retrieval Pipeline v2)
当用户发送消息时,系统按以下 8 个步骤进行混合检索:
Anchor Position (锁点定位):
- 从用户输入中提取关键词,在
Memory表中查找type="entity"节点。 - 将匹配到的实体节点赋予高初始能量(默认 2.0),作为图扩散“入口”。
- 从用户输入中提取关键词,在
Vector Recall (向量召回):
- 使用 Embedding 对用户输入编码,从 VectorDB 召回 Top-20 语义相似候选节点,注入初始能量。
NMF Semantic Analysis (NMF 语义结构分析) (v2 新增):
- 对 Entity 嵌入矩阵执行非负矩阵分解(Multiplicative Update NMF),得到 k 个语义主题向量组成的基矩阵 H。
- 将查询向量投影到主题空间,输出三个诊断指标:
semantic_depth(聚焦度)、topic_coverage(主题覆盖数)、novelty(新颖度)。 - 基矩阵按 Agent 缓存,Entity 集合不变时跳过重算。
Sparse Coding Residual (稀疏编码残差) (v2 新增, 由 NMF novelty 门控):
novelty超过阈值时触发:使用 FISTA 算法求解 LASSO 问题,得到查询的最稀疏 Entity 表示。- 计算残差向量
R = query - reconstruction,若残差范数足够大,以 R 为新查询发起二次向量检索,发现被主流结果逐蔽的次要意图。
PEDSA + PPR Graph Spreading (PEDSA + 回家概率图扩散 - Rust) (v2 增强):
- 将所有能量注入 Rust
CognitiveGraphEngine,执行 2 跳 PEDSA 扩散。 - 新增
teleport_alpha回家概率:每步传播能量乘以(1-α),每步结束后将种子节点能量按α混合回初始値,防止能量在大图谱中发散到无关区域。
- 将所有能量注入 Rust
Co-occurrence Boost (共现增益) (v2 新增):
- 查询
EntityCooccurrence表,获取本次锁点 Entity 的历史共现邻居。 - 对共现邻居施加对数阻尼增益:
bonus = score × log(1 + co_count) × scale,叠加在 PEDSA 扩散分上。
- 查询
Multi-dimensional Ranking (多维重排):
- 应用混合评分公式,结合 GraphScore、VectorScore、Importance 和对数时间衰减,按综合分降序排列全部候选。
DPP Diversity Sampling (DPP 多样性采样) (v2 新增):
- 从排序后取
limit × multiplier个候选,构建质量加权 L-ensemble 核矩阵。 - 使用贪心行列式点过程(DPP)选取
limit个内容多样且质量高的记忆,避免语义重叠的记忆重复占位。
- 从排序后取
Reconstruction (语境重构):
- 根据选定记忆的
prev_id和next_id自动拉取前后上下文,格式化为自然语言文本注入 Prompt。
- 根据选定记忆的
运行时参数调控: 所有 v2 增强算法的开关与参数均通过
backend/retrieval_params.json配置,支持热更新(修改文件后下次检索自动生效,无需重启服务)。
7. 数据结构 (Data Structures)
7.1. Memory Node (记忆节点)
class Memory(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
content: str
type: str = "event" # entity(实体), event(事件), fact(事实), etc.
clusters: Optional[str] # 思维簇 (如 "计划", "社交")
# 权重与动力学
importance: int = 1 # 0-10 权重
base_importance: float # 基础重要性 (动态强化)
access_count: int = 0 # 激活次数
last_accessed: datetime # 最后激活时间
# 时序上下文 (Linked List)
timestamp: float # 毫秒级时间戳
prev_id: Optional[int]
next_id: Optional[int]
agent_id: str = "pero" # 隔离多 Agent
embedding_json: str # 向量数据7.2. Relation Edge (关联边)
class MemoryRelation(SQLModel, table=True):
source_id: int
target_id: int
strength: float # 0.0 - 1.0 (映射到 Rust u16)
relation_type: str # associative, causal, thematic, temporal, inhibitory7.3. Entity Co-occurrence (实体共现统计)
class EntityCooccurrence(SQLModel, table=True):
entity_a_id: int # Entity 节点 A 的 ID(较小值)
entity_b_id: int # Entity 节点 B 的 ID(较大值)
co_count: int # 在同一批对话中共同出现的次数
agent_id: str # 所属 Agent(多 Agent 隔离)8. 开发者指南 (Developer Guide)
如果你需要修改记忆系统,请参考以下文件:
- 核心算法 (Rust):
backend/rust_core/src/lib.rs(PEDSA + PPR 实现) - 向量搜索 (Rust):
backend/rust_core/src/intent_engine.rs - 检索编排 (Python):
backend/services/memory/memory_service.py(8 层检索管线) - 检索增强算法 (Python):
backend/services/memory/retrieval_enhancer.py(NMF / FISTA / DPP / 共现增益) - 图谱构建 (Python):
backend/services/memory/reflection_service.py(GraphGardener + 共现统计) - 数据模型 (Python):
backend/models.py(Memory / MemoryRelation / EntityCooccurrence) - 运行时参数:
backend/retrieval_params.json(热更新,无需重启)
