记忆让智能体从"金鱼脑"变成能积累经验的助手,是长期可用性的关键。
大语言模型本身是无状态的:每次调用都是独立的,模型不记得上一轮说了什么。我们在对话中感受到的"上下文连贯",实际上是开发者把历史消息重新喂给模型实现的。当对话变长或任务变复杂时,简单的"全部重放"就行不通了,需要设计结构化的记忆机制。
| 维度 | 短期记忆 | 长期记忆 |
|---|---|---|
| 存储位置 | 模型上下文窗口 | 外部数据库/文件 |
| 生命周期 | 单次会话内有效 | 跨会话持久存在 |
| 容量限制 | 受token上限约束 | 理论上无限 |
| 检索方式 | 按时间顺序全量放入 | 按相关性检索部分放入 |
| 典型实现 | 消息历史数组 | 向量数据库、键值存储 |
短期记忆解决"当前对话的连贯性",长期记忆解决"跨对话的知识积累"。一个完整的智能体通常两者都需要。
最简单的短期记忆就是把所有历史消息原样放入上下文。但对话轮次一多,token消耗会迅速增长,甚至超出上下文窗口。常用策略有三种:
只保留最近 N 轮对话,更早的消息直接丢弃。实现简单,适合问答类场景。缺点是会"遗忘"早期的重要信息。
每隔几轮对话,用模型把较早的历史消息压缩成一段摘要,用摘要替代原始消息。这样既保留了关键信息,又控制了token用量。摘要的频率和粒度需要根据任务调整——太频繁会增加延迟和成本,太稀疏会丢失细节。
前几轮和最近几轮保留原文,中间部分用摘要替代。这是目前大多数生产系统的做法,兼顾了准确性和成本。
# 伪代码示例
messages = []
if len(history) > 20:
# 保留最近5轮原文,其余压缩为摘要
old_messages = history[:-10]
recent_messages = history[-10:]
summary = summarize(old_messages)
messages = [{"role": "system", "content": f"之前对话摘要: {summary}"}] + recent_messages
else:
messages = history
长期记忆的核心问题是"怎么存"和"怎么取"。
把用户的关键信息以键值对形式存储,每次对话开始时加载到系统提示词中。适合存储明确的偏好和事实:
{
"user_name": "张三",
"preferred_tone": "简洁直接",
"industry": "自媒体运营",
"known_topics": ["短视频", "私域流量", "社群运营"]
}
这种方式实现简单,检索精确,但只能存储预先定义好字段的信息,无法处理模糊的语义匹配。
把每条记忆编码为向量存入向量数据库,对话时把当前问题也编码为向量,检索语义最相近的记忆片段。这种方式不需要预定义字段,能处理模糊查询,是目前长期记忆的主流方案。
流程如下:
把记忆存为Markdown文件或JSON文件,用户可以直接查看和编辑。这种方式透明度高,用户对"AI记住了什么"有完全的控制感,适合个人助手类场景。
不是所有对话内容都值得记住。写入时机有三种模式:
实践中推荐"批量+按需"的组合:对话结束时自动提取结论性信息,同时支持用户主动触发记忆。
长期记忆如果不淘汰,会越来越臃肿,检索质量也会下降。常见的淘汰规则:
记忆机制的设计没有标准答案,需要根据智能体的使用场景和用户期望来调整。核心原则是:该记的不能忘,不该记的不要存,过时的要及时更新。