看完逻辑哲学论后重新思考的记忆系统
翻一本七十几页的小书,被「世界是事实的总和,而不是事物的总和」这句话钉住,作者回头审视自己做的记忆系统:模型缺的不是知识,而是一条能判断「这件事在我记下的事实里吗」的边界。文章把维特根斯坦的四个命题落到原子事实、因果边和可追溯的时间上。

这本书的名声很邪门。薄得离谱,拢共七十几页,正文只有七个命题,但据说全世界能真正读透它的人两只手数得过来。罗素给这本书写过序,写完之后维特根斯坦看完说,罗素根本没看懂。俩人谁也没说服谁,那篇序照样印在书的前面,成了哲学史上最尴尬的一篇序。
这种书我一般是拿它当安眠药使的,睡前翻两页,昏了就睡。结果那天晚上翻到第一页,第一句话就把我钉在床头了。
「世界是事实的总和,而不是事物的总和。」
我盯着这行字看了足足五分钟。当时没想明白,放下书去洗了个澡,洗到一半突然反应过来,这说的不就是我这半年一直在死磕的那个东西吗。
先别急,我从书说起。
维特根斯坦这个人写书有个特点,他不跟你铺垫,不跟你客气,上来就是断言。世界是什么,事实是什么,语言是什么,一条一条往下推,像欧几里得写几何原本。你要问他为什么,他的回答经常是,这就是逻辑的结构,没法再拆了。
书里的核心逻辑,我用大白话捋一遍,就四条。
第一条
世界不是一堆东西摆在那,是一堆正在发生的事。这话听着像绕口令,我举个例子。你桌上有个杯子,杯子就是个东西。但杯子在桌子左边这件事,是个事实。东西本身没有真假对错,事实才有。你可以说「杯子在桌子左边」是真的还是假的,但你没法说一个杯子本身是真是假。维特根斯坦认为,我们描述世界的时候,描述的从来不是东西,是事实。世界就是被这些大大小小的事实塞满的。
第二条
语言是世界的图像。你说出一句话,这句话就是给世界某一个角落拍的一张快照。它跟事实对得上,就是真的。对不上,就是假的。就这么朴素。我再打个比方。你手机里的导航地图,不是北京城本身,但地图上的每一个路口,都对应着城里一个真实的路口。语言跟世界的关系就是这样,一句话不是世界本身,但句子里的每个零件,都对应世界里的一个事实零件,零件全对上了,这句话就是真的。这也顺便解释了假话是怎么来的。地图上完全可以画一条不存在的路,画是画得出来的,但它跟真实的城市对不上,你按它开,一跑就露馅。语言能说假话,恰恰是因为它跟世界之间是图像关系,图像可以错位。
第三条
复杂的事实是由简单的原子事实拼出来的,跟乐高一样。你说张三上午十点在店里买了杯拿铁,这句话可以拆成张三、时间、地点、动作,一粒一粒的原子事实。原子事实拼对了,任何能说清楚的事情都拼得出来。反过来说,凡是拼不出来的东西,说明它压根不在能说清楚的范围内。
第四条
也是全书最出名的一句压轴。凡是你说不清楚的东西,就必须保持沉默。语言有边界,边界里面是能讲清的事实,边界外面,别瞎说。
好,书就介绍到这。你要是觉得这四条跟AI八竿子打不着,正常,我一开始也这么觉得。
接下来聊聊我这半年在死磕的东西。
我在给自己的Agent搭记忆系统。这个东西业内折腾了好几年,方案换了一茬又一茬,从最早把聊天记录全量存下来,到后来的向量数据库,再到最近各种花活,但始终没有什么一锤定音的方案。为什么,因为这个问题比大家想象的难。
难在哪。真实世界的信息是非标的。人跟人说话,东一榔头西一棒子,同一个意思有一百种说法,每一句里面还埋着语气、背景、没说出口的半截话。这两年大家往AI里扔的东西还越来越糙,业务同学一个文档压缩包直接甩过来,对着AI许愿,帮我看看价格合理不合理,帮我出个分析报告。这些形状不规则的、带情绪的、缺上下文的玩意儿,就是记忆系统要吃下去的原料。
你要把这些东西塞进计算机,第一步就是量化,把它们规整成一条条数据。可一旦量化,失真就开始了。
客户跟业务说,这批货有点不太行。业务把这五六个字存进系统的时候,可能就变成了一条,客户满意度下降。完蛋。什么叫有点不太行,是包装破了,还是口味变了,还是单纯这周心情不好随口一说,全丢了。更离谱的是我见过有人把这半句话交给AI打分,AI给这条信息标了个满意度零点六。客户那句带着表情、带着前三周铺垫、带着他们家上个月刚出过一次质量问题的「有点不太行」,最后在系统里就剩一个孤零零的零点六。
现在更流行的做法,是把整段话转成一串数字向量,扔进向量库,检索的时候按相似度捞。这招在找大概类似的东西的时候很好使,但它存的是语义的雾,不是事实的骨。你捞回来的是几句长得像的话,至于哪句现在还有效、哪句早被推翻了、哪句是用户随口一提哪句是拍板定论,向量里没有这个信息。雾能帮你找到类似的东西,骨才能撑得起判断。
信息在转换的每一层都在漏,漏到最后,含义早就不是原来那个含义了。而且这么存出来的东西天生不结构化,你想查的时候对不上,想推理的时候接不起来。
拿最常见的做法举例。传统记忆系统怎么存,Agent聊着聊着学到一件事,比如你说你现在做的项目用Vue,它就往库里写一条。过仨月你说项目换React了,怎么办,把Vue那条改掉,覆盖,写上React。
听起来没毛病对吧。我以前也觉得没毛病。
但你想想看,覆盖的那一瞬间,「你曾经用Vue、上个月刚迁过来」这个事实,永远消失了。库里只剩一条React记录,干干净净,好像你天生就用React。然后某天你随口提了句刚从Vue那边迁过来,有个老写法不知道怎么改,Agent一脸自信地接了一句,都写这么多年React了这还能不会。。。
你敢信???
它不是在撒谎,它是真不知道。因为知道的那部分证据,被它自己亲手覆盖掉了。
还有一个更隐蔽的坑,因果的丢失。Agent干活经常是一串连锁动作,检测到库存不足,触发判断,创建订单,支付失败,切换渠道,修复成功。传统记忆只记结果,订单支付成功了。中间那一串为什么失败、当时是什么状态、怎么修好的,全没了。下次再出同样的问题,它还得从头错一遍。它在同一个坑里摔了两次,但它连自己摔过跤这件事都不记得。
你说这怪谁。怪设计师蠢吗,倒也不是。覆盖式存储便宜、省空间、实现简单,大多数场景真够用了。要求每个系统都记录完整的历史流变,有点像要求每个人写日记精确到秒,正常人谁这么活。
但Agent不是正常人。它的工作就是基于记忆做判断,记忆里少一块,判断就歪一块。这也是为什么记忆系统大家反复研究反复推翻,始终没有定论。它不是一个工程问题,它是一个你打算让机器怎么「记住世界」的哲学问题。
那天晚上我在浴室里想明白的就是这个。
维特根斯坦说世界是事实的总和。那我Agent的世界呢,不就是它经历过、记录下来的那些东西的总和吗。可我原来那套记忆存的是什么,是一堆随时会被覆盖的最终值。它存了一个摘要,而不是事实本身。它的世界里没有历史,没有流变,没有因果,只有一个干巴巴的「现在」。
问题是,真实世界是由事实的流变构成的。状态会变,但每一个曾经为真的状态,都是世界的一部分。
那能不能干脆用维特根斯坦那套逻辑,重新搭记忆系统的骨架。
我把方案整理出来了。接下来用大白话讲,不贴任何代码,就讲思路。整个方案拢共四件事。
第一件事:最小单位改为事实
把记忆的最小单位,从一条数据,改成一个事实。
一个事实长什么样,三样东西拼起来,谁,怎么样了,变成什么。你在聊天里说项目正在用Vue,落进记忆就是一粒原子,你,当前技术栈,Vue。Agent自己干的事也一样,它试了方案A去修一个支付问题,没修成,又是一粒原子,方案A,修复支付,失败。就这一粒一粒的原子,是整套方案里最基础的砖,对应维特根斯坦说的原子事实。
光有砖还不够,每个事实还得随身带几个标签。这事什么时候发生的,是谁说的,可信度有多高。来源这栏尤其讲究,用户亲口说的要记成用户说的,Agent自己猜的要标成推理,工具查回来的要标成系统返回。同样一句话,三种来源的分量完全不同,就像法庭上,当事人陈述、律师推测、鉴定报告,能一样吗。这几个标签特别关键,直接决定了后面真假判断的时候这句话能不能采信。
写到这,肯定有朋友想说,这不就是知识图谱那一套吗,实体、关系、属性。还真不是一回事,而且这个区别是整个方案的地基,必须掰清楚。知识图谱是给外部世界建档案,它关心的是对象的属性和对象之间的关系,张三是什么会员、某个商品卖多少钱、谁跟谁有合作,那是数据库和图谱的地盘。记忆系统记的是Agent自己的经历,是用户哪句话推翻了哪句话、哪次尝试砸了、哪个判断是今天刚被证伪的。一个对外,一个对内。硬要打比方,知识图谱像户口本,记忆像日记本。户口本上的张三今年三十二岁,年年都是三十二岁,日记里的你,昨天的想法今天就能推翻。所以张三是什么会员,让数据库去记,Agent要用的时候现查就行。记忆系统要记的,是「今天用户说预算砍半,上个月的方案得推翻重来」这种事。记住这个区别,后面的事就好讲了。
第二件事:永远不覆盖,只追加
第二件事,也是整个方案最反直觉的一件事。写入记忆的时候,永远不覆盖,只追加。
你从Vue换成React,不是把Vue那条记录改掉,而是新写一条,你,当前技术栈,React。同时给旧的那条Vue打个标记,叫已被取代。Vue那条还在,只是它不再是当前有效的状态了。
这个思路现实里早有原型,银行。你卡里的余额变了,银行不会把你以前的对账单撕了,每一笔流水都留着,余额只是一个基于全部流水算出来的当前视图。你三个月前的那笔支出,随时能翻出来,一分都不会少。
为什么非要这么干。因为「曾经为真」本身就是有价值的信息。一个上个月刚从Vue迁过来的用户,和一个写了五年React的老手,会踩的坑、该给的方案、能开的玩笑,全都不一样。一个只会覆盖的记忆系统,等于强行把发生过的一半事情抹掉了。
第三件事:把记忆分三层
第三件事,把记忆分三层。
第一层:短期记忆
Agent正在手头处理的这一摊事。容量小,寿命短,像你脑子里的工作台,正在算的那几笔账。用户跟它聊补货,库存多少、安全库存多少、聊到哪一步了,全搁在这。一段时间没被用到的,自动衰减,要么沉到下一层去,要么扔掉。跟人一样,你不会一辈子记得上周三下午临时记的一个门牌号。从短期沉到长期是有门槛的,不是所有东西都配得上成为常识,得验证过、可信度够高才收。这个动作有点像睡觉,人白天经历的事,夜里大脑挑挑拣拣,重要的转成长期记忆,不重要的就真的忘了。Agent的固化,也是同一个过程。
第二层:长期记忆
已经反复验证过的、稳定成立的事实和规律。像人的常识,像一本经验手册。这个用户的部署流程得先跑测试再动手、判断补货要看库存和安全库存两个输入、这类任务放在周五发版容易翻车,这种被验证过好几回的东西放这。注意,进来的是规律,不是某一天的流水,某天的流水归有序记忆管。Agent每次干活要查经验,都是从这层拿。
第三层:有序记忆
这是我认为最重要的一层。它不记单个的事实,它记事件的序列,谁导致了谁。检测到库存不足,触发了判断,判断说需要补货,于是建了单,支付失败了,于是切换了渠道,修好了。一格一格串起来,每一格里都记着,动作发生前的世界长什么样,干了什么,之后世界变成了什么样,上一格是谁。
你可以把它理解成行车记录仪加日记本的合体。光有行车记录仪,你只有画面没有动机。光有日记,你只有心情没有现场。两个合在一起,一件事情的前因后果、里外三层,全有了。
我拿一次完整的补货任务走一遍,你就知道三层是怎么咬合的。用户说,城东那家店该补货了。这句话先落进短期记忆,同时开出一个事件格子。Agent去长期记忆里翻经验,翻到补货判断要看库存和安全库存两个数,再去业务数据库把这家店现在的库存捞出来,八十,安全库存一百。注意,库存数字是现查的,不是记忆里存的,那是业务数据的户口本,记忆只记Agent自己的经历。判断一跑,八十小于一百,需要补货,这个结论作为新事实写进短期记忆,事件链上添一格。接着创建订单,订单建出来了,又是一格。支付的时候失败了,再一格。系统切换渠道,补扣成功,最后一格。任务收尾,短期记忆开始分拣,这家店需要补货的任务背景沉进长期记忆,库存八十这种时效性的数字丢弃,整条事件链原样存进有序记忆。三个月后用户回来问那天到底怎么回事,Agent把链拖出来,一格一格讲给你听。
有了这层,Agent才第一次拥有了复盘的能力。用户问,我那单为什么支付失败了。它不用现编,顺着链条往回走就行。您的订单创建的时候一切正常,支付环节渠道A超时了,系统自动切到了渠道B,钱是下午三点补扣成功的。有理有据,每个环节都有出处,每个状态都有时间。
这不是背答案,这是真懂。同样两个Agent,一个记住了结果,一个记住了过程,用起来是两个物种。
第四件事:读取用真假判断筛选
第四件事,读取记忆的时候,用真假判断来做筛选。
Agent查记忆,查的从来不是跟这句话像不像,而是这件事现在还是不是真的。把所有已被取代的、过期的、可信度不够的,全部过滤掉,剩下的里面挑最新的版本。这套筛选规则,对应维特根斯坦说的真值函数。它自己不产生任何新事实,它只负责回答一个问题,当前世界里,哪些事是真的。这里有个点很多人会搞混,读和写这两件事,在逻辑上不是一回事。写,是在改变世界,一次写入就是一个新事实诞生,旧事实让位。读,是在描述世界,它不改变任何东西,只负责如实报告。现实里很多系统把读写混在一个流程里,查着查着顺手就改,查出来的东西已经被污染了。分开之后,读永远是描述,写永远走追加那一条路,各自干净。
顺带说一个特别妙的对位。长期记忆里的东西,如果太久没人用,这个方案不删它,只是让它退出当前的有效事实集,不再参与推理。维特根斯坦说,对于不可说的东西,必须保持沉默。Agent的遗忘,就是它的不可说。不是不存在,只是不再说。我第一次想通这个对位的时候,起了一身鸡皮疙瘩。一本一百年前讨论语言边界的书,里面居然藏着一台机器该怎么遗忘的答案。
方案的纪律
方案讲完了。还有几条纪律要交代,这些纪律比功能本身更重要,因为记忆系统最大的死法不是没功能,是自相矛盾。
- 写回之前必须核对前置条件。你要把用户项目标记为已上线,得先确认它当前的状态还是开发中。万一你读的是一小时前的旧状态,这一小时里别的流程已经把它标成上线了,你这一笔写下去,账就乱了。跟多人编辑在线文档一个道理,文件已经被别人改过了,系统会拦着让你先刷新再动手。机器也得守同样的规矩。
- 所有读取都带上时间坐标。别问用户的技术栈是什么,要问,截至此刻,用户的技术栈是什么。一字之差,天壤之别。不带时间的提问,等于默认过去不存在。
- 因果链必须完整。每个事件都得记下它是被谁引起的。断了一环,整条链的复盘价值就打折。记录事件的时候偷这个懒,以后要用的时候就是拿十倍的工夫来还。
当然,代价也得说清楚,我不画饼。这套方案写得多、存得多,追加式的空间消耗肯定比覆盖式大。实现复杂度也高了一截,光「事实被取代」这个状态的流转,就有一堆边角情况要处理,两个事件同时改同一个事实怎么办,冲突怎么裁决,都是硬骨头。我自己也还在搭,有序记忆那一层的因果链怎么高效检索,我到现在也没完全跑通。有些想法不一定成熟,你就当听一个还在挖坑的人,聊聊他为什么要挖这个坑。
但我已经能确定一件事。这套思路至少让记忆系统第一次具备了三种以前没有的能力。
- 可追溯。任何状态的来龙去脉都能翻出来,用户的技术栈为什么从Vue换成React、什么时候换的、当时是基于什么说的,一路查到底。
- 可解释。Agent说出口的每句话,都能给出事实依据,而不是模型现编的语气。这在关键业务里是生死线,一个说不出依据的判断,你敢让它自动执行吗。
- 不自相矛盾。同一个事实,任何一个时刻都只有一个有效版本,不存在两个都算数。这听着像废话,但传统覆盖式系统里,脏数据打架是家常便饭,两条流程同时改一个人,改完谁也不认谁。规则钉死之后,Agent才可能有一个稳定的、不打架的世界观。
书以外的思考
聊到这,说点书以外的。
维特根斯坦这个人的一生,比他的书还离谱。他原本是学航空工程的,在曼彻斯特研究螺旋桨,因为想搞明白数学的底座是什么,跑去剑桥找罗素。他问罗素,你看看我是不是个彻底的废物。罗素让他回去写点东西,暑假后再答复。暑假结束罗素读完他的逻辑笔记,回信说,别搞航空了,你来搞哲学吧,你是个天才。
后来一战爆发,他主动申请上前线,在东线的战壕里和战俘营里,就着炮火写完了《逻辑哲学论》的大部分手稿。书写完了,他宣布哲学问题已经被全部解决,然后跑去奥地利乡下当小学老师,教一群山村小孩认单词、做算术。晚年他又亲手推翻了这本书里的很多观点,写了另一本《哲学研究》,把「语言是世界的图像」换成了「语言是游戏」。
一个用逻辑给世界划边界的人,自己一辈子都在边界上反复横跳。
这本书当年在维也纳炸出了一整个学派,一群人捧着它当圣经读。但维特根斯坦本人后来背过身去,说当年在战壕里想岔了。天才的自我推翻,比天才的建立更少见。
还有个冷知识。1939年图灵在剑桥选了一门课,讲师就是维特根斯坦,讲数学基础。全世界第一个认真琢磨怎么让机器思考的人,和全世界第一个给语言划边界的人,在同一个教室里坐了一个学期。图灵关心机器能不能算,维特根斯坦关心话能不能说清楚。这两条线各走各的,走了八十多年,今天在Agent身上撞了个满怀。一个负责想,一个负责记,谁也离不开谁。
我有时候觉得,做AI的人最该从他身上学的,不是任何一条具体理论,而是那种对「说清楚」的执念。一个事实的边界在哪,一句话在什么条件下为真,哪些东西根本说不清楚。说不清楚的地方,老老实实沉默。
AI现在最大的毛病之一,就是从不沉默。它对答如流,对那些它手里没有任何事实依据的问题,也照样对答如流。它缺的不是知识,是维特根斯坦画的那条边界线。你想想看,如果它的记忆里存的是一粒一粒带时间、带来源、带可信度的原子事实,那它在回答之前,至少可以先问自己一句,我现在要说的这个东西,在我的事实里吗。不在,那就闭嘴。
这可比让它多背几本书重要多了。
顺带一提,这套方案跟我之前聊过的五层控制体系是能接上的。Skill干完活把结果写回记忆,写进去的就是一粒原子事实,Loop每跑一轮就是事件链上添一格。之前我说Loop是AI回归产品基本功的证据,现在可以再补半句,记忆是Loop留下的脚印。没有脚印的Loop,跑一万轮也等于白跑。
那天晚上合上书,我又把开头那句话读了一遍。世界是事实的总和,而不是事物的总和。
对Agent来说,这句话可能更狠一点。它的世界,就是它记下的所有事实的总和。你喂给它的每一笔记录,每一次追加,每一条因果边,都是它世界的砖。
砖垒得歪,它的世界就是歪的。砖垒得干净、带着时间的刻度和完整的来路,它才有可能真正看懂这个被交给它的世界。
它可不可信,不看它多聪明,看它的事实垒得有多老实。
对于不可说的东西,必须保持沉默。
对于记不清的事实,也请诚实标注。
这话是说给Agent听的,也是说给我们自己听。
本文由人人都是产品经理作者【产品老高】,微信公众号:【产品老高】,原创/授权 发布于人人都是产品经理,未经许可,禁止转载
题图来自Unsplash,基于 CC0 协议
- 目前还没评论,等你发挥!

起点课堂会员权益



