《AI Agent原理与实战》2026版 第14课 记忆管理

本文收录于专栏 《AI Agent原理与实战》2026版 ------ 专栏系统覆盖 AI Agent 的记忆、工具、插件与实战,点击订阅可跟踪后续更新。
本课定位:上下文是"当前看见的",记忆是"跨会话留下的"。本课讲记忆三时间尺度、NUS Forms-Functions-Dynamics 分类、写入/检索/遗忘三操作,配客服偏好记忆实战。第 24 课赛博小镇居民的记忆、Hermes 的自成长都建立在第 14 课的机制上。
阶段 2|单 Agent 核心机制 | 来源:【微·13】(微软 AI Agents for Beginners 第 13 课)+ NUS 综述补充

关键字: Agent记忆、长期记忆、短期记忆、记忆三时间尺度、记忆写入、记忆检索、跨会话状态、用户偏好

本节目录

  • [14.1 记忆 ≠ 上下文:三个时间尺度](#14.1 记忆 ≠ 上下文:三个时间尺度)
  • [14.2 NUS 统一分类:Forms-Functions-Dynamics](#14.2 NUS 统一分类:Forms-Functions-Dynamics)
  • [14.3 记忆的三个操作:写入、检索、遗忘](#14.3 记忆的三个操作:写入、检索、遗忘)
  • [14.4 可靠事实 vs 历史记录 vs 模型推断](#14.4 可靠事实 vs 历史记录 vs 模型推断)
  • [14.5 专用记忆工具一览](#14.5 专用记忆工具一览)
  • [14.6 核心代码](#14.6 核心代码)
  • [14.7 实测输出](#14.7 实测输出)
  • [14.8 动手练习](#14.8 动手练习)

概念讲解

14.1 记忆 ≠ 上下文:三个时间尺度

微软原课按时间尺度把记忆分成三层(与认知科学的 working/short-term/long-term 对应):

层 生命周期 工程载体 对应
工作记忆(Working) 单个任务步内 上下文窗口内的即时信息 CPU 寄存器
短期记忆(Short-term) 单次会话内 对话历史(messages 数组) 内存
长期记忆(Long-term) 跨会话持久 数据库/向量库/文件 磁盘

关键认知:上下文窗口只是记忆的"工作区",不是存储本身 。长期记忆活在窗口外,按需检索注入------这正是第 13 课"选择"操作的数据来源。原课还列了几个细分类目(在三层之上按用途再分):情景记忆 (episodic,过去的任务经历------第 12 课 Reflexion 的反思文本就存这里)、实体记忆 (entity,人/物/事件的结构化记录)、人格记忆(persona,Agent 自身的角色设定)。分类学意义大于工程意义------工程上真正要设计的是下一节的三个操作。

14.2 NUS 统一分类:Forms-Functions-Dynamics

总纲指定的深入参考是新加坡国立大学牵头的综述《Memory in the Age of AI Agents: A Survey------Forms, Functions and Dynamics》(arXiv:2512.13564,2026-01 发布,覆盖 NUS/人大/复旦/北大等十余机构,GitHub 配套论文列表)。它对传统"长/短期"二分法的不满与重构:

  • Forms(形式)------记忆由什么承载:token 级(显式文本单元,可增删改查------数据库/向量库属于这类)、参数级(编码进模型权重,微调写入)、潜空间级(模型内部隐状态,推理期持续更新)。
  • Functions(功能)------记忆为什么存在 :事实记忆 (factual,记录与用户/环境交互中学到的事实)、经验记忆 (experiential,记录任务执行经验,让 Agent 越用越强)、工作记忆 (working,单任务工作区)。注意这个功能三分替换了"长/短期"时间分类------同样是长期存储,存"用户偏好蓝色"(事实)和存"上次这个坑怎么绕过的"(经验)是两种记忆,写入/检索/遗忘策略完全不同。
  • Dynamics(动态)------记忆如何运转:形成(什么进记忆)、检索(怎么取回)、演化(怎么更新与淘汰)。

这个框架的价值:当有人说"给 Agent 加记忆"时,先问三个问题------什么形式承载?为什么功能服务?形成-检索-演化怎么设计?本课案例就按 Dynamics 三操作展开。

14.3 记忆的三个操作:写入、检索、遗忘

写入(Formation) :从对话中抽取值得长期保留的信息。两个设计点:一是抽取判据 (什么值得记------用户明说的偏好值得,寒暄不值得);二是冲突处理(新信息与旧记忆矛盾时怎么办------用户"我现在更喜欢红色了",旧记忆"偏好蓝色"应被更新而非并存,否则检索时两条都命中,Agent 人格分裂)。

检索(Retrieval):按当前查询选相关记忆注入上下文。检索即第 13 课的"选择"操作:相关性排序 + top-k 截断 + 命中计数(命中数本身是遗忘的输入信号)。

遗忘(Forgetting):反直觉但必要的一环。三类清理策略:

  • TTL 过期:推断类记忆(模型猜的)设定有效期,到期未验证就删------防推断累积成"事实"
  • 低价值淘汰:长期零命中的记忆降权/删除(记忆库不是仓库,检索质量比库存量重要)
  • 用户删除权:合规要求(GDPR 类),用户说忘就必须忘------微软原课的设计原则里"控制(Control)"明确包含"可遗忘"

14.4 可靠事实 vs 历史记录 vs 模型推断

记忆的可信度不是均质的,检索注入时应带来源档位标注:

档位 来源 示例 使用姿态
可靠事实 用户明说 "我偏好蓝色" 可直接作为决策依据
历史记录 真实发生的事件 "上次投诉过物流" 参考背景,不代表当前状态
模型推断 从行为推测 "对价格敏感" 提示词级参考,不当确定事实用

不给档位标注的记忆系统有个隐蔽风险:三个月前的推断被后来的对话反复检索强化,最终 Agent 把猜测当成了铁的事实------这是第 13 课"毒化"失败模式在记忆层的翻版。

14.5 专用记忆工具一览

原课介绍了两个代表性框架(工程选型时了解即可,机制都是上述三操作的工业化实现):Mem0 (两阶段管线:LLM 抽取记忆 → LLM 决定增/改/删,混合向量+图+KV 存储);Cognee (把非结构化数据转成知识图谱 + 嵌入的双存储架构,擅长关系型查询)。另有微软 Agent Framework 的 AgentSession(会话级短期记忆的框架内建方案)。第 16 课框架实战时会再遇到它们。

原课还给了两条生产化优化建议 :①延迟管理 ------为避免记忆读写拖慢交互,用便宜快速的小模型先判断信息是否值得存储/检索,仅在必要时才调用复杂的抽取/检索流程(本课案例每回合都跑 LLM 抽取,是教学简化;生产加一道小模型闸门);②知识库维护------不断增长的记忆库要把低频使用的信息迁移到"冷存储"控制成本(与本课 TTL/低命中淘汰互补:淘汰是删,冷存是降级)。

案例实战:客服 Agent 的偏好记忆系统

目标

给第 7 课的客服 Agent 加上长期记忆,完整跑三个回合:老用户回访(记忆检索注入)、偏好变更(冲突更新)、时间流逝(遗忘 GC)。

环境

  • Windows(推荐) :Windows 10/11 + Python 3.9+,pip install openai==3.6.0,setx DEEPSEEK_API_KEY "sk-..." 后新开终端运行 python 14_memory_agent.py------脚本无操作系统相关依赖
  • Linux(本课实测环境):Ubuntu 22.04,Python 3.10.12,openai 3.6.0,deepseek-chat,2026-10-01 实测。记忆库用 dict 演示机制(生产替换为向量库 + 数据库)
  • JSON 输出模式(response_format)为 DeepSeek API 特性,注意事项同第 10 课;三个回合全程约 2 分钟
  • 换国内模型:接入参数与实测行为见第 7 课"国内模型适配"节;记忆抽取的 origin 档位判断质量会随模型变化,GLM/MiniMax 用户建议先跑回合 1 观察抽取是否稳定再上量

14.6 核心代码

python 复制代码
# 14_memory_agent.py(节选)
# 每条记忆:content + origin(来源档位) + ts(时间戳) + hits(命中计数)
MEMORY = {"user_42": [
    {"id": "m1", "content": "偏好蓝色商品",   "origin": "user_stated", "ts": 1.0, "hits": 3},
    {"id": "m3", "content": "对价格敏感,倾向等促销", "origin": "inferred", "ts": 2.0, "hits": 1},
    ...
]}

EXTRACT_PROMPT = """从客服对话中提取值得长期记住的用户偏好/事实。
输出 {"memories": [{"content": "...", "origin": "user_stated|event|inferred"}]}。
- user_stated:用户原话明说的偏好(最可靠)
- event:发生过的交互事件(记录性)
- inferred:从行为推断的(需后续验证)
没有值得记的就输出空数组。"""

def memory_write(user_id, conversation, now):      # 写入:抽取 + 冲突合并
    out = chat_json(EXTRACT_PROMPT, conversation)
    for item in out["memories"]:
        if 同主题旧记忆存在:                        # 冲突:新陈述覆盖旧记忆
            旧记忆.update(content=新内容, ts=now, hits=0)
        else:
            MEMORY[user_id].append(新记忆)

def memory_read(user_id, query, top_k=3):          # 检索:相关性 + top-k + 命中计数
    picked = sorted(按相关度打分(MEMORY[user_id]), reverse=True)[:top_k]
    for m in picked: m["hits"] += 1
    return picked

def memory_gc(user_id, now, ttl_inferred=5.0):     # 遗忘:TTL + 低命中淘汰
    for m in MEMORY[user_id]:
        if m["origin"] == "inferred" and 老化超过TTL and m["hits"] <= 1: 删除
        elif m["origin"] == "event" and m["hits"] == 0 and 长期未命中: 删除

def serve(user_id, user_msg, now):                 # 带记忆的客服回合
    mems = memory_read(user_id, user_msg)
    reply = chat(系统提示含来源档位说明, f"[用户记忆]\n{memory_block(mems)}", user_msg)
    memory_write(user_id, 本轮对话, now)            # 写回新记忆
    return reply

【已实测】2026-10-01,deepseek-chat。

14.7 实测输出

回合 1:老用户回访("帮我推荐个新到货的商品")

text 复制代码
注入的记忆:
  - 用户偏好蓝色商品(可靠事实)
  - 收货地址在杭州(可靠事实)
  - 对价格敏感,倾向等促销(模型推断)
回复: 您好~我们最近新到了一批商品,请问您想看哪一类呢?......之前您提到比较喜欢蓝色,
      如果有合适的品类,我可以优先帮您留意蓝色款的哦~
写入: ['更新: m1 -> 用户偏好蓝色商品']     ← 注意:这条"更新"是多余的(见下)

回合 2:偏好变更("我现在更喜欢红色了,蓝色看腻了")

text 复制代码
写入: ['更新: m1 -> 用户现在更喜欢红色,蓝色看腻了']
m1 现状: {'content': '用户现在更喜欢红色...', 'origin': 'user_stated', 'ts': 11.0, 'hits': 0}

回合 3:时间流逝 20 单位后 GC

text 复制代码
清理: ['事件遗忘: 上次投诉物流慢']
剩余记忆: [('m1','...更喜欢红色...','可靠事实'), ('m2','收货地址在杭州','可靠事实'),
          ('m3','对价格敏感...','模型推断')]

三处精读:

  1. 记忆注入直接改变回复行为:Agent 主动提出"优先留意蓝色款"------个性化不是提示词魔法,是检索到的记忆在起作用。且回复里对推断类记忆(价格敏感)的态度比对事实类(蓝色)克制,来源档位标注在起效。
  2. 回合 1 的多余写入是真实的翻车样本 :本轮对话里客服只是引用了"蓝色偏好"(记忆里的旧信息),抽取器却把它当新信息又"更新"了一遍 m1。危害有两层:时间戳被无谓刷新(影响遗忘判断),若对话里 Agent 复述过错误记忆还会自我强化。修法是写入判据里加一条"与已检索注入的记忆重复的内容不写入"------记忆系统必须区分"用户说的"和"Agent 复述的"。
  3. 回合 2 的冲突更新是记忆正确性的关键机制 :新偏好(红色)直接覆盖旧偏好(蓝色),时间戳刷新、命中清零------如果没有这一步,两条偏好并存,下次检索双双命中,Agent 就"精神分裂"了。而 GC 阶段推断类记忆 m3 因仍有命中被保留、事件类 m4(投诉物流)零命中老化被清除------遗忘策略按 origin 档位区别对待,不是一刀切。

14.8 动手练习

  1. 修掉回合 1 的多余写入:在 memory_write 里把本轮已注入的记忆列表传进去,抽取结果与之去重后再落库。
  2. 把 m3 的 origin 改成 user_stated 再跑 GC------观察"价格敏感"从可遗忘变成永久保留,体会档位标注对记忆生命周期的影响;再考虑:这条其实该让用户确认后升级档位(推断 → 事实的验证流)。

小结

  • 记忆 ≠ 上下文:窗口是工作区,存储在窗外;按时间尺度分工作/短期/长期,工程要设计的是写入、检索、遗忘三操作(Dynamics)。
  • NUS Forms-Functions-Dynamics 框架(arXiv:2512.13564):形式(token/参数/潜空间)、功能(事实/经验/工作)、动态(形成/检索/演化)------替代粗糙的"长短期"二分。
  • 记忆带来源档位:可靠事实 / 历史记录 / 模型推断------不同档位不同的使用姿态与遗忘策略;写入要区分"用户说的"和"Agent 复述的"。
  • 冲突更新防人格分裂,TTL+低命中淘汰防记忆库变垃圾场,用户删除权是合规硬要求。

至此阶段 2(单 Agent 核心机制)八课齐了:工具(07-08)、模式(09)、规划(10)、检索(11)、反思(12)、上下文(13)、记忆(14)。工具多了要框架管(第 15-17 课),任务大了要多 Agent 分工(第 21-24 课)------都建立在这八课的机制之上。另外按总纲提示,学完本课建议提前学习第 25 课《可信赖的 Agent:边界与审核》------Agent 有了工具、记忆、自主循环之后,安全边界意识越早建立越好。

扩展阅读

🌐 网络提示:github.com 需代理(clone 可走 ghproxy 加速、push 优先 SSH);学术站 arxiv.org 境内多可直连(慢),其余评测/规范站需代理;pip 安装建议加清华镜像 -i https://pypi.tuna.tsinghua.edu.cn/simple。详见总纲附录《国内网络访问与国产适配指南》。


我的专栏

蛋白 / 抗体 / 多肽 / 核酸 分子模拟 / 动力学 / 对接 药物 / 设计 / 案例 AI / Agent / 大模型
开源蛋白结构预测 分子模拟基础 小分子药物设计案例 AI Agent系列
开源蛋白生成方法实践 分子动力学模拟-Amber 蛋白药物设计案例 化学大模型
开源多肽设计模型 分子动力学模拟-Gromacs 多肽药物设计案例 《AI Agent原理与实战》
开源多肽性质预测 分子动力学模拟-OpenMM 开源小分子生成设计 CADD中的机器学习模型
DNA/RNA药物设计 結合自由能 高效计算配置 《MCP 入门实战》
siRNA药物设计模型 UCSF DOCK系列 我胡师兄说药 《AI入门实战2026》
ASO药物设计模型 rDock系列 LeDock系列 gnina系列 《经典机器学习实战》
相关推荐
救救孩子把4 天前
AI面试八股文-02_2-Prompt Engineering 面试题
人工智能·面试·llm·prompt·agent·agent记忆·agent面试题
Summer-Bright6 天前
深度 | 记忆的第二幕:当聊天记录变成生产状态
ai·agent记忆·记忆层
救救孩子把7 天前
Agent面试题-记忆治理-上下文-多Agent协作与工程落地
面试·agent·多agent·agent记忆·agent面试题·上下文治理
七夜zippoe19 天前
短期记忆 vs 长期记忆:Agent 记忆系统的分层架构设计
ai·agent·长期记忆·短期记忆·记忆系统
我是小邵1 个月前
长对话先收口:用“工作记忆 vs 长期记忆“管理 AI 上下文
人工智能·ai·llm·长期记忆·中间迷失·上下文收口
小沈同学呀2 个月前
【Agent开发第七期】记忆系统:让 Agent 跨会话也记得你
人工智能·agent·长期记忆·记忆系统
thesky1234562 个月前
智能体面试准备(五十九):智能体长期记忆架构与检索增强记忆——MemGPT、记忆巩固与多会话隔离
智能体·memgpt·向量库·长期记忆·记忆架构·检索增强记忆·多会话隔离
小沈同学呀3 个月前
【Agent开发第三期】短期记忆history,让模型“记住“上一句
人工智能·ai编程·agent开发·agent记忆