一、四层记忆架构总览Gliding Horse 的记忆系统模仿了 CPU 的缓存层次越靠近 LLM 的层级容量越小、速度越快但保存的是高度压缩的摘要越远离 LLM 的层级容量越大、速度越慢但保存的是完整的原始数据。投影/失效归档/加载归档/检索L0 持久化存储 (L0Store)sled KV 存储标签 命名图索引JSON-LD 节点合并L1 会话摘要链 (L1Session)摘要链 Token 预算两阶段语义淘汰L2 共享黑板 (Blackboard)DashMap 缓存 Oxigraph SPARQL任务树 DAGAgent 态势感知资源锁 权限矩阵L3 投影引擎 (ProjectionEngine)物化视图缓存 反向索引9个预定义投影帧每一层都有明确的职责边界L0基于 sled 的持久化存储保存所有原始数据全量可靠。L1每个 Agent 会话内的高压缩摘要链严格控制 Token 预算。L2多 Agent 共享的内存黑板基于 Oxigraph 图数据库提供实时协作与态势感知。L3按需从 L0/L2 提取子图并物化为视图起到“图虚拟内存”的作用。此外还有 一致性引擎 (MESI)、Hyperspace 向量引擎、预取引擎、记忆总线 和 调度器 等关键组件共同编织起整套记忆基础设施。二、L0 持久化存储永不丢失的“磁盘”L0 是整个记忆体系的基石。它使用高性能嵌入式数据库 sled 作为存储后端每个记忆条目都包含完整的 JSON-LD 内容以及丰富的元数据。pub struct L0Entry {pub iri: String,pub content: String, // 完整 JSON-LDpub importance: f32,pub access_count: u32,pub tags: Vec,pub mesi_state: MesiState,pub content_hash: String,pub named_graph: Option,pub qdrant_point_id: Option,pub jsonld_context: Option,pub jsonld_types: Vec,}关键设计JSON-LD 节点存储store_jsonld_node() 和 retrieve_jsonld_node() 提供了直接存取 JSON-LD 文档的能力并自动合并具有相同 id 的条目标签取并集、重要性取平均、内容保留较长者。多级索引标签二级索引tag:{tag}和命名图索引graph:{name}让检索不再只是线性扫描前缀范围扫描还能高效支持 IRI 前缀查询。与 Hyperspace 引擎联动写入 L0 时可以同步将嵌入向量存入 Hyperspace 引擎并在条目中记录向量索引信息打通语义搜索通道。L0 的定位是“永不丢失的全量记忆”但并不会直接暴露给 LLM。上层通过 IRI 引用按需拉取细节这正是 Token 控制的核心。三、L1 会话摘要链像 CPU L1 缓存一样精简L1 直接服务于 LLM 的上下文窗口是记忆系统中对 Token 最敏感的一层。它并不保存完整的对话内容而是将每一轮 LLM 的 summary 输出串联成一条摘要链。pub struct L1Session {turns: Vec,token_budget: usize,}pub struct L1Turn {pub role: String,pub summary: String,pub l0_archive_iri: Option, // 完整内容在 L0 的地址pub embedding: OptionVec,pub relevance_score: f32, // 当前任务关联度pub is_supplement: bool, // 是否为补充输入}两阶段语义淘汰当摘要链的 Token 总量超出预算时L1 并非简单截断而是执行一个两阶段淘汰策略硬阈值淘汰对 relevance_score 低于阈值默认 0.3且已超过安全窗口默认 5 分钟的条目直接移除但补充输入is_supplementtrue受到保护。评分淘汰对剩余条目计算得分综合语义相关度、最近访问时间和Token 成本三个因子得分最低的条目被淘汰。具体公式为score β * semantic_relevance (1-β) * (recency * w_r token_cost * w_c)其中 semantic_relevance 是该条目与当前查询的向量余弦相似度β 默认为 0.6。被淘汰的摘要并不会彻底消失它的 l0_archive_iri 会被移至一个弱引用列表Agent 随时可以通过此 IRI 从 L0 调取完整历史。这保证了即使上下文窗口被“清扫”记忆本身依然是完整的。四、L2 共享黑板多 Agent 协作的“工作内存”L2 是整个记忆系统中最高频的读写区域。它是一个基于 Oxigraph 图数据库 的内存黑板所有 Agent 实例都可以通过 SPARQL 直接查询和更新。核心能力节点缓存与持久化双写每个写入操作同时更新 DashMap 内存缓存和 Oxigraph 存储兼顾速度与持久性。任务树 DAG复杂任务可以被拆解为子任务并在 L2 中维护一棵有向无环图。拓扑排序、依赖检查、子树释放等功能让并行 Agent 协作变得井然有序。Agent 态势感知每个 Agent 在 L2 中注册自己的心跳和状态Idle/Working/Waiting/Completed/Error。超时未心跳的 Agent 会被自动检测防止“僵尸”进程占用资源。资源锁与权限矩阵对关键资源支持 Read/Write/Exclusive 三级锁并提供基于角色的图级权限控制CRUD保障并发安全。协调消息Agent 之间可以通过黑板发布/订阅协调消息实现松耦合通信。L2 的定位是“当前任务的工作区”。当任务完成后脏节点会被批量刷入 L0形成持久记忆。五、L3 投影引擎按需裁剪的“图虚拟内存”L3 是记忆系统的“内存管理单元MMU”。它不存储数据本身而是根据 Agent 的当前需求从 L0/L2 中实时裁剪出相关子图物化为 JSON-LD 视图。9 个预定义投影帧覆盖了常见的 Agent 上下文场景帧名 用途 目标角色summary_only 仅摘要 通用pa_init PA 初始化上下文 计划 Agentda_input DA 输入上下文 执行 Agentca_review CA 审查上下文 检查 Agentaa_decision AA 决策上下文 决策 Agenthealth_check 健康检查 运维error_analysis 错误分析 调试reference_only 仅引用数据 预取5w2h_summary 5W2H 摘要 通用每个投影帧本质上是一个预编译的 SPARQL CONSTRUCT 查询它决定了该角色“能看到什么、看到多少”。例如 pa_init 帧会提取当前任务相关的技能、历史决策和领域实体而不会包含庞大的代码详情。物化视图缓存 反向索引 O(1) 失效一旦从 L0/L2 提取出子图L3 会将其缓存。当某个节点的数据发生变更时反向索引可以在 O(1) 时间内定位到所有包含该节点的物化视图并将其标记为失效。这种机制既保证了视图的实时性又避免了每次请求都重新执行昂贵的图查询。Token 预算控制project_with_budget() 允许指定最大 Token 数如果投影结果过大会自动截断或降级为更轻量的引用模式确保上下文窗口不会超限。六、周边关键组件Hyperspace 向量引擎记忆的语义检索能力由 Hyperspace Engine 提供。它并非单一的外部向量数据库而是一个融合了多种嵌入空间与索引策略的统一向量计算层。与黑箱式的外部服务不同Hyperspace Engine 深度集成在流马内核中与 JSON‑LD 图存储共享同一个 Arc实现了零拷贝的语义增强。其核心能力包括双空间嵌入每个实体都可以获得两种嵌入表示——文本嵌入用于常规语义相似度和结构嵌入基于 Poincaré 双曲空间专门捕捉类层次结构。Poincaré 嵌入使得“检查 Agent”和“执行 Agent”这种在文本上差异巨大的概念在结构空间中却非常接近。混合搜索支持向量相似度与结构化过滤标签、类型、命名图、重要性范围的联动查询。例如可以高效检索“带有 auth 标签、类型为 DesignDecision 且语义上与‘JWT 密钥长度’最相似的记忆”。自动降级与多后端引擎可以根据配置自动切换后端——生产环境可对接 OpenAI 兼容 API 或本地 ONNX 模型测试环境则使用轻量级的哈希降级方案始终保证可用性。与 L0/L3 无缝集成写入 L0 的节点可自动生成嵌入并存入 Hyperspace EngineL3 投影引擎在做语义投影时会并行发起 SPARQL 结构查询和 Hyperspace 语义搜索最终按可配置的权重混合排序兼顾精确与模糊。预取引擎基于意图驱动的预取机制能够主动预测 Agent 即将需要的数据。当 SA 检测到任务意图发生变化时预取引擎会从当前涉及的实体出发沿知识图谱做 BFS 扩展默认 2 跳根据衰减因子排序后选取 Top-K 个相关实体异步加载到 L2 缓存。这种“想 Agent 之所想”的设计大幅减少了上下文切换时的等待延迟。一致性引擎 (MESI)借鉴 CPU 的 MESI 缓存一致性协议记忆系统在多 Agent 并发写入时保持数据一致。每个 L0/L2 的节点都携带有状态标记Modified/Exclusive/Shared/Invalid。当 L2 中的节点被修改引擎会根据数据的关键程度自动选择 WriteThrough关键标签如用户意图、确认事实或 WriteBack普通推理中间结果并通过记忆总线广播失效事件确保所有层最终一致。记忆总线与调度器MemoryBus 作为轻量级事件总线负责传递缓存失效、预取请求等信号。MemoryScheduler 则统一调度上下文请求根据 Agent 角色自动匹配对应的 L3 投影帧并提供 L3→L2→L0 的三级回退读取路径。七、给平台带来的核心优势Token 经济性通过“摘要 IRI”取代“全文”将上下文 Token 消耗从 O(n) 降为 O(1)长对话场景下 Token 节省超过 40%。长程记忆能力Agent 可以随时通过 IRI 回溯任意历史轮次的完整细节真正摆脱了“失忆”困境。多 Agent 协作安全MESI 一致性、资源锁和权限矩阵让多个 Agent 可以像多核 CPU 一样安全地共享和修改记忆。可追溯与可审计所有记忆都以 JSON-LD 节点形式存储拥有全球唯一 IRI任何决策都能被精确溯源。自适应淘汰基于语义相关度的淘汰策略让记忆系统在有限的 Token 预算内始终保留最重要的信息。主动性预取引擎和 L3 投影让系统能提前准备好 Agent 所需的知识而非被动等待请求。层次化语义搜索Hyperspace 引擎的双空间嵌入让系统既能理解“文本相似”也能理解“结构相似”在模式识别与知识关联上远超普通向量检索。八、结语Gliding Horse 的记忆系统不是简单的“对话历史存储”而是一套借鉴计算机体系结构思想、面向 AI Agent 深度定制的认知基础设施。它将 JSON-LD 的语义能力、图数据库的查询能力、Hyperspace 引擎的双空间嵌入能力以及操作系统的缓存一致性思想融为一体为构建可信赖、可演化的自主 Agent 提供了坚实的基座。如果你正在探索如何让 AI Agent 拥有真正的长期记忆欢迎来 GitHub 交流https://github.com/doiito/gliding_horse。九、实战示例L1Session 两阶段淘汰模拟下面通过一个完整的 Rust 代码示例展示如何初始化 L1Session 并模拟其两阶段淘汰策略。该示例定义了 L1Turn 结构、计算淘汰分数以及触发淘汰的完整流程。use std::time::{Duration, Instant};/// 单轮对话摘要#[derive(Clone, Debug)]pub struct L1Turn {pub role: String,pub summary: String,pub l0_archive_iri: Option,pub relevance_score: f32,pub is_supplement: bool,pub created_at: Instant,pub token_cost: usize,}/// L1 会话摘要链pub struct L1Session {pub turns: Vec,pub token_budget: usize,}impl L1Session {pub fn new(token_budget: usize) - Self {Self {turns: Vec::new(),token_budget,}}/// 添加一轮摘要 pub fn add_turn(mut self, turn: L1Turn) { self.turns.push(turn); } /// 计算当前总 Token 数 pub fn total_tokens(self) - usize { self.turns.iter().map(|t| t.token_cost).sum() } /// 两阶段淘汰 pub fn evict(mut self, query_embedding: [f32]) { let now Instant::now(); let safe_window Duration::from_secs(300); // 5 分钟 // 阶段一硬阈值淘汰 self.turns.retain(|turn| { if turn.is_supplement { return true; // 补充输入受保护 } let age now.duration_since(turn.created_at); !(turn.relevance_score 0.3 age safe_window) }); // 阶段二评分淘汰直到总 Token 低于预算 while self.total_tokens() self.token_budget !self.turns.is_empty() { let beta 0.6; let w_r 0.5; let w_c 0.5; // 找到得分最低的条目 let idx self .turns .iter() .enumerate() .map(|(i, turn)| { let semantic_relevance cosine_similarity( query_embedding, turn.relevance_score, ); let age now.duration_since(turn.created_at); let recency 1.0 / (1.0 age.as_secs_f32()); let token_cost 1.0 / (1.0 turn.token_cost as f32); let score beta * semantic_relevance (1.0 - beta) * (recency * w_r token_cost * w_c); (i, score) }) .min_by(|a, b| a.1.partial_cmp(b.1).unwrap()) .map(|(i, _)| i) .unwrap(); // 移除得分最低的条目保留 l0_archive_iri 到弱引用列表 let removed self.turns.remove(idx); println!( 淘汰条目: role{}, summary{:.20}..., score{:.4}, removed.role, removed.summary, removed.relevance_score ); } }}/// 简化的余弦相似度实际应使用 Hyperspace 引擎的向量fn cosine_similarity(a: [f32], b: [f32]) - f32 {let dot: f32 a.iter().zip(b.iter()).map(|(x, y)| x * y).sum();let norm_a: f32 a.iter().map(|x| x * x).sum::().sqrt();let norm_b: f32 b.iter().map(|x| x * x).sum::().sqrt();if norm_a 0.0 || norm_b 0.0 {0.0} else {dot / (norm_a * norm_b)}}fn main() {let mut session L1Session::new(200); // Token 预算 200// 模拟添加 5 轮对话摘要 let turns vec![ L1Turn { role: user.into(), summary: 用户询问如何配置 JWT 认证.into(), l0_archive_iri: Some(mem://jwt-config.into()), relevance_score: 0.9, is_supplement: false, created_at: Instant::now(), token_cost: 60, }, L1Turn { role: assistant.into(), summary: 提供了 JWT 密钥生成和验证的代码.into(), l0_archive_iri: Some(mem://jwt-code.into()), relevance_score: 0.85, is_supplement: false, created_at: Instant::now(), token_cost: 80, }, L1Turn { role: user.into(), summary: 补充说明需要支持 RS256 算法.into(), l0_archive_iri: Some(mem://rs256-supplement.into()), relevance_score: 0.2, // 低相关度 is_supplement: true, // 补充输入受保护 created_at: Instant::now() - Duration::from_secs(400), // 超过 5 分钟 token_cost: 40, }, L1Turn { role: user.into(), summary: 用户切换到讨论数据库连接池.into(), l0_archive_iri: Some(mem://db-pool.into()), relevance_score: 0.1, // 低相关度 is_supplement: false, created_at: Instant::now() - Duration::from_secs(600), // 超过 5 分钟 token_cost: 50, }, L1Turn { role: assistant.into(), summary: 提供了 HikariCP 配置示例.into(), l0_archive_iri: Some(mem://hikari-example.into()), relevance_score: 0.15, // 低相关度 is_supplement: false, created_at: Instant::now() - Duration::from_secs(600), // 超过 5 分钟 token_cost: 70, }, ]; for turn in turns { session.add_turn(turn); } println!(淘汰前总 Token: {}, session.total_tokens()); println!(淘汰前条目数: {}, session.turns.len()); // 模拟查询向量实际由 Hyperspace 引擎生成 let query_embedding vec![0.5, 0.3, 0.8, 0.1]; session.evict(query_embedding); println!(淘汰后总 Token: {}, session.total_tokens()); println!(淘汰后条目数: {}, session.turns.len()); for turn in session.turns { println!( 保留: role{}, summary{:.30}..., relevance{:.2}, turn.role, turn.summary, turn.relevance_score ); }}运行结果分析硬阈值淘汰第 4、5 轮数据库连接池相关的 relevance_score 低于 0.3 且超过 5 分钟被直接移除。第 3 轮虽然是低相关度且超时但因为 is_supplementtrue 受到保护得以保留。评分淘汰剩余条目总 Token 为 180608040未超过预算 200因此无需进入评分淘汰阶段。如果预算设为 150则系统会计算各条目的综合得分淘汰得分最低的条目。记忆完整性被淘汰的条目仍可通过 l0_archive_iri 从 L0 存储中完整恢复实现了“上下文窗口有限但记忆无限”的设计目标。