工作记忆管理
概述
工作记忆(也称短期记忆)是智能体当前正在推理的活跃状态——包括持续进行的对话,以及模型在推理时能够看到的草稿空间。它存在于 LLM 的上下文窗口中,是整个记忆系统中成本最高、容量最受限的部分。有效的工作记忆管理对于维持对话连贯性、避免上下文溢出错误以及控制推理成本至关重要。
在 CoALA 分类体系中,工作记忆是唯一的上下文内记忆类型。其余三种长期记忆类型(语义记忆、情景记忆、过程记忆)均存储在上下文窗口之外,需要时必须被检索到工作记忆中。
核心挑战
LLM 拥有固定大小的上下文窗口(随模型不同,从 4K 到 1M+ token 不等)。随着对话不断增长,你必须决定: - 哪些内容保留在上下文窗口中(工作记忆) - 哪些内容需要摘要或压缩 - 哪些内容应卸载到语义记忆、情景记忆或过程记忆 - 哪些内容可以直接丢弃
上下文窗口 Token 预算布局
使用大上下文模型(例如拥有 200K token 的 Claude)的生产环境智能体,需要在多个相互竞争的区域之间管理分层 Token 预算:
| 上下文区域 | 典型大小 | 说明 |
|---|---|---|
| 系统提示词 | 稳定、设计时确定 | KV cache 的最佳候选;跨轮次保持稳定可为这部分输入 token 节省约 85% 的成本 |
| 窗口化对话历史 | 每轮约 1,200–3,500 token(窗口化后) | 动态变化;由下文策略管理 |
| 检索到的 RAG 分块 | top-k × chunk_size token | 每轮注入;大小取决于检索策略 |
| 工具调用结果 | 各工具不同,通常较大 | 在推理期间累积;可能需要摘要 |
| 智能体草稿区 / CoT | 中间推理 | 位于 LLM 内部;是否公开取决于框架 |
| 为响应预留 | max_tokens 预算 | 必须预留,不能被历史记录占用 |
关键指标:KV cache 命中率。在 Amazon Bedrock 上,Claude 会缓存每个上下文中的系统提示词部分;缓存命中可为该部分输入 token 节省约 85% 的成本。系统提示词应跨轮次保持稳定,不要把每轮动态内容注入系统提示词块。
工作记忆技术
滑动窗口
逻辑:只保留最近固定数量的消息,一旦达到上限便丢弃最旧的消息。
主要优势:防止上下文溢出错误,并维持较低延迟。
权衡:会完全丢失较早的上下文——智能体会"遗忘"对话的前期内容。
适合场景:简单聊天机器人和任务智能体,此类场景中近期上下文最为重要。
# LangChain ConversationBufferWindowMemory
from langchain.memory import ConversationBufferWindowMemory
memory = ConversationBufferWindowMemory(k=5) # Keep last 5 exchanges
Token 裁剪
逻辑:动态计算并从历史记录开头移除最少数量的 token,使其适配模型的上下文限制。
主要优势:在不崩溃的前提下,最大化利用可用的上下文窗口。
权衡:可能在句子中间截断重要的早期上下文。
适合场景:希望尽可能利用上下文、又不想手动调优的应用场景。
递归摘要
逻辑:定期将对话中较旧的部分压缩为简短段落,同时保留近期消息的完整内容。
主要优势:在节省大量 token 空间的同时,保留长期叙事上下文。
权衡:摘要会引入信息损失,并增加延迟。
适合场景:长时间运行的对话,其中早期上下文仍有意义,但无需逐字回忆。
# LangChain ConversationSummaryMemory
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
memory = ConversationSummaryMemory(llm=ChatOpenAI())
消息选择
逻辑:使用"主管"模型检索与当前用户查询相关的历史消息。
主要优势:对于只有特定历史事实才重要的复杂非线性任务,效率极高。
权衡:检索步骤会增加延迟和成本,且可能遗漏相关上下文。
适合场景:对话历史丰富多样、但大多数历史消息与当前查询无关的长期运行智能体。
草稿区 / 工作记忆
逻辑:为智能体提供专用空间(如文件或隐藏块),用于存储中间思路和计算过程。
主要优势:将技术复杂性从主聊天历史中剥离,保持对话整洁。
权衡:需要智能体具备明确的行为才能有效使用草稿区。
适合场景:多步骤推理任务、代码生成以及复杂问题求解,此类场景中中间步骤不应污染对话记录。
上下文固定
逻辑:将关键信息(如系统指令或核心用户偏好)锁定,使其永远不会被裁剪或滑动窗口操作丢弃。
主要优势:确保智能体永远不会忘记其主要角色、使命或关键用户偏好。
权衡:会减少动态上下文的可用空间。
适合场景:所有生产环境智能体——始终固定系统指令和关键用户上下文。
语义窗口(语义压缩)
逻辑:将全部历史分块嵌入向量库,再根据当前查询只检索语义相关的轮次,而不是最近的 k 轮。
主要优势:可将 50+ 轮历史缩减为 3–5 个高度相关轮次。对于存在话题分支的长期会话,可提升响应质量。
权衡:需要使用向量库存储历史记录,并增加约 15ms 检索延迟。实现复杂度高于滑动窗口。
适合场景:长期运行且话题不断分支,近期性无法准确代表相关性的会话。
渐进式摘要
逻辑:当累计 token 数超过阈值时,调用模型总结较早的轮次,并以结构化摘要对象替换原始轮次。
主要优势:在保留语义内容的同时,将 token 数减少 80–90%。
权衡:每次触发压缩都会多一次 LLM 调用,从而增加延迟。
适合场景:原始历史超出上下文预算,但又必须保持语义保真度的会话。
工作记忆解决方案
| 类别 | 方案 | 记忆理念 | 适合场景 |
|---|---|---|---|
| 框架 | LangGraph Checkpoints | 有状态线程 | 保存多步骤工作流的精确"快照" |
| 框架 | LangChain Window | 滑动缓冲区 | 只保留最近 N 次交互以节省 token |
| 框架 | Letta (MemGPT) | 虚拟上下文 | 动态地将信息换入/换出上下文窗口 |
| 内存 | Redis / Upstash | 临时缓存 | 高速聊天应用的低延迟会话存储 |
| 托管 | OpenAI Threads | 有状态 API | 免手动管理当前对话历史 |
| 技术 | 摘要 | 递归压缩 | 将旧消息压缩为简短"回顾"以节省空间 |
| 技术 | 草稿区 | 工作草稿 | 智能体撰写的笔记,仅用于当前任务逻辑 |
窗口策略对比
| 策略 | 淘汰逻辑 | 复杂度 | 延迟 | 适合场景 |
|---|---|---|---|---|
| 最近 k 轮 | 保留最近 k=10–20 轮 | O(1) | 无 | 大多数对话智能体 |
| Token 预算窗口 | 滑动窗口直至 token 数 ≤ 预算;先加入最新内容,再淘汰最旧内容 | 低 | 无 | 精确控制 token |
| 语义窗口 | 嵌入全部轮次;检索与当前查询最相关的 top-k | 中等(需向量库) | +15ms | 话题分支较多的长期会话 |
| 渐进式摘要 | 超过阈值后总结最早的历史片段 | 高(需调用 LLM) | +模型延迟 | 大规模、高保真地保留历史 |
LangGraph Checkpointer 模式
LangGraph checkpointer 为会话记忆实现检查点存取模式。每次调用 invoke() 时,智能体运行“思考-行动-观察”循环,序列化状态,并写入以 thread_id + checkpoint_id 为键的原子检查点。下一轮则加载该检查点、反序列化状态并继续执行。
存储后端:Amazon DynamoDB(强一致读取,通过 thread_id 执行 GET)或 Amazon ElastiCache(亚毫秒级 PUT/GET)。
LangGraph 的检查点系统会在每个步骤保存图执行的完整状态,从而支持:
- 暂停与恢复:停止长时间运行的智能体,稍后继续
- 人在回路(HITL):在继续之前暂停并等待人工审批
- 时间旅行:从任意历史检查点重放,便于调试
- 容错:从故障中恢复,无需从头重启
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph
checkpointer = MemorySaver()
graph = StateGraph(AgentState)
# ... add nodes and edges ...
app = graph.compile(checkpointer=checkpointer)
# Run with thread ID for persistence
config = {"configurable": {"thread_id": "user-123"}}
result = app.invoke({"messages": [...]}, config=config)
Letta (MemGPT) — 操作系统启发的记忆架构
Letta(前身为 MemGPT)实现了一种受操作系统启发的记忆架构,智能体像操作系统管理 RAM 一样管理自身的上下文窗口:
- 主上下文(RAM):活跃的上下文窗口——速度快但容量有限
- 归档存储(磁盘):用于溢出内容的外部存储——容量无限但需要检索
- 召回存储:可搜索的历史交互记录
智能体使用专用的记忆管理函数(core_memory_append、archival_memory_search)来显式管理哪些内容留在上下文中、哪些内容被卸载出去。
最佳实践
- 始终固定系统指令:使用上下文固定,确保智能体的角色设定和核心指令永远不会被裁剪
- 稳定系统提示词:让系统提示词内容跨轮次保持稳定,最大化 KV cache 命中率(在 Amazon Bedrock 上,缓存 token 可节省约 85% 的成本)
- 选择合适的窗口策略:简单对话智能体使用最近 k 轮;精确控制使用 Token 预算;话题分支使用语义窗口;高保真长会话使用渐进式摘要
- 监控上下文利用率:跟踪上下文窗口的使用比例,识别优化机会
- 测试边界情况:验证上下文接近满载时的行为——智能体是否能优雅降级?
- 考虑成本:上下文越长,每次推理的成本越高——在质量与成本之间寻求平衡
参见
参考资料
- AWS Marketplace — Building Agentic Systems: Agent Memory Systems (Module 7) —— 上下文窗口 Token 预算布局、窗口策略、LangGraph checkpointer 模式与 KV cache 优化