# 时序上下文如何解决 Agent 记忆过期：四个机制与两条开源路线

- 来源：AYi (@AYi_AInotes)
- 发布时间：2026-08-18 17:40
- AIHOT 分数：63
- AIHOT 链接：https://aihot.virxact.com/items/cmsyikhhq0wmrroz02ca5102v
- 原文链接：https://x.com/AYi_AInotes/status/2089648609671172441

## AI 摘要

阿易 AI Notes 指出，向量检索无法表达“新事实取代旧事实”，导致 Agent 回答矛盾（如预算 50 万与 30 万并存）。文章拆解时序上下文四个核心机制：有效期、取代关系、软删除与审计日志，并对比 Graphiti 与 OpenContext 两条开源路线。

## 正文

https://x.com/i/article/2089627201750650880

我终于想明白 RAG 为什么治不了 Agent 记忆过期：时序上下文的四个机制、两条开源路线和真实边界实操

做 RAG 应用，最危险的不是检索不到，而是新旧事实一起被检索出来：客户三月确认预算 50 万，六月改成 30 万，Agent 却回答 "预算在 30 万到 50 万之间"。

我起初以为加时间戳、按最新排序就能解决，后来才发现：

时间戳只能判断先后，不能表达 "新事实已经取代旧事实"。普通向量库把两条记录平行召回，塞进 Prompt，最后还是让模型猜哪条是真的。

这不是偶发 bug，是向量检索的结构性缺陷。这篇跟大家保姆级拆解时序上下文的四个核心机制，以 Graphiti 和 OpenContext 为参照，讲清怎么落地、怎么选，以及它解决不了什么。

先看事故现场

构造一个最小案例，假设你在给一家律所做 Agent，知识库里有这样几条记录：

现在问 Agent 三个问题：

1. 客户 A 的项目预算是多少？

1. 这个项目现在谁负责？

1. 当前有效的合同版本是哪个？

如果你用标准 RAG——文本切分、向量化、top-k 召回、拼进 Prompt——大概率会出现这些情况：

• 问预算，同时召回"50 万“和”30 万"两条，模型要么取其一，要么含糊其辞；

• 问负责人，可能召回张律师、李律师、王律师三条，模型不知道哪条是当前状态；

• 问合同版本，V2 和 V3 的语义相似度几乎一样高，检索无法区分。

其实并不是模型不够聪明，关键在于数据层没有告诉它哪条是有效在线的。

一、为什么向量检索治不了这个病

你可能会想：给每条记录加个时间戳，检索时按时间排序取最新的那条，不就行了？

但实际没那么简单，咱们把问题拆成三层看。

第一层：向量空间没有时间轴。

时间戳能告诉你"哪条更新"，但不能告诉你"旧的那条是否已经作废"。一条三月的记录可能仍然有效（比如客户名称没变），另一条三月的记录可能早就被六月的新决定推翻了。"更新"不等于"取代"，而向量检索对这两件事一视同仁。

更基础的问题是，"预算 50 万“和”预算 30 万"在 embedding 空间里的距离非常近——它们讲的是同一件事，只是数字不同。余弦相似度不会因为一条是三月写的、一条是六月写的就给出不同分数。检索系统看到的是两条同等相关的结果。

第二层：检索不理解"取代"关系。

在真实业务里，六月那条"预算调整为 30 万"不是一条独立信息，它的语义是"废止前一条，以这条为准"。但向量数据库里没有"废止"这个概念。两条记录是平行存在的，没有谁取代谁。

第三层：把矛盾甩给模型是错误的分工。

当两条互相矛盾的信息同时出现在 Prompt 里，你实际上是在要求 LLM 做一个它没有足够信息完成的判断——哪条是当前有效的？模型可能猜对，也可能猜错，而且你无法预测它什么时候会猜错。

这是一个数据层的结构性问题，不应该在推理层用概率去赌。

二、时序上下文的核心思路

解决方案的方向其实不复杂：给每条信息标记它的有效期，并且在信息变更时建立明确的"取代"关系。

这个思路在数据库领域并不新鲜——bi-temporal modeling（双时态建模）在金融和保险行业用了几十年，但在 Agent Memory 领域，它直到最近才被认真对待。

OpenContext 是 Alloomi 团队最近开源的一个项目，它的自我定位很直接：the context runtime substrate that powers agentic applications。不是 UI，也不是 chat surface，更不是模型提供商——是 Agent 应用底下那层“胶水”：持久记忆、检索、上下文纠错、多平台连接、定时感知，以及把这些粘在一起的 embedding 持久化层。

它的核心数据结构叫 Temporal Context Graph——一个有向无环图，每个节点（fact）都有 valid_from / valid_until 字段，所有修正都是 append-only，不做破坏性覆盖。

用它的术语来讲，上面那个预算案例会变成：

查询时，系统不是做相似度匹配，而是先确定查询时间点（默认是"现在"），然后只返回在该时间点有效的事实。过期事实不会进入 Prompt，矛盾在数据层就被解决了。

三、四个关键机制

不管具体用哪个框架，时序上下文要解决的核心问题可以拆成四个机制。OpenContext 把它们浓缩成了四个动词 API——remember、recall、improve、forget——刚好一一对应。

1. 有效期（valid_from / valid_until）

每条信息不是永真的。它有一个生效时间和一个失效时间。失效时间为空表示"当前仍然有效"。

这看起来简单，但它改变了检索的基本逻辑：从"找最相关的"变成"找最相关且当前有效的"。一个 where 条件的差别，结果完全不同。

在 OpenContext 里，recall 可以传入一个 as-of 时间戳，过滤条件是 valid_from ≤ t < valid_until——你可以问“上周二用户相信什么”，也可以问“现在哪条偏好是当前的”。

2. 取代关系（supersede）

新信息不覆盖旧信息，而是"接替"它。旧记录保留在系统里，但被标记为已失效，同时记录是被哪条新信息取代的。

回到前面那个预算案例——系统不只是知道"30 万比 50 万新"，而是明确记录了"30 万这条事实废止了 50 万那条事实"。这意味着你可以回答两类问题：

• "现在的预算是多少？"——返回当前有效的那条；

• "三月份的时候预算是多少？"——返回当时有效的那条。

历史不丢失，但不会污染当前查询。

在 OpenContext 里，这对应 improve 动词——它在图上追加一条 supersession 或 contradiction 边，原始节点永远不会被硬删除。

3. 软删除与遗忘

有些信息需要从系统中退役——比如客户要求删除个人数据，或者某条记录被证明是错误的。

硬删除意味着这条信息从未存在过，审计时无法追踪。软删除（或者叫"遗忘"）的做法是：标记这条信息已退役，记录退役时间和原因，查询时默认不返回，但审计时仍然可以看到它曾经存在过。

这对企业合规很重要。数据删除请求（比如 GDPR 的"被遗忘权"）需要你能证明"已经删了"，而不是"从来没有过"。

OpenContext 的 forget 动词做的就是这件事：valid_until = now，GDPR 的 right-to-erasure 由一个独立的合规流程处理，不走主 API 路径。

4. 审计日志与证据链

每个"当前状态"都应该能回溯到它是怎么来的：

• 原始信息是什么；

• 什么时候被谁修改；

• 修改的依据是什么；

• 当前版本是第几次变更的结果。

这不只是合规需求。当 Agent 给出一个基于历史信息的回答时，用户可能会追问"你这个结论的依据是什么？"——如果系统能返回完整的证据链，比如"这条信息来自 6 月 1 日的预算调整通知，它取代了 3 月 15 日的原始预算确认"，可信度完全不同。没有证据链的回答，本质上还是让用户信任一个黑盒。

OpenContext 的做法是结构化审计日志写入 ~/.opencontext/logs/audit.jsonl，加上 Fernet 对称加密保护敏感字段、URL 白名单/黑名单控制外发调用。

四、两条开源路线

前面讲的四个机制是通用思路。落到实操，目前有两条值得关注的开源路线。

路线一：OpenContext——可嵌入的时序上下文运行时

OpenContext（github.com/melandlabs/opencontext）是 Alloomi 团队开源的 context runtime，Apache 2.0 协议。它不是一个 UI 产品，也不是一个向量数据库——它是一层可以嵌入任何 host process 的运行时基底。

核心能力：

Temporal Context Graph. 有向无环图，每个 fact 节点带 valid_from / valid_until. Supersession、contradiction、merge 是一等公民边，修正是 append-only.

四动词 API。 remember（写入，基于 scope + content-hash 幂等）、recall（统一检索，跨语义、词法、图和时间维度）、improve（追加取代/矛盾/合并边）、forget（软删除）。这四个动词覆盖了一条事实的完整生命周期。

Platform Integration Mesh. 统一的 IntegrationRecord 格式，覆盖 Gmail、Slack、Telegram、Linear、Jira、iMessage、飞书、微信等——凭证轮换、限流、重连逻辑都在 adapter 后面。

Deterministic Loop Engine. 一个调度器，先判断有没有真正需要处理的事，有才调用 Agent Runtime。LLM 调用不是基础——是最后一步。

Library-First 安装。 pnpm add @melandlabs/opencontext 一行搞定，不依赖 React、Next 或 Tauri。同时提供 MCP Server 模式，可以直接接入 Claude Desktop、Cursor、Claude Code、Codex CLI 等 MCP-capable 的 Agent Runtime.

它和纯向量数据库的区别在于：Pinecone、Weaviate、Qdrant 做的是相似度匹配，OpenContext 在这之上加了时序图——事实会被取代，不只是被相似度排序。它和纯记忆库的区别在于：它不只是一个 library，而是一个 runtime——HTTP daemon、MCP server、CLI、集成网格和循环引擎都包含在内。

路线二：Graphiti / Zep——专注时序记忆引擎

Graphiti 是 Zep 团队开源的时序知识图谱引擎，底层跑在 Neo4j 或 FalkorDB 上，设计目标是给任何 Agent 提供时序记忆能力。它的论文报告了在 Deep Memory Retrieval benchmark 上相比 MemGPT 最高 18.5% 的准确率提升，同时延迟降低 90%。Zep 是基于 Graphiti 的商业化托管服务。

它的定位很纯粹：一个可插拔的记忆层。你的 Agent 框架不管是 LangChain、LlamaIndex 还是自研的，都可以把 Graphiti 接进来当时序记忆后端。适合有工程能力、想深度定制的团队。

怎么选

两者不是直接竞品，更像是不同切面的解决方案：

• Graphiti 是一个纯粹的时序知识图谱引擎。你已经有 Agent 框架，想加一层时序记忆后端，它是最直接的选择。需要自己部署 Neo4j，自己处理数据接入。

• OpenContext 是一个完整的 context runtime。它不只做时序记忆，还包含集成网格（多平台数据汇入）、循环引擎（调度和唤醒）、检索原语（chunking + embedding + 多后端适配）和 Agent Runtime 接口。如果你在从零搭建一个需要长期记忆的 Agent 应用，它提供的是一个更完整的基底层。

简单说：Graphiti 解决“时序记忆怎么存和查”，OpenContext 解决“一个有记忆的 Agent 应用底下需要什么”。

五、用开头那个案例跑一遍 OpenContext

前面构造的律所案例，用 OpenContext 的四动词 API 走一遍完整流程。以下代码基于 @melandlabs/opencontext 的公开接口，Node 22.6+ 可直接运行。

Step 1：remember——写入原始事实

remember 基于 (scope, content-hash) 幂等——同一条事实重复写入不会产生重复节点。

Step 2：recall——按时间点检索当前有效事实

recall 的 asOf 参数对应过滤条件 valid_from ≤ t < valid_until。不传则默认“现在”。

Step 3：improve——六月预算变更，建立取代关系

improve 在图上追加一条 supersession 边。原始节点的 valid_until 被设为 2024-06-01，新节点的 valid_from 为 2024-06-01、valid_until 为 null（当前有效）。原始节点永远不会被硬删除。

Step 4：再次 recall——矛盾已在数据层解决

注意：七月查询时，“50 万”那条不会出现在结果里——矛盾在数据层就被过滤掉了，不需要模型去猜。

Step 5：forget——客户要求删除个人数据

forget 是软删除：valid_until = now。GDPR 的 right-to-erasure 由独立合规流程处理，不走主 API 路径。审计日志（~/.opencontext/logs/audit.jsonl）仍然可以证明“这条数据曾经存在过，已按要求退役”。

六、从 runtime 到产品：Alloomi 做了什么

OpenContext 是基础设施层——它解决的是“一个有记忆的 Agent 应用底下需要什么”。但对终端用户来说，没有人想直接操作一个 runtime。

Alloomi 是基于 OpenContext 构建的面向专业人员的 AI coworker 产品。它把 OpenContext 的能力包装成了一个可以直接使用的桌面端工作助手。

从被动检索到主动感知。 OpenContext 提供了 Deterministic Loop Engine（循环引擎），Alloomi 用它实现了 Attention Agent——不是“你问我答”，而是系统主动判断“这件事需要你决定”。回到律所案例：当客户 A 的预算从 50 万变成 30 万时，系统不只是更新记忆图谱，还会主动提醒负责律师“预算发生了变更，相关合同条款可能需要调整”。

跨平台的上下文汇聚。 OpenContext 的 Platform Integration Mesh 覆盖了 Gmail、Slack、Notion、飞书、微信等几十个平台。Alloomi 用它把散落在不同工具里的业务信息统一到同一条时间线上——“预算变更”来自一封邮件，“负责人变更”来自一条 Slack 消息，“合同版本”来自一个 Notion 页面，系统自动识别它们属于同一个项目、同一个客户。

经验随工作积累。 Alloomi 的核心主张是“让 AI 每完成一次交付，就获得一次成长”。OpenContext 的 remember → improve 循环让每次业务变化都变成可追溯的经验节点。对于律所场景，这意味着：处理过的合同版本、客户偏好变化、审批流程中的判断——这些工作过程数据不再随对话窗口关闭而消失，而是沉淀为 Agent 的长期记忆。

本地优先，数据不出机器。 所有上下文数据存在本地，AES-256 加密，有完整审计日志。对于律所、金融、保险这类对数据主权敏感的行业，这是一个硬性前提。

简单说：OpenContext 是引擎，Alloomi 是基于这个引擎造出来的车。开发者可以直接用 OpenContext 造自己的车；不想从零开始的专业团队，可以直接开 Alloomi。

七、真实边界

机制讲完了，接下来是更重要的问题：它不能做什么？

时序上下文解决的是外部记忆层的正确性，不等于模型"学会了"。

即使系统能准确返回当前有效的信息，模型本身并没有因此变得更有经验。它仍然是在每次查询时临时获取上下文，然后生成回答。真正的"经验内化"——让模型不依赖检索就能做出更好判断——需要后训练闭环，那是另一个更难的问题。

实体统一仍然很难。

"张律师""张三""Zhang San""项目负责人张"可能指的是同一个人。时序上下文能追踪一个实体的状态变化，但前提是系统已经正确识别了"这是同一个实体"。实体消歧在真实企业数据里仍然是个硬问题。

不是所有场景都需要时序上下文。

如果你的知识库是一份产品文档、一个 FAQ 列表或一组技术规范——内容基本不随时间变化——标准 RAG 完全够用。时序上下文的价值出现在信息会频繁更新、会互相取代、需要区分"曾经正确“和”现在正确"的场景。典型的包括：

• 客户关系管理（偏好、预算、决策人会变）；

• 法律事务（合同版本、条款修改、判例更新）；

• 金融投资（持仓、评级、市场判断会变）；

• 项目管理（负责人、进度、优先级会变）；

• 人事与组织（职位、汇报关系、权限会变）。

如果你的业务不涉及这类动态信息，不必过度设计。

八、对开发者来说，现在能做什么

如果你正在构建 Agent 应用，想在记忆层加入时序能力，四条路可以走：

1. 用 OpenContext 作为 context runtime. pnpm add @melandlabs/opencontext 一行安装，四个动词 API 覆盖事实的完整生命周期。支持 SQLite-vec（桌面端）、Postgres（服务端）、IndexedDB（浏览器）多后端，同时提供 MCP Server 模式直接接入 Claude Code、Cursor 等 Agent Runtime。适合从零搭建需要长期记忆的 Agent 应用。

2. 用 Graphiti 自建时序记忆层。 开源、Apache 2.0、文档齐全、有论文背书。需要自己部署 Neo4j，自己处理数据接入和查询逻辑。适合已有 Agent 框架、想加一层时序记忆后端的团队。

3. 用 Zep Cloud 托管服务。 如果不想自己运维图数据库，Zep 提供开箱即用的 API。返回的 context block 可以直接塞进 Prompt。适合快速验证。

4. 直接用 Alloomi. 如果你的需求不是“给自己的 Agent 加记忆”，而是“团队需要一个能长期跟踪业务状态的 AI 工作助手”，Alloomi 提供了基于 OpenContext 的完整产品体验——桌面端、主动提醒、跨平台连接、本地数据，开箱即用。

5. 在现有 RAG 上加最小时序层。 如果暂时不想引入新框架，最简单的改进是：给每条知识库记录加一个 valid_until 字段，检索时过滤掉已失效的记录。这不能解决所有问题（比如取代关系和实体统一），但能挡住最常见的"返回过期信息"bug。

九、回到最初的问题

Agent 记忆里的"过期与冲突"看起来是个工程细节。但如果你退一步想，它指向一个更大的判断：

Agent 的长期记忆不应该是一个越堆越大的向量库。它应该是一个能持续追踪人物、项目、判断和时间变化的系统——知道什么是当前状态，什么已经被取代，什么曾经正确但现在不再适用。

这件事做对了，Agent 才有可能从"每次都重新开始"走向"理解业务是怎么演变到今天的"。而理解演变，是积累经验的前提。

相关资源：

• OpenContext 开源仓库：github.com/melandlabs/opencontext

• OpenContext 架构文档：github.com/melandlabs/opencontext/blob/main/docs/architecture.md

• Alloomi 官网：alloomi.ai

• Graphiti 开源仓库：github.com/getzep/graphiti

• Zep 论文：arxiv.org/abs/2501.13956

待核实事项：

• Graphiti 论文中报告的 18.5% 准确率提升和 90% 延迟降低数字来自其 DMR benchmark 评测，具体测试条件建议查阅原论文。
