当 AI 突然“失忆“:DeepSeek Harness 的 Session Log 怎么做单一事实源

这篇拆解 DeepSeek Harness 的 Session Log:把会话做成一条只追加的事件流,为什么能同时解决"记忆丢失"和"多视图不一致"这两个问题。

0. 一个很多人踩过的坑

你有没有遇到过这种情况:跟 AI 聊得好好的,它突然"失忆"------上一句你刚说的话,下一句它就不认了。

第一反应通常是:这模型不行,记性太差。

但问题大概率不在模型。先说结论:大多数 Agent 框架里的模型,根本没有"记忆"这件事。 它每轮能看到的上下文,都是临时从一条事件日志里投影出来的。那段一旦被压缩、替换,它就再也看不见了------它表现出的"失忆",只是因为那一段已经不在它看得见的上下文里。

下面拆开看:为什么大多数框架会丢记忆,Harness 又是怎么解决的。

1. 大多数框架的记忆是怎么丢的

很多框架图省事:把整个会话塞进一个会溢出的数组,当作模型的上下文。

这在短对话里没问题。可一旦任务跑得久------比如一个多轮、带工具调用的长篇任务------前面的对话就会因为数组满了被静默挤掉。没有报错,没有提示,旧内容就这么没了。

模型不是"忘了"。它本来就看的是那份上下文;那段被挤掉之后,它对发生过什么一无所知。你问它"刚才那步的结果呢",它只能含糊其辞,因为它手里真的没有。

根子上的设计选择是:上下文是唯一的事实载体,而上下文又是会变、会丢的。

2. Harness 的做法:真相只在一条日志里

DeepSeek Harness 换了个思路。它不把真相装进上下文,而是写进一条只追加(append-only)的事件流------Session Log。

几个关键点:

  • 会话是一串事件。每条事件有类型、序号和负载;turn、step、用户消息、工具调用、工具结果,全按发生顺序记下来。
  • 模型看到的是"投影",不是"存储" 。系统跑一次 deriveMessages(),按规则把日志映射成模型这轮能读的消息列表。模型不持有任何记忆,它每轮只是拿到一份刚从日志投影出来的上下文。
  • 一条硬性不变量 :model-visible means logged------模型能看到的,必然已经写进日志。想给模型加一种新的可见输入?正确的做法是先加一种新事件类型,再从日志里渲染出来。而不是在某个角落偷偷塞一段。

这就引出了"单一事实源"的含义:

真相只存一份,就躺在日志里。模型要看、界面要显示、调试要回放------谁需要,都从这份日志投影出来,而不是各处各存一份。

为什么强调"不另存副本"?因为如果真相在日志里只留一份,那么模型视图、UI 视图、调试回放、审计记录,全是从同一份投影出来的,不存在"两份对不上"的中间态------要么日志有,要么没有,没有模棱两可。

3. surface 与 log-only:什么算对话,什么只是记录

并不是所有事件都该进模型的上下文。Harness 把事件分成两类:

  • surface 类:用户消息、助手消息、工具结果------这些会进模型历史,是真正"对话"的一部分。
  • log-only 类:只进持久化、UI 或审计,不进模型历史。

这条线划清了一件事:什么算对话,什么只是记录。 把日志当成单一事实源,不等于把所有日志都喂给模型;投影规则决定哪些事件该露出来、哪些只留在底层。

4. 因为一切都是投影,fork 变得不可思议地简单

这是整件事里最反直觉、也最有用的一点。

既然模型上下文、回放、持久化全都是从同一条事件流投影出来的,那么派生出一个新会话,就只是从这条事件流里选个边界、重建出一份新的投影------不需要复制状态,不需要迁移数据库。

由此派生出来的一整套能力都变得轻量:

  • 回放(replay):重新投影同一段事件;
  • resume(续跑):从某个边界继续;
  • 转写、遥测:同一种数据源的不同视角。

这里有一个很关键的纪律:未识别的事件类型,默认必须拒绝重建,而不是悄悄丢弃。 日志是向前兼容设计的------遇到将来才定义的事件类型,老 reader 可以标记为 ignorable 跳过;但在做"重建会话"这种严肃操作时,不认识的类型必须显式报错,绝不把一个残缺的会话悄悄续上。跳过和拒绝,是两件事。

5. 回到开头的"失忆"

回到第 0 节那个场景。在 Harness 里,它不会再以那种"上一句不认"的方式失忆了------因为真相只存一份,谁都没法偷偷改上下文而不留下记录。

对开发者,这意味着三件具体的事:

  • 可复现:同样的事件流,投影出同样的上下文;
  • 可调试:出了 bug,翻日志就知道模型当时到底看到了什么,而不是去猜;
  • 可审计:谁在什么时候做了什么,日志里全在。

一句话收束这套设计:只要真相只留一份,出错的机会就少一份。

6. 一个容易被误会的点:日志不可变,但细节仍会消失

前面用"失忆"打比方,容易让人误以为用户"亲手删了话"。这里需要澄清一个边界:

日志本身是不可变 的,事件一旦写入就不会被修改或删除。真正让模型的视野里少了某些细节的,是compaction(上下文压缩)------用摘要替换掉原始的 surface 节点------以及显式的编辑操作。细节不是被删除了,而是被压缩、替换了;而模型只看得到投影后的结果,所以表现得像失了忆。

换句话说:"失忆"不是记忆被抹除,而是投影源被压缩后,细节不再可见。 这两者的区别,决定了调试时是去查日志(记录还在),还是去查压缩策略(内容被替换了)。

相关推荐
9624567 小时前
Go EVM 链上数据平台实践:从 RPC Demo 到可演进架构
rpc·架构·golang
考拉讲支付7 小时前
母婴亲子服务平台分账架构设计:多场景多方分账与合规清结算实践
大数据·运维·人工智能·微信小程序·架构·微信公众平台
黄俊懿7 小时前
【架构师从入门到进阶】第六章:服务集群优化——第八节:线程数公式
java·服务器·数据库·分布式·性能优化·架构·系统架构
行者全栈架构师7 小时前
【鸿蒙心迹】互动卡片全链路——把核心功能放到桌面(FormKit 实战)(HarmonyOS 7.x)
前端·算法·架构
海带紫菜菠萝汤8 小时前
PostgreSQL 19 延期一个月:AI 把找 bug 变便宜了,修 bug 还是人工价
人工智能·ai·程序员·架构·大模型
Thneonl8 小时前
主从延迟 0 秒的谎言:SBM 的三个盲区
后端·架构
Dawson Zhu8 小时前
【AI Infra小白入门⑦】Transformer架构工程拆解:从Attention到MLA的优化密码
人工智能·语言模型·架构·aigc·agi
吴建旭 智宅焕8 小时前
智能家居全国交付的县域节点架构:远程技术大脑与本地执行端的标准化实现
架构·智能家居
行者全栈架构师8 小时前
【鸿蒙心迹】让应用“悬浮“起来——闪控球(floatingBall)从接入到实战全链路(HarmonyOS 7.x)
前端·算法·架构
stillstream_ink9 小时前
‌双端电商系统的测试差异分析——别让“只测一端”漏掉80%的联动缺陷
架构·测试