KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
01. Agent 到底需要什么样的记忆? — keel 龙骨
你先不要写向量检索。先观察一个最小实验。
你先不要写向量检索。先观察一个最小实验。
第一次运行时,用户说:
以后故障报告请使用中文,先给结论,再列证据。
第二次运行时,用户只问:
支付服务刚刚超时,帮我分析一下。
如果第二次运行仍能遵循语言和格式偏好,才说明系统在运行之间保留了有用信息。这个实验同时揭示一个问题:第二次运行开始时,模型并没有“自动知道”第一次发生过什么。程序必须决定保存什么,并在合适的时机再次提供什么。
1. 先区分五个数据空间
在 Agent 系统里,下面五个词经常都被口语化地叫作“记忆”,但它们解决的是不同问题。
| 名称 | 它保存什么 | 谁需要它 | 什么时候失效 |
|---|---|---|---|
| 对话历史(chat history) | 用户和 Agent 原来说过的话 | 当前对话继续生成 | 会话结束、裁剪或归档 |
| 上下文(context) | 本次模型调用真正看到的材料 | 模型 | 当前调用结束 |
| 运行状态(run state) | 任务走到哪一步、已有哪个工具结果 | Harness、worker | 任务结束或被清理 |
| 检查点(checkpoint) | 某个运行状态的可恢复快照 | 恢复、暂停、重试 | 运行生命周期或保留期结束 |
| 持久记忆(long-term memory) | 未来运行仍可能有用的、经过筛选的信息 | 后续 Harness | 被更新、过期或删除 |
可以用一个简单比喻理解它们:对话历史像录音,上下文像这次会议摆在桌上的材料,运行状态像项目看板,检查点像看板的存档照片,持久记忆像经过确认后写入团队知识库的条目。它们可以互相产生数据,但不能互相替代。
对话历史不等于持久记忆
把第一次对话全部重新发送给模型,可能暂时实现“记住”。但它会带来三个问题:
- 对话越长,token 成本越高;
- 过期、错误和敏感内容也会被重新带入;
- 一旦历史被裁剪,偏好就消失了。
持久记忆只保存经过选择的内容,并且有自己的 ID、来源、作用域和生命周期。
上下文不等于数据库
上下文是一次调用的输入集合,不是永久仓库。某条数据库记录可能因为权限或任务不相关而不进入上下文;某段临时工具输出可能进入上下文,却不值得长期保存。
可以先记住这个关系:
持久数据 --经过检索和筛选--> 当前上下文 --> 模型
当前对话 --经过判断--------> 记忆候选 --> 写入策略
运行状态和检查点不等于事实记忆
“工具已经执行到第二步”是运行状态;“用户是支付服务的负责人”才可能是长期事实。检查点的任务是让程序从中断处继续,不是判断哪些内容以后仍然成立。
thinking 不等于事实
模型的 thinking 可能包含猜测、尝试和错误。它可以帮助调试当前回答,但不应直接进入长期数据库。只有有来源、经过业务或用户确认的信息,才有资格进入写入流程。
不同框架的命名不完全相同,但边界很接近。例如 LangGraph 用 checkpointer 保存 thread 级运行状态,用 store 保存跨 session 的长期数据;Google ADK 区分 Session/State 和可搜索的 MemoryService。你以后换框架时,先看它的对象属于“运行恢复”还是“跨运行事实”,不要只按类名判断。
参考:LangGraph Memory、Google ADK Memory。
2. 从一次运行看数据如何流动
sequenceDiagram
participant U as 用户
participant H as Harness
participant M as 记忆存储
participant L as 模型
U->>H: 当前问题
H->>M: 按用户作用域查询
M-->>H: 可用的历史记忆
H->>L: 当前消息 + 筛选后的上下文
L-->>H: 回答或下一步决定
H->>M: 后台保存经过审核的候选
读路径发生在模型调用前,写路径通常发生在回答完成后。这样,即使抽取模型暂时不可用,当前回答也不必被记忆服务拖住。
3. 现在做一个不依赖大模型的对照实验
打开 配套项目,运行:
python examples/01_store_and_recall.py
这个例子会把一条记录写入临时 SQLite 文件,关闭连接,再重新打开。你应该观察到:重新打开后仍然能读到记录。这里没有模型,也没有向量;它只证明“跨进程保留数据”和“聊天历史继续存在”是两件事。
然后回答三个问题:
- 如果不保存记录,第二次运行如何知道用户的偏好?
- 如果把所有聊天记录保存,哪些内容会被不必要地带回来?
- 如果这条偏好属于 Alice,Bob 查询时为什么不能看到它?
第三个问题会自然引出作用域,第二个问题会引出记忆分类,第二章正是为此准备的。
4. 本章的专业结论
持久记忆不是一个“更长的 prompt”,而是一个外部数据系统。它至少需要同时考虑:
- 信息是否值得跨运行保存;
- 谁拥有和谁可以读取它;
- 它来自哪里、是否已经确认;
- 它什么时候失效;
- 用户怎样修改和删除它;
- 它如何经过检索进入本次上下文。
如果你现在能用自己的话解释“上下文为什么不是数据库”,就可以继续。