文章摘要
Spring AI项目做多轮对话时,开发者会遇到三类“记忆”:MessageWindowChatMemory保存近期消息,Session API通过事件流和上下文压缩管理复杂Agent会话,向量长期记忆则从大量历史事实中检索相关内容。三者解决的问题不同,不能简单互相替代。本文从Token成本、工具调用、多Agent、持久化、检索准确性和合规删除等方面,给出企业项目的分层选型方法。
一、先区分四个概念
Chat History
完整聊天记录,用于页面展示、审计、分析和导出。
短期Chat Memory
模型当前上下文所需的近期消息,用于理解“继续”“第二点”等指代。
Session状态
Agent运行过程中的结构化事件,包括工具调用、检查点、人工输入、任务状态和Agent切换。
长期记忆
跨会话保存的偏好、项目事实、历史决策和重要事件。
很多系统失败,是因为把四类数据全部塞进一个消息表。
二、MessageWindowChatMemory
它维护最近N条消息:
旧消息 → 超出窗口后淘汰 近期消息 → 进入下一次模型Prompt优点:
- 简单;
- 延迟低;
- 行为清晰;
- 容易接入ChatClient Advisor。
缺点:
- 长对话会遗忘早期信息;
- N条消息不等于稳定Token数;
- 不适合复杂工具轨迹;
- 不提供长期语义检索。
三、适用场景
适合:
- FAQ助手;
- 简单客服;
- 短时技术问答;
- 单Agent;
- 对话通常少于几十轮。
典型架构:
Chat History数据库 +MessageWindowChatMemory +MessageChatMemoryAdvisor四、窗口大小不要只按消息数
一条消息可能只有两个字,也可能是一份两万字报告。
应该做Token预算:
模型上下文:128K System与工具:20K RAG证据:30K 输出预留:8K 安全余量:10K 可用历史:60K只设置maxMessages=100可能轻易超过上下文。
五、Session API解决什么问题
Session API把会话视为事件序列,而不是简单消息数组。
事件包括:
- 用户消息;
- 模型消息;
- 工具调用;
- 工具结果;
- Agent切换;
- 摘要;
- 人工输入;
- 任务状态变化。
优势:
事件溯源 上下文压缩 工具消息完整 多Agent就绪 恢复与重放六、什么时候用Session API
适合:
- 多步骤Agent;
- 多Agent协作;
- 工具调用很多;
- 任务运行时间长;
- 需要断点恢复;
- 需要完整事件审计;
- 需要人工中断与继续。
例如售前方案Agent:
读取需求 → 检索知识 → 生成提纲 → 人工确认 → 查询产品能力 → 生成方案 → 审核 → 导出文件这不是普通窗口记忆可以完整表达的。
七、Session API的代价
- 架构更复杂;
- 事件Schema需要治理;
- 存储量更大;
- 重放需要版本兼容;
- 压缩策略需要评测;
- 多Agent权限更难。
简单FAQ不需要为了“先进”而使用Session API。
八、向量长期记忆
历史事实或偏好被转换为Embedding:
记忆文本 → 向量 → Vector Store新请求到来时:
当前问题 → 检索相关记忆 → 加入Prompt它按语义相关性取内容,而不是按时间顺序取最近消息。
九、适合什么场景
- 跨会话偏好;
- 长期项目背景;
- 大量历史事件;
- 用户画像;
- 过去决策;
- 相似案例。
不适合:
- 精确订单状态;
- 当前审批结果;
- 余额;
- 权限;
- 强一致业务数据。
这些信息必须实时查询业务系统。
十、向量长期记忆的风险
1. 错误记忆永久化
模型生成的错误总结被写入长期记忆。
2. 过时记忆
用户岗位或偏好已经变化。
3. 权限泄露
其他用户或租户的记忆被召回。
4. 删除不完整
原始消息删除后,摘要和向量仍然存在。
十一、三种方案对比
| 维度 | MessageWindow | Session API | 向量长期记忆 |
|---|---|---|---|
| 目标 | 近期对话 | Agent事件与状态 | 跨会话相关事实 |
| 读取方式 | 最近N条 | 事件重放/压缩 | 语义检索 |
| 工具调用 | 基础 | 完整 | 不适合作为轨迹 |
| 多Agent | 较弱 | 强 | 可共享 |
| Token控制 | 窗口淘汰 | 压缩 | Top K |
| 复杂度 | 低 | 高 | 中 |
| 顺序 | 精确 | 精确 | 不保证 |
| 长期保存 | 不适合 | 可持久化 | 适合 |
十二、生产系统通常是组合
普通客服
Chat History +MessageWindow复杂客服Agent
Chat History +Session API +上下文压缩个人助理
Chat History +MessageWindow +长期向量记忆多Agent项目
Session API +长期记忆 +独立业务状态十三、长期记忆写入策略
不要把每句话都写入长期记忆。
写入前判断:
是否长期有效 是否经过用户确认 是否包含敏感信息 是否已有重复 是否需要过期结构示例:
{"memoryId":"M1001","subjectId":"U1008","type":"PREFERENCE","content":"输出技术方案时优先给出Java示例","sourceConversationId":"C9001","confidence":0.95,"expiresAt":null}十四、上下文压缩要结构化
长会话可以压缩为:
目标 已确认事实 关键决策 未解决问题 工具结果 下一步示例:
{"goal":"完成客户RAG方案","confirmedFacts":["客户使用PostgreSQL","数据不能出私有云"],"decisions":["向量库选择pgvector"],"openQuestions":["并发目标尚未确认"]}原始事件用于审计,模型只加载压缩结果和近期消息。
十五、合规删除要覆盖派生数据
用户删除会话时要检查:
原始消息 窗口Memory Session事件 摘要 向量记忆 缓存 文件 评测样本建立source_message_id和source_conversation_id才能追踪派生数据。
十六、决策树
只需要最近对话? → MessageWindowChatMemory 需要工具轨迹、恢复和多Agent? → Session API 需要跨会话偏好和事实? → 向量长期记忆 需要页面展示和审计? → 独立Chat History十七、推荐起步架构
多数Spring AI企业项目可以先使用:
PostgreSQL Chat History +JdbcChatMemoryRepository +MessageWindowChatMemory出现长任务、多Agent、工具轨迹和断点恢复后,再引入Session API。
只有业务明确需要跨会话个性化时,再增加长期向量记忆。
总结
三类记忆的分工是:
MessageWindow → 最近发生了什么 Session API → Agent执行过程发生了什么 向量长期记忆 → 过去哪些事实与当前问题相关选型关键不是谁更高级,而是业务需要时间顺序、执行状态还是语义相关性。