后端第十四课:Agent 记忆系统(让 Agent 记住上下文和用户,跨会话不健忘)

👋 我是 Yulia,一线 AI 应用开发工程师:4 年工程经验,在职做大模型应用落地。

只写一件事------把最新 AI 技术讲成人话 + 给你能直接上手用的代码 (真实可验证,不搬运不注水)。

有用就点个 关注,持续更新大模型应用的前沿实战。
📚 本文是《后端开发从入门到靠谱》系列第 14 篇。第十二课我们做出了会调工具的 Agent,但它有个致命短板------每次对话都像第一次见你,记不住你上一句说过什么,更记不住你是谁。这一课给它装上"记忆",让它真正像个靠谱的助理。

你用 AI 助手问了个问题,聊了半天;第二天再打开,它完全不记得你昨天说过什么------又要从头自我介绍一遍 。这就是没有记忆的 Agent:一个失忆的助理。

记忆系统(Memory) 就是让 Agent 摆脱"失忆",能记住对话上下文、记住用户偏好,跨会话持续提供个性化服务。这是 Agent 从"玩具"到"能用"的关键一跃。

读完你会拿到:

  • 一个直觉模型:为什么大模型天生"失忆"(无状态)
  • 记忆的两个层次:短期记忆(本次会话)vs 长期记忆(跨会话)
  • 短期记忆的实现:上下文管理三招(滑动窗口 / 摘要压缩 / 分层)
  • 长期记忆的三类:事实记忆 / 语义记忆 / 情景记忆
  • 长期记忆的写入 与检索(什么时候存、什么时候取,Agent 记忆的灵魂)
  • 一个完整记忆系统的代码骨架
  • 常见坑:记忆爆炸、错误记忆、隐私与遗忘权

先看全景图,Agent 记忆系统长这样:
#mermaid-svg-wXk03on3RDpAblQg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wXk03on3RDpAblQg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wXk03on3RDpAblQg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wXk03on3RDpAblQg .error-icon{fill:#552222;}#mermaid-svg-wXk03on3RDpAblQg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wXk03on3RDpAblQg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wXk03on3RDpAblQg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wXk03on3RDpAblQg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wXk03on3RDpAblQg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wXk03on3RDpAblQg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wXk03on3RDpAblQg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wXk03on3RDpAblQg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wXk03on3RDpAblQg .marker.cross{stroke:#333333;}#mermaid-svg-wXk03on3RDpAblQg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wXk03on3RDpAblQg p{margin:0;}#mermaid-svg-wXk03on3RDpAblQg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wXk03on3RDpAblQg .cluster-label text{fill:#333;}#mermaid-svg-wXk03on3RDpAblQg .cluster-label span{color:#333;}#mermaid-svg-wXk03on3RDpAblQg .cluster-label span p{background-color:transparent;}#mermaid-svg-wXk03on3RDpAblQg .label text,#mermaid-svg-wXk03on3RDpAblQg span{fill:#333;color:#333;}#mermaid-svg-wXk03on3RDpAblQg .node rect,#mermaid-svg-wXk03on3RDpAblQg .node circle,#mermaid-svg-wXk03on3RDpAblQg .node ellipse,#mermaid-svg-wXk03on3RDpAblQg .node polygon,#mermaid-svg-wXk03on3RDpAblQg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wXk03on3RDpAblQg .rough-node .label text,#mermaid-svg-wXk03on3RDpAblQg .node .label text,#mermaid-svg-wXk03on3RDpAblQg .image-shape .label,#mermaid-svg-wXk03on3RDpAblQg .icon-shape .label{text-anchor:middle;}#mermaid-svg-wXk03on3RDpAblQg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wXk03on3RDpAblQg .rough-node .label,#mermaid-svg-wXk03on3RDpAblQg .node .label,#mermaid-svg-wXk03on3RDpAblQg .image-shape .label,#mermaid-svg-wXk03on3RDpAblQg .icon-shape .label{text-align:center;}#mermaid-svg-wXk03on3RDpAblQg .node.clickable{cursor:pointer;}#mermaid-svg-wXk03on3RDpAblQg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wXk03on3RDpAblQg .arrowheadPath{fill:#333333;}#mermaid-svg-wXk03on3RDpAblQg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wXk03on3RDpAblQg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wXk03on3RDpAblQg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wXk03on3RDpAblQg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wXk03on3RDpAblQg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wXk03on3RDpAblQg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wXk03on3RDpAblQg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wXk03on3RDpAblQg .cluster text{fill:#333;}#mermaid-svg-wXk03on3RDpAblQg .cluster span{color:#333;}#mermaid-svg-wXk03on3RDpAblQg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wXk03on3RDpAblQg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wXk03on3RDpAblQg rect.text{fill:none;stroke-width:0;}#mermaid-svg-wXk03on3RDpAblQg .icon-shape,#mermaid-svg-wXk03on3RDpAblQg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wXk03on3RDpAblQg .icon-shape p,#mermaid-svg-wXk03on3RDpAblQg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wXk03on3RDpAblQg .icon-shape .label rect,#mermaid-svg-wXk03on3RDpAblQg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wXk03on3RDpAblQg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wXk03on3RDpAblQg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wXk03on3RDpAblQg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-wXk03on3RDpAblQg .blue>*{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .blue span{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .blue tspan{fill:#fff!important;}#mermaid-svg-wXk03on3RDpAblQg .orange>*{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .orange span{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .orange tspan{fill:#fff!important;}#mermaid-svg-wXk03on3RDpAblQg .green>*{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .green span{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .green tspan{fill:#fff!important;}#mermaid-svg-wXk03on3RDpAblQg .red>*{fill:#E15759!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .red span{fill:#E15759!important;color:#fff!important;stroke:none!important;}#mermaid-svg-wXk03on3RDpAblQg .red tspan{fill:#fff!important;} 检索相关记忆
提取记忆写入
用户
Agent 大脑
短期记忆 本次会话
长期记忆 跨会话

一、为什么 Agent 天生"失忆"?

先搞懂根本原因,后面的设计才有根基。

大模型是无状态的(stateless)。 每次调用 API,它只看你这一次传进去的内容,不会自动记住上一次的对话。你可以把大模型想象成"一个每次都格式化过的临时工":
#mermaid-svg-MBNLHb2bYfHskuao{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MBNLHb2bYfHskuao .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MBNLHb2bYfHskuao .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MBNLHb2bYfHskuao .error-icon{fill:#552222;}#mermaid-svg-MBNLHb2bYfHskuao .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MBNLHb2bYfHskuao .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MBNLHb2bYfHskuao .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MBNLHb2bYfHskuao .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MBNLHb2bYfHskuao .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MBNLHb2bYfHskuao .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MBNLHb2bYfHskuao .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MBNLHb2bYfHskuao .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MBNLHb2bYfHskuao .marker.cross{stroke:#333333;}#mermaid-svg-MBNLHb2bYfHskuao svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MBNLHb2bYfHskuao p{margin:0;}#mermaid-svg-MBNLHb2bYfHskuao .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MBNLHb2bYfHskuao .cluster-label text{fill:#333;}#mermaid-svg-MBNLHb2bYfHskuao .cluster-label span{color:#333;}#mermaid-svg-MBNLHb2bYfHskuao .cluster-label span p{background-color:transparent;}#mermaid-svg-MBNLHb2bYfHskuao .label text,#mermaid-svg-MBNLHb2bYfHskuao span{fill:#333;color:#333;}#mermaid-svg-MBNLHb2bYfHskuao .node rect,#mermaid-svg-MBNLHb2bYfHskuao .node circle,#mermaid-svg-MBNLHb2bYfHskuao .node ellipse,#mermaid-svg-MBNLHb2bYfHskuao .node polygon,#mermaid-svg-MBNLHb2bYfHskuao .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MBNLHb2bYfHskuao .rough-node .label text,#mermaid-svg-MBNLHb2bYfHskuao .node .label text,#mermaid-svg-MBNLHb2bYfHskuao .image-shape .label,#mermaid-svg-MBNLHb2bYfHskuao .icon-shape .label{text-anchor:middle;}#mermaid-svg-MBNLHb2bYfHskuao .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MBNLHb2bYfHskuao .rough-node .label,#mermaid-svg-MBNLHb2bYfHskuao .node .label,#mermaid-svg-MBNLHb2bYfHskuao .image-shape .label,#mermaid-svg-MBNLHb2bYfHskuao .icon-shape .label{text-align:center;}#mermaid-svg-MBNLHb2bYfHskuao .node.clickable{cursor:pointer;}#mermaid-svg-MBNLHb2bYfHskuao .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MBNLHb2bYfHskuao .arrowheadPath{fill:#333333;}#mermaid-svg-MBNLHb2bYfHskuao .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MBNLHb2bYfHskuao .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MBNLHb2bYfHskuao .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MBNLHb2bYfHskuao .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MBNLHb2bYfHskuao .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MBNLHb2bYfHskuao .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MBNLHb2bYfHskuao .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MBNLHb2bYfHskuao .cluster text{fill:#333;}#mermaid-svg-MBNLHb2bYfHskuao .cluster span{color:#333;}#mermaid-svg-MBNLHb2bYfHskuao div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MBNLHb2bYfHskuao .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MBNLHb2bYfHskuao rect.text{fill:none;stroke-width:0;}#mermaid-svg-MBNLHb2bYfHskuao .icon-shape,#mermaid-svg-MBNLHb2bYfHskuao .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MBNLHb2bYfHskuao .icon-shape p,#mermaid-svg-MBNLHb2bYfHskuao .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MBNLHb2bYfHskuao .icon-shape .label rect,#mermaid-svg-MBNLHb2bYfHskuao .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MBNLHb2bYfHskuao .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MBNLHb2bYfHskuao .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MBNLHb2bYfHskuao :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-MBNLHb2bYfHskuao .blue>*{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-MBNLHb2bYfHskuao .blue span{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-MBNLHb2bYfHskuao .blue tspan{fill:#fff!important;}#mermaid-svg-MBNLHb2bYfHskuao .orange>*{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-MBNLHb2bYfHskuao .orange span{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-MBNLHb2bYfHskuao .orange tspan{fill:#fff!important;} 无记忆
每次都失忆 重新介绍
有记忆
记住用户和偏好

所以"记忆"不是大模型自带的能力,而是你在外面给它搭的一套系统------把该记住的东西存下来,下次再喂回给它。这个"存 + 取"的系统,就是 Agent 记忆系统。

二、记忆的两个层次:短期 vs 长期

Agent 记忆分成两个层次,这是理解整个系统的框架:

短期记忆(Working Memory) 长期记忆(Long-term Memory)
作用域 当前这一次会话 跨会话、永久
存什么 本次对话的历史消息 用户偏好、历史事实、知识
类比 脑子里的临时记忆 随身笔记本
生命周期 会话结束就清空 持久保存

一句话:短期记忆负责"这次对话别聊着聊着忘了上文",长期记忆负责"下次再来还认识你"。

三、短期记忆:上下文管理

短期记忆的实现,本质是把历史消息拼进 prompt 。你在代码里维护一个 messages 列表:

python 复制代码
messages = []   # 短期记忆:本次对话的历史

def chat(user_input):
    messages.append({"role": "user", "content": user_input})   # 加进历史
    resp = call_llm(messages)          # 整个 messages 一起传给大模型
    messages.append({"role": "assistant", "content": resp})
    return resp

大模型每次都能"看到"前面的历史,所以能接上话。但这里有个硬约束:大模型上下文长度有限(token 数),历史不能无限塞。于是有了三种管理策略:
#mermaid-svg-hrOsznpHgeTZMvZB{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hrOsznpHgeTZMvZB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hrOsznpHgeTZMvZB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hrOsznpHgeTZMvZB .error-icon{fill:#552222;}#mermaid-svg-hrOsznpHgeTZMvZB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hrOsznpHgeTZMvZB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hrOsznpHgeTZMvZB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hrOsznpHgeTZMvZB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hrOsznpHgeTZMvZB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hrOsznpHgeTZMvZB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hrOsznpHgeTZMvZB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hrOsznpHgeTZMvZB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hrOsznpHgeTZMvZB .marker.cross{stroke:#333333;}#mermaid-svg-hrOsznpHgeTZMvZB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hrOsznpHgeTZMvZB p{margin:0;}#mermaid-svg-hrOsznpHgeTZMvZB .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hrOsznpHgeTZMvZB .cluster-label text{fill:#333;}#mermaid-svg-hrOsznpHgeTZMvZB .cluster-label span{color:#333;}#mermaid-svg-hrOsznpHgeTZMvZB .cluster-label span p{background-color:transparent;}#mermaid-svg-hrOsznpHgeTZMvZB .label text,#mermaid-svg-hrOsznpHgeTZMvZB span{fill:#333;color:#333;}#mermaid-svg-hrOsznpHgeTZMvZB .node rect,#mermaid-svg-hrOsznpHgeTZMvZB .node circle,#mermaid-svg-hrOsznpHgeTZMvZB .node ellipse,#mermaid-svg-hrOsznpHgeTZMvZB .node polygon,#mermaid-svg-hrOsznpHgeTZMvZB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hrOsznpHgeTZMvZB .rough-node .label text,#mermaid-svg-hrOsznpHgeTZMvZB .node .label text,#mermaid-svg-hrOsznpHgeTZMvZB .image-shape .label,#mermaid-svg-hrOsznpHgeTZMvZB .icon-shape .label{text-anchor:middle;}#mermaid-svg-hrOsznpHgeTZMvZB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hrOsznpHgeTZMvZB .rough-node .label,#mermaid-svg-hrOsznpHgeTZMvZB .node .label,#mermaid-svg-hrOsznpHgeTZMvZB .image-shape .label,#mermaid-svg-hrOsznpHgeTZMvZB .icon-shape .label{text-align:center;}#mermaid-svg-hrOsznpHgeTZMvZB .node.clickable{cursor:pointer;}#mermaid-svg-hrOsznpHgeTZMvZB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hrOsznpHgeTZMvZB .arrowheadPath{fill:#333333;}#mermaid-svg-hrOsznpHgeTZMvZB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hrOsznpHgeTZMvZB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hrOsznpHgeTZMvZB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hrOsznpHgeTZMvZB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hrOsznpHgeTZMvZB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hrOsznpHgeTZMvZB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hrOsznpHgeTZMvZB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hrOsznpHgeTZMvZB .cluster text{fill:#333;}#mermaid-svg-hrOsznpHgeTZMvZB .cluster span{color:#333;}#mermaid-svg-hrOsznpHgeTZMvZB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hrOsznpHgeTZMvZB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hrOsznpHgeTZMvZB rect.text{fill:none;stroke-width:0;}#mermaid-svg-hrOsznpHgeTZMvZB .icon-shape,#mermaid-svg-hrOsznpHgeTZMvZB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hrOsznpHgeTZMvZB .icon-shape p,#mermaid-svg-hrOsznpHgeTZMvZB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hrOsznpHgeTZMvZB .icon-shape .label rect,#mermaid-svg-hrOsznpHgeTZMvZB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hrOsznpHgeTZMvZB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hrOsznpHgeTZMvZB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hrOsznpHgeTZMvZB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-hrOsznpHgeTZMvZB .blue>*{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-hrOsznpHgeTZMvZB .blue span{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-hrOsznpHgeTZMvZB .blue tspan{fill:#fff!important;}#mermaid-svg-hrOsznpHgeTZMvZB .orange>*{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-hrOsznpHgeTZMvZB .orange span{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-hrOsznpHgeTZMvZB .orange tspan{fill:#fff!important;}#mermaid-svg-hrOsznpHgeTZMvZB .green>*{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-hrOsznpHgeTZMvZB .green span{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-hrOsznpHgeTZMvZB .green tspan{fill:#fff!important;} 历史消息太多
滑动窗口 只留最近N条
摘要压缩 把旧对话压成摘要

  1. 滑动窗口:只保留最近 N 条消息,旧的直接丢掉。简单,但会丢掉"很久之前的关键信息"。
  2. 摘要压缩:把较早的历史用大模型压缩成一段摘要("用户刚才说他想学 AI 后端..."),既省 token 又保留要点。
  3. 分层记忆:最近几条保留原文 + 更早的保留摘要,两者结合。

这就是"上下文管理"(之前系列里提过):短期记忆的本质,是在 token 有限的约束下,尽量保留有用的上下文。

四、长期记忆:跨会话记住用户

短期记忆会话一结束就没了。要让 Agent"下次还认识你",需要长期记忆 ------把重要信息持久化到数据库/向量库里,下次再取出来。

长期记忆通常分三类:
#mermaid-svg-ofTE3ScDcIItMlTR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ofTE3ScDcIItMlTR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ofTE3ScDcIItMlTR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ofTE3ScDcIItMlTR .error-icon{fill:#552222;}#mermaid-svg-ofTE3ScDcIItMlTR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ofTE3ScDcIItMlTR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ofTE3ScDcIItMlTR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ofTE3ScDcIItMlTR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ofTE3ScDcIItMlTR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ofTE3ScDcIItMlTR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ofTE3ScDcIItMlTR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ofTE3ScDcIItMlTR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ofTE3ScDcIItMlTR .marker.cross{stroke:#333333;}#mermaid-svg-ofTE3ScDcIItMlTR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ofTE3ScDcIItMlTR p{margin:0;}#mermaid-svg-ofTE3ScDcIItMlTR .edge{stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .section--1 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section--1 path,#mermaid-svg-ofTE3ScDcIItMlTR .section--1 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section--1 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section--1 text{fill:#ffffff;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth--1{stroke-width:17;}#mermaid-svg-ofTE3ScDcIItMlTR .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-0 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-0 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-0 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-0 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-0 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-0{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-0{stroke-width:14;}#mermaid-svg-ofTE3ScDcIItMlTR .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-1 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-1 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-1 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-1 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-1 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-1{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-1{stroke-width:11;}#mermaid-svg-ofTE3ScDcIItMlTR .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-2 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-2 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-2 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-2 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-2 text{fill:#ffffff;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-2{stroke-width:8;}#mermaid-svg-ofTE3ScDcIItMlTR .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-3 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-3 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-3 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-3 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-3 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-3{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-3{stroke-width:5;}#mermaid-svg-ofTE3ScDcIItMlTR .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-4 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-4 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-4 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-4 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-4 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-4{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-4{stroke-width:2;}#mermaid-svg-ofTE3ScDcIItMlTR .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-5 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-5 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-5 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-5 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-5 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-5{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-5{stroke-width:-1;}#mermaid-svg-ofTE3ScDcIItMlTR .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-6 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-6 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-6 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-6 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-6 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-6{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-6{stroke-width:-4;}#mermaid-svg-ofTE3ScDcIItMlTR .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-7 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-7 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-7 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-7 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-7 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-7{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-7{stroke-width:-7;}#mermaid-svg-ofTE3ScDcIItMlTR .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-8 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-8 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-8 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-8 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-8 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-8{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-8{stroke-width:-10;}#mermaid-svg-ofTE3ScDcIItMlTR .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-9 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-9 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-9 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-9 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-9 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-9{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-9{stroke-width:-13;}#mermaid-svg-ofTE3ScDcIItMlTR .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-10 rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-10 path,#mermaid-svg-ofTE3ScDcIItMlTR .section-10 circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-10 polygon,#mermaid-svg-ofTE3ScDcIItMlTR .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-10 text{fill:black;}#mermaid-svg-ofTE3ScDcIItMlTR .node-icon-10{font-size:40px;color:black;}#mermaid-svg-ofTE3ScDcIItMlTR .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .edge-depth-10{stroke-width:-16;}#mermaid-svg-ofTE3ScDcIItMlTR .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled,#mermaid-svg-ofTE3ScDcIItMlTR .disabled circle,#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:lightgray;}#mermaid-svg-ofTE3ScDcIItMlTR .disabled text{fill:#efefef;}#mermaid-svg-ofTE3ScDcIItMlTR .section-root rect,#mermaid-svg-ofTE3ScDcIItMlTR .section-root path,#mermaid-svg-ofTE3ScDcIItMlTR .section-root circle,#mermaid-svg-ofTE3ScDcIItMlTR .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-ofTE3ScDcIItMlTR .section-root text{fill:#ffffff;}#mermaid-svg-ofTE3ScDcIItMlTR .section-root span{color:#ffffff;}#mermaid-svg-ofTE3ScDcIItMlTR .section-2 span{color:#ffffff;}#mermaid-svg-ofTE3ScDcIItMlTR .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-ofTE3ScDcIItMlTR .edge{fill:none;}#mermaid-svg-ofTE3ScDcIItMlTR .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-ofTE3ScDcIItMlTR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 长期记忆三类
事实记忆
用户是谁
偏好
语义记忆
知识库
RAG
情景记忆
历史交互
做过什么

  • 事实记忆:关于用户的事实------"用户叫 Yulia,是后端工程师,用 FastAPI";
  • 语义记忆:通用知识库------公司的产品文档、领域知识(这就是 RAG 的向量库);
  • 情景记忆:历史交互记录------"上次我帮你解决过 XX 问题"。

注意:RAG(第十一课)本质上是语义记忆的一种实现。所以记忆系统和 RAG 不是两回事,RAG 是记忆系统里的一个子集。

五、长期记忆的写入:什么时候存

长期记忆最关键的设计是**"什么时候写入"------因为不可能把每一句话都存下来(会爆炸),要挑有价值的存**。
#mermaid-svg-JTh2iQDsVkH6GfNn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-JTh2iQDsVkH6GfNn .error-icon{fill:#552222;}#mermaid-svg-JTh2iQDsVkH6GfNn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JTh2iQDsVkH6GfNn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JTh2iQDsVkH6GfNn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JTh2iQDsVkH6GfNn .marker.cross{stroke:#333333;}#mermaid-svg-JTh2iQDsVkH6GfNn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JTh2iQDsVkH6GfNn p{margin:0;}#mermaid-svg-JTh2iQDsVkH6GfNn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-JTh2iQDsVkH6GfNn .cluster-label text{fill:#333;}#mermaid-svg-JTh2iQDsVkH6GfNn .cluster-label span{color:#333;}#mermaid-svg-JTh2iQDsVkH6GfNn .cluster-label span p{background-color:transparent;}#mermaid-svg-JTh2iQDsVkH6GfNn .label text,#mermaid-svg-JTh2iQDsVkH6GfNn span{fill:#333;color:#333;}#mermaid-svg-JTh2iQDsVkH6GfNn .node rect,#mermaid-svg-JTh2iQDsVkH6GfNn .node circle,#mermaid-svg-JTh2iQDsVkH6GfNn .node ellipse,#mermaid-svg-JTh2iQDsVkH6GfNn .node polygon,#mermaid-svg-JTh2iQDsVkH6GfNn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-JTh2iQDsVkH6GfNn .rough-node .label text,#mermaid-svg-JTh2iQDsVkH6GfNn .node .label text,#mermaid-svg-JTh2iQDsVkH6GfNn .image-shape .label,#mermaid-svg-JTh2iQDsVkH6GfNn .icon-shape .label{text-anchor:middle;}#mermaid-svg-JTh2iQDsVkH6GfNn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-JTh2iQDsVkH6GfNn .rough-node .label,#mermaid-svg-JTh2iQDsVkH6GfNn .node .label,#mermaid-svg-JTh2iQDsVkH6GfNn .image-shape .label,#mermaid-svg-JTh2iQDsVkH6GfNn .icon-shape .label{text-align:center;}#mermaid-svg-JTh2iQDsVkH6GfNn .node.clickable{cursor:pointer;}#mermaid-svg-JTh2iQDsVkH6GfNn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-JTh2iQDsVkH6GfNn .arrowheadPath{fill:#333333;}#mermaid-svg-JTh2iQDsVkH6GfNn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-JTh2iQDsVkH6GfNn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-JTh2iQDsVkH6GfNn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JTh2iQDsVkH6GfNn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-JTh2iQDsVkH6GfNn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JTh2iQDsVkH6GfNn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-JTh2iQDsVkH6GfNn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-JTh2iQDsVkH6GfNn .cluster text{fill:#333;}#mermaid-svg-JTh2iQDsVkH6GfNn .cluster span{color:#333;}#mermaid-svg-JTh2iQDsVkH6GfNn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-JTh2iQDsVkH6GfNn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-JTh2iQDsVkH6GfNn rect.text{fill:none;stroke-width:0;}#mermaid-svg-JTh2iQDsVkH6GfNn .icon-shape,#mermaid-svg-JTh2iQDsVkH6GfNn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JTh2iQDsVkH6GfNn .icon-shape p,#mermaid-svg-JTh2iQDsVkH6GfNn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-JTh2iQDsVkH6GfNn .icon-shape .label rect,#mermaid-svg-JTh2iQDsVkH6GfNn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JTh2iQDsVkH6GfNn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-JTh2iQDsVkH6GfNn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-JTh2iQDsVkH6GfNn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-JTh2iQDsVkH6GfNn .blue>*{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .blue span{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .blue tspan{fill:#fff!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .orange>*{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .orange span{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .orange tspan{fill:#fff!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .green>*{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .green span{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-JTh2iQDsVkH6GfNn .green tspan{fill:#fff!important;} 有 值得记
无 闲聊
对话结束
LLM 判断有无价值
提取成记忆
写入数据库 向量库
丢弃

核心是用大模型做"记忆提取(memory extraction)":对话结束后,让大模型判断"这段对话里有没有值得长期记住的信息",有就提取成一条结构化记忆。例如:

python 复制代码
def extract_memory(dialogue: str) -> str | None:
    prompt = f"""判断下面的对话里有没有值得长期记住的信息(用户身份、偏好、重要事实)。
    如果有,提取成一句话记忆;如果没有,返回"无"。

    对话:
    {dialogue}
    """
    memory = call_llm(prompt)
    return None if "无" in memory else memory

# 示例:对话"我叫 Yulia,是做后端开发的"
# 提取出记忆:"用户叫 Yulia,是后端开发工程师"

提取出的记忆写入数据库,下次对话时检索出来用。

六、长期记忆的检索:什么时候取

存了记忆,还要在合适的时候取出来用。每次新对话开始时,根据用户当前的问题,去检索最相关的记忆:
#mermaid-svg-Kb2lDREBnDQs5DjT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Kb2lDREBnDQs5DjT .error-icon{fill:#552222;}#mermaid-svg-Kb2lDREBnDQs5DjT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Kb2lDREBnDQs5DjT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Kb2lDREBnDQs5DjT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Kb2lDREBnDQs5DjT .marker.cross{stroke:#333333;}#mermaid-svg-Kb2lDREBnDQs5DjT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Kb2lDREBnDQs5DjT p{margin:0;}#mermaid-svg-Kb2lDREBnDQs5DjT .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Kb2lDREBnDQs5DjT .cluster-label text{fill:#333;}#mermaid-svg-Kb2lDREBnDQs5DjT .cluster-label span{color:#333;}#mermaid-svg-Kb2lDREBnDQs5DjT .cluster-label span p{background-color:transparent;}#mermaid-svg-Kb2lDREBnDQs5DjT .label text,#mermaid-svg-Kb2lDREBnDQs5DjT span{fill:#333;color:#333;}#mermaid-svg-Kb2lDREBnDQs5DjT .node rect,#mermaid-svg-Kb2lDREBnDQs5DjT .node circle,#mermaid-svg-Kb2lDREBnDQs5DjT .node ellipse,#mermaid-svg-Kb2lDREBnDQs5DjT .node polygon,#mermaid-svg-Kb2lDREBnDQs5DjT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Kb2lDREBnDQs5DjT .rough-node .label text,#mermaid-svg-Kb2lDREBnDQs5DjT .node .label text,#mermaid-svg-Kb2lDREBnDQs5DjT .image-shape .label,#mermaid-svg-Kb2lDREBnDQs5DjT .icon-shape .label{text-anchor:middle;}#mermaid-svg-Kb2lDREBnDQs5DjT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Kb2lDREBnDQs5DjT .rough-node .label,#mermaid-svg-Kb2lDREBnDQs5DjT .node .label,#mermaid-svg-Kb2lDREBnDQs5DjT .image-shape .label,#mermaid-svg-Kb2lDREBnDQs5DjT .icon-shape .label{text-align:center;}#mermaid-svg-Kb2lDREBnDQs5DjT .node.clickable{cursor:pointer;}#mermaid-svg-Kb2lDREBnDQs5DjT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Kb2lDREBnDQs5DjT .arrowheadPath{fill:#333333;}#mermaid-svg-Kb2lDREBnDQs5DjT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Kb2lDREBnDQs5DjT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Kb2lDREBnDQs5DjT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Kb2lDREBnDQs5DjT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Kb2lDREBnDQs5DjT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Kb2lDREBnDQs5DjT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Kb2lDREBnDQs5DjT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Kb2lDREBnDQs5DjT .cluster text{fill:#333;}#mermaid-svg-Kb2lDREBnDQs5DjT .cluster span{color:#333;}#mermaid-svg-Kb2lDREBnDQs5DjT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Kb2lDREBnDQs5DjT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Kb2lDREBnDQs5DjT rect.text{fill:none;stroke-width:0;}#mermaid-svg-Kb2lDREBnDQs5DjT .icon-shape,#mermaid-svg-Kb2lDREBnDQs5DjT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Kb2lDREBnDQs5DjT .icon-shape p,#mermaid-svg-Kb2lDREBnDQs5DjT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Kb2lDREBnDQs5DjT .icon-shape .label rect,#mermaid-svg-Kb2lDREBnDQs5DjT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Kb2lDREBnDQs5DjT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Kb2lDREBnDQs5DjT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Kb2lDREBnDQs5DjT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-Kb2lDREBnDQs5DjT .blue>*{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .blue span{fill:#4E79A7!important;color:#fff!important;stroke:none!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .blue tspan{fill:#fff!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .orange>*{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .orange span{fill:#F28E2B!important;color:#fff!important;stroke:none!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .orange tspan{fill:#fff!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .green>*{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .green span{fill:#59A14F!important;color:#fff!important;stroke:none!important;}#mermaid-svg-Kb2lDREBnDQs5DjT .green tspan{fill:#fff!important;} 新对话
向量检索记忆
取相关记忆
注入 prompt

检索用向量相似度(和 RAG 一样)------把用户当前问题向量化,去找最相关的记忆。比如用户问"帮我推荐一个后端框架",就能检索出"用户是后端工程师、用 FastAPI"这条记忆,然后回答就能个性化。

七、完整实现:一个带记忆的 Agent

把短期 + 长期记忆串起来:

python 复制代码
# 短期记忆:本次会话的 messages
messages = []

def chat(user_id: str, user_input: str):
    # 1. 检索长期记忆
    relevant_memories = retrieve_memories(user_id, user_input)   # 向量检索

    # 2. 拼 prompt:长期记忆 + 短期上下文 + 当前问题
    memory_text = "\n".join(relevant_memories)
    messages.append({"role": "user", "content": user_input})
    prompt_messages = [
        {"role": "system", "content": f"关于用户,你已知:\n{memory_text}"},
    ] + messages[-10:]          # 短期记忆:滑动窗口,只留最近 10 条

    # 3. 调大模型
    resp = call_llm(prompt_messages)
    messages.append({"role": "assistant", "content": resp})

    # 4. 提取新记忆,写入长期记忆
    new_memory = extract_memory(f"用户:{user_input}\n助手:{resp}")
    if new_memory:
        store_memory(user_id, new_memory)   # 写入向量库/数据库

    return resp

这段代码把整篇文章串起来了:检索长期记忆 → 拼短期上下文 → 生成 → 提取新记忆写入。四个步骤就是 Agent 记忆系统的完整闭环。

八、常见坑与避坑指南

坑 原因 解决方案
记忆爆炸 什么都存,越存越多 用 LLM 判断"值不值得记",只存有价值的
错误/过时记忆 记错了或用户情况变了 支持记忆更新、过期,冲突时以新为准
记忆污染上下文 检索出无关记忆塞进 prompt 限制检索数量,做相关性阈值过滤
隐私泄露 记忆里存了敏感信息 做权限隔离 + 支持"遗忘"(删除指定记忆)
短期上下文太长 历史无脑堆 滑动窗口 + 摘要压缩

隐私与遗忘权 是记忆系统特有的红线:用户有权要求"忘了我"。一个合格的记忆系统必须支持删除指定用户的记忆,这在合规上越来越重要。

总结:一张图带走

这课的核心,一句话串起来:

  • 大模型天生无状态,记忆是你在外面给它搭的"存 + 取"系统。
  • 两层记忆:短期记忆(本次会话,用 messages + 滑动窗口/摘要)vs 长期记忆(跨会话,持久化)。
  • 长期记忆三类:事实记忆(用户是谁)、语义记忆(RAG 知识库)、情景记忆(历史交互)。
  • 写入靠"记忆提取":用大模型判断"值不值得记",只存有价值的,防爆炸。
  • 检索靠向量相似度:新对话时检索最相关的记忆注入 prompt,实现个性化。
  • 完整闭环:检索记忆 → 拼上下文 → 生成 → 提取新记忆写入。

三个立即可用的行动:

  1. 给第十二课的 Agent 加一个最简单的短期记忆(messages 列表 + 滑动窗口),感受它"记得上文"的变化;
  2. 写一个 extract_memory 函数,让大模型从对话里提取"值得记住"的信息,存进数据库;
  3. 下次对话前,用向量检索把相关记忆取出来注入 prompt,实现"下次还认识你"。

如果这篇对你有帮助,点个赞、收藏一下 ,下一篇我们讲 Multi-Agent 多智能体------让多个 Agent 分工协作。

关注我,我会持续更新 AI 应用开发的前沿实战,陪你从单 Agent 一路进阶到多智能体系统。

你在做 Agent 记忆时,遇到过"记忆越存越多、检索越来越不准"的问题吗?你是怎么解决的?评论区聊聊,我挨个回。

(本文记忆系统方案基于主流 Agent 框架的通用设计,存储可用数据库 + 向量库实现,具体技术栈可替换,评论区提醒我。)

相关推荐
国科安芯5 小时前
四重证据,一条逻辑链:商业航天级微控制器MCU抗辐射验证方法学综述——以国科安芯AS32S601为例
人工智能·单片机·嵌入式硬件·mcu·安全·抗辐射
dk_tjy5 小时前
AI驱动的自动化攻击背景下:企业端点安全体系的技术架构与建设路径
网络·人工智能·安全·自动化·终端安全管理·数据防泄漏
曹牧5 小时前
C#:空合并运算符
java·前端·数据库
happylifetree5 小时前
Python67:核心语法-函数进阶-参数类型(函数作为参数)
python
布吉岛的石头5 小时前
Java 程序员第 50 阶段2:预训练的目标函数:自回归语言建模本质
java·开发语言·人工智能·深度学习·回归·transformer
2601_965454236 小时前
用AI把开源项目功能清单做成MG动画介绍视频
人工智能·开源·音视频
风雅GW6 小时前
局域网访问为何少一半配置页:DSH 的安全边界设计复盘
人工智能
golang学习记6 小时前
IDEA 2026年的玩法已经完全不同
java·ide·intellij-idea