Appearance
上下文压缩与记忆分层专题
版本:
v1.1最后更新:
2026-07-07适用对象:需要为 Agent、RAG、长任务工作流、企业知识助手和多轮会话系统设计上下文治理、状态持久化、长期记忆和成本控制策略的产品、平台、算法与工程同学
很多 AI 系统一开始都会有一个朴素想法:
- 只要把所有相关信息都塞给模型,模型就会更聪明
很快团队就会撞上几个现实问题:
- 上下文越来越长
- 成本越来越高
- 延迟越来越差
- 关键内容反而被淹没
- 同样的信息在不同层反复出现
- 该记住的没记住,不该记住的却一路带着走
这也是为什么工程上常常需要同时做两件事:
- 上下文压缩
- 记忆分层
OpenAI 的 token counting、prompt caching、context engineering、session memory / context personalization cookbook,和 LangGraph / LangChain 的 short-term memory、long-term memory、persistence 文档,都指向同一个核心原则:
- 大上下文窗口有帮助,但它不能替代上下文治理
一句话理解:
上下文压缩解决“给模型看的内容要足够短且足够有用”,记忆分层解决“什么信息该以什么形态存在哪一层、在什么时机拿回来”
1. 什么是上下文压缩
更实用的理解通常是:
- 不把所有原始信息直接丢给模型
- 先把信息整理成更短、更结构化、更有决策价值的表达
压缩的目标不是单纯:
- 少一点 token
而是:
- 保留后续决策真正需要的信号
所以压缩是一种信息治理,不只是文本摘要。
2. 什么是记忆分层
记忆分层更偏向:
- 按时间跨度、更新频率、用途和重要程度管理信息
也就是说,不同信息不应该全部挤在同一个 prompt 里竞争注意力。
更典型的思路是:
- 当前轮工作上下文
- 短期会话记忆
- 中期任务状态
- 长期用户记忆
- 长期知识记忆
这样系统才不会把:
- 聊天记录
- 任务进度
- 用户偏好
- 企业知识
混成一坨。
3. 为什么不能只依赖大上下文窗口
上下文窗口变大确实有帮助,但工程上依然会碰到现实约束:
- 成本上升
- 延迟上升
- 噪声变多
- 关键片段注意力下降
- 工具 schema、系统规则和历史消息本身就占掉大量 token
OpenAI Token counting 和 Prompt caching 文档都说明:
- token 不是免费资源
- 大量稳定前缀虽然可缓存,但并不意味着可以无限堆上下文
更重要的是:
- 模型能“装下”很多信息,不等于模型会“稳定使用好”这些信息
所以更大的窗口不等于:
- 不再需要上下文治理
4. 为什么上下文压缩和普通摘要不是一回事
很多团队会把压缩理解成:
- 让模型生成一段摘要
这只是压缩的一种形式,而且往往不是最稳的形式。
普通摘要更偏向:
- 讲个大概
而上下文压缩更关注:
- 哪些步骤已经完成
- 哪些结论仍然有效
- 哪些证据仍能支撑后续动作
- 哪些风险约束绝不能丢
- 哪些失败原因需要保留
所以它是为了支持:
- 后续执行
- 后续检索
- 后续决策
而不是为了“让人读起来舒服”。
5. 一个更实用的总体视角
可以把上下文治理拆成两个问题。
5.1 现在给模型看什么
这属于:
- 上下文装配
- 压缩
- 检索
- token 预算
5.2 长期要记住什么
这属于:
- 记忆分层
- 状态持久化
- 用户档案
- 企业知识
很多系统做不好,是因为把这两个问题混在一起。
比如:
- 用会话历史承担长期知识记忆
- 用长期向量记忆承担当前任务状态
- 用聊天摘要承担审批状态记录
这些都会很快变乱。
6. 哪些信息最适合压缩
尤其这些内容更适合先压缩再使用:
- 冗长聊天记录
- 多轮工具返回
- 长文档摘要
- 批量检索结果
- 长任务阶段总结
- 重复出现的限制条件
- 多次失败后的试错轨迹
如果原样塞回模型,常见后果包括:
- 模型把大量注意力浪费在低价值重复上
- 成本增加
- 关键约束淹没
- 后续回合越来越慢
7. 哪些信息不适合过度压缩
不是所有东西都适合压。
尤其以下信息如果压缩过头,很容易引发事故:
- 审批边界
- 权限范围
- 最新业务状态
- 用户明确偏好或禁令
- 高风险失败原因
- 关键引用与证据
- 当前任务必须满足的验收标准
更稳妥的做法通常是:
- 先定义哪些信息属于“绝不能丢”的信号
否则压缩会从“降噪”变成“删掉关键事实”。
8. 一个更实用的记忆分层视角
可以按用途把记忆拆成五层。
8.1 工作记忆
定义:
- 当前这一轮必须看到的事实
特点:
- 生命周期最短
- 更新最频繁
- token 预算最敏感
典型内容:
- 当前问题
- 当前工具结果
- 当前步骤所需约束
8.2 会话记忆
定义:
- 这次对话中持续有效的上下文
典型内容:
- 对话目标
- 最近关键互动
- 当前话题分支
8.3 任务记忆
定义:
- 本次任务的目标、状态、待办、已完成步骤
典型内容:
- 当前工作流状态
- planner 产出的计划
- 已完成步骤与失败原因
8.4 用户记忆
定义:
- 用户长期偏好、角色、背景
典型内容:
- 用户部门
- 语言偏好
- 常用格式
- 风险偏好
8.5 知识记忆
定义:
- 与当前任务相关、可复用的组织知识和文档事实
典型内容:
- 企业制度
- 产品文档
- FAQ
- 技术知识库
这五层不是理论分类,它们决定了:
- 该不该压缩
- 该怎么存
- 什么时候取回
9. 一个最小可行的状态模型
建议至少把系统里的“状态”和“知识”拆开。
json
{
"working_context": {
"current_goal": "完成退款审批流程",
"latest_user_request": "帮我看下这笔退款是否需要审批"
},
"task_state": {
"task_id": "task_001",
"current_step": "policy_check",
"completed_steps": ["load_order"],
"pending_steps": ["approval_decision", "crm_update"]
},
"user_profile": {
"role": "support_agent",
"locale": "zh-CN"
},
"knowledge_refs": [
"policy_2026_07",
"refund_sop_v3"
]
}这类最小状态模型的好处是:
- 不会用长会话去承载工作流状态
- 不会用任务状态去替代知识引用
- 不会让用户偏好反复出现在聊天摘要里
10. 不同层的更新频率应该不同
很多系统记忆越做越乱,一个根因是:
- 所有层都用同一种更新机制
这通常会导致:
- 该稳定的层频繁抖动
- 该实时变化的层又更新不及时
更稳妥的策略通常是:
| 层 | 更新频率 |
|---|---|
| 工作记忆 | 每回合或每节点更新 |
| 会话记忆 | 每 1-3 轮或话题切换时更新 |
| 任务记忆 | 状态变化时更新 |
| 用户记忆 | 低频更新,通常需显式确认 |
| 知识记忆 | 由知识流水线更新,不由会话直接改写 |
一旦更新频率混乱,后面就很容易出现:
- 用户临时一句话被错误写成长期偏好
- 某次任务状态被误带到下一个任务
11. 上下文压缩到底有哪些形式
摘要只是其中一种。
真实系统里更常见的压缩形式还包括:
11.1 去重
- 删除重复规则
- 删除重复检索片段
- 删除相同含义的多轮消息
11.2 结构化提取
- 从长文里提取关键字段
- 从工具结果里提取关键状态
11.3 状态归纳
- 把多轮过程归纳成当前状态
11.4 证据裁剪
- 只保留高分、最新、最相关的证据
11.5 轨迹压缩
- 把试错过程转成阶段摘要和决策信号
11.6 分层持久化
- 只把需要长期记住的东西写入长期层
所以压缩是一个组合策略,不是单个摘要按钮。
12. 为什么轨迹压缩和记忆分层是强关联的
推理轨迹压缩专题 关注的是:
- 长链路过程信息如何压成后续可用的状态、证据和决策信号
而记忆分层关注的是:
- 压完之后,这些信息该落在哪一层
例如:
- 试错细节不一定该长期保存
- 最终失败原因可能要进入任务记忆
- 用户偏好不该从推理轨迹里自动抽出来
所以更稳妥的做法不是:
- 先压一下,然后全存
而是:
- 先压
- 再决定进入哪一层
13. 一个更实用的压缩触发条件
不要随意压缩。
更实用的触发方式通常包括:
13.1 token 阈值触发
- 总上下文超过预算
13.2 阶段边界触发
- 某个工作流阶段结束
- 计划节点执行完
13.3 轮次阈值触发
- 会话连续达到 N 轮
13.4 工具批次触发
- 一轮里累积了大量工具结果
13.5 人工节点触发
- 提交审批前
- 人工接管前
13.6 恢复节点触发
- 长任务恢复前做阶段摘要
压缩时机应该是设计项,而不是临时凑出来的。
14. 一个更实用的上下文装配顺序
建议把 prompt / context 装配顺序尽量固定。
text
系统规则
-> 当前任务目标
-> 当前工作状态
-> 本轮所需最新证据
-> 必要的用户偏好
-> 必要的历史摘要
-> 当前用户输入这种顺序的价值在于:
- 稳定前缀更适合 prompt caching
- 动态内容不会污染稳定层
- 更容易做 token 预算和问题定位
OpenAI Prompt caching 文档特别强调:
- 稳定内容要尽量固定在前缀
- 动态变量尽量后置
这和上下文治理是天然一致的。
15. 为什么 prompt caching 和记忆分层要一起设计
很多人把 prompt caching 只看成成本优化点。
其实它和分层非常契合。
更适合缓存的通常是:
- 稳定系统提示词
- 稳定工具 schema
- 稳定 few-shot
- 稳定背景知识
而不适合缓存的通常是:
- 当前用户输入
- 每次变化的检索片段
- 当前任务瞬时状态
换句话说:
- 稳定层天然更适合进入 cacheable prefix
- 高频变化层应尽量后置
如果系统把所有层混在一起,缓存命中率和上下文可维护性都会变差。
16. 上下文压缩为什么不能只盯 token 长度
一个很常见的误区是:
- 压缩只看少了多少 token
但真正更重要的问题通常是:
- 留下来的信息质量怎么样
压缩效果至少要同时看:
- token 降了多少
- 关键约束保留了多少
- 后续成功率是否下降
- 失败率是否上升
- 人工接管率是否变化
否则很容易出现一种假优化:
- token 看起来降了很多
- 但任务表现明显变差
17. 为什么记忆写入策略必须保守
很多团队一开始做记忆系统时,喜欢:
- 只要模型觉得有用,就写进去
这会很快带来污染问题。
常见污染包括:
- 把临时偏好写成长期偏好
- 把猜测写成事实
- 把某次异常状态写成稳定状态
- 把敏感内容写入不该长期保存的层
更稳妥的写入策略通常是:
| 层 | 写入策略 |
|---|---|
| 工作记忆 | 自动、短期、可覆盖 |
| 会话记忆 | 自动但保守,优先摘要 |
| 任务记忆 | 基于状态变化写入 |
| 用户记忆 | 低频、需验证或显式确认 |
| 知识记忆 | 由知识流水线维护,不由会话直接写 |
这会比“只要有点像信息就写进长期记忆”稳很多。
18. 记忆失效和清理机制为什么重要
很多系统只讨论怎么记,不讨论怎么忘。
这会带来两个问题:
- 成本持续上升
- 错误信息长期存活
所以不同层都应该有自己的失效策略。
18.1 工作记忆
- 回合结束或任务结束后清理
18.2 会话记忆
- 会话结束后只保留摘要版
18.3 任务记忆
- 任务关闭后冻结,后续仅用于回放
18.4 用户记忆
- 需支持人工更正、过期与撤销
18.5 知识记忆
- 跟随知识版本和文档生命周期更新
没有“忘记”的设计,记忆系统通常会越来越重,也越来越不可信。
19. 一个更实用的多层检索策略
不要每次都从所有层同时拉信息。
更稳妥的做法通常是按问题类型选层。
例如:
19.1 当前任务步骤判断
优先取:
- 任务记忆
- 最近工作状态
19.2 用户格式偏好
优先取:
- 用户记忆
19.3 企业制度与政策问答
优先取:
- 知识记忆
- 当前轮检索证据
19.4 长任务恢复
优先取:
- 任务记忆
- 阶段摘要
- 最近补偿和审批事件
这种分层检索会比“一股脑全捞回来”稳定得多。
20. 一个更实用的压缩对象示例
20.1 会话摘要对象
json
{
"topic": "退款审批",
"resolved_points": [
"已确认订单属于企业版",
"金额 6200 超过审批阈值"
],
"open_questions": [
"审批人是否已确认"
],
"must_keep_constraints": [
"金额大于5000必须审批"
]
}20.2 任务状态对象
json
{
"task_id": "task_001",
"status": "awaiting_approval",
"completed_steps": ["load_order", "policy_check"],
"pending_steps": ["approval", "crm_update"],
"latest_failure": null
}20.3 用户偏好对象
json
{
"user_id": "u_001",
"preferences": {
"language": "zh-CN",
"answer_style": "concise"
},
"confidence": "confirmed"
}对象一旦结构化,压缩和检索都会更稳。
21. 为什么长任务恢复特别依赖记忆分层
长任务恢复策略专题 里最核心的一个问题是:
- 任务中断后,系统如何快速恢复,而不是从零读完所有历史轨迹
这就要求系统在恢复时优先拿到的是:
- 当前阶段状态
- 已完成步骤
- 未完成步骤
- 最新关键证据
- 必须继续遵守的约束
而不是:
- 几百轮原始日志
这本质上就是:
- 压缩好的任务记忆服务恢复
22. 线上应该监控哪些上下文治理指标
22.1 成本和体积指标
| 指标 | 用途 |
|---|---|
| avg_prompt_tokens | 平均上下文体积 |
| p95_prompt_tokens | 长尾上下文体积 |
| cache_hit_rate | 稳定层是否真的命中缓存 |
| context_assembly_latency | 上下文装配耗时 |
22.2 质量指标
| 指标 | 用途 |
|---|---|
| answer_quality_after_compression | 压缩后质量是否下降 |
| unsupported_claim_rate | 压缩后是否更容易无证据回答 |
| constraint_drop_rate | 关键约束是否被压掉 |
| memory_pollution_rate | 错误信息写入长期层比例 |
22.3 恢复与任务指标
| 指标 | 用途 |
|---|---|
| resume_success_rate | 长任务恢复是否更顺 |
| replan_after_resume_rate | 恢复后是否频繁重新规划 |
| human_handoff_due_to_context_loss | 因上下文丢失转人工比例 |
如果没有这些指标,团队通常只能凭体感判断压缩是不是有效。
23. 上下文压缩和记忆分层怎样进入评测体系
这类能力不能只靠线上主观感觉。
建议至少构建三类评测。
23.1 压缩前后对比评测
看:
- 成功率
- 成本
- 延迟
- 关键约束保留情况
23.2 恢复场景评测
看:
- 长任务中断后是否能正确恢复
- 压缩状态是否足以支持后续执行
23.3 记忆污染评测
看:
- 临时信息是否误写长期层
- 错误事实是否长期存活
OpenAI Evaluate agent workflows 和 LangSmith / LangGraph 的记忆能力都启发了一件事:
- 记忆系统不是“装上就好”,而是要像其他核心链路一样被持续评估
24. 常见失败模式
24.1 所有历史对话都原样塞回模型
后果:
- token 暴涨
- 噪声积累
24.2 把用户偏好、任务状态和知识内容混在一起
后果:
- 信息层次混乱
- 更新策略无法稳定
24.3 压缩只保留一句泛化总结
后果:
- 关键约束和失败原因丢失
24.4 长期记忆写入过于激进
后果:
- 记忆污染
24.5 没有清理和过期机制
后果:
- 旧信息长期干扰新任务
24.6 只关注 token 长度,不关注信息质量
后果:
- 看似省钱,实际上性能下滑
25. 优化上下文压缩与记忆分层的常见手段
25.1 先定义层,再定义压缩
- 不要先压,再临时决定往哪放
25.2 把状态对象结构化
- 状态比散文摘要更稳定
25.3 稳定层前置,动态层后置
- 同时服务 caching 和可维护性
25.4 给长期层加写入门槛
- 不是所有内容都值得长期保存
25.5 把恢复需求反推回压缩设计
- 长任务恢复要什么,就让阶段摘要保留什么
25.6 用评测而不是感觉来调压缩策略
- 否则很容易把关键信息压没
26. 一个可执行的落地流程
26.1 先盘点当前上下文来源
列出:
- 系统规则
- 历史会话
- 工具结果
- 任务状态
- 用户偏好
- 知识库片段
26.2 给信息分层
明确:
- 哪些属于工作记忆
- 哪些属于会话记忆
- 哪些属于任务记忆
- 哪些属于用户记忆
- 哪些属于知识记忆
26.3 为每层定义更新和失效策略
包括:
- 何时写入
- 何时压缩
- 何时清理
- 何时取回
26.4 设计装配顺序和 token 预算
不要让每次请求自由拼接。
26.5 做压缩前后评测
重点看:
- 成本
- 延迟
- 成功率
- 关键约束保留率
26.6 接入监控和回放
让团队能看到:
- 压缩触发了多少次
- 哪层写得最多
- 哪层最容易污染
27. 推荐搭配阅读
28. 落地检查清单
- 是否区分当前轮、会话态、任务态、用户态和知识态信息?
- 是否能解释每条信息进入哪一层、由谁写、何时失效?
- 是否对长会话、长日志和批量检索结果做了压缩,而不是全量直塞?
- 是否明确了哪些约束、状态和证据绝不能在压缩中丢失?
- 是否按阶段边界、token 阈值或恢复节点触发压缩?
- 是否把稳定层和动态层分开组织,以提升可维护性和 prompt caching 命中?
- 是否对长期记忆设置了保守写入、纠错和清理策略?
- 是否评估过压缩前后对成功率、成本、延迟和恢复能力的影响?
- 是否监控了 prompt tokens、cache_hit_rate、constraint_drop_rate 和 memory_pollution_rate?
- 是否保留原始轨迹和原始知识引用,支持回放与复盘?
29. 推荐资源
以下资源在 2026-07-07 检查时可访问,适合作为上下文工程、压缩、缓存和记忆分层的官方参考。
OpenAI
- Agents cookbook topic:https://developers.openai.com/cookbook/topic/agents
- Prompt caching:https://developers.openai.com/api/docs/guides/prompt-caching
- Token counting:https://developers.openai.com/api/docs/guides/token-counting
- Agents SDK session memory:https://developers.openai.com/cookbook/examples/agents_sdk/session_memory
- Context personalization:https://developers.openai.com/cookbook/examples/agents_sdk/context_personalization
- Evaluate agent workflows:https://developers.openai.com/api/docs/guides/agent-evals
LangGraph / LangChain
- Memory overview:https://docs.langchain.com/oss/python/concepts/memory
- Context engineering:https://docs.langchain.com/oss/python/langchain/context-engineering
- Add short-term memory:https://docs.langchain.com/oss/python/langgraph/add-memory
- Add long-term memory:https://docs.langchain.com/oss/python/langgraph/add-memory#add-long-term-memory
- Persistence:https://docs.langchain.com/oss/python/langgraph/persistence
30. 最后总结
上下文压缩与记忆分层不是“为了省 token 做一点摘要”,而是让系统在有限预算内持续保持清晰、稳定、可恢复的重要基础能力。
它真正要解决的是:
- 当前这次推理到底该看什么
- 哪些信息应该只短暂保留
- 哪些信息值得跨轮、跨任务甚至长期保留
- 压缩之后如何既省成本,又不丢关键约束和关键证据
如果这些问题没有被机制化,系统就会很快走向两种极端:
- 要么什么都塞,成本和噪声失控
- 要么什么都压,关键事实被一起压掉
更成熟的做法,是把信息分层、把压缩对象结构化、把写入和失效策略设计清楚,并持续用评测和监控验证:
- 我们究竟保住了什么
- 又删掉了什么
这样上下文工程才会从“临时拼 prompt”进化成真正可维护的系统能力。