在 Agent 系统里,短期记忆就是上下文窗口本身,随会话结束即消失,每次调用都按输入 token 计费;长期记忆是放在模型外部的持久化存储,必须显式检索才能回到上下文。生产级 Agent 两种都依赖:短期记忆扛当前任务的连贯性,长期记忆扛跨会话的事实与偏好。短期记忆靠裁剪和摘要管理,长期记忆靠”关键词 + 向量 + 重排”的混合检索召回。
一、先分清两种记忆的边界
业界对两类记忆的划分已经形成共识:短期记忆映射到 LLM 的上下文窗口,长期记忆落到外部数据库。二者在工作位置、容量、成本上的差异直接决定各自的实现路线。
| 维度 | 短期记忆 | 长期记忆 |
|---|---|---|
| 存放位置 | 当前提示词内部 | 模型外部,数据库或文件 |
| 容量 | 受上下文窗口硬限制(如 128K–1M tokens) | 理论无限,受存储成本约束 |
| 访问方式 | 注意力机制自动全量可及 | 必须主动查询后回填上下文 |
| 成本 | 每次调用都算输入 token | 仅查询与回填时产生检索成本 |
| 生命周期 | 会话或窗口重置即消失 | 跨会话保留,显式删除才消亡 |
| 失败模式 | 旧上下文被截断、静默丢失 | 检索不中、召回偏差或命中过期事实 |
短期记忆的失败不发出任何信号:模型不知道上下文里丢了东西,照样自信作答。长期记忆的失败同样隐蔽——查回来一条语义相近但无关的记忆,Agent 也会照单全收。设计记忆系统的本质,就是决定哪条信息该放在哪一层。
二、短期记忆:存进上下文,靠注意力读取
短期记忆的”存储”动作其实只有一个:把内容拼进 context window。真正要下功夫的是管理——窗口空间有限,塞得越满,模型越容易丢重点。
2.1 三类常见存储介质
- 进程内内存(Python dict、状态对象):访问延迟低于 1ms,进程退出即丢,适合原型验证;
- Redis 这类带 TTL 的结构化 KV:毫秒级访问,可配置过期,生产级会话状态常用它;
- 检查点快照:LangGraph 的 MemorySaver 在每个图节点保存完整 Agent 状态,支持回滚与恢复。
2.2 窗口管理两种主流策略
滑动窗口只保留最近 N 轮对话,实现简单但会整段丢弃早期信息;摘要压缩则让 LLM 把旧轮次浓缩成摘要再放回窗口,保留关键事实但多一次模型调用。LangChain 的 ConversationBufferWindowMemory 与 ConversationSummaryMemory 分别对应这两种思路。
上下文太长还会带来注意力稀释问题。研究显示模型对上下文中间位置的内容注意力显著衰减,长对话中 Agent 可能反复重复历史动作而非推进任务。所以窗口不是越大越好,主动裁剪与压缩才是短期记忆的正解。
三、长期记忆:存进外部,靠查询取回
长期记忆解决”信息活过这次会话”的问题。用户偏好、项目背景、历史经验都适合放这一层,避免和当前任务抢上下文空间。
3.1 三层存储谱系
- 向量数据库:把文本切块、嵌入成向量,用近似近邻搜索召回语义相关片段。Pinecone、Milvus、Qdrant、Chroma 各有侧重,开源私有部署选 Milvus,轻量原型选 Chroma;
- 图数据库:Neo4j 这类图库承载实体与关系,擅长表达”这个模块被谁调用、依赖什么库”的链式知识;
- 结构化库:偏好、账户信息这类需要精确匹配的数据,放 SQLite 或 Redis 比向量检索更可靠。
3.2 混合检索四步走
单一向量检索会漏掉专有名词和代码标识符,生产环境普遍改用混合检索:
- 用 BM25 做关键词召回,抓专有名词、术语、代码片段;
- 用稠密向量做语义召回,抓同义转述与概念关联;
- 用倒数排名融合(RRF)合并两路结果,平衡词法精度与语义广度;
- 用交叉编码器对候选段逐条重排,取最相关的 3–5 条注入上下文。
def hybrid_retrieve(query: str, top_k: int = 5) -> list[Memory]:
bm25_hits = bm25_index.search(query, k=top_k * 3) # 关键词路
vec_hits = vector_store.similarity_search(
embed(query), k=top_k * 3) # 语义路
fused = rrf_merge(bm25_hits, vec_hits) # 倒数排名融合
return cross_encoder.rerank(query, fused)[:top_k] # 重排取前 k
存储侧的一个典型 Schema 大致长这样:每条记忆带内容、向量、时间戳与权重字段,写入时去重合并,检索时按相关度排序。
{
"id": "mem_8f2a",
"content": "用户偏好:早上 9 点前不要发通知",
"embedding": "[0.031, -0.122, ...]",
"created_at": "2026-04-02T08:00:00Z",
"last_accessed_at": "2026-04-11T09:12:00Z",
"importance": 0.9,
"source_session": "sess_43aa"
}
四、两条记忆怎么衔接
哪些信息从短期升级到长期,是记忆系统里最难的设计决策。主流做法有三类:显式写入(Agent 主动调用 remember 工具,可审计但依赖模型自觉)、周期性摘要(每 N 轮让模型总结一次并入库,稳定但消耗调用)、事后提取(后台进程在会话结束后抽取持久事实,与实时对话解耦)。三者的取舍是”可控性”与”可靠性”的平衡。
落地时按四步推进:
- 短期层先接会话缓存,设置窗口上限与摘要压缩触发点;
- 长期层选一个向量库,设计好记忆 Schema 与去重规则;
- 接通混合检索,用召回测试集验证”该中的中、不该中的不中”;
- 为长期记忆加过期与降权机制,长时间未访问的记忆自动沉底。
MemGPT/Letta 与 Mem0 是两条成熟路线:前者让模型自己决定何时把上下文”换页”到持久存储,后者把记忆抽成独立基础设施层,由框架强制一致性与去重。
常见问题(FAQ)
Q1:短期记忆和长期记忆能互相替代吗?
不能。即时任务留在上下文窗口,持久事实进外部存储,两者各管一段。
Q2:检索长期记忆用向量搜索就够了吗?
不够。专有名词和代码要靠 BM25 补召回,混合检索加重排更稳。
Q3:记忆太多会不会拖累模型?
会。无关记忆分散注意力,需靠时间衰减、重要性评分和过期清理控制注入量。