Agent 长对话 Memory 怎么设计?四层机制解决摘要丢信息
长对话的 Agent Memory 不是「压缩就行」,是分层管理。
- 问题核心:summary 平等压缩所有内容,用户核心目标和硬性偏好被一起稀释。
- Working Memory:类似 system prompt 的常驻字段,永久不参与压缩,守住硬性约束。
- 分段增量摘要:滚动窗口分段保存,每段打时间戳 + 优先级标签,不合并。
- 向量数据库兜底:摘要丢细节没关系,原文存向量库按需召回。
- 多 Agent 方案:Coordinator + Observer + Reflect + Retriever 四角色分工。
- 场景选型:几十轮轻量对话 / 中长期 / 超长期多工具三档,对号入座。
摘要为什么会丢信息?
根因是「一锅煮」——所有内容被平等压缩,没有分层。
多轮对话 summary 丢信息是工程界公认的痛点,但 4 个具体原因往往被混在一起讨论:
- 平等对待所有内容:核心需求和闲聊被同等压缩,硬性约束被噪声淹没。
- 时序丢失:早期「不要用 Vue」和后期闲聊「今天天气不错」,几轮后根本分不清哪条是约束。
- 静态偏好和临时会话混在一起压缩:用户身份、长期目标这些不该压缩的东西,被一起扔进 summary。
- 粗颗粒度丢失细节:否定类需求("不要出错"、"输出简洁")、工具参数级别的约束,summary 根本装不下。
说白了,这不是 summary 模型的锅,是 system prompt 没设计好——没告诉模型「哪些是底线、哪些可以压缩」。
四层机制组合拳
第一层:Working Memory 兜住底线
Working Memory 是一组常驻字段,类似 system prompt,每轮对话都注入 context,永远不参与 summary 压缩。
具体存什么:
- 用户核心目标(硬性)
- 硬性偏好(语言、风格、工具栈)
- 禁止项(明确禁止的行为)
- 身份信息、业务约束
关键设计:字段化更新,不是字符串叠加。用户改了一个偏好,直接替换对应字段,不要往 working memory 末尾追加新内容。叠加会导致前后信息不一致,模型产生「幻觉」——其实不是模型幻觉,是你自己存的内容前后矛盾。
优势:低成本,守住最高优先级硬性要求。
局限:只能存预设字段,无法覆盖零散的历史对话细节——这些交给后面三层。
第二层:分段增量摘要保留时序
不要一次性把全部对话压成一段 summary 。
设置阈值(经验值 2K token),超过就滚动压缩:
- 第 1~10 轮 → summary_1
- 第 11~20 轮 → summary_2
- 每段独立保存,不合并
- 每段打标签:时间戳 + 优先级标志 + 约束条件
用户目标、硬性约束标高权重,闲聊标低权重。检索时优先加载高优先级分段,低权重内容按需取舍。
对比一次性总摘要的优势:分段保留时序逻辑,不会抹平早期的关键信息。
实操时,优先级打标完全可以在 system prompt 里写好——让模型在生成 summary 时顺手标,不是额外工程。
第三层:向量数据库存原文兜底
摘要丢细节没关系,向量数据库存的是完整原文,按需召回。
具体做法:
- 每次对话完结,request + response 全文存入向量数据库,不只存 summary
- 喂给 LLM 的 context 里,塞的是精简 summary
- 当模型发现 summary 信息不足、回答不上来时,触发向量检索,召回原始上下文
核心设计哲学:summary 是给 LLM 看的「压缩视图」,向量数据库是「原文档案库」。两者不冲突,是不同抽象层级的互补。
第四层:多 Agent 分工
超长期对话 + 高频工具调用 + 海量返回结果,单 agent 撑不住,需要 共享 memory bus + 多 Agent 分工:
- Coordinator(主对话 agent):只拿近期上下文 + memory store 注入的高优信息,负责回复用户。
- Observer agent:订阅对话流和工具流,抽取结构化事实,写入 memory store。
- Reflect agent:对 memory store 做优先级评估、冲突消解、过时标记。
- Retriever agent:负责向量数据库的语义召回,补全细节。
通过事件队列解耦,各 agent 异步处理,主对话 agent 只看「已经处理好的」有效记忆。
三种场景怎么落地?
按对话长度和工具复杂度,分三档。
场景一:轻量对话(几十轮 + 少量工具)
单 agent,无需向量数据库。
context 拼装:
system prompt
+ 最近的 N 轮对话(滑动窗口截断)
+ working memory 固定字段
典型场景:客服电话问答,客户问完就走,没必要保存偏好到向量库。
场景二:中长期对话
加一层向量数据库召回。
context 拼装:
system prompt
+ working memory(高频固定信息,markdown 格式)
+ chat history(最近对话历史)
+ 向量数据库 top K 召回(query embedding 检索)
对话完结后,把完整原文存到向量数据库,下次召回用。