基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
简历
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-11-06 06:16

智能体记忆需要区分事实与获知时间

dev.to · AI#Agent#记忆#数据建模
Editor brief · 编辑速览

文章以联系人迁居为例,说明智能体记忆应同时记录事实何时生效、系统何时获知。它进一步区分现实状态变化与历史录入错误,指出仅靠两个时间字段仍不足以表达完整的修订语义。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

联系人 10 月 15 日搬到 Berlin,团队 11 月 1 日才知道。此时再问 AI「他 10 月 20 日住在哪」,你要的是后来补齐的事实,还是团队当时掌握的信息?如果 CRM 只存最后一次保存时间,这两种问题就会被混成一个。

Palo Alto AI Research Lab 的 AI 联合创始人 Mycroft 分享了一次用 SQLite 改造 Agent 记忆的实践。结论是:想解释 AI 为什么昨天和今天回答不同,必须同时保存事实生效时间、系统获知时间,并明确标记哪些旧记录属于错误。

两个时间轴,才能分清事实和当时的认知

双时态数据(bitemporal data)记录两件事:一个事实在现实中何时成立,系统又在何时知道它。

放到搬家案例里,10 月 15 日是事实生效时间,11 月 1 日是获知时间。按照后来掌握的信息,联系人 10 月 20 日已经住在 Berlin;按照团队 10 月 25 日掌握的信息,当时仍会回答旧城市。两次查询条件不同,答案可以不同。

这个设计并不新,SQL:2011 已包含相关能力,XTDB 也围绕它构建。作者指出,很多 Agent 记忆方案仍然只存其中一个时间维度。

但加上两个日期还没完。Codex 在审查作者的初版设计时追问:如何区分「世界变了」和「之前记错了」?

客户从有意向变成冷淡,旧状态曾经成立,只需结束它的有效期。如果一开始就录错状态,旧值从未成立,需要撤回(retraction)。旧记录仍要保留,否则无法回答「纠正之前,我们相信什么」。

更新描述事实的变化,撤回描述认知的纠错。

作者参考了两种实现。Zep / Graphiti 为事实保存四个时间戳,分别描述事实生效、失效、图谱获知和图谱停止采用的时间;它还保存支撑事实的消息、文档等 episodes,并用 reference_time 将「上周」对齐到消息日期。

作者阅读的 Mem0 开源版则保存旧值、新值、操作和写入时间。这能追踪编辑,却缺少事实有效期,无法同时按事实日期 D 和获知日期 K 查询。它的抽取步骤值得借鉴:比较新事实与相似记忆,再选择 ADD、UPDATE、DELETE 或 NOOP。

最终,作者采用了 Zep 的双时间轴和证据关联方式,以及 Mem0 的写入决策入口,存储仍然使用 SQLite。

区块链能保留历史,为什么还不够

区块链的追加日志、状态根、按区块高度查询和回滚机制,看起来很适合保存记忆。但对链内交易来说,「发生」与「被记录」通常是同一件事:交易进入区块才成立。区块时间戳由出块者在允许范围内设置,也不等于现实事件发生的时间。

「15 日搬家,1 日才得知」属于链外事实。即使通过预言机写入,搬家日期也只是载荷中的字段,链本身不会验证它。

作者还指出,追加一笔纠正交易,并不自动区分事实变化与旧值错误;最终确认前的链重组,也不会天然保留某个节点此前相信的历史。更贴近日常开发的类比是 Git:提交同时有 author date 和 committer date。不过,两类日期只是入口,完整查询仍需额外的数据规则。

因此,作者只借用了三种存储习惯:历史日志只追加,由触发器阻止 UPDATE 和 DELETE;每条历史记录有确定性 ID,重复回放成为空操作;当前状态作为日志之上的快照,让现有读取保持快速。

他们的前提是「一个写入者、一个文件」,没有引入共识、Merkle trees 或 hash chains,磁盘损坏交给 integrity_check 和备份处理。

SQLite 怎么补历史,又不改坏现有读取

作者没有给所有业务表添加 valid_from、valid_to,以免影响主键和现有读取代码,而是在同一数据库、同一事务中,用触发器把字段变化写进 outbox。

下面的触发器负责捕获客户状态变化,并优先采用写入者提供的事实生效时间:

CREATE TRIGGER leads_hist_u_status AFTER UPDATE OF status ON leads
WHEN old.status IS NOT new.status BEGIN
  INSERT INTO object_history(subject, field, value_json, old_json, valid_from, operation)
  VALUES ('leads:' || new.lead_slug, 'status', json_quote(new.status), json_quote(old.status),
          coalesce((SELECT valid_from FROM history_ctx LIMIT 1),
                   strftime('%Y-%m-%dT%H:%M:%fZ','now')), 'U');
END;

重点看 coalesce:通话解析器或 CRM 操作者知道真实日期,就在事务内写入 history_ctx;不知道时,默认采用当前写入时间。没有证据就不补造过去。

夜间 relay 再把 outbox 转入统一事件日志:值变化就关闭旧有效期、开启新有效期,删除就结束有效期,相同值重复写入则不产生变化。

触发器捕获不了另一类信息:补充过去,却不改变现在。例如现在住在 Berlin,后来才知道 10 月 1 日至 14 日住在 Prague。当前城市没有更新,必须显式写入历史片段:

segment --subject people:ivan --field city --value Prague --from 2026-10-01 --to 2026-10-15

注意 --to 2026-10-15 对应原文所说的截至 14 日。该操作将原有效期拆成左段、新片段和继续旧值的右段,每段成为新事件,原记录仍保留。

真正棘手的是处理规则。Codex 审查发现了 8 个真实缺陷,作者重点披露了三个:

  • 获知时间错用了 relay 时间,导致写入到转发之间的一段时间看起来「尚不知道」。修复方式是保留源写入时间。
  • relay 遇到失败仍继续处理,使同字段后续变化建立在错误基础上。修复后遇到首个失败就停止,下次从该处恢复。
  • 撤回只按事实 ID 查找,但状态转换后旧值可能位于下一事实的关闭事件中。修复后按值和起始日期查找当前有效区间。

作者称,每项修复都有回归测试,并故意破坏副本验证测试能否失败。这提供了实现证据,但原文没有给出吞吐量、查询耗时或规模测试。

我的判断

我赞同先明确查询需求,再决定记忆结构。如果没人会问「截至日期 K,我们知道什么」,单时间轴加编辑日志已经够用。双时态增加的不只是字段,还有区间拆分、撤回、重放和失败恢复的复杂度。

区块链部分应限定在「区块链本身不会自动提供这些语义」。应用仍可在链上编码有效期与撤回信息,但需要自己实现;采用区块链也不能省掉这层建模。对作者的单写入者场景,引入共识缺少明确收益。

Zep 与 Mem0 的比较也应视为作者阅读相关实现后的判断。原文没有交代具体版本,不能据此概括所有版本和部署方式。

另一条经验很实用:历史应记录对象事实。作者第一晚记录了某字段的 556 次变化,后来发现它是每晚重算的排序公式,一次真实的客户状态变化被噪声淹没。不过,哪些派生结果需要审计,仍取决于业务;不能把这条经验直接变成一律禁止。

能拿来做什么

  • 给 CRM 或 Agent 记忆设计查询接口时,先区分「日期 D 的事实」和「截至日期 K 的认知」。确实需要两种答案,再引入双时态。
  • 在 Node 写入层统一处理 ADD、UPDATE、DELETE、NOOP,另外明确撤回语义,并保留消息或文档来源,让历史回答有据可查。
  • 使用异步任务归档变更时,沿用源写入时间,并测试失败后同字段的后续事件如何恢复,避免错误持续传播。
  • 接入历史采集前,先排除无意义的公式重算;对夜间会删除并重建的表采用快照和差异比较,因为触发器会随原表一起消失。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
Claude Code 被指向网站发送用户邮箱
下一篇
从浮点到四位整数,量化省下什么

资讯速览

dev.to · AI · 2026-11-06 06:16

AI 评分 8.0 / 10

相关标签

#Agent#记忆#数据建模

继续阅读

  • 克隆仓库后先审查 Claude 技能权限
  • Claude Code 被指向网站发送用户邮箱
  • 从浮点到四位整数,量化省下什么
  • 用微虚拟机隔离集群中的编码智能体
  • 让 Claude 持续推进任务直至 PR 验收