现在谈 agent memory,很容易滑向一个过于工程化的误解:只要把聊天记录存起来,做一次摘要,或者扔进向量库,未来再检索回来,就算有记忆了。
这当然有用,但它解决的只是“过去还在不在”。真正的记忆要回答另一个问题:过去有没有资格影响未来?
对一个 agent 来说,记忆不是存档。存档只说明某件事发生过,记忆则意味着系统选择了某些过去,解释了它们,并允许它们参与之后的判断。这里多出来的不是存储能力,而是治理能力。
所以我更愿意把 agent memory 看成一层 experience governance:它治理过去如何进入未来。
记录不是记忆
聊天历史不是记忆,摘要也不是记忆,向量检索更不是记忆。
它们分别提供了不同能力:聊天历史保留了完整上下文,摘要压缩了信息,检索让历史在未来可被找到。但这些能力都没有天然回答“这段历史应该以什么身份被使用”。
用户今天说“我最近讨厌开会”,这句话可能是一种稳定偏好,可能只是今天状态不好,也可能是对某个具体项目的抱怨。助手如果立刻把它升级成“用户讨厌会议”,未来每次安排日程都绕着这个结论走,就是把一次情绪误读成了长期事实。
很多 memory 系统的问题就在这里:它们把“曾经出现过”误认为“值得长期影响行为”。这会让 agent 看起来更懂用户,但也更容易固化误解。
记忆真正困难的地方,不是如何把过去找回来,而是如何判断过去应不应该被带回来。
证据先于结论
tinybot 的 memory 设计里有一个我很重视的选择:每轮普通对话结束后,系统并不会立刻把内容写成长期记忆,而是先留下干净、可追溯的 conversation evidence。
这个设计的关键不在于“多存了一份原文”,而在于它把证据和结论分开了。
用户说过什么,是证据。助手当时如何回应,也是证据。但长期记忆不是这些文本本身,而是系统经过判断后暂时认可的结论。
这个边界非常重要。没有证据层,memory 很容易变成一堆无法追溯的断言:用户喜欢什么,讨厌什么,正在做什么,性格如何,目标是什么。它们在 prompt 里看起来很有用,但一旦错了,系统很难解释错从哪里来,也很难判断应该如何修正。
先保留证据,不急着下结论,是一种克制。它承认对话里的很多东西只是材料,还不是记忆。
记忆需要沉淀
tinybot 里还有一条后台路径:对话证据保存之后,系统会安排 Dream 去处理。它不是在用户请求路径上实时吞咽所有内容,而是在后台、在间隔、在用户停下来之后,重新看一遍未处理的证据,判断哪些东西值得留下,哪些应该跳过,哪些需要替换已有结论,哪些应该被拒绝。
我觉得 Dream 这个名字很贴切。它不只是一个抽取器,更像记忆形成过程里的延迟判断。
人并不会把每一句话都即时变成长期记忆。很多经验是在事后整理、比较、反复出现之后,才开始具有稳定意义。agent 虽然不需要模拟人的心理过程,但它需要类似的工程缓冲:不要让每次交互都直接改写长期状态。
实时记住有一种诱惑,因为它显得智能、敏捷、个性化。但写入错误比召回错误更危险。召回错了,通常污染的是一次回答;写入错了,污染的是未来很多次回答。
因此,memory 系统应该把“写入”看得比“召回”更重。召回是使用过去,写入是定义未来可使用的过去。
长期记忆是可修正的结论
当 tinybot 把某些内容沉淀成长期记忆时,真正可用的不是一份 MEMORY.md,也不是某个用户画像文件,而是一组结构化的 memory notes。那些可读文件更像视图,方便人和 agent 理解当前记忆状态,但不应该成为唯一权威来源。
这里的重点不是具体有哪些字段,而是长期记忆应该以“可治理的结论”存在。
它不是聊天摘要,因为摘要追求压缩;它也不是人格设定,因为人格设定容易把流动经验凝固成标签。长期记忆更应该像系统当前认可的一组判断:有来源,有边界,有状态,也允许被后来的证据推翻。
这使得记忆不是一条单向追加日志,而是一个会被修正的经验系统。
如果用户后来改变了习惯,旧记忆不应该继续以同样强度影响行为。如果新证据和旧结论冲突,系统不应该简单地把两者都塞进上下文,让模型临场猜测。memory 层需要负责承认冲突、处理冲突,并把处理结果变成之后可用的状态。
也就是说,长期记忆不应该追求“永远记住”,而应该追求“当前可信”。
召回应该像证词,不像命令
记忆形成之后,还有一个同样关键的问题:它如何进入当前上下文?
我不喜欢把 memory、knowledge、recent context、experience 全部混成一段大 prompt。这样做实现简单,但会模糊不同信息的身份。知识库内容、最近对话、历史偏好、过往失败经验、当前用户指令,它们对 agent 的约束力并不相同。
tinybot 的召回路径把 memory 单独放进上下文,并且和其他材料分开。这背后的原则是:memory should inform the agent, not command it.
记忆应该像证词。它可以提醒 agent:用户过去可能表达过某种偏好,某个任务曾经采用过某种做法,某个判断曾经被证明有问题。但它不应该自动覆盖当前用户指令,也不应该伪装成系统规则。
如果用户今天明确说“这次不用按我以前的习惯来”,那么当前意图应该优先。如果知识库里有更可靠的事实,memory 中的旧印象也应该让位。agent memory 的价值不是让过去更强势,而是让过去在合适的位置发挥作用。
好的召回不是把更多东西塞给模型,而是把过去以正确身份交给模型。
自动记忆必须有纠错路径
一旦系统可以自动记住,它就必须允许显式纠错。
tinybot 同时有后台 Dream 和前台 memory 工具,这个组合很重要。Dream 负责自动沉淀,让系统不需要每次都打断用户确认;显式工具则提供修正路径,让用户或 agent 可以主动保存、搜索、追踪、拒绝、替换记忆。
没有前台纠错,自动 memory 会变成一种隐形权力。系统在后台形成了关于用户的判断,未来又用这些判断影响回答,但用户很难知道它记住了什么,也很难纠正它为什么错。
这不是简单的隐私问题,也是产品可信度问题。
一个 agent 如果会说“我记得你喜欢这样”,它也应该能回答“我是根据什么记得的”。如果它能把某个结论带到未来,它也应该允许这个结论被撤回、被替换、被标记为不再适用。
否则 memory 会从能力变成债务。
记忆治理的是未来
从这个角度看,agent memory 的工程问题可以重新表述。
不是“我们要不要存聊天记录”,而是“什么材料可以成为证据”。不是“怎么做长期存储”,而是“什么结论有资格长期存在”。不是“怎么提高召回率”,而是“召回的内容以什么身份参与当前判断”。不是“怎么让 agent 更懂用户”,而是“当它懂错了,系统如何发现、解释和修正”。
这也是为什么我不认为 agent memory 的核心是向量库、无限上下文或者用户画像。它们都可能是组件,但不是答案。
真正的答案是一套经验治理机制:先保留证据,再延迟沉淀,把长期记忆作为可修正的结论管理,并在召回时保持边界,同时给用户和 agent 留出明确的纠错路径。
记录解决的是过去还在不在。记忆解决的是过去有没有资格影响未来。
Agent 记忆不是保存过去,而是治理未来。