记忆机制:从上下文到持久化
上周跟它说过,这个项目用 Kotlin,不要写 Java。
记忆机制:从上下文到持久化
上周跟它说过,这个项目用 Kotlin,不要写 Java。
今天新开一个会话,它又建议我用 Java。
不是它没记住,是那次对话的上下文已经不在了。
一、上下文不是记忆
前面讲过,所谓”它记得”,是每次把历史重新拼一遍发过去。
这个机制有个硬边界:会话结束,历史就不再被发送。下次开新会话,上下文从零开始,昨天聊过的所有东西都不在里面。
所以严格说,Agent 没有记忆,只有”这一轮发了什么”。要跨会话记住一件事,必须把它从上下文里搬到一个不随会话消失的地方。
那个地方是文件。
二、两层记忆
| 工作记忆 | 长期记忆 | |
|---|---|---|
| 载体 | 上下文数组 | 磁盘上的 Markdown |
| 生命周期 | 一次会话 | 永久,直到被删 |
| 写入方式 | 自动(每轮追加) | 主动(模型调用工具) |
| 读取方式 | 全量重发 | 注入 + 检索 |
| 成本 | 每轮都付 token | 只在注入或检索时付 |
这两层不是替代关系,是配合关系:长期记忆负责”跨会话不失忆”,工作记忆负责”这一轮想得起来”。
麻烦在于,从长期到工作记忆的那一步,没有自动通道。你得决定什么时候把它捞上来。
三、写入:由模型判断什么值得记
长期记忆的写入口是一个工具:
memory_write(content: "...")
它把内容追加到当天的日志文件里,每条前面带时间戳。文件按日期分,一天一个。
这个设计有两个含义。第一,记忆是按时间组织的,不是按主题。第二,写入是追加的,不覆盖,所以旧记录不会因为新记录而消失。
关键问题是谁来判断”什么值得记”。答案是模型自己。工具描述里给了标准:
- 用户偏好(用什么语言、什么风格、什么工具)
- 反复出现的模式
- 关键事实(项目名、路径、约束)
- 项目约定
- 可复用的知识
同时明确了几条不该记的:密码、API Key、令牌,除非用户在被警告后明确同意。
把判断权交给模型,是有代价的。它可能记太多,日志变成流水账;也可能记太少,真正重要的东西没留下。而且它的判断标准来自工具描述,描述写得含糊,记下来的东西就含糊。
四、读取:注入和检索
记忆有两种被用上的方式。
注入:新会话开始时,把全局记忆和最近几天的日志直接拼进系统提示。模型一开口就已经”知道”了这些事,不需要主动去查。
检索:模型觉得需要更多背景时,调用工具按关键词搜索:
memory_get(scope: "all", keywords: "kotlin 项目约定")
搜索是模糊匹配,空格分隔的多个关键词必须同时命中某一行或它的上下文。
这就是一个最小化的检索系统:注入解决”高频常识”,检索解决”低频细节”。
两者的成本结构完全不同。注入的代价是每轮固定支付——写进系统提示的东西,每一次请求都要重发。检索的代价是按需支付——不查就不花钱,查了多一轮工具调用。
所以判断标准很直接:经常用到的才值得注入,偶尔用到的应该去检索。
五、记忆也要算预算
沿着上面的逻辑,记忆不能无限增长。
如果全局记忆写到一万字,每个新会话的系统提示就多一万字。十轮对话下来,这是十万 token 的额外开销,而且每一轮都在为”可能用不上”的信息付费。
所以记忆系统必须有容量意识,只是这个意识通常不写在代码里,而写在设计里:
- 全局记忆保持短,只放最稳定的偏好和约定;
- 日常日志按天分文件,注入时只取最近几天;
- 更早的内容靠检索,不靠注入。
这和前面的上下文预算是同一个问题,只是时间尺度更长:上下文管的是”这一轮装什么”,记忆管的是”哪些东西值得跨会话保留”。
六、记忆会怎么坏
比上下文污染更麻烦的是,记忆的错误是持久的。
| 失效 | 表现 | 后果 |
|---|---|---|
| 记错 | 把”A 方案”记成”B 方案” | 之后每次都按错的来 |
| 记旧 | 用户换了技术栈,旧偏好还在 | 建议过时,且理直气壮 |
| 记漏 | 关键约束没写进去 | 下次重犯同一个错 |
| 冲突 | 两条记录互相矛盾 | 模型随机选一条执行 |
上下文污染至少会随会话结束消失,记忆污染会一直跟着你。
所以记忆系统比上下文系统更需要可编辑性:用户能看见它记了什么,能改,能删。看不见的记忆比没有记忆更危险,因为你不知道它凭什么做出某个判断。
七、记忆属于谁
最后一点,也是最容易被忽略的:记忆的所有权。
理想的模型是:记忆是用户的资产,不是模型的内部状态。它存在用户能访问的文件里,用普通文本,能备份、能迁移、能删除。工具只能追加,不能悄悄改写历史。
这也解释了为什么全局记忆通常不允许模型直接写——那是用户自己维护的部分,模型只能读。模型写日志,人写原则。
下一篇讲这些工具到底跑在什么地方:一个没有 root、没有命名空间的 Android 手机,怎么装下一个 Linux。