第5章 记忆管理——让Agent记住事情

第4章我们给Agent加上了工具调用能力。它现在能查数据库、查天气、计算数字了。

但你用着用着会发现一个尴尬的问题:这Agent怎么聊着聊着就忘了事呢?

举个例子。你跟Agent聊:

你:我叫小明,在济南工作,是个程序员。

Agent:好的小明,济南的程序员你好!

你:今天心情不太好。

Agent:怎么了?

你:你还记得我是干什么工作的吗?

Agent:抱歉,我不记得了。

看到没?才聊了3句,Agent就把你的信息忘了。

这章我们就来解决这个"Agent失忆"的老大难。


5.1 为什么Agent会"失忆"?

你可能以为这是模型的问题。其实不是。 这是设计上的限制

上下文窗口:Agent的"工作台"就这么大

每个大语言模型都有一个上下文窗口(Context Window),你可以把它理解成Agent的"工作台"。
#mermaid-svg-H1NQT00ZtNaWXVeP{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-H1NQT00ZtNaWXVeP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H1NQT00ZtNaWXVeP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H1NQT00ZtNaWXVeP .error-icon{fill:#552222;}#mermaid-svg-H1NQT00ZtNaWXVeP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H1NQT00ZtNaWXVeP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H1NQT00ZtNaWXVeP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H1NQT00ZtNaWXVeP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H1NQT00ZtNaWXVeP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H1NQT00ZtNaWXVeP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H1NQT00ZtNaWXVeP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H1NQT00ZtNaWXVeP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H1NQT00ZtNaWXVeP .marker.cross{stroke:#333333;}#mermaid-svg-H1NQT00ZtNaWXVeP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H1NQT00ZtNaWXVeP p{margin:0;}#mermaid-svg-H1NQT00ZtNaWXVeP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-H1NQT00ZtNaWXVeP .cluster-label text{fill:#333;}#mermaid-svg-H1NQT00ZtNaWXVeP .cluster-label span{color:#333;}#mermaid-svg-H1NQT00ZtNaWXVeP .cluster-label span p{background-color:transparent;}#mermaid-svg-H1NQT00ZtNaWXVeP .label text,#mermaid-svg-H1NQT00ZtNaWXVeP span{fill:#333;color:#333;}#mermaid-svg-H1NQT00ZtNaWXVeP .node rect,#mermaid-svg-H1NQT00ZtNaWXVeP .node circle,#mermaid-svg-H1NQT00ZtNaWXVeP .node ellipse,#mermaid-svg-H1NQT00ZtNaWXVeP .node polygon,#mermaid-svg-H1NQT00ZtNaWXVeP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H1NQT00ZtNaWXVeP .rough-node .label text,#mermaid-svg-H1NQT00ZtNaWXVeP .node .label text,#mermaid-svg-H1NQT00ZtNaWXVeP .image-shape .label,#mermaid-svg-H1NQT00ZtNaWXVeP .icon-shape .label{text-anchor:middle;}#mermaid-svg-H1NQT00ZtNaWXVeP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H1NQT00ZtNaWXVeP .rough-node .label,#mermaid-svg-H1NQT00ZtNaWXVeP .node .label,#mermaid-svg-H1NQT00ZtNaWXVeP .image-shape .label,#mermaid-svg-H1NQT00ZtNaWXVeP .icon-shape .label{text-align:center;}#mermaid-svg-H1NQT00ZtNaWXVeP .node.clickable{cursor:pointer;}#mermaid-svg-H1NQT00ZtNaWXVeP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H1NQT00ZtNaWXVeP .arrowheadPath{fill:#333333;}#mermaid-svg-H1NQT00ZtNaWXVeP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H1NQT00ZtNaWXVeP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H1NQT00ZtNaWXVeP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H1NQT00ZtNaWXVeP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H1NQT00ZtNaWXVeP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H1NQT00ZtNaWXVeP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H1NQT00ZtNaWXVeP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H1NQT00ZtNaWXVeP .cluster text{fill:#333;}#mermaid-svg-H1NQT00ZtNaWXVeP .cluster span{color:#333;}#mermaid-svg-H1NQT00ZtNaWXVeP 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-H1NQT00ZtNaWXVeP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H1NQT00ZtNaWXVeP rect.text{fill:none;stroke-width:0;}#mermaid-svg-H1NQT00ZtNaWXVeP .icon-shape,#mermaid-svg-H1NQT00ZtNaWXVeP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H1NQT00ZtNaWXVeP .icon-shape p,#mermaid-svg-H1NQT00ZtNaWXVeP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H1NQT00ZtNaWXVeP .icon-shape .label rect,#mermaid-svg-H1NQT00ZtNaWXVeP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H1NQT00ZtNaWXVeP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H1NQT00ZtNaWXVeP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H1NQT00ZtNaWXVeP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Agent的工作台

(上下文窗口)
📝 系统提示词

3k tokens
💬 对话历史

每轮约500 tokens
🛠️ 工具定义

每个工具约300 tokens
📚 RAG检索内容

每次约2000 tokens
🤔 模型生成的回复

约500 tokens
❌ 没空间了

超出的内容会被截断

我给你算一笔账。GPT-4.1的上下文窗口是128k tokens(约等于10万字)。听起来挺多?来看看Agent一次"完整调用"会消耗多少:

占用项 典型大小 备注
系统提示词 2000 tokens Agent的"人设"和工具说明
工具定义 3000 tokens 10个工具约3k
对话历史 每轮500 tokens 聊20轮就是1万
RAG检索内容 2000 tokens/次 每次问答都要塞进相关文档
模型回复 1000 tokens 一次约500-1000字

算一下:20轮对话 + 5次工具调用 = 2k+3k+1万+1万+5k = 3万token。

看起来离128k远着呢。但问题是------Token会按次收费的! 一次Agent调用花的钱是简单聊天的几十倍。

更关键的是,对话越长,单次调用的成本越高,速度越慢。你每问一句话,模型都要把整段历史重新"读一遍"。

模型会"忘记中间":Lost in the Middle

还有个更反直觉的问题:模型对超长上下文的"中间部分"会视而不见。

研究者做过实验:把一段很长的文本喂给模型,把关键信息藏在不同位置,问模型"刚才第X段说了什么"?

结果:
#mermaid-svg-NpeRfLvOSD2vyMkb{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-NpeRfLvOSD2vyMkb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NpeRfLvOSD2vyMkb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NpeRfLvOSD2vyMkb .error-icon{fill:#552222;}#mermaid-svg-NpeRfLvOSD2vyMkb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NpeRfLvOSD2vyMkb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NpeRfLvOSD2vyMkb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NpeRfLvOSD2vyMkb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NpeRfLvOSD2vyMkb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NpeRfLvOSD2vyMkb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NpeRfLvOSD2vyMkb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NpeRfLvOSD2vyMkb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NpeRfLvOSD2vyMkb .marker.cross{stroke:#333333;}#mermaid-svg-NpeRfLvOSD2vyMkb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NpeRfLvOSD2vyMkb p{margin:0;}#mermaid-svg-NpeRfLvOSD2vyMkb .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-NpeRfLvOSD2vyMkb .cluster-label text{fill:#333;}#mermaid-svg-NpeRfLvOSD2vyMkb .cluster-label span{color:#333;}#mermaid-svg-NpeRfLvOSD2vyMkb .cluster-label span p{background-color:transparent;}#mermaid-svg-NpeRfLvOSD2vyMkb .label text,#mermaid-svg-NpeRfLvOSD2vyMkb span{fill:#333;color:#333;}#mermaid-svg-NpeRfLvOSD2vyMkb .node rect,#mermaid-svg-NpeRfLvOSD2vyMkb .node circle,#mermaid-svg-NpeRfLvOSD2vyMkb .node ellipse,#mermaid-svg-NpeRfLvOSD2vyMkb .node polygon,#mermaid-svg-NpeRfLvOSD2vyMkb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NpeRfLvOSD2vyMkb .rough-node .label text,#mermaid-svg-NpeRfLvOSD2vyMkb .node .label text,#mermaid-svg-NpeRfLvOSD2vyMkb .image-shape .label,#mermaid-svg-NpeRfLvOSD2vyMkb .icon-shape .label{text-anchor:middle;}#mermaid-svg-NpeRfLvOSD2vyMkb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NpeRfLvOSD2vyMkb .rough-node .label,#mermaid-svg-NpeRfLvOSD2vyMkb .node .label,#mermaid-svg-NpeRfLvOSD2vyMkb .image-shape .label,#mermaid-svg-NpeRfLvOSD2vyMkb .icon-shape .label{text-align:center;}#mermaid-svg-NpeRfLvOSD2vyMkb .node.clickable{cursor:pointer;}#mermaid-svg-NpeRfLvOSD2vyMkb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NpeRfLvOSD2vyMkb .arrowheadPath{fill:#333333;}#mermaid-svg-NpeRfLvOSD2vyMkb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NpeRfLvOSD2vyMkb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NpeRfLvOSD2vyMkb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NpeRfLvOSD2vyMkb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NpeRfLvOSD2vyMkb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NpeRfLvOSD2vyMkb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NpeRfLvOSD2vyMkb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NpeRfLvOSD2vyMkb .cluster text{fill:#333;}#mermaid-svg-NpeRfLvOSD2vyMkb .cluster span{color:#333;}#mermaid-svg-NpeRfLvOSD2vyMkb 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-NpeRfLvOSD2vyMkb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NpeRfLvOSD2vyMkb rect.text{fill:none;stroke-width:0;}#mermaid-svg-NpeRfLvOSD2vyMkb .icon-shape,#mermaid-svg-NpeRfLvOSD2vyMkb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NpeRfLvOSD2vyMkb .icon-shape p,#mermaid-svg-NpeRfLvOSD2vyMkb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NpeRfLvOSD2vyMkb .icon-shape .label rect,#mermaid-svg-NpeRfLvOSD2vyMkb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NpeRfLvOSD2vyMkb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NpeRfLvOSD2vyMkb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NpeRfLvOSD2vyMkb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 关键信息
关键信息
关键信息
开头
找到率: 95%
中间
找到率: 40%
结尾
找到率: 90%

U形的注意力曲线------模型对开头和结尾的内容记得最清楚,中间的部分经常"看漏"。

这意味着什么?你把对话历史全塞进prompt里,模型也不一定真的"读"了。 它可能只看了头尾。

一个比喻:Agent的短期记忆像便利贴

我再给你打个比方,保管你忘不了。

Agent的上下文窗口就像办公桌上贴满便利贴。每来一条新消息,Agent就贴一张新便利贴。
#mermaid-svg-npralA1nyyEoGC2a{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-npralA1nyyEoGC2a .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-npralA1nyyEoGC2a .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-npralA1nyyEoGC2a .error-icon{fill:#552222;}#mermaid-svg-npralA1nyyEoGC2a .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-npralA1nyyEoGC2a .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-npralA1nyyEoGC2a .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-npralA1nyyEoGC2a .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-npralA1nyyEoGC2a .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-npralA1nyyEoGC2a .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-npralA1nyyEoGC2a .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-npralA1nyyEoGC2a .marker{fill:#333333;stroke:#333333;}#mermaid-svg-npralA1nyyEoGC2a .marker.cross{stroke:#333333;}#mermaid-svg-npralA1nyyEoGC2a svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-npralA1nyyEoGC2a p{margin:0;}#mermaid-svg-npralA1nyyEoGC2a .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-npralA1nyyEoGC2a .cluster-label text{fill:#333;}#mermaid-svg-npralA1nyyEoGC2a .cluster-label span{color:#333;}#mermaid-svg-npralA1nyyEoGC2a .cluster-label span p{background-color:transparent;}#mermaid-svg-npralA1nyyEoGC2a .label text,#mermaid-svg-npralA1nyyEoGC2a span{fill:#333;color:#333;}#mermaid-svg-npralA1nyyEoGC2a .node rect,#mermaid-svg-npralA1nyyEoGC2a .node circle,#mermaid-svg-npralA1nyyEoGC2a .node ellipse,#mermaid-svg-npralA1nyyEoGC2a .node polygon,#mermaid-svg-npralA1nyyEoGC2a .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-npralA1nyyEoGC2a .rough-node .label text,#mermaid-svg-npralA1nyyEoGC2a .node .label text,#mermaid-svg-npralA1nyyEoGC2a .image-shape .label,#mermaid-svg-npralA1nyyEoGC2a .icon-shape .label{text-anchor:middle;}#mermaid-svg-npralA1nyyEoGC2a .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-npralA1nyyEoGC2a .rough-node .label,#mermaid-svg-npralA1nyyEoGC2a .node .label,#mermaid-svg-npralA1nyyEoGC2a .image-shape .label,#mermaid-svg-npralA1nyyEoGC2a .icon-shape .label{text-align:center;}#mermaid-svg-npralA1nyyEoGC2a .node.clickable{cursor:pointer;}#mermaid-svg-npralA1nyyEoGC2a .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-npralA1nyyEoGC2a .arrowheadPath{fill:#333333;}#mermaid-svg-npralA1nyyEoGC2a .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-npralA1nyyEoGC2a .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-npralA1nyyEoGC2a .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-npralA1nyyEoGC2a .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-npralA1nyyEoGC2a .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-npralA1nyyEoGC2a .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-npralA1nyyEoGC2a .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-npralA1nyyEoGC2a .cluster text{fill:#333;}#mermaid-svg-npralA1nyyEoGC2a .cluster span{color:#333;}#mermaid-svg-npralA1nyyEoGC2a 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-npralA1nyyEoGC2a .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-npralA1nyyEoGC2a rect.text{fill:none;stroke-width:0;}#mermaid-svg-npralA1nyyEoGC2a .icon-shape,#mermaid-svg-npralA1nyyEoGC2a .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-npralA1nyyEoGC2a .icon-shape p,#mermaid-svg-npralA1nyyEoGC2a .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-npralA1nyyEoGC2a .icon-shape .label rect,#mermaid-svg-npralA1nyyEoGC2a .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-npralA1nyyEoGC2a .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-npralA1nyyEoGC2a .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-npralA1nyyEoGC2a :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 扔掉旧的
换大桌子
建档案室
桌子的面积(上下文窗口)

= 128k tokens

约10万字
便利贴越贴越多
桌面贴满了
怎么办?
桌子能继续用

但旧事记不住了
换200k tokens的模型

更贵,更慢
✅ 旧事存起来

需要时再调出来

短期记忆(贴在桌上的便利贴)= 上下文窗口

长期记忆(档案室)= 外部存储

这就是为什么Agent需要记忆管理


5.2 两种记忆系统:短期和长期

跟人脑一样,Agent的记忆也得分成两套。
#mermaid-svg-y0DjCkf86zR1snK4{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-y0DjCkf86zR1snK4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-y0DjCkf86zR1snK4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-y0DjCkf86zR1snK4 .error-icon{fill:#552222;}#mermaid-svg-y0DjCkf86zR1snK4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-y0DjCkf86zR1snK4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-y0DjCkf86zR1snK4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-y0DjCkf86zR1snK4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-y0DjCkf86zR1snK4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-y0DjCkf86zR1snK4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-y0DjCkf86zR1snK4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-y0DjCkf86zR1snK4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-y0DjCkf86zR1snK4 .marker.cross{stroke:#333333;}#mermaid-svg-y0DjCkf86zR1snK4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-y0DjCkf86zR1snK4 p{margin:0;}#mermaid-svg-y0DjCkf86zR1snK4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-y0DjCkf86zR1snK4 .cluster-label text{fill:#333;}#mermaid-svg-y0DjCkf86zR1snK4 .cluster-label span{color:#333;}#mermaid-svg-y0DjCkf86zR1snK4 .cluster-label span p{background-color:transparent;}#mermaid-svg-y0DjCkf86zR1snK4 .label text,#mermaid-svg-y0DjCkf86zR1snK4 span{fill:#333;color:#333;}#mermaid-svg-y0DjCkf86zR1snK4 .node rect,#mermaid-svg-y0DjCkf86zR1snK4 .node circle,#mermaid-svg-y0DjCkf86zR1snK4 .node ellipse,#mermaid-svg-y0DjCkf86zR1snK4 .node polygon,#mermaid-svg-y0DjCkf86zR1snK4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-y0DjCkf86zR1snK4 .rough-node .label text,#mermaid-svg-y0DjCkf86zR1snK4 .node .label text,#mermaid-svg-y0DjCkf86zR1snK4 .image-shape .label,#mermaid-svg-y0DjCkf86zR1snK4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-y0DjCkf86zR1snK4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-y0DjCkf86zR1snK4 .rough-node .label,#mermaid-svg-y0DjCkf86zR1snK4 .node .label,#mermaid-svg-y0DjCkf86zR1snK4 .image-shape .label,#mermaid-svg-y0DjCkf86zR1snK4 .icon-shape .label{text-align:center;}#mermaid-svg-y0DjCkf86zR1snK4 .node.clickable{cursor:pointer;}#mermaid-svg-y0DjCkf86zR1snK4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-y0DjCkf86zR1snK4 .arrowheadPath{fill:#333333;}#mermaid-svg-y0DjCkf86zR1snK4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-y0DjCkf86zR1snK4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-y0DjCkf86zR1snK4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y0DjCkf86zR1snK4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-y0DjCkf86zR1snK4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y0DjCkf86zR1snK4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-y0DjCkf86zR1snK4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-y0DjCkf86zR1snK4 .cluster text{fill:#333;}#mermaid-svg-y0DjCkf86zR1snK4 .cluster span{color:#333;}#mermaid-svg-y0DjCkf86zR1snK4 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-y0DjCkf86zR1snK4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-y0DjCkf86zR1snK4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-y0DjCkf86zR1snK4 .icon-shape,#mermaid-svg-y0DjCkf86zR1snK4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y0DjCkf86zR1snK4 .icon-shape p,#mermaid-svg-y0DjCkf86zR1snK4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-y0DjCkf86zR1snK4 .icon-shape .label rect,#mermaid-svg-y0DjCkf86zR1snK4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y0DjCkf86zR1snK4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-y0DjCkf86zR1snK4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-y0DjCkf86zR1snK4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 长期记忆
短期记忆



当前对话历史

存在上下文窗口里
关键事实

用户姓名/偏好
历史对话摘要

很久以前聊的
文档知识

RAG检索
用户消息
需要查长期记忆?
模型回答

短期记忆:当前对话历史

最简单粗暴的短期记忆,就是把整段对话历史都塞进prompt里

python 复制代码
messages = [
    {"role": "system", "content": "你是一个友好的助手"},
    {"role": "user", "content": "你好"},
    {"role": "assistant", "content": "你好!有什么能帮你的?"},
    {"role": "user", "content": "我叫小明"},
    {"role": "assistant", "content": "你好小明!"},
    {"role": "user", "content": "今天天气怎么样?"}  # 当前问题
]

优点:简单,模型能看到完整对话。

缺点

  • 对话长了Token消耗爆炸
  • 模型对中间内容"视而不见"
  • 跨对话不持久(关掉就没了)

什么时候用:对话轮次少(<20轮)的简单场景。

长期记忆:3种实现方案

长期记忆就是把Agent"以前"知道的东西存起来,需要时再调出来。3种常见方案:

方案1:用文件存(最简单)

python 复制代码
import json
import os

MEMORY_FILE = "agent_memory.json"

def save_memory(key, value):
    """存一条记忆"""
    if os.path.exists(MEMORY_FILE):
        with open(MEMORY_FILE, "r", encoding="utf-8") as f:
            memory = json.load(f)
    else:
        memory = {}
    
    memory[key] = value
    with open(MEMORY_FILE, "w", encoding="utf-8") as f:
        json.dump(memory, f, ensure_ascii=False, indent=2)

def load_memory():
    """读所有记忆"""
    if os.path.exists(MEMORY_FILE):
        with open(MEMORY_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}

# 用法
save_memory("user_name", "小明")
save_memory("user_city", "济南")
save_memory("user_job", "程序员")

print(load_memory())
# {'user_name': '小明', 'user_city': '济南', 'user_job': '程序员'}

方案2:用数据库存(适合生产)

python 复制代码
import sqlite3

class MemoryDB:
    def __init__(self, db_path="memory.db"):
        self.conn = sqlite3.connect(db_path)
        self._create_table()
    
    def _create_table(self):
        self.conn.execute("""
            CREATE TABLE IF NOT EXISTS memories (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id TEXT,
                key TEXT,
                value TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        self.conn.commit()
    
    def save(self, user_id, key, value):
        self.conn.execute(
            "INSERT INTO memories (user_id, key, value) VALUES (?, ?, ?)",
            (user_id, key, value)
        )
        self.conn.commit()
    
    def get(self, user_id, key):
        cursor = self.conn.execute(
            "SELECT value FROM memories WHERE user_id=? AND key=? ORDER BY created_at DESC LIMIT 1",
            (user_id, key)
        )
        row = cursor.fetchone()
        return row[0] if row else None
    
    def get_all(self, user_id):
        cursor = self.conn.execute(
            "SELECT key, value FROM memories WHERE user_id=?",
            (user_id,)
        )
        return dict(cursor.fetchall())

# 用法
db = MemoryDB()
db.save("user_001", "姓名", "小明")
db.save("user_001", "城市", "济南")
print(db.get("user_001", "姓名"))  # 输出:小明
print(db.get_all("user_001"))     # 输出:{'姓名': '小明', '城市': '济南'}

方案3:用向量数据库(语义搜索)

前两种都只能"按key精确查找"。但如果用户问"我以前告诉过你我喜欢什么?"------你得按意思找,不是按key。

这时候就要向量数据库了。


5.3 向量数据库:让Agent"按意思"搜索

这节我们搞懂一个看起来高大上其实没那么玄的概念------向量数据库

先理解"向量"

你把一句话扔进一个叫"嵌入模型"(Embedding Model)的小模型,它会给你吐出来一组数字------这就是向量

python 复制代码
from openai import OpenAI

client = OpenAI(api_key="你的Key", base_url="https://api.deepseek.com")

# 把一段文本转成向量
response = client.embeddings.create(
    model="text-embedding-v3",  # Embedding专用模型
    input="我喜欢吃川菜,尤其是火锅"
)

vector = response.data[0].embedding
print(f"向量维度: {len(vector)}")  # 1536维
print(f"前5个数字: {vector[:5]}")  # [0.012, -0.034, 0.056, ...]

一段文字变成了一串数字。关键是:意思相近的文本,数字也相近。

比如:

  • "我喜欢吃川菜" → [0.1, 0.2, 0.3, ...]
  • "我爱吃麻辣火锅" → [0.11, 0.21, 0.31, ...] (很接近!)
  • "我不喜欢吃西餐" → [-0.1, -0.2, -0.3, ...] (方向相反)

这就是向量数据库的魔法------按"意思"搜索,而不是按"关键词"。
#mermaid-svg-nZePLxU89qfdJe9r{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-nZePLxU89qfdJe9r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nZePLxU89qfdJe9r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nZePLxU89qfdJe9r .error-icon{fill:#552222;}#mermaid-svg-nZePLxU89qfdJe9r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nZePLxU89qfdJe9r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nZePLxU89qfdJe9r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nZePLxU89qfdJe9r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nZePLxU89qfdJe9r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nZePLxU89qfdJe9r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nZePLxU89qfdJe9r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nZePLxU89qfdJe9r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nZePLxU89qfdJe9r .marker.cross{stroke:#333333;}#mermaid-svg-nZePLxU89qfdJe9r svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nZePLxU89qfdJe9r p{margin:0;}#mermaid-svg-nZePLxU89qfdJe9r .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-nZePLxU89qfdJe9r .cluster-label text{fill:#333;}#mermaid-svg-nZePLxU89qfdJe9r .cluster-label span{color:#333;}#mermaid-svg-nZePLxU89qfdJe9r .cluster-label span p{background-color:transparent;}#mermaid-svg-nZePLxU89qfdJe9r .label text,#mermaid-svg-nZePLxU89qfdJe9r span{fill:#333;color:#333;}#mermaid-svg-nZePLxU89qfdJe9r .node rect,#mermaid-svg-nZePLxU89qfdJe9r .node circle,#mermaid-svg-nZePLxU89qfdJe9r .node ellipse,#mermaid-svg-nZePLxU89qfdJe9r .node polygon,#mermaid-svg-nZePLxU89qfdJe9r .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nZePLxU89qfdJe9r .rough-node .label text,#mermaid-svg-nZePLxU89qfdJe9r .node .label text,#mermaid-svg-nZePLxU89qfdJe9r .image-shape .label,#mermaid-svg-nZePLxU89qfdJe9r .icon-shape .label{text-anchor:middle;}#mermaid-svg-nZePLxU89qfdJe9r .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-nZePLxU89qfdJe9r .rough-node .label,#mermaid-svg-nZePLxU89qfdJe9r .node .label,#mermaid-svg-nZePLxU89qfdJe9r .image-shape .label,#mermaid-svg-nZePLxU89qfdJe9r .icon-shape .label{text-align:center;}#mermaid-svg-nZePLxU89qfdJe9r .node.clickable{cursor:pointer;}#mermaid-svg-nZePLxU89qfdJe9r .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-nZePLxU89qfdJe9r .arrowheadPath{fill:#333333;}#mermaid-svg-nZePLxU89qfdJe9r .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nZePLxU89qfdJe9r .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nZePLxU89qfdJe9r .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nZePLxU89qfdJe9r .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-nZePLxU89qfdJe9r .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nZePLxU89qfdJe9r .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-nZePLxU89qfdJe9r .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nZePLxU89qfdJe9r .cluster text{fill:#333;}#mermaid-svg-nZePLxU89qfdJe9r .cluster span{color:#333;}#mermaid-svg-nZePLxU89qfdJe9r 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-nZePLxU89qfdJe9r .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-nZePLxU89qfdJe9r rect.text{fill:none;stroke-width:0;}#mermaid-svg-nZePLxU89qfdJe9r .icon-shape,#mermaid-svg-nZePLxU89qfdJe9r .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nZePLxU89qfdJe9r .icon-shape p,#mermaid-svg-nZePLxU89qfdJe9r .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-nZePLxU89qfdJe9r .icon-shape .label rect,#mermaid-svg-nZePLxU89qfdJe9r .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nZePLxU89qfdJe9r .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-nZePLxU89qfdJe9r .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-nZePLxU89qfdJe9r :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Embed
Embed
Embed
距离近 ✅
距离远 ❌
'我喜欢吃川菜'
向量 1
'我爱吃麻辣火锅'
向量 2
'今天天气真好'
向量 3

ChromaDB:新手最友好的向量数据库

向量数据库有很多(Chroma、Milvus、Pinecone、Qdrant)。对新手来说,Chroma最友好------5分钟上手。

bash 复制代码
# 安装
pip install chromadb
python 复制代码
import chromadb

# ===== 1. 初始化 =====
client = chromadb.PersistentClient(path="./chroma_db")  # 数据存到本地
collection = client.get_or_create_collection(name="user_memories")

# ===== 2. 存记忆 =====
# Chroma会自动把文本转成向量(用默认的Embedding模型)
collection.add(
    documents=[
        "用户姓名是小明",
        "用户住在济南",
        "用户是程序员",
        "用户喜欢吃川菜"
    ],
    ids=["mem1", "mem2", "mem3", "mem4"]  # 每条记忆的唯一ID
)

# ===== 3. 查记忆(按意思)=====
results = collection.query(
    query_texts=["你还记得我家在哪吗?"],  # 用自然语言查
    n_results=2  # 返回最相关的2条
)

print("查到的记忆:")
for doc in results["documents"][0]:
    print(f"  - {doc}")
# 输出:
#   - 用户住在济南
#   - 用户姓名是小明

看到没? 你问"我家在哪",系统自动找到了"用户住在济南"------因为意思相近,不需要关键词匹配

完整实战:给Agent加上"记仇"功能

我们把上面这些拼起来,做一个完整的Agent------它能记住用户的偏好和重要信息。

python 复制代码
import chromadb
from openai import OpenAI
from datetime import datetime

class MemoryAgent:
    def __init__(self):
        # LLM客户端
        self.llm = OpenAI(
            api_key="你的Key",
            base_url="https://api.deepseek.com"
        )
        
        # 向量数据库(长期记忆)
        self.chroma = chromadb.PersistentClient(path="./agent_memory")
        self.memory = self.chroma.get_or_create_collection(name="memories")
        
        # 短期记忆(当前对话)
        self.short_term = []
    
    def memorize(self, content: str, importance: int = 5):
        """主动记忆:把信息存进长期记忆"""
        memory_id = f"mem_{datetime.now().timestamp()}"
        self.memory.add(
            documents=[f"[重要性:{importance}] {content}"],
            ids=[memory_id]
        )
        print(f"💾 已记住: {content}")
    
    def recall(self, query: str, top_k: int = 3) -> str:
        """主动回忆:从长期记忆里找相关的信息"""
        results = self.memory.query(
            query_texts=[query],
            n_results=top_k
        )
        
        if not results["documents"][0]:
            return "(没有相关记忆)"
        
        memories = "\n".join([f"- {doc}" for doc in results["documents"][0]])
        return memories
    
    def chat(self, user_input: str) -> str:
        """主对话流程"""
        # 1. 从长期记忆里找相关信息
        relevant_memories = self.recall(user_input)
        
        # 2. 构建prompt(带记忆的)
        system_prompt = f"""你是一个贴心的助手。你记得用户的以下信息:

{relevant_memories}

请基于这些信息回答用户。如果用户告诉了新的重要信息,请在回答末尾用[MEMORY:内容]标注。"""
        
        # 3. 调用模型
        self.short_term.append({"role": "user", "content": user_input})
        messages = [{"role": "system", "content": system_prompt}] + self.short_term
        
        response = self.llm.chat.completions.create(
            model="deepseek-chat",
            messages=messages
        )
        reply = response.choices[0].message.content
        
        # 4. 把模型回复加入短期记忆
        self.short_term.append({"role": "assistant", "content": reply})
        
        # 5. 检查是否有需要长期记忆的内容
        if "[MEMORY:" in reply:
            # 提取[MEMORY:xxx]中的内容
            import re
            mem_content = re.search(r'\[MEMORY:(.*?)\]', reply).group(1)
            self.memorize(mem_content)
            # 把标记去掉再给用户看
            reply = re.sub(r'\[MEMORY:.*?\]', '', reply).strip()
        
        return reply


# ===== 使用示例 =====
if __name__ == "__main__":
    agent = MemoryAgent()
    
    # 第1轮对话
    print("\n👤: 我叫小明,在济南工作")
    print(f"🤖: {agent.chat('我叫小明,在济南工作')}")
    
    # 第2轮
    print("\n👤: 我喜欢吃川菜,尤其是火锅")
    print(f"🤖: {agent.chat('我喜欢吃川菜,尤其是火锅')}")
    
    # 第3轮
    print("\n👤: 今天心情不太好")
    print(f"🤖: {agent.chat('今天心情不太好')}")
    
    # 第4轮------测一下它还记不记得
    print("\n👤: 你还记得我是干什么工作的吗?")
    print(f"🤖: {agent.chat('你还记得我是干什么工作的吗?')}")
    
    # 第5轮
    print("\n👤: 我家在哪?")
    print(f"🤖: {agent.chat('我家在哪?')}")

跑一下你就会发现------Agent真的"记住"了! 哪怕对话过了很多轮,它也能从长期记忆里把关键信息调出来。

这就是向量数据库+短期记忆的协作威力。


5.4 MemGPT论文:把"虚拟内存"搬进LLM

如果上面的方案是"小修小补",那MemGPT这论文就是"大刀阔斧"------它重新设计了Agent的记忆架构。

一句话讲清MemGPT

把LLM当成操作系统,用"主存+外存"的方式管理记忆,让LLM自己决定什么时候换页。

这是UC Berkeley 2023年发的论文,作者是大名鼎鼎的Joseph Gonzalez和Ion Stoica(这俩人是Spark和Ray的核心人物)。

核心思想:LLM = 操作系统

你可能没意识到:你电脑的内存管理,和LLM的记忆管理,原理上是一样的。
#mermaid-svg-1G05ohF4zM5jWr0d{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-1G05ohF4zM5jWr0d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1G05ohF4zM5jWr0d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1G05ohF4zM5jWr0d .error-icon{fill:#552222;}#mermaid-svg-1G05ohF4zM5jWr0d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1G05ohF4zM5jWr0d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1G05ohF4zM5jWr0d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1G05ohF4zM5jWr0d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1G05ohF4zM5jWr0d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1G05ohF4zM5jWr0d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1G05ohF4zM5jWr0d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1G05ohF4zM5jWr0d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1G05ohF4zM5jWr0d .marker.cross{stroke:#333333;}#mermaid-svg-1G05ohF4zM5jWr0d svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1G05ohF4zM5jWr0d p{margin:0;}#mermaid-svg-1G05ohF4zM5jWr0d .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1G05ohF4zM5jWr0d .cluster-label text{fill:#333;}#mermaid-svg-1G05ohF4zM5jWr0d .cluster-label span{color:#333;}#mermaid-svg-1G05ohF4zM5jWr0d .cluster-label span p{background-color:transparent;}#mermaid-svg-1G05ohF4zM5jWr0d .label text,#mermaid-svg-1G05ohF4zM5jWr0d span{fill:#333;color:#333;}#mermaid-svg-1G05ohF4zM5jWr0d .node rect,#mermaid-svg-1G05ohF4zM5jWr0d .node circle,#mermaid-svg-1G05ohF4zM5jWr0d .node ellipse,#mermaid-svg-1G05ohF4zM5jWr0d .node polygon,#mermaid-svg-1G05ohF4zM5jWr0d .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1G05ohF4zM5jWr0d .rough-node .label text,#mermaid-svg-1G05ohF4zM5jWr0d .node .label text,#mermaid-svg-1G05ohF4zM5jWr0d .image-shape .label,#mermaid-svg-1G05ohF4zM5jWr0d .icon-shape .label{text-anchor:middle;}#mermaid-svg-1G05ohF4zM5jWr0d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1G05ohF4zM5jWr0d .rough-node .label,#mermaid-svg-1G05ohF4zM5jWr0d .node .label,#mermaid-svg-1G05ohF4zM5jWr0d .image-shape .label,#mermaid-svg-1G05ohF4zM5jWr0d .icon-shape .label{text-align:center;}#mermaid-svg-1G05ohF4zM5jWr0d .node.clickable{cursor:pointer;}#mermaid-svg-1G05ohF4zM5jWr0d .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1G05ohF4zM5jWr0d .arrowheadPath{fill:#333333;}#mermaid-svg-1G05ohF4zM5jWr0d .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1G05ohF4zM5jWr0d .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1G05ohF4zM5jWr0d .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1G05ohF4zM5jWr0d .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1G05ohF4zM5jWr0d .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1G05ohF4zM5jWr0d .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1G05ohF4zM5jWr0d .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1G05ohF4zM5jWr0d .cluster text{fill:#333;}#mermaid-svg-1G05ohF4zM5jWr0d .cluster span{color:#333;}#mermaid-svg-1G05ohF4zM5jWr0d 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-1G05ohF4zM5jWr0d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1G05ohF4zM5jWr0d rect.text{fill:none;stroke-width:0;}#mermaid-svg-1G05ohF4zM5jWr0d .icon-shape,#mermaid-svg-1G05ohF4zM5jWr0d .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1G05ohF4zM5jWr0d .icon-shape p,#mermaid-svg-1G05ohF4zM5jWr0d .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1G05ohF4zM5jWr0d .icon-shape .label rect,#mermaid-svg-1G05ohF4zM5jWr0d .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1G05ohF4zM5jWr0d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1G05ohF4zM5jWr0d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1G05ohF4zM5jWr0d :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} LLM的记忆
需要时调入
主上下文(快、小、贵)
外部存储(慢、大、便宜)
LLM自己决定

什么时候换页
电脑的内存
需要时调入
RAM(快、小、贵)
Disk(慢、大、便宜)
操作系统决定

什么时候换页

MemGPT的核心洞见就是:把这套机制照搬到LLM上。

  • RAM → 主上下文(Main Context):能装下系统指令、工作上下文、当前对话
  • Disk → 外部上下文(External Context):更大的存储,LLM需要时主动调用函数加载

MemGPT的三层记忆

MemGPT把记忆分成了三层,层层递进:

层级 比喻 大小 访问方式
主上下文 工作台 128k tokens 模型直接"看到"
召回存储 桌面抽屉 几百MB 关键词搜索
归档存储 档案室 几十GB 向量搜索

#mermaid-svg-LyL7KUyYVT2MIthH{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-LyL7KUyYVT2MIthH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LyL7KUyYVT2MIthH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LyL7KUyYVT2MIthH .error-icon{fill:#552222;}#mermaid-svg-LyL7KUyYVT2MIthH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LyL7KUyYVT2MIthH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LyL7KUyYVT2MIthH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LyL7KUyYVT2MIthH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LyL7KUyYVT2MIthH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LyL7KUyYVT2MIthH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LyL7KUyYVT2MIthH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LyL7KUyYVT2MIthH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LyL7KUyYVT2MIthH .marker.cross{stroke:#333333;}#mermaid-svg-LyL7KUyYVT2MIthH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LyL7KUyYVT2MIthH p{margin:0;}#mermaid-svg-LyL7KUyYVT2MIthH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LyL7KUyYVT2MIthH .cluster-label text{fill:#333;}#mermaid-svg-LyL7KUyYVT2MIthH .cluster-label span{color:#333;}#mermaid-svg-LyL7KUyYVT2MIthH .cluster-label span p{background-color:transparent;}#mermaid-svg-LyL7KUyYVT2MIthH .label text,#mermaid-svg-LyL7KUyYVT2MIthH span{fill:#333;color:#333;}#mermaid-svg-LyL7KUyYVT2MIthH .node rect,#mermaid-svg-LyL7KUyYVT2MIthH .node circle,#mermaid-svg-LyL7KUyYVT2MIthH .node ellipse,#mermaid-svg-LyL7KUyYVT2MIthH .node polygon,#mermaid-svg-LyL7KUyYVT2MIthH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LyL7KUyYVT2MIthH .rough-node .label text,#mermaid-svg-LyL7KUyYVT2MIthH .node .label text,#mermaid-svg-LyL7KUyYVT2MIthH .image-shape .label,#mermaid-svg-LyL7KUyYVT2MIthH .icon-shape .label{text-anchor:middle;}#mermaid-svg-LyL7KUyYVT2MIthH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LyL7KUyYVT2MIthH .rough-node .label,#mermaid-svg-LyL7KUyYVT2MIthH .node .label,#mermaid-svg-LyL7KUyYVT2MIthH .image-shape .label,#mermaid-svg-LyL7KUyYVT2MIthH .icon-shape .label{text-align:center;}#mermaid-svg-LyL7KUyYVT2MIthH .node.clickable{cursor:pointer;}#mermaid-svg-LyL7KUyYVT2MIthH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LyL7KUyYVT2MIthH .arrowheadPath{fill:#333333;}#mermaid-svg-LyL7KUyYVT2MIthH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LyL7KUyYVT2MIthH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LyL7KUyYVT2MIthH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LyL7KUyYVT2MIthH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LyL7KUyYVT2MIthH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LyL7KUyYVT2MIthH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LyL7KUyYVT2MIthH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LyL7KUyYVT2MIthH .cluster text{fill:#333;}#mermaid-svg-LyL7KUyYVT2MIthH .cluster span{color:#333;}#mermaid-svg-LyL7KUyYVT2MIthH 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-LyL7KUyYVT2MIthH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LyL7KUyYVT2MIthH rect.text{fill:none;stroke-width:0;}#mermaid-svg-LyL7KUyYVT2MIthH .icon-shape,#mermaid-svg-LyL7KUyYVT2MIthH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LyL7KUyYVT2MIthH .icon-shape p,#mermaid-svg-LyL7KUyYVT2MIthH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LyL7KUyYVT2MIthH .icon-shape .label rect,#mermaid-svg-LyL7KUyYVT2MIthH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LyL7KUyYVT2MIthH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LyL7KUyYVT2MIthH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LyL7KUyYVT2MIthH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} retrieve()
向量搜索
满了
🤖 LLM

(看得到主上下文)
📋 主上下文

128k tokens

系统指令 + 当前对话 + 关键事实
📁 召回存储

全部历史消息

关键词搜索
🗄️ 归档存储

向量数据库

语义搜索
⚠️ 触发摘要

递归压缩旧对话

三个核心函数:retrieve / insert / update

LLM通过调用三个函数来管理自己的记忆:

python 复制代码
# 1. retrieve:从档案室找资料
memory.retrieve(query="用户上次说想吃什么?")

# 2. insert:把新信息存进档案室
memory.insert(content="用户喜欢川菜,尤其是火锅")

# 3. update:更新已有记录
memory.update(memory_id="mem_123", new_content="用户现在不爱吃川菜了")

关键来了:这三个函数不是开发者调的,是LLM自己调的。

MemGPT的设计哲学是:让LLM自己决定什么时候调什么函数。 不需要写死规则。

MemGPT的实战效果

论文里有个实验特别有意思:把"嵌套K-V查找"的任务------也就是多跳记忆检索。

比如:

  • 文档1:"Alice在巴黎"
  • 文档2:"巴黎的法语是Paris"
  • 文档3:"Paris的市长是Jean"

问"Alice所在城市的市长的名字",需要先查文档1,再查文档2,再查文档3。
#mermaid-svg-AcqdC65eICXSPx8h{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-AcqdC65eICXSPx8h .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AcqdC65eICXSPx8h .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AcqdC65eICXSPx8h .error-icon{fill:#552222;}#mermaid-svg-AcqdC65eICXSPx8h .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AcqdC65eICXSPx8h .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AcqdC65eICXSPx8h .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AcqdC65eICXSPx8h .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AcqdC65eICXSPx8h .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AcqdC65eICXSPx8h .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AcqdC65eICXSPx8h .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AcqdC65eICXSPx8h .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AcqdC65eICXSPx8h .marker.cross{stroke:#333333;}#mermaid-svg-AcqdC65eICXSPx8h svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AcqdC65eICXSPx8h p{margin:0;}#mermaid-svg-AcqdC65eICXSPx8h .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-AcqdC65eICXSPx8h .cluster-label text{fill:#333;}#mermaid-svg-AcqdC65eICXSPx8h .cluster-label span{color:#333;}#mermaid-svg-AcqdC65eICXSPx8h .cluster-label span p{background-color:transparent;}#mermaid-svg-AcqdC65eICXSPx8h .label text,#mermaid-svg-AcqdC65eICXSPx8h span{fill:#333;color:#333;}#mermaid-svg-AcqdC65eICXSPx8h .node rect,#mermaid-svg-AcqdC65eICXSPx8h .node circle,#mermaid-svg-AcqdC65eICXSPx8h .node ellipse,#mermaid-svg-AcqdC65eICXSPx8h .node polygon,#mermaid-svg-AcqdC65eICXSPx8h .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AcqdC65eICXSPx8h .rough-node .label text,#mermaid-svg-AcqdC65eICXSPx8h .node .label text,#mermaid-svg-AcqdC65eICXSPx8h .image-shape .label,#mermaid-svg-AcqdC65eICXSPx8h .icon-shape .label{text-anchor:middle;}#mermaid-svg-AcqdC65eICXSPx8h .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AcqdC65eICXSPx8h .rough-node .label,#mermaid-svg-AcqdC65eICXSPx8h .node .label,#mermaid-svg-AcqdC65eICXSPx8h .image-shape .label,#mermaid-svg-AcqdC65eICXSPx8h .icon-shape .label{text-align:center;}#mermaid-svg-AcqdC65eICXSPx8h .node.clickable{cursor:pointer;}#mermaid-svg-AcqdC65eICXSPx8h .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AcqdC65eICXSPx8h .arrowheadPath{fill:#333333;}#mermaid-svg-AcqdC65eICXSPx8h .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AcqdC65eICXSPx8h .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AcqdC65eICXSPx8h .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AcqdC65eICXSPx8h .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AcqdC65eICXSPx8h .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AcqdC65eICXSPx8h .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AcqdC65eICXSPx8h .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AcqdC65eICXSPx8h .cluster text{fill:#333;}#mermaid-svg-AcqdC65eICXSPx8h .cluster span{color:#333;}#mermaid-svg-AcqdC65eICXSPx8h 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-AcqdC65eICXSPx8h .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AcqdC65eICXSPx8h rect.text{fill:none;stroke-width:0;}#mermaid-svg-AcqdC65eICXSPx8h .icon-shape,#mermaid-svg-AcqdC65eICXSPx8h .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AcqdC65eICXSPx8h .icon-shape p,#mermaid-svg-AcqdC65eICXSPx8h .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AcqdC65eICXSPx8h .icon-shape .label rect,#mermaid-svg-AcqdC65eICXSPx8h .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AcqdC65eICXSPx8h .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AcqdC65eICXSPx8h .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AcqdC65eICXSPx8h :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 文档1
文档2
文档3
Alice在哪?
巴黎
Paris
Jean

传统LLM(不管理记忆)的准确率:

模型 1层查找 2层查找 3层查找
GPT-3.5 70% 35% 5%
GPT-4 75% 40% 10%
GPT-4 Turbo 80% 50% 15%

加了MemGPT之后:

模型 1层查找 2层查找 3层查找
GPT-3.5 + MemGPT 85% 70% 50%
GPT-4 + MemGPT 95% 92% 88%

天差地别。 在多跳查找任务上,MemGPT把GPT-4从15%拉到了88%。

一句话总结MemGPT

不要让LLM的"脑子"装所有东西。让它学会"翻本子"。

MemGPT后来演变成了开源项目Letta(GitHub 30k+⭐),专门做"有状态的LLM Agent"。

对普通开发者的启示

虽然MemGPT的设计很精妙,但对普通Agent开发 来说,80%的场景用短期记忆+向量数据库就够了。MemGPT是处理超长对话、复杂文档分析时才需要。
#mermaid-svg-FKEzixE3Zx3rB2Pe{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-FKEzixE3Zx3rB2Pe .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FKEzixE3Zx3rB2Pe .error-icon{fill:#552222;}#mermaid-svg-FKEzixE3Zx3rB2Pe .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FKEzixE3Zx3rB2Pe .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .marker.cross{stroke:#333333;}#mermaid-svg-FKEzixE3Zx3rB2Pe svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FKEzixE3Zx3rB2Pe p{margin:0;}#mermaid-svg-FKEzixE3Zx3rB2Pe .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .cluster-label text{fill:#333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .cluster-label span{color:#333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .cluster-label span p{background-color:transparent;}#mermaid-svg-FKEzixE3Zx3rB2Pe .label text,#mermaid-svg-FKEzixE3Zx3rB2Pe span{fill:#333;color:#333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .node rect,#mermaid-svg-FKEzixE3Zx3rB2Pe .node circle,#mermaid-svg-FKEzixE3Zx3rB2Pe .node ellipse,#mermaid-svg-FKEzixE3Zx3rB2Pe .node polygon,#mermaid-svg-FKEzixE3Zx3rB2Pe .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FKEzixE3Zx3rB2Pe .rough-node .label text,#mermaid-svg-FKEzixE3Zx3rB2Pe .node .label text,#mermaid-svg-FKEzixE3Zx3rB2Pe .image-shape .label,#mermaid-svg-FKEzixE3Zx3rB2Pe .icon-shape .label{text-anchor:middle;}#mermaid-svg-FKEzixE3Zx3rB2Pe .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FKEzixE3Zx3rB2Pe .rough-node .label,#mermaid-svg-FKEzixE3Zx3rB2Pe .node .label,#mermaid-svg-FKEzixE3Zx3rB2Pe .image-shape .label,#mermaid-svg-FKEzixE3Zx3rB2Pe .icon-shape .label{text-align:center;}#mermaid-svg-FKEzixE3Zx3rB2Pe .node.clickable{cursor:pointer;}#mermaid-svg-FKEzixE3Zx3rB2Pe .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .arrowheadPath{fill:#333333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FKEzixE3Zx3rB2Pe .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FKEzixE3Zx3rB2Pe .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FKEzixE3Zx3rB2Pe .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FKEzixE3Zx3rB2Pe .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FKEzixE3Zx3rB2Pe .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FKEzixE3Zx3rB2Pe .cluster text{fill:#333;}#mermaid-svg-FKEzixE3Zx3rB2Pe .cluster span{color:#333;}#mermaid-svg-FKEzixE3Zx3rB2Pe 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-FKEzixE3Zx3rB2Pe .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FKEzixE3Zx3rB2Pe rect.text{fill:none;stroke-width:0;}#mermaid-svg-FKEzixE3Zx3rB2Pe .icon-shape,#mermaid-svg-FKEzixE3Zx3rB2Pe .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FKEzixE3Zx3rB2Pe .icon-shape p,#mermaid-svg-FKEzixE3Zx3rB2Pe .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FKEzixE3Zx3rB2Pe .icon-shape .label rect,#mermaid-svg-FKEzixE3Zx3rB2Pe .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FKEzixE3Zx3rB2Pe .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FKEzixE3Zx3rB2Pe .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FKEzixE3Zx3rB2Pe :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 对话短(<20轮)

文档少
对话中等

需要查文档
对话超长

多跳记忆检索
企业级文档分析
你的场景?
✅ 短期记忆

塞进prompt就行
✅ 短期+向量库

ChromaDB够用
✅ MemGPT/Letta

用框架
✅ MemGPT+自定义

生产环境


5.5 Generative Agents:25个AI在虚拟小镇生活

如果说MemGPT是"系统级"的方案,那Generative Agents就是"应用级"的奇迹。

论文做了什么?

2023年,斯坦福和Google的研究者搞了个虚拟小镇Smallville,放了25个AI居民。每个AI都有自己的人设、记忆、社交关系。
#mermaid-svg-Yy5Rtf2Dwnmx2gNz{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-Yy5Rtf2Dwnmx2gNz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .error-icon{fill:#552222;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .marker.cross{stroke:#333333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz p{margin:0;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .cluster-label text{fill:#333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .cluster-label span{color:#333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .cluster-label span p{background-color:transparent;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .label text,#mermaid-svg-Yy5Rtf2Dwnmx2gNz span{fill:#333;color:#333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node rect,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node circle,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node ellipse,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node polygon,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .rough-node .label text,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node .label text,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .image-shape .label,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .icon-shape .label{text-anchor:middle;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .rough-node .label,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node .label,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .image-shape .label,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .icon-shape .label{text-align:center;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node.clickable{cursor:pointer;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .arrowheadPath{fill:#333333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .cluster text{fill:#333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .cluster span{color:#333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz 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-Yy5Rtf2Dwnmx2gNz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz rect.text{fill:none;stroke-width:0;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .icon-shape,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .icon-shape p,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .icon-shape .label rect,#mermaid-svg-Yy5Rtf2Dwnmx2gNz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Yy5Rtf2Dwnmx2gNz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 有生意往来
是朋友
有共同爱好
🏘️ Smallville 虚拟小镇
👨 25个AI居民
👤 Isabella

咖啡店老板
👤 Tom

作家
👤 Mary

画家
...
👤 John

最后一个居民

最神奇的是:这些AI能自主组织活动。比如情人节那天,几个AI自发决定办一个情人节派对------这个行为不是人写的,是AI自己涌现出来的。

研究者只是给了25个AI基本人设,它们就自己发展出了社交网络、传播八卦、结成同盟。

三大核心机制

Generative Agents成功的关键,是它设计了三个互相配合的机制
#mermaid-svg-WjxKApmh8Qs6zh9x{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-WjxKApmh8Qs6zh9x .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WjxKApmh8Qs6zh9x .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WjxKApmh8Qs6zh9x .error-icon{fill:#552222;}#mermaid-svg-WjxKApmh8Qs6zh9x .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WjxKApmh8Qs6zh9x .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WjxKApmh8Qs6zh9x .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WjxKApmh8Qs6zh9x .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WjxKApmh8Qs6zh9x .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WjxKApmh8Qs6zh9x .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WjxKApmh8Qs6zh9x .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WjxKApmh8Qs6zh9x .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WjxKApmh8Qs6zh9x .marker.cross{stroke:#333333;}#mermaid-svg-WjxKApmh8Qs6zh9x svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WjxKApmh8Qs6zh9x p{margin:0;}#mermaid-svg-WjxKApmh8Qs6zh9x .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-WjxKApmh8Qs6zh9x .cluster-label text{fill:#333;}#mermaid-svg-WjxKApmh8Qs6zh9x .cluster-label span{color:#333;}#mermaid-svg-WjxKApmh8Qs6zh9x .cluster-label span p{background-color:transparent;}#mermaid-svg-WjxKApmh8Qs6zh9x .label text,#mermaid-svg-WjxKApmh8Qs6zh9x span{fill:#333;color:#333;}#mermaid-svg-WjxKApmh8Qs6zh9x .node rect,#mermaid-svg-WjxKApmh8Qs6zh9x .node circle,#mermaid-svg-WjxKApmh8Qs6zh9x .node ellipse,#mermaid-svg-WjxKApmh8Qs6zh9x .node polygon,#mermaid-svg-WjxKApmh8Qs6zh9x .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WjxKApmh8Qs6zh9x .rough-node .label text,#mermaid-svg-WjxKApmh8Qs6zh9x .node .label text,#mermaid-svg-WjxKApmh8Qs6zh9x .image-shape .label,#mermaid-svg-WjxKApmh8Qs6zh9x .icon-shape .label{text-anchor:middle;}#mermaid-svg-WjxKApmh8Qs6zh9x .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WjxKApmh8Qs6zh9x .rough-node .label,#mermaid-svg-WjxKApmh8Qs6zh9x .node .label,#mermaid-svg-WjxKApmh8Qs6zh9x .image-shape .label,#mermaid-svg-WjxKApmh8Qs6zh9x .icon-shape .label{text-align:center;}#mermaid-svg-WjxKApmh8Qs6zh9x .node.clickable{cursor:pointer;}#mermaid-svg-WjxKApmh8Qs6zh9x .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WjxKApmh8Qs6zh9x .arrowheadPath{fill:#333333;}#mermaid-svg-WjxKApmh8Qs6zh9x .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WjxKApmh8Qs6zh9x .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WjxKApmh8Qs6zh9x .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WjxKApmh8Qs6zh9x .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WjxKApmh8Qs6zh9x .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WjxKApmh8Qs6zh9x .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WjxKApmh8Qs6zh9x .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WjxKApmh8Qs6zh9x .cluster text{fill:#333;}#mermaid-svg-WjxKApmh8Qs6zh9x .cluster span{color:#333;}#mermaid-svg-WjxKApmh8Qs6zh9x 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-WjxKApmh8Qs6zh9x .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WjxKApmh8Qs6zh9x rect.text{fill:none;stroke-width:0;}#mermaid-svg-WjxKApmh8Qs6zh9x .icon-shape,#mermaid-svg-WjxKApmh8Qs6zh9x .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WjxKApmh8Qs6zh9x .icon-shape p,#mermaid-svg-WjxKApmh8Qs6zh9x .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WjxKApmh8Qs6zh9x .icon-shape .label rect,#mermaid-svg-WjxKApmh8Qs6zh9x .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WjxKApmh8Qs6zh9x .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WjxKApmh8Qs6zh9x .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WjxKApmh8Qs6zh9x :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 👀 Memory Stream

记忆流
🤔 Reflection

反思
📋 Planning

规划
🎬 Action

行动

机制1:记忆流(Memory Stream)

每个AI都有个"小本本",按时间顺序记下看到、听到、做过的事。

python 复制代码
class MemoryStream:
    def __init__(self):
        self.memories = []  # 所有记忆
    
    def add_observation(self, content, importance_score):
        """加一条新记忆(带重要性打分)"""
        self.memories.append({
            "time": current_time(),
            "content": content,
            "importance": importance_score,  # 0-10分
            "type": "observation"
        })
    
    def retrieve(self, query, top_k=10):
        """检索时综合考虑:相关性 + 重要性 + 时间新鲜度"""
        scored = []
        for mem in self.memories:
            relevance = compute_relevance(query, mem["content"])
            recency = time_decay(mem["time"])
            score = relevance + mem["importance"]/10 + recency
            scored.append((score, mem))
        scored.sort(reverse=True)
        return [m for _, m in scored[:top_k]]

关键创新 :检索时不是只看相关性,而是相关性 × 重要性 × 新鲜度的综合分数。

这意味着:

  • 跟当前问题相关的(语义近)
  • 重要性高的(重要的事)
  • 最近发生的(新鲜的)

这三个维度综合起来,决定哪些记忆被调出来。

机制2:反思(Reflection)

光记流水账不够,AI还得有自己的"想法"

当记忆积累到一定数量(论文里是100+条),LLM会主动总结:

python 复制代码
class Reflection:
    def generate(self, recent_memories):
        prompt = f"""
        基于以下最近的{len(recent_memories)}条重要记忆,
        总结出几条高级洞察(用问题和答案的形式):
        
        {recent_memories}
        
        输出3条反思:
        - 问题1:...
          答案1:...
        - 问题2:...
          答案2:...
        """
        reflections = llm_generate(prompt)
        
        # 反思本身就是一条记忆
        for reflection in reflections:
            memory_stream.add(reflection, importance=9)

举个例子

  • 流水账:"早上起床了","和Bob吵架了","吃了个三明治"
  • 反思:"我最近和Bob的关系变差了,可能因为上次项目的事"

反思是带"洞察"的------它把一堆散乱的事提炼成了一句"我学到了什么"。

机制3:规划(Planning)

有了记忆和反思,AI就能规划自己的行动。

python 复制代码
class Planning:
    def make_plan(self, agent, current_time):
        # 1. 收集上下文:相关记忆 + 当前反思
        context = memory_stream.retrieve("今天要做什么")
        context += [r["content"] for r in reflection.reflections]
        
        # 2. 让LLM生成分层计划
        prompt = f"""
        你是{agent.name}。
        你最近的记忆和反思:{context}
        当前时间:{current_time}
        
        生成今日计划:
        - 总体目标
        - 上午计划
        - 下午计划
        - 晚上计划
        """
        plan = llm_generate(prompt)

关键创新:递归规划。不是"我要做X",而是"我要做X,因为X,所以X"------一棵规划树。

三大机制怎么配合?

记忆流是数据库,反思是自我意识,规划是执行力。
#mermaid-svg-LdxzGy9H1aKzDcnp{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-LdxzGy9H1aKzDcnp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LdxzGy9H1aKzDcnp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LdxzGy9H1aKzDcnp .error-icon{fill:#552222;}#mermaid-svg-LdxzGy9H1aKzDcnp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LdxzGy9H1aKzDcnp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LdxzGy9H1aKzDcnp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LdxzGy9H1aKzDcnp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LdxzGy9H1aKzDcnp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LdxzGy9H1aKzDcnp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LdxzGy9H1aKzDcnp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LdxzGy9H1aKzDcnp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LdxzGy9H1aKzDcnp .marker.cross{stroke:#333333;}#mermaid-svg-LdxzGy9H1aKzDcnp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LdxzGy9H1aKzDcnp p{margin:0;}#mermaid-svg-LdxzGy9H1aKzDcnp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LdxzGy9H1aKzDcnp .cluster-label text{fill:#333;}#mermaid-svg-LdxzGy9H1aKzDcnp .cluster-label span{color:#333;}#mermaid-svg-LdxzGy9H1aKzDcnp .cluster-label span p{background-color:transparent;}#mermaid-svg-LdxzGy9H1aKzDcnp .label text,#mermaid-svg-LdxzGy9H1aKzDcnp span{fill:#333;color:#333;}#mermaid-svg-LdxzGy9H1aKzDcnp .node rect,#mermaid-svg-LdxzGy9H1aKzDcnp .node circle,#mermaid-svg-LdxzGy9H1aKzDcnp .node ellipse,#mermaid-svg-LdxzGy9H1aKzDcnp .node polygon,#mermaid-svg-LdxzGy9H1aKzDcnp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LdxzGy9H1aKzDcnp .rough-node .label text,#mermaid-svg-LdxzGy9H1aKzDcnp .node .label text,#mermaid-svg-LdxzGy9H1aKzDcnp .image-shape .label,#mermaid-svg-LdxzGy9H1aKzDcnp .icon-shape .label{text-anchor:middle;}#mermaid-svg-LdxzGy9H1aKzDcnp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LdxzGy9H1aKzDcnp .rough-node .label,#mermaid-svg-LdxzGy9H1aKzDcnp .node .label,#mermaid-svg-LdxzGy9H1aKzDcnp .image-shape .label,#mermaid-svg-LdxzGy9H1aKzDcnp .icon-shape .label{text-align:center;}#mermaid-svg-LdxzGy9H1aKzDcnp .node.clickable{cursor:pointer;}#mermaid-svg-LdxzGy9H1aKzDcnp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LdxzGy9H1aKzDcnp .arrowheadPath{fill:#333333;}#mermaid-svg-LdxzGy9H1aKzDcnp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LdxzGy9H1aKzDcnp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LdxzGy9H1aKzDcnp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LdxzGy9H1aKzDcnp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LdxzGy9H1aKzDcnp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LdxzGy9H1aKzDcnp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LdxzGy9H1aKzDcnp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LdxzGy9H1aKzDcnp .cluster text{fill:#333;}#mermaid-svg-LdxzGy9H1aKzDcnp .cluster span{color:#333;}#mermaid-svg-LdxzGy9H1aKzDcnp 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-LdxzGy9H1aKzDcnp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LdxzGy9H1aKzDcnp rect.text{fill:none;stroke-width:0;}#mermaid-svg-LdxzGy9H1aKzDcnp .icon-shape,#mermaid-svg-LdxzGy9H1aKzDcnp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LdxzGy9H1aKzDcnp .icon-shape p,#mermaid-svg-LdxzGy9H1aKzDcnp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LdxzGy9H1aKzDcnp .icon-shape .label rect,#mermaid-svg-LdxzGy9H1aKzDcnp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LdxzGy9H1aKzDcnp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LdxzGy9H1aKzDcnp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LdxzGy9H1aKzDcnp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 提供素材
变成记忆
检索相关
影响决策
产生新观察
👀 Memory Stream

数据库
🤔 Reflection

自我意识
📋 Planning

执行力

三者形成自我增强的循环

  • 记忆 → 反思(从经验中学到什么)
  • 反思 → 记忆(反思本身被记住)
  • 记忆+反思 → 规划(决定做什么)
  • 规划 → 行动 → 新记忆

25个AI自己办了个情人节派对

论文里最惊艳的实验:研究者没写任何"办派对"的代码。

他们只是在情人节那天,告诉其中一个AI Isabella"你想办个情人节派对"。然后啥也没管。

接下来两天里,AI们自己:

  1. Isabella发了邀请
  2. AI们互相传播消息
  3. 大家主动准备礼物
  4. 派对那天按时到达

这一切是"涌现"出来的。 没有人写规则。

一句话总结Generative Agents

记忆+反思+规划,让Agent像人一样活着。

对我们的启示

Generative Agents对普通Agent开发的启示是:

  1. 重要性打分很有用------不要把所有记忆都平等对待
  2. 反思机制能大幅提升决策质量------"我学到了什么"比"我做了啥"更有价值
  3. 分层规划比"走一步看一步"更稳定

但要小心:这套机制很贵、很慢 。每次规划都要LLM生成,每次反思都要LLM总结。生产环境慎用。


5.6 三种记忆方案对比 + 选型指南

维度 短期记忆 长期记忆(向量库) MemGPT
原理 对话历史塞进prompt 文本→向量→按语义查 操作系统式分层管理
适合场景 短对话(<20轮) 中等复杂Agent 超长对话/复杂文档
优点 简单直接 跨对话持久 突破上下文限制
缺点 Token爆涨 检索不准会误导 实现复杂、贵
实现成本 ⭐⭐ ⭐⭐⭐⭐
代表项目 直接用 LangChain Memory Letta(原MemGPT)
GitHub Stars - Mem0 52k Letta 30k

选型决策图

#mermaid-svg-GKzfLJ3hjCfTklnf{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-GKzfLJ3hjCfTklnf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GKzfLJ3hjCfTklnf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GKzfLJ3hjCfTklnf .error-icon{fill:#552222;}#mermaid-svg-GKzfLJ3hjCfTklnf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GKzfLJ3hjCfTklnf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GKzfLJ3hjCfTklnf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GKzfLJ3hjCfTklnf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GKzfLJ3hjCfTklnf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GKzfLJ3hjCfTklnf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GKzfLJ3hjCfTklnf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GKzfLJ3hjCfTklnf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GKzfLJ3hjCfTklnf .marker.cross{stroke:#333333;}#mermaid-svg-GKzfLJ3hjCfTklnf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GKzfLJ3hjCfTklnf p{margin:0;}#mermaid-svg-GKzfLJ3hjCfTklnf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GKzfLJ3hjCfTklnf .cluster-label text{fill:#333;}#mermaid-svg-GKzfLJ3hjCfTklnf .cluster-label span{color:#333;}#mermaid-svg-GKzfLJ3hjCfTklnf .cluster-label span p{background-color:transparent;}#mermaid-svg-GKzfLJ3hjCfTklnf .label text,#mermaid-svg-GKzfLJ3hjCfTklnf span{fill:#333;color:#333;}#mermaid-svg-GKzfLJ3hjCfTklnf .node rect,#mermaid-svg-GKzfLJ3hjCfTklnf .node circle,#mermaid-svg-GKzfLJ3hjCfTklnf .node ellipse,#mermaid-svg-GKzfLJ3hjCfTklnf .node polygon,#mermaid-svg-GKzfLJ3hjCfTklnf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GKzfLJ3hjCfTklnf .rough-node .label text,#mermaid-svg-GKzfLJ3hjCfTklnf .node .label text,#mermaid-svg-GKzfLJ3hjCfTklnf .image-shape .label,#mermaid-svg-GKzfLJ3hjCfTklnf .icon-shape .label{text-anchor:middle;}#mermaid-svg-GKzfLJ3hjCfTklnf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GKzfLJ3hjCfTklnf .rough-node .label,#mermaid-svg-GKzfLJ3hjCfTklnf .node .label,#mermaid-svg-GKzfLJ3hjCfTklnf .image-shape .label,#mermaid-svg-GKzfLJ3hjCfTklnf .icon-shape .label{text-align:center;}#mermaid-svg-GKzfLJ3hjCfTklnf .node.clickable{cursor:pointer;}#mermaid-svg-GKzfLJ3hjCfTklnf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GKzfLJ3hjCfTklnf .arrowheadPath{fill:#333333;}#mermaid-svg-GKzfLJ3hjCfTklnf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GKzfLJ3hjCfTklnf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GKzfLJ3hjCfTklnf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GKzfLJ3hjCfTklnf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GKzfLJ3hjCfTklnf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GKzfLJ3hjCfTklnf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GKzfLJ3hjCfTklnf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GKzfLJ3hjCfTklnf .cluster text{fill:#333;}#mermaid-svg-GKzfLJ3hjCfTklnf .cluster span{color:#333;}#mermaid-svg-GKzfLJ3hjCfTklnf 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-GKzfLJ3hjCfTklnf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GKzfLJ3hjCfTklnf rect.text{fill:none;stroke-width:0;}#mermaid-svg-GKzfLJ3hjCfTklnf .icon-shape,#mermaid-svg-GKzfLJ3hjCfTklnf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GKzfLJ3hjCfTklnf .icon-shape p,#mermaid-svg-GKzfLJ3hjCfTklnf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GKzfLJ3hjCfTklnf .icon-shape .label rect,#mermaid-svg-GKzfLJ3hjCfTklnf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GKzfLJ3hjCfTklnf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GKzfLJ3hjCfTklnf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GKzfLJ3hjCfTklnf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 几句话就完事
需要跨对话记用户偏好
需要按意思搜索历史
上千轮对话

多跳推理
你的Agent

要记多少东西?
短期记忆

塞prompt
文件/数据库

key-value存
向量数据库

ChromaDB
MemGPT/Letta

企业级方案

我的实战建议

80%的Agent项目,用这套就够了:

python 复制代码
# 1. 短期记忆:最近10轮对话
recent_messages = full_history[-10:]

# 2. 长期记忆:用向量库存关键事实
long_term = chromadb.get_relevant_facts(user_query, top_k=5)

# 3. 拼成prompt
prompt_messages = [
    {"role": "system", "content": system_prompt_with_memories(long_term)},
    *recent_messages,
    {"role": "user", "content": user_query}
]

简单、有效、好维护。 别一上来就上MemGPT那种重量级方案。


5.7 Mem0:开箱即用的Agent记忆层

如果你不想自己写记忆管理代码,可以用Mem0(GitHub 52k⭐)------一个专门做Agent记忆的开源项目。

一行代码加记忆

bash 复制代码
pip install mem0ai
python 复制代码
from mem0 import Memory

m = Memory()

# 存记忆
m.add("用户叫小明,在济南工作,是程序员,喜欢吃川菜", user_id="user_001")

# 查记忆
relevant = m.search("用户住在哪里?", user_id="user_001")
print(relevant)
# [{'memory': '用户叫小明...', 'score': 0.92}, ...]

Mem0会自动做几件事:

  1. 从文本里提取关键事实(用了LLM)
  2. 去重(如果已有类似记忆就不重复存)
  3. 更新(如果新信息和旧信息矛盾,自动更新)
  4. 按用户/会话分类

#mermaid-svg-EwBHeXA8vDEOQf5K{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-EwBHeXA8vDEOQf5K .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EwBHeXA8vDEOQf5K .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EwBHeXA8vDEOQf5K .error-icon{fill:#552222;}#mermaid-svg-EwBHeXA8vDEOQf5K .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EwBHeXA8vDEOQf5K .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EwBHeXA8vDEOQf5K .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EwBHeXA8vDEOQf5K .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EwBHeXA8vDEOQf5K .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EwBHeXA8vDEOQf5K .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EwBHeXA8vDEOQf5K .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EwBHeXA8vDEOQf5K .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EwBHeXA8vDEOQf5K .marker.cross{stroke:#333333;}#mermaid-svg-EwBHeXA8vDEOQf5K svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EwBHeXA8vDEOQf5K p{margin:0;}#mermaid-svg-EwBHeXA8vDEOQf5K .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EwBHeXA8vDEOQf5K .cluster-label text{fill:#333;}#mermaid-svg-EwBHeXA8vDEOQf5K .cluster-label span{color:#333;}#mermaid-svg-EwBHeXA8vDEOQf5K .cluster-label span p{background-color:transparent;}#mermaid-svg-EwBHeXA8vDEOQf5K .label text,#mermaid-svg-EwBHeXA8vDEOQf5K span{fill:#333;color:#333;}#mermaid-svg-EwBHeXA8vDEOQf5K .node rect,#mermaid-svg-EwBHeXA8vDEOQf5K .node circle,#mermaid-svg-EwBHeXA8vDEOQf5K .node ellipse,#mermaid-svg-EwBHeXA8vDEOQf5K .node polygon,#mermaid-svg-EwBHeXA8vDEOQf5K .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EwBHeXA8vDEOQf5K .rough-node .label text,#mermaid-svg-EwBHeXA8vDEOQf5K .node .label text,#mermaid-svg-EwBHeXA8vDEOQf5K .image-shape .label,#mermaid-svg-EwBHeXA8vDEOQf5K .icon-shape .label{text-anchor:middle;}#mermaid-svg-EwBHeXA8vDEOQf5K .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-EwBHeXA8vDEOQf5K .rough-node .label,#mermaid-svg-EwBHeXA8vDEOQf5K .node .label,#mermaid-svg-EwBHeXA8vDEOQf5K .image-shape .label,#mermaid-svg-EwBHeXA8vDEOQf5K .icon-shape .label{text-align:center;}#mermaid-svg-EwBHeXA8vDEOQf5K .node.clickable{cursor:pointer;}#mermaid-svg-EwBHeXA8vDEOQf5K .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-EwBHeXA8vDEOQf5K .arrowheadPath{fill:#333333;}#mermaid-svg-EwBHeXA8vDEOQf5K .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EwBHeXA8vDEOQf5K .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EwBHeXA8vDEOQf5K .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EwBHeXA8vDEOQf5K .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-EwBHeXA8vDEOQf5K .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EwBHeXA8vDEOQf5K .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-EwBHeXA8vDEOQf5K .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EwBHeXA8vDEOQf5K .cluster text{fill:#333;}#mermaid-svg-EwBHeXA8vDEOQf5K .cluster span{color:#333;}#mermaid-svg-EwBHeXA8vDEOQf5K 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-EwBHeXA8vDEOQf5K .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-EwBHeXA8vDEOQf5K rect.text{fill:none;stroke-width:0;}#mermaid-svg-EwBHeXA8vDEOQf5K .icon-shape,#mermaid-svg-EwBHeXA8vDEOQf5K .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EwBHeXA8vDEOQf5K .icon-shape p,#mermaid-svg-EwBHeXA8vDEOQf5K .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-EwBHeXA8vDEOQf5K .icon-shape .label rect,#mermaid-svg-EwBHeXA8vDEOQf5K .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EwBHeXA8vDEOQf5K .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-EwBHeXA8vDEOQf5K .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-EwBHeXA8vDEOQf5K :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

'用户叫小明

喜欢川菜'
Mem0
提取事实
已有类似?
更新/合并
存入向量库

Mem0的局限

免费版有调用次数限制 ,生产环境要付费。而且它对中文支持有时候不太准------提取关键事实时偶尔会漏掉一些信息。

生产建议:免费版用来做原型和小流量产品,大流量上付费版或者自建。


本章的坑

  1. 向量数据库不是万能的。 它的检索是基于"语义相似度",不是"绝对正确" 。有时候语义相近但事实相反的文本也会被检索出来,模型会照单全收然后答错。关键事实要人工校验。

  2. Embedding模型选错,效果会差很多。 不同语言、不同领域要用不同的Embedding模型。中文场景推荐用:

    • text-embedding-v3(阿里通义)
    • bge-large-zh(BAAI开源)
    • 不要用英文模型处理中文------降维打击
  3. 文档切分粒度是个大坑。 太粗(一整篇文章作为一个chunk)→ 检索不准;太细(每句话一个chunk)→ 丢上下文。经验值:500字左右为一个chunk,重叠50字

  4. Mem0的免费版有调用次数限制。 跑Demo够用,生产环境要付费或者自建。

  5. 不要把所有对话都存进长期记忆。 重要性低的对话(比如"你吃饭了吗?")会污染记忆库。至少做简单的过滤------比如只在用户说出关键信息时才存。

  6. "重要性打分"是主观的。 让LLM评估一条记忆"重不重要"有时候不靠谱。同样的事,不同prompt、不同模型,评估结果都不一样。生产环境可以加规则做硬过滤

  7. 上下文窗口不是越大越好。 GPT-4.1的128k tokens看着多,但长上下文模型更贵、更慢、还有"Lost in the Middle"问题该用向量库就老老实实用,别硬塞。

  8. 记忆会过期。 用户的偏好会变(以前喜欢川菜,现在不爱了)。记忆要有"遗忘"机制------比如超过6个月没被检索过的记忆自动降低权重。


本章配套论文

  • MemGPT (UC Berkeley, Packer et al., 2023):把操作系统的虚拟内存管理搬进LLM,突破上下文窗口限制。Letta项目(30k+⭐)就是这个论文的开源实现。

  • Generative Agents (Stanford, Park et al., 2023):25个AI在虚拟小镇生活,提出"记忆流+反思+规划"三大机制,证明了带记忆+反思+规划的Agent能涌现出复杂行为。

📌 怎么读这两篇? 重点看Introduction和Method,别一上来啃Related Work。MemGPT的"分层内存"设计和Generative Agents的"重要性打分"是核心,其他都是工程实现。


实战作业

挑一个做完,做完发评论区我给你看:

作业1:给第4章的客服Agent加记忆功能

要求:

  • 用户告诉Agent自己的订单偏好(比如"我的快递一般都放快递柜"),Agent要记住
  • 下次用户问"我的快递怎么处理"时,Agent能调用之前的记忆

作业2:搭建一个私人知识库Agent

要求:

  • 准备5-10个文档(txt/markdown/pdf都行)
  • 用ChromaDB存成向量
  • 写一个Agent,能基于这些文档回答问题

作业3:跑一遍Generative Agents的开源实现

GitHub搜generative-agents,有官方复现的项目(5k+⭐)。跑起来看看25个AI自己生活是什么样子。


下一章预告

第6章我们进入Agent最核心的"思考"能力:规划与推理------Agent的思考方式

你会学到:

  • ReAct:让Agent边想边做(所有Agent框架的祖宗)
  • CoT / ToT:让模型"一步一步想"
  • AutoGPT的规划模块源码拆解
  • Plan-and-Solve:先想好再做

这些是Agent的"脑子怎么转"的核心机制。掌握了这章,你才算真正理解了Agent的"智能"从哪里来。

下一章我们一起揭开Agent思考的秘密。

相关推荐
生信碱移1 小时前
Vscode 连接 ipynb 选择内核无法自动显示 conda 环境对应的 python
服务器·人工智能·经验分享·vscode·python
lazy_ma1 小时前
大模型实操-Spring Boot集成LangChain4j
人工智能·后端
CHHH_HHH1 小时前
【C++】哈希表原理与实战:从冲突解决到性能优化
开发语言·数据结构·c++·学习·算法·哈希算法·散列表
Cloud_Shy6181 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第七章 Item 48 - 50)
开发语言·人工智能·笔记·python·microsoft·学习方法
麦哲思科技任甲林1 小时前
人类编程爱敏捷,AI编程爱CMMI
人工智能·ai编程·敏捷开发·cmmi
sali-tec1 小时前
C# 基于OpenCv的视觉工作流-章84-包胶有无检测
图像处理·人工智能·opencv·算法·计算机视觉
哈哈,柳暗花明1 小时前
人工智能专业术语详解(P)
人工智能·专业术语
Web极客码1 小时前
从生成式AI到智能代理:AI正在进入“第二阶段”
服务器·人工智能·ai
万俟淋曦1 小时前
【论文速递】2026年第04周(Jan-18-24)(Robotics/Embodied AI/LLM)
人工智能·ai·机器人·大模型·llm·具身智能·vla