Skip to content

专题 03 状态管理、记忆与会话设计

本专题解决的是一个非常典型、也非常容易被低估的问题:为什么一个 Agent 刚开始聊天时看起来挺聪明,聊到第三轮、第五轮之后就开始跑偏、遗忘、重复,甚至把上一位用户的信息带到当前会话里。

对前端工程师来说,这个问题并不陌生。它本质上和复杂页面里的状态污染、上下文漂移、生命周期管理失控非常像。区别只是页面状态变成了模型上下文、会话摘要、用户画像和外部记忆。

1. 为什么记忆与会话设计重要

如果一个 Agent 只有单轮能力,它只能算“会回答问题”。 如果它要支撑连续任务、多轮澄清、长期助手、工作流跟进,就必须解决以下问题:

  • 这一轮回答时,哪些历史信息应该带上。
  • 哪些旧信息应该丢弃,避免污染当前任务。
  • 哪些信息应该长期保存,形成用户偏好或业务记忆。
  • 哪些信息涉及隐私或权限,不应该跨会话延续。

很多系统失败,不是模型理解能力不够,而是记忆策略失控:

  • 该记住的没记住。
  • 不该记住的反而长期保存。
  • 短期任务和长期偏好混在一起。
  • 一个用户的上下文影响到另一个用户。

2. 用前端视角理解“记忆”

前端工程师可以把记忆系统类比成三层状态:

  • 页面级临时状态:只对当前一次交互有效。
  • 会话级状态:在当前任务或当前聊天窗口持续有效。
  • 用户级持久状态:跨会话保留,例如偏好、身份、常用配置。

如果继续往下拆,Agent 场景里通常有四类“记忆”:

  • 短期上下文:当前轮次需要立刻使用的信息。
  • 会话摘要:为了降低 token 消耗,对多轮历史做压缩后的结果。
  • 长期偏好:用户习惯、常用风格、默认工作方式。
  • 业务记忆:和任务本身相关的结构化记录,例如已创建的工单、未完成的流程状态。

3. 常见记忆类型与适用边界

3.1 短期记忆

短期记忆主要服务当前任务。 例如用户刚刚补充的约束、当前审批链上下文、最近一次工具调用结果等。

它的特点是:

  • 生命周期短。
  • 对当下回答影响大。
  • 一旦任务结束,很多内容应该被丢弃或摘要化。

3.2 会话摘要

会话摘要的目标不是“保留全部细节”,而是把已经发生的交流压缩成后续仍然有用的事实。

适合被保留下来的通常是:

  • 当前任务是什么。
  • 已明确的关键约束。
  • 已经完成的步骤。
  • 尚未解决的问题。
  • 用户已确认的决策。

不适合保留的通常是:

  • 冗长寒暄。
  • 已经失效的猜测过程。
  • 对当前目标没有帮助的枝节信息。

3.3 长期偏好记忆

长期偏好是用户画像的一部分,例如:

  • 用户喜欢简洁回答还是详细说明。
  • 默认使用中文还是英文。
  • 更关注技术深度还是业务方案。
  • 常用的产品、团队或项目背景。

这类信息适合长期保存,但必须让来源可追踪、可更新、可删除。

3.4 业务状态记忆

这类记忆不只是“聊天历史”,而是任务状态本身。 例如:

  • 一个工单已经创建到哪一步。
  • 某个审批流程已经经过哪些节点。
  • 某个自动化任务是待执行、执行中还是失败待重试。

严格来说,它更接近工作流状态,而不是自然语言记忆。 但很多 Agent 项目里,这类状态会和对话系统混在一起,最终导致系统难以维护。

4. 会话边界怎么设计

这是最容易做错的一层。 你必须先定义“会话”的业务含义,而不是默认把一个聊天窗口视为一个天然会话。

4.1 按用户会话划分

适合通用助手场景。 同一用户在一段时间内的交互共享上下文。

风险在于:

  • 不同任务容易串线。
  • 历史消息会越来越长。
  • 当前问题被旧信息污染。

4.2 按任务会话划分

适合多步骤任务、工作流和办公助手场景。 例如“帮我整理这次产品评审纪要”是一个任务;“再帮我生成周报”是另一个任务。

这种方式更利于:

  • 清晰管理上下文。
  • 任务完成后归档。
  • 在任务级别做回放和审计。

4.3 按资源对象划分

适合知识库、工单、文档协作类场景。 例如:

  • 围绕同一份文档展开的交互共享上下文。
  • 围绕同一个工单编号展开的交互共享上下文。

这有利于把自然语言交互和业务对象绑定起来。

5. 记忆系统的设计原则

5.1 先分层,再存储

不要一开始就把所有历史对话丢进一个“memory”表。 应该先分清:

  • 哪些是临时消息。
  • 哪些是摘要。
  • 哪些是长期偏好。
  • 哪些是业务状态。

只有分层清楚,后续清理、更新、授权和调试才会可控。

5.2 先定义更新规则,再决定保存什么

一个成熟系统必须回答:

  • 什么触发记忆写入。
  • 谁来更新旧记忆。
  • 什么条件下删除记忆。
  • 冲突信息出现时如何合并。

如果没有更新规则,记忆会越来越脏。

5.3 记忆必须可解释

当系统表现异常时,你需要能回答:

  • 这次回答引用了哪些历史信息。
  • 哪一条摘要影响了决策。
  • 这个用户偏好是何时写入的。
  • 为什么系统认为当前任务仍在继续。

记忆如果不可解释,排查成本会非常高。

5.4 记忆必须有权限边界

尤其在企业场景里,要特别注意:

  • 同一个账号能否看到不同团队的历史。
  • 用户偏好能否被管理员覆盖。
  • 敏感信息是否会被摘要长期保存。
  • 是否支持用户删除或重置历史。

6. 一套可执行的设计方法

6.1 先画状态图

建议先画出下面几类状态:

  • 会话创建。
  • 消息进入。
  • 是否触发摘要。
  • 是否写入长期记忆。
  • 是否触发业务状态变更。
  • 会话结束或归档。

前端工程师很适合做这件事,因为你本来就熟悉状态流转图。

6.2 定义摘要时机

不要每轮都摘要,也不要永远不摘要。 建议定义触发条件,例如:

  • 超过指定轮数。
  • 总 token 超过阈值。
  • 任务从探索阶段进入执行阶段。
  • 用户已确认关键结论。

6.3 定义长期记忆写入条件

不是所有用户说的话都应该进入长期记忆。 比较适合写入的通常是:

  • 明确表达且高频重复的偏好。
  • 已确认的个人资料或项目背景。
  • 经过用户确认的工作方式。

不适合直接写入的通常是:

  • 一次性的临时要求。
  • 带有猜测性质的内容。
  • 敏感信息。

6.4 为记忆设置过期策略

建议明确:

  • 哪些内容在任务结束后即失效。
  • 哪些长期偏好需要定期确认。
  • 哪些摘要在新任务开始时不应继续沿用。
  • 哪些业务状态在流程结束后应该归档。

6.5 把自然语言记忆与结构化状态分开

例如:

  • “用户偏好简洁回答”可以是自然语言或结构化标签。
  • “工单 #103 进入待审批”则更适合结构化状态表。

不要让模型自己在长段对话里猜当前流程进度。 这类业务状态最好由系统显式维护。

7. 面向前端的实现建议

7.1 UI 层要让用户知道“系统记住了什么”

用户对 Agent 的不信任,很大一部分来自“它到底记住了哪些信息,我并不知道”。

前端可以考虑提供:

  • 当前会话摘要概览。
  • 已保存的偏好标签。
  • 会话重置按钮。
  • 删除历史或清空记忆入口。

7.2 区分“聊天历史”与“有效记忆”

聊天记录不等于有效记忆。 有些内容只是展示日志,不应该参与后续推理。

建议在设计上区分:

  • 供用户回看的消息流。
  • 供系统继续使用的摘要与状态。

7.3 任务型产品建议做“任务面板”

如果 Agent 目标是完成任务,而不只是闲聊,建议增加任务面板展示:

  • 当前任务名称。
  • 已确认约束。
  • 已完成步骤。
  • 待办动作。
  • 失败与阻塞原因。

这会比单纯依赖聊天记录更可靠。

8. 常见失败模式

8.1 全量透传历史消息

现象:对话越久越乱、越慢、越偏。 原因:历史对当前目标贡献不大,但持续占用上下文预算。

8.2 摘要过早或过度压缩

现象:模型忘记关键约束。 原因:还没稳定下来的信息被过早摘要,或者摘要粒度太粗。

8.3 长期记忆污染短期任务

现象:用户这次临时说“输出详细一点”,系统后面每次都变得很啰嗦。 原因:把一次性要求错误写入了长期偏好。

8.4 业务状态只靠自然语言维持

现象:Agent 对当前流程走到哪一步说不清楚。 原因:把结构化工作流状态交给自然语言上下文去记。

8.5 缺少记忆重置机制

现象:用户想开始一个全新话题,但系统仍受旧对话影响。 原因:没有显式的新会话入口或任务切换逻辑。

9. 验证方式

可以用以下指标或检查项验证设计是否站住:

  • 长会话场景下,回答质量不会明显随轮次下降。
  • 相同任务跨 5 到 10 轮后,关键约束仍能被正确遵守。
  • 新任务开始后,旧任务信息不会污染当前输出。
  • 用户偏好更新后,系统能稳定生效且可撤销。
  • 任务状态在 UI、日志和服务层三处保持一致。

10. 可复用模板

10.1 会话状态清单模板

text
会话 ID:
会话类型:通用聊天 / 任务执行 / 文档协作 / 工单处理
当前任务:
关键约束:
最近已完成动作:
待确认事项:
是否需要写入长期记忆:是 / 否
是否需要生成会话摘要:是 / 否

10.2 长期记忆写入判断模板

text
候选记忆:
来源:用户明确表达 / 系统推断 / 人工录入
类型:偏好 / 背景 / 业务状态
是否跨会话有效:是 / 否
是否涉及敏感信息:是 / 否
是否允许用户删除:是 / 否
写入结论:保留 / 不保留 / 待确认

11. 面试表达

你可以这样讲:

“我在做 Agent 时,没有把记忆理解成简单的聊天历史,而是拆成了短期上下文、会话摘要、长期偏好和业务状态四层。这样做的好处是每类信息的生命周期、更新策略和权限边界都更清晰。前端侧我还增加了会话重置、摘要展示和任务面板,避免系统越聊越乱,也让用户知道系统到底记住了什么。”