在 Agent 中加入 ChatMemory 只是第一步。真正做长对话和长任务以后,很快会遇到更多问题:聊天太长导致 Token 爆炸,旧消息污染当前任务;服务重启后会话丢失;用户修改前面的消息后,新旧分支互相污染;一个任务执行半小时,中途失败后不知道从哪里继续;长期记忆越来越多,却不知道当前应该取哪几条;Context 明明塞了很多信息,模型还是遗漏最关键的一段。
这一阶段真正需要掌握的,就是围绕这些问题形成的一组 Memory、State 和 Context Engineering 技术。

一、先建立这一阶段的"技术树"
这一阶段可以先记住下面这张图:
bash
Agent
│
├── Conversation Memory
│ ├── Conversation ID / Thread
│ ├── Sliding Window
│ ├── Summary Memory
│ ├── Persistent Memory
│ └── Long-term Memory
│
├── Task State
│ ├── State Store
│ ├── Checkpoint
│ ├── Resume
│ ├── Branch
│ └── State Machine
│
└── Context Engineering
├── Context Window
├── Token Budget
├── Context Assembly
├── Context Compression
├── Memory Retrieval
├── Lost in the Middle
└── Context Pollution
这些术语没有必要一次研究很深。关键是知道它们分别在解决什么问题。
二、Conversation ID、Session、Thread:先把不同对话隔离开
第一个实际问题通常是:
两个用户同时聊天,Memory 怎么知道哪条消息属于谁?
因此会出现:
bash
Conversation ID
Session ID
Thread ID
三个词在不同框架里的命名并不完全一致,核心思想都是:给一段连续会话一个唯一标识。
Spring AI 中最直接的是:
bash
.advisors(a -> a.param(
ChatMemory.CONVERSATION_ID,
conversationId
))
于是:
bash
user-A-session-01
→ A用户当前聊天记录
user-B-session-03
→ B用户当前聊天记录
典型 Badcase 是"串会话":A 用户的信息突然进入 B 用户 Context。生产系统中 Conversation ID 还必须和真实用户身份、Tenant、权限体系绑定,不能只依赖前端随便传一个字符串**【必须将ID嵌入至关键的身份验证、权限、信息等内容绑定】**。
三、Sliding Window:聊天越来越长怎么办
用户聊了 300 轮,不可能每一次都把 300 轮重新发给模型。
于是有了:
Sliding Window,滑动窗口。
例如:
bash
历史 300 条消息
↓
只保留最近 20 条
↓
进入当前 Context
Spring AI 的:
bash
MessageWindowChatMemory
就是这一思路。
它解决:
bash
Token越来越多
成本越来越高
旧内容干扰新问题
但它又会产生新的 Badcase:
用户 50 轮以前说过一个重要条件,现在被窗口删除了。
因此 Sliding Window 后面自然会引出 Summary Memory 和 Long-term Memory。
四、Summary Memory 与 Context Compression:不能保留全文,就压缩
长对话中通常没有必要保留所有原始句子。【尤其是Sliding Window,更需要压缩技术】
例如 50 轮对话可以压缩成:
bash
用户正在申请深圳企业补贴。
企业成立于2021年。
已确认满足注册年限要求。
当前正在核验营收条件。
这种思路常见术语包括:
bash
Summary Memory
Context Summarization
Context Compression
Compaction
它们的共同目标是:
用更少的 Token 保留对后续任务仍然重要的信息。【删除旧消息后,又怕重要消息丢失。涉及到重要消息(非关键业务数据时),需要想到Summary Memory等压缩技术】
例如:
bash
原始历史 20,000 tokens
↓
Summary / Compression
↓
1,500 tokens
需要注意压缩可能造成信息损失,所以不能把订单金额、身份证号、审批状态等重要业务数据只存在自然语言摘要里。这些内容应该进入明确的 Task State 或数据库。
五、Working Memory、Long-term Memory:长期信息怎么保存
Agent Memory 中还经常出现两个词:
bash
Working Memory
Long-term Memory
Working Memory 可以理解为当前任务正在使用的信息,例如最近对话、当前计划、刚刚执行的 Tool Result。
Long-term Memory 则指跨较长时间甚至跨会话仍然值得保留的信息。例如:
bash
用户长期偏好
历史任务经验
项目长期事实
曾经确认的重要规则
Long-term Memory 很少采用:
bash
全部长期记录
→ 全部塞进 Prompt
更合理的是:
bash
长期记忆库
↓
根据当前问题检索相关 Memory
↓
只取少量相关内容
↓
加入 Context
于是又会出现一个术语:
Memory Retrieval。
它和 RAG 非常相似,只不过 RAG 检索的是外部知识,Memory Retrieval 检索的是过去保存的用户或任务记忆。
六、Episodic Memory 与 Semantic Memory:长期记忆还会继续分类
进一步看 Agent 论文或框架时,经常出现:
Episodic Memory:事件记忆。
例如:
bash
2026-09-10
用户曾经完成一次深圳政策申报,
最终使用材料A、B、C。
它保存的是"过去发生过什么",电视剧的剧情 。【你做了什么】
Semantic Memory:语义记忆。
例如:
bash
用户所在企业属于科技服务行业。
用户偏好中文输出。
它保存的是相对稳定的事实和知识,用户/场景画像 。【我能通过"你做了什么"来保存重要信息】
还有:
Procedural Memory ,程序性记忆,强调"某类任务应该怎样完成",和现在常见的 Skill 思想比较接近。【你要怎么做】
初学阶段知道三者区别即可,不需要马上实现三套数据库。
七、Persistent Memory 与 TTL:重启以后还要不要记得
默认内存 Memory 会遇到:
bash
Spring Boot 重启
↓
Memory 消失
因此生产系统需要:
Persistent Memory / Memory Persistence
即把 Memory 保存到:
bash
Redis
MySQL
MongoDB
PostgreSQL
...
Spring AI 对应的重要接口就是:
bash
ChatMemoryRepository
此外经常还会看到:
TTL(Time To Live):临时会话/任务,刷新后就没有任何问答或记忆记录,大幅减少Token成本
例如:
bash
普通临时会话:
7天后自动删除
长期项目会话:
180天
敏感临时任务:
1小时
TTL 解决 Memory 无限增长以及隐私、存储成本等问题。
八、State Store:任务执行状态不能只靠聊天记录
如果 Agent 正在执行:
bash
读取文件
→ 分析
→ 搜索
→ 生成报告
→ 导出Word
执行到"搜索"以后程序崩溃,仅保存聊天记录很难准确知道:
bash
哪些步骤完成了?
哪些没完成?
生成过哪些文件?
哪些工具已经执行?
这就需要:
State Store。
例如:
bash
{
"taskId": "agent-001",
"currentStep": "SEARCH",
"completedSteps": ["READ", "ANALYZE"],
"artifactId": null,
"status": "RUNNING"
}
State Store 通常放在 Redis、数据库或工作流引擎里。
这里最重要的认知是:
bash
Memory
→ 保存模型需要理解的过去
State Store
→ 保存程序必须准确知道的当前状态
九、Checkpoint 与 Resume:长任务失败后从哪里继续
只要 Agent 开始执行几十秒甚至几十分钟的任务,两个术语会迅速出现:
bash
Checkpoint
Resume
Checkpoint 表示在关键节点保存任务快照。
例如:
bash
Step 1 完成
↓
Checkpoint 1
Step 2 完成
↓
Checkpoint 2
Step 3 失败
系统恢复以后:
bash
读取 Checkpoint 2
↓
从 Step 3 继续
而不是重新执行:
bash
Step 1 → Step 2 → Step 3
这对于收费 API、生成文件、数据库修改等操作非常重要。
后面学习真正的 Agent Workflow、LangGraph 或工作流引擎时,会频繁看到 Checkpoint。
十、Branch / Fork:用户修改旧问题怎么办
聊天产品还有一个很实际的问题。
原对话:
bash
Q1
↓
A1
↓
Q2
↓
A2
用户突然修改 Q1:
bash
Q1'
那么新的合理结构应该是:
bash
Q1
/ \
A1 Q1'
↓ ↓
Q2 New A1
这类概念通常称为:
bash
Branch
Fork
Conversation Tree
它解决的是多分支会话状态隔离。
如果仍然把旧分支 A1、Q2 放进新分支 Context,就会形成典型的:
Context Pollution,上下文污染。
十一、Context Window 与 Token Budget:模型能看到多少东西
LLM 都有 Context Window。
它表示一次调用能够接受的上下文总量,包括:
bash
System Prompt
Chat History
RAG Documents
Tool Result
Task State
User Query
Output空间
所以 Agent 工程里会出现:
Token Budget。
例如整个窗口允许:
bash
128K tokens
应用可能人为分配:
bash
System Prompt 5K
Memory 15K
RAG 20K
Tool Result 8K
当前任务 5K
预留模型输出 8K
这并不是固定公式,而是一种资源管理思想。
因此 Context Management 的真正问题不是:
"还能不能继续塞?"
而是:
"有限 Context 中哪些信息最值得保留?"
十二、Lost in the Middle:放进 Context 也不代表模型一定用得到
还有一个很重要的术语:
Lost in the Middle。
研究发现,长 Context 中的信息如果被埋在中间位置,模型有时更容易忽略它。
例如:
bash
重要规则
↓
50页无关资料
↓
另一条重要规则
即使 Context Window 没有超限,模型也可能遗漏第一条规则。
因此 Context Engineering 会进行:
bash
Rerank
重要内容前置
去除重复
Context Compression
分阶段调用
这和前面 RAG 学到的 Rerank 实际上开始联系起来。
十三、Context Pollution 与 Stale Context:旧信息可能比没有信息更危险
Agent 还有两种很典型的问题。
Context Pollution:无关信息污染当前推理。
例如之前讨论过广东政策,现在切换到海南政策,广东资料仍然大量存在 Context 中。
Stale Context:过期上下文。
例如 Memory 中记录:
bash
2025年政策:
补贴最高100万
而 RAG 已经找到:
bash
2026年最新政策:
最高80万
如果系统没有处理版本和时间优先级,模型可能使用旧 Memory。
因此工程中常见:
bash
Freshness
Version
Timestamp
Source Priority
Memory Invalidation
Memory Invalidation 指某些事实已经失效时,需要删除或标记旧 Memory。
十四、用 Badcase 快速选择技术
这一阶段真正需要记住的是下面这张表:
| 出现的问题 | 首先想到的技术 |
|---|---|
| 用户说"第二条",模型不知道指什么 | Conversation Memory |
| 不同用户聊天串了 | Conversation ID / Isolation |
| 聊天太长、Token太多 | Sliding Window |
| 删除旧消息以后又忘记重要信息 | Summary Memory |
| 跨会话还需要记住用户事实 | Long-term Memory |
| 长期 Memory 太多 | Memory Retrieval |
| 重启以后聊天消失 | Persistent Memory |
| 临时 Memory 永远不删除 | TTL |
| 不知道任务执行到哪一步 | State Store |
| 长任务失败需要继续 | Checkpoint / Resume |
| 修改旧消息后上下文混乱 | Branch / Fork |
| Context 太长 | Token Budget / Compression |
| 信息明明存在但模型没使用 | Lost in the Middle |
| 旧任务信息影响新任务 | Context Pollution |
| 过去信息已经失效 | Stale Context / Invalidation |
到这里,这一阶段就基本够用了。
面试如果被问"Agent 的 Memory 怎么设计",回答也不应只停留在 MessageChatMemoryAdvisor。更完整的回答可以是:
我会先区分会话 Memory 和 Task State。短期聊天可以通过 Conversation ID 和 Sliding Window 管理,长会话需要 Summary 或 Context Compression;跨会话的重要事实进入 Long-term Memory,并按当前问题做 Memory Retrieval。长任务的确定状态单独放 State Store,通过 Checkpoint 支持恢复。同时需要控制 Token Budget、Context Pollution、Stale Context 和多用户隔离,避免把所有历史消息简单塞进 Prompt。
**【不同场景的技术工程能力-恢复能力-实际成本控制与多租户问题】**这已经是一个比较完整、同时仍属于中等难度的 Agent 工程回答。
下一阶段进入 Tool Calling 与 Action 时,也应该继续采用完全相同的学习方式:不再反复解释"Tool 是什么",而是直接学习这一阶段的技术树------Tool Schema、Tool Registry、Tool Selection、Dynamic Tool Discovery、Structured Parameters、Validation、Retry、Timeout、Fallback、Idempotency、Human-in-the-loop、Termination Condition、Tool Error Handling、Parallel Tool Calls、Native Tool / MCP Tool 等常见术语,以及分别在什么 Badcase 下使用。这样推进速度会快很多。