AI Agent 记忆管理实战:上下文窗口、RAG 与会话持久化怎么做才稳定

HTMLPAGE 团队
26 分钟阅读

记忆不是“把历史都塞进 prompt”。本文用工程视角拆解 AI Agent 的三层记忆(短期/长期/外部),给出上下文窗口管理策略、摘要与结构化状态的落地方式、RAG 作为外部记忆的注入协议,以及多用户会话持久化与评估指标,帮你把多轮对话做得稳定可迭代。

#AI Agent #记忆机制 #上下文管理 #RAG #工程化

很多人做 Agent 的“记忆”,最后都会变成两种极端:

  • 极端 A:把所有聊天记录都拼到 prompt 里,直到窗口爆掉、成本爆掉、输出开始胡。
  • 极端 B:只保留最近几轮,模型经常忘记目标、反复问同样的问题。

这两种做法的共同问题是:你把记忆当成了文本拼接,而不是系统设计

这篇文章给你一个可落地的答案:把 Agent 的记忆拆成三层,并且为每一层定义清晰的职责、存储形态、注入规则和评估指标。

延伸阅读(相关基础):


零、先看一个真实会翻车的失败案例:摘要压缩后把关键约束弄丢了

很多团队会在上下文快满时做一件看起来很合理的事:

“把历史对话总结成一段摘要,再继续往下聊。”

问题是,如果你只压缩自然语言,不保留结构化约束,系统会在几轮之后出现一种非常隐蔽但很致命的错误。

0.1 失败现象

一个采购支持 Agent 在前几轮已经明确拿到用户约束:

  • 预算上限 20 万
  • 只能推荐华东可交付方案
  • 不能使用海外云服务

对话进入第 9 轮后,系统触发摘要压缩,把最近 8 轮合成一段“用户希望尽快获得稳定方案,重点关注交付效率与长期可维护性”的文字描述。

结果到了第 10 轮,模型开始推荐预算 35 万的方案,还引用了需要海外区域部署的产品。

0.2 根因定位

这个问题通常不是“模型太笨”,而是记忆管线设计错了:

  • 摘要层:把硬约束压成了模糊偏好
  • 状态层:没有独立保存 budget_capregion_scopecompliance_constraints
  • 注入层:Prompt 里只有 narrative summary,没有 machine-checkable state
  • 校验层:输出前没有做约束对照校验

0.3 修复策略

正确修复不是“把摘要写得更长”,而是把工作记忆拆成两层:

  1. 摘要层:只保留语境与任务进展
  2. 状态层:把关键约束固化为结构化字段

例如:

{
  "goal": "筛选可交付的企业采购方案",
  "constraints": {
    "budget_cap": 200000,
    "region_scope": ["cn-east"],
    "forbidden_options": ["overseas_cloud"]
  },
  "stage": "vendor_comparison",
  "open_questions": ["交付周期是否可放宽到 45 天"]
}

0.4 回归测试怎么做

把这个案例写进你的评估集,至少做三类断言:

  1. 摘要压缩前后,关键约束字段保持一致
  2. 推荐结果不突破预算上限
  3. 输出 validator 能拦截违反地域/合规限制的候选项

0.5 一组可对外讲清楚的指标

你不需要一上来就有完美数据,但至少要能追踪以下口径:

指标修复前常见问题修复后目标
constraint_violation_rate摘要后约束丢失,出现越界推荐< 2%
avg_context_tokens原文全塞导致成本持续上涨稳定在预算内
long_context_success_rate对话轮次一长成功率明显下降在长对话中保持可接受波动

这类“记忆丢字段”的失败案例,比泛泛谈 RAG 更能说明你理解了系统为什么会失控。


一、先统一术语:Agent 里“记忆”到底是什么?

在工程视角里,记忆不等于聊天记录。你至少要区分三类:

  1. 短期记忆(Short-term / Context):最近几轮对话原文 + 当前任务输入。
  2. 长期记忆(Long-term / Profile & Facts):用户偏好、身份信息、长期目标、可复用事实。
  3. 外部记忆(External / Evidence):来自知识库/文档/数据库/工具的证据片段(RAG/工具结果)。

你要做的不是“更聪明地拼接”,而是回答四个工程问题:

  • 放什么? 什么信息值得进入上下文,什么必须留在外部。
  • 何时放? 什么时候注入摘要、什么时候检索、什么时候拒答/追问。
  • 怎么放? 注入协议(结构、顺序、来源标签、引用约束)。
  • 怎么证明有效? 用指标与回放验证“记住了该记的、忘掉了该忘的”。

二、一个可复用的“记忆管线”(Memory Pipeline)

推荐你把每次用户输入都走同一条管线,而不是“想到什么塞什么”。

2.1 输入到输出的最小闭环

每次请求的流程可以抽象成:

  1. Build State:从会话存储加载结构化状态(目标、约束、已完成步骤)。
  2. Summarize:必要时对历史对话做摘要/压缩(生成新的工作记忆)。
  3. Retrieve Evidence:根据当前问题检索外部证据(RAG / DB / 工具)。
  4. Assemble Prompt:按协议把短期 + 工作记忆 + 证据拼装成上下文。
  5. Generate:模型生成。
  6. Validate:校验是否满足结构/引用/边界;不满足则触发修复回路。
  7. Persist:把本轮关键信息写回会话存储(状态/摘要/索引)。

如果你已经在做 Agent 项目含金量升级,可以把这段作为“工程闭环”的核心叙事:

2.2 为什么一定要有“结构化状态”(State),而不是只有文本摘要?

文本摘要很容易出现两类不可见错误:

  • 丢字段:忘了用户的限制条件、截止日期、预算、地域等。
  • 歪语义:把“不要 A”总结成“更倾向 A”。

更稳妥的做法是把“工作记忆”拆为两部分:

  • 摘要(narrative summary):让模型保持语境(可读的短段落)。
  • 结构化状态(state JSON):让系统保持约束(可校验的字段)。

你甚至可以要求模型输出/更新状态时必须符合 schema:

2.3 一张文字版流程图:把记忆链路固定下来

如果你要把记忆系统讲给团队成员、面试官,或者写进技术设计文档,下面这张文字版流程图足够实用:

USER_INPUT
  -> LOAD_SESSION_STATE
  -> CHECK_TOKEN_BUDGET
    -> IF overflow: SUMMARIZE_HISTORY
  -> RETRIEVE_EVIDENCE
  -> ASSEMBLE_CONTEXT
  -> GENERATE
  -> VALIDATE_CONSTRAINTS
    -> IF failed: REPAIR_OR_ASK
  -> PERSIST
    -> WRITE_SUMMARY
    -> WRITE_STRUCTURED_STATE
    -> WRITE_RETRIEVAL_TRACE

这个流程的价值在于:每一个节点都能打点、回放、做 A/B 对比,而不是把“记忆好不好”全交给主观感觉判断。


三、上下文窗口管理:不要问“放多少轮”,要问“放哪些信息”

窗口管理的目标是:在固定 token 预算下最大化任务成功率

3.1 推荐的上下文预算分配(可直接用)

以一个“面向生产”的默认配比作为起点(你可以按业务调整):

  • 30%:短期原文(最近 3~8 轮)
  • 20%:摘要 + 结构化状态(工作记忆)
  • 40%:外部证据(RAG/工具结果)
  • 10%:系统协议(角色、输出结构、工具策略、失败策略)

3.2 截断不是策略,策略是“分层与触发条件”

把“何时摘要、何时检索、何时清理”做成显式条件:

  • 触发摘要:上下文超过阈值(如 70% token 预算)或任务阶段推进(从收集信息→执行)。
  • 触发检索:用户问题涉及事实/文档/历史决策,且状态里不存在可靠答案。
  • 触发追问:状态缺关键字段(如缺少时间范围/地区/产品版本),或证据不足。

你会发现这和 Prompt 的“失败回路/协议”强相关:


四、长期记忆:你必须回答“写入标准”与“删除标准”

长期记忆最容易翻车的点不是“不会存”,而是:什么该写?写错了怎么办?

4.1 长期记忆的写入标准(Write Policy)

建议把长期记忆限定为:

  • 稳定偏好:比如语言风格、格式偏好、常用单位、时区。
  • 身份事实:但要最小化(不要存敏感信息,或至少做脱敏/加密)。
  • 长期目标:例如“准备 AI Agent 面试,目标公司 X,周期 8 周”。

不建议写入:

  • 一次性信息(本轮临时需求)
  • 模型推测(“用户可能喜欢…”)
  • 未经确认的事实

4.2 删除与纠错:长期记忆需要“可回收”

你至少要有:

  • 过期策略:TTL(比如 30/90 天)
  • 覆盖策略:同字段新值覆盖旧值,但保留审计轨迹
  • 用户可控:提供“查看/删除/禁用记忆”入口(即使是后台开关)

这会显著提升你的项目“可信度”叙事:记忆不是玄学,而是可治理。

4.3 写入/读取时机表:什么时候该写,什么时候不能乱写

长期记忆系统一旦没有“触发条件”,很容易变成垃圾仓库。下面这个表可以直接作为默认策略起点:

触发条件写入内容存储位置TTL 建议备注
用户明确表达长期偏好语言、格式、输出偏好profile store90 天必须允许用户关闭
用户确认长期目标学习路线、项目目标、周期goal state30~90 天目标变化时需覆盖旧值
本轮临时任务约束预算、地区、截止时间session state当前会话或短 TTL不要升级成长期记忆
工具返回权威事实工单号、订单号、版本号evidence cache / state按业务周期需要来源与时间戳
模型推测用户意图不写入推测不应进入长期存储

读取时也建议分层:

  • 先读 session state,确认本轮约束与阶段
  • 再读 profile / long-term goal,补稳定偏好
  • 最后按当前问题检索 external evidence

顺序反了,系统就容易被旧偏好、陈旧事实或无关证据干扰。


五、外部记忆(RAG/工具结果):关键在“证据注入协议”

RAG 的常见失败不是检索不到,而是:检索到了也没被模型正确使用

5.1 给证据打上来源与置信度

把证据注入做成统一结构(示例):

  • source_id: 文档/URL/记录主键
  • snippet: 证据片段
  • timestamp: 证据产生时间
  • confidence: 检索置信度或排序分
  • scope: 适用范围/版本/地域

然后在系统协议里写成硬约束:

  • 没证据就拒答或追问
  • 有证据必须引用 source_id
  • 证据冲突要列出冲突并请求用户决策

这类约束通常需要 schema + validator 才真正可靠。

5.2 “RAG + 引用证据 + 拒答”是一整套,不要拆开

你可以把输出结构定义成:

  • answer: 给用户的答案
  • citations: 引用的 source_id 列表
  • open_questions: 当前缺失的关键字段
  • actions_taken: 调用了哪些工具/检索

这样你才能在回放时判定错误来自:检索、注入、还是生成。


六、会话持久化:多用户隔离与幂等是底线

如果你的 Agent 面向多人使用,你至少要保证:

  • 会话隔离user_id + conversation_id 作为分区键
  • 写入幂等:同一条消息重复提交不会污染状态(用 request_id 去重)
  • 并发一致性:同一会话的并发请求要么排队,要么用乐观锁合并状态

很多“记忆很乱”的问题,本质上不是 LLM,而是会话存储的并发写入。


七、怎么评估“记忆做得好”?给你一套最小指标

不要只看主观体验。一个能持续迭代的记忆系统,至少要有“可采集口径 + 评估集规模 + 目标区间”。下面这套指标足够作为第一版仪表盘:

指标说明如何采集建议评估集目标区间
repeat_question_rate模型是否重复追问已知信息对多轮会话做规则比对,标记重复询问字段20~50 条长对话越低越好
constraint_violation_rate是否违反已知约束输出后跑 constraint validator20~50 条带约束任务< 2%
long_context_success_rate对话轮次变长后是否仍完成任务按 8 轮、12 轮、16 轮分组评估至少 20 条长上下文样本不随轮次明显塌陷
citation_rate需要证据的问题是否给出引用检查输出结构里的 citations/source_id20 条证据密集问题应保持稳定
avg_context_tokens每轮平均上下文成本在 assemble 阶段统一记录 token全量线上样本抽样在预算阈值内

如果你要进一步提高说服力,可以把这些指标按版本做 before/after 对比,而不是只报一个绝对值。

每周做一次回放时,建议把失败样本分类到:

  • 摘要丢字段
  • 状态字段更新错误
  • 检索噪声(召回差/重排差)
  • 注入协议不清晰
  • 输出校验缺失

这就是可迭代的工程闭环。


八、落地清单:把“记忆”从 Demo 升级到可上线

你可以按这个顺序做(每步都能独立交付):

  1. 把“工作记忆”做成 摘要 + 结构化状态
  2. 做窗口预算与触发条件(摘要/检索/追问)
  3. 把外部证据做成统一结构 + 引用约束
  4. 增加 validator:无证据拒答、字段缺失追问
  5. 加入会话隔离/幂等/并发一致性
  6. 建立最小指标与回放机制

如果你希望团队能直接执行,可以把它再细化成发布前检查清单:

  • 是否已经定义 session state schema
  • 是否明确哪些字段允许进长期记忆
  • 是否有摘要触发阈值与回滚策略
  • 是否对证据注入打了 source_id
  • 是否有至少 20 条长对话评估样本
  • 是否能对“约束违反”做自动拦截

记忆系统最终不是“记住更多”,而是在有限预算内稳定保留任务真正需要的信息

下一篇如果你要继续把系统做“能抗压”,就该进入并发与可靠性:

而如果你的系统已经开始接入多用户资料、业务字段和长期偏好,下一步要看的就是权限与最小暴露: