课程首页 › Module 6 · 协议与工程:MCP / Agent 协议 / 可信赖 / Context / Memory › L15

L15 代理记忆:让 Agent 不再是"金鱼脑"

课程目标:理解 Agent 记忆的七大类型,掌握短期/长期记忆的实现路径,能用 Mem0 或 Cognee 给 Agent 装上"持续学习"的能力。


零、L14 vs L15:先搞清楚边界#

L14 和 L15 是学生最常混淆的两节课——它们都和"LLM 该看到什么信息"相关,关注点却完全不同。先把边界划清楚,再看后面七大类型。

0.1 一句话区别#

L14 Context EngineeringL15 Agent 记忆
关注的时间尺度这一次请求(毫秒~分钟)跨会话历史(天~周~永久)
关心的问题"送给 LLM 的内容怎么排版、怎么塞,它才发挥最好?""用户上次/上上次说过什么?怎么记得?记多久?怎么取?"
类比 1给厨师摆好砧板和食材 → 这一顿做得好冰箱里长期存着什么菜 → 下一顿能做什么
类比 2一次会议的议程 · 会议室布置 · 参会名单公司 CRM 系统里存的所有客户档案

0.2 用厨师的故事讲清楚#

把 LLM 想象成一个记性不好但很聪明的厨师:

┌─────────────────────────────────────────────────────┐
│  L14 Context Engineering(砧板工程)                  │
│  ─────────────────────────────────                   │
│  • 你给他摆好食材(写好系统提示)                     │
│  • 你给他铺好砧板(按结构组织 context)               │
│  • 你告诉他要做什么(清晰的指令)                     │
│  • 一次做饭就这么多菜,全在砧板上                     │
│                                                     │
│  砧板摆得好 → 这一顿做得好                            │
│  砧板摆得乱 → 再厉害的厨师也做不出好菜                │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│  L15 Agent 记忆(冰箱 + 采购记录)                    │
│  ─────────────────────────────────                   │
│  • 客人上次说"我不吃辣" → 记到冰箱里                  │
│  • 客人三周前订过的菜 → 查采购记录                    │
│  • 客人偏爱的设计师 → 写在客户档案本里                │
│                                                     │
│  没记忆的 Agent → 每次都把客人当陌生人                │
│  有记忆的 Agent → "您上次说不吃辣,这次鸡翅做微辣"   │
└─────────────────────────────────────────────────────┘

0.3 为什么大家会混?#

"我把用户的偏好写在 system prompt 里,不就是记忆了吗?"

是的——任何 LLM 能"看到"的信息都叫 Context。但 L15 的"记忆"指的是 跨 session 的持久化机制:

能力L14 能不能做L15 才做
把信息塞进 system prompt✅ 能(但 prompt 会爆)✅ 更专业
跨 session 保留❌ 一次请求结束就丢✅ 持久化到 DB
智能检索(只取相关的)❌ 全塞进去会爆 context✅ 用 embedding/RAG
区分短期/长期/实体❌ 不区分✅ 分层管理
自动遗忘/更新❌ 不会自动✅ 有生命周期
处理百万级历史❌ context 有上限✅ 只检索 Top-K

0.4 代码对照#

L14 场景——一次请求内部怎么组织塞给 LLM 的内容:

# 这一顿的"砧板":system + 历史对话 + 当前问题
system_prompt = """
你是客服 Agent。

## 能力
- 查订单
- 查 FAQ

## 规则
- 不知道就说不知道
- 不超过 200 字
""".strip()

messages = [
    {"role": "system", "content": system_prompt},
    {"role": "user", "content": f"订单 {order_id} 的状态是什么?"}
]

L15 场景——三天后用户又来了,Agent 怎么记得他:

# 三天后,从"冰箱"里取出用户档案,摆到新砧板上
user_profile = memory.get(user_id)  
# → {"name": "老王", "allergy": "不吃辣", "previous_orders": [...]}

new_system_prompt = base_prompt + f"\n用户档案:{user_profile}"
# ↑ 把"冰箱里"的东西拿出来摆到"砧板"上,再走 L14 的 context 编排逻辑

0.5 一句话总结#

L14 关心"这一顿饭的砧板怎么摆"。

L15 关心"客人过去在我店里吃过什么、忌什么、喜欢什么"。

学完 L14,Agent 这一次回答得好。 学完 L15,Agent 下次还认得这个用户。 两者结合 → 一个"每次都表现好 + 永远记得用户"的完整 Agent。


一、没有记忆的 Agent = 金鱼脑#

金鱼的记忆只有 7 秒。

你现在的 Agent 也差不多——

# 用户第一天
user: "我不吃辣"
agent: "好的,我以后会记得"

# 用户第二天(新的 session)
user: "推荐个餐厅"
agent: "好的,请问您有什么口味偏好吗?"
# (完全忘了用户第一天说过"不吃辣")

没记忆的 Agent 永远是陌生人。

Memory for AI Agents 想解决的核心问题:

怎么让 Agent 拥有跨 session 的长期记忆,并且能持续学习、自我进化。


二、用一个比喻:Agent 记忆 = 私人秘书的笔记本#

把 Agent 比作一位私人秘书:

秘书Agent 记忆
今天的会议纪要Working Memory(工作记忆)
这一周的日程Short-Term Memory(短期记忆)
老板的长期偏好("老板不爱吃辣")Long-Term Memory(长期记忆)
老板的性格特征("老板喜欢简洁")Persona Memory(人格记忆)
上次搞砸的事("上次订错机票了")Episodic Memory(情节记忆)
公司里的人物关系Entity Memory(实体记忆)
老板的合同文档结构Structured RAG(结构化 RAG)

好秘书 = 知道什么写哪里、什么该忘——不是什么都塞进脑子里。


三、Agent 记忆的七大类型#

类型用途差旅 Agent 案例
Working单个任务的即时 context记住"用户要订去巴黎的机票"
Short-Term当前 session 的对话知道"there"指巴黎
Long-Term跨 session 的持久化偏好记住 Ben 喜欢滑雪,避开高级道
Persona维持 Agent 人设强化"专业滑雪规划师"语气
Episodic过去的行动/成败记录"上次航班预订失败"
Entity实体信息(人/地/事)提取"巴黎"、"埃菲尔铁塔"
Structured RAG结构化信息的精确检索从邮件解析航班细节

没有一种记忆能解决所有问题——好 Agent 用多种记忆组合。


四、记忆为什么重要#

[L4 介绍] 列出四大价值:

  1. 反思(Reflective):从过去的行动中学习

  2. 互动(Interactive):维持对话的连贯性

  3. 主动(Proactive & Reactive):基于历史预测需求

  4. 自主(Autonomous):靠积累的知识独立运作

没有记忆,Agent 永远在重复犯同样的错。


五、记忆的实现路径#

5.1 短期记忆:LangGraph 的 thread#

短期记忆 = 当前 session 的对话历史。LangGraph 用 checkpoint 实现:

from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph

# 每个 thread(会话)都有自己的状态
checkpointer = MemorySaver()
workflow = StateGraph(...)
app = workflow.compile(checkpointer=checkpointer)

# 同一个 thread_id 对话:上文的记忆能延续
config = {"configurable": {"thread_id": "user_123"}}

# 第一轮
app.invoke({"messages": [HumanMessage("我不吃辣")]}, config)

# 第二轮(同一 thread)
result = app.invoke({"messages": [HumanMessage("推荐个餐厅")]}, config)
# Agent 记得"不吃辣"

5.2 长期记忆:Mem0 + 向量数据库#

跨 session 持久化——用 Mem0 这类专门做记忆管理的库:

from mem0 import Memory

# 初始化:连接向量数据库
m = Memory()

# 第一天:写入记忆
messages = [
    {"role": "user", "content": "我不吃辣"},
    {"role": "assistant", "content": "好的,我记下了"}
]
m.add(messages, user_id="ben")

# 第二天:新 session 开始
new_messages = [{"role": "user", "content": "推荐个餐厅"}]
relevant_memories = m.search("推荐餐厅", user_id="ben")
# → ["用户不吃辣", "用户预算 300 元以内", ...]

# 把这些记忆喂给 LLM
context = relevant_memories + new_messages
response = llm.complete(context)
# Agent:"好的,考虑到您不吃辣,推荐..."

Mem0 的核心:两阶段 pipeline

  1. Extraction:LLM 总结对话历史,提取新记忆

  2. Update:LLM 决定添加/修改/删除哪些记忆

5.3 长期记忆:Cognee 知识图谱#

另一种实现——用知识图谱表达实体间的关系:

import cognee

# 把文本喂给 Cognee
cognee.add("Ben 喜欢滑雪,但避开高级道。他计划 12 月去 Aspen。")

# 构建知识图谱
await cognee.cognify()

# 查询
result = await cognee.search("Ben 喜欢什么运动?")
# → "Ben 喜欢滑雪(来自 Aspen 计划)"

Cognee 的优势:双存储架构(向量 + 图谱)——既能相似度搜索,也能理解实体关系。

生产环境用 Azure AI Search 做记忆后端:

from azure.search.documents import SearchClient

search_client = SearchClient(endpoint=endpoint, index_name="agent_memory")

# 写入记忆
search_client.upload_documents([{
    "id": "mem_001",
    "content": "用户不吃辣",
    "user_id": "ben",
    "timestamp": "2026-10-04",
    "embedding": get_embedding("用户不吃辣")
}])

# 检索记忆
results = search_client.search(
    "推荐餐厅",
    filter="user_id eq 'ben'",
    top=5
)

优势:高精度的结构化 RAG,支持对话、邮件、图片等多种数据。


六、让 Agent"自我进化"#

Memory for AI Agents 提到了一个关键模式——Knowledge Agent:

主对话 Agent ─── 观察 ───> Knowledge Agent
                                    │
                                    ├─ 1. 识别值得保存的信息
                                    ├─ 2. 提取/摘要
                                    ├─ 3. 存入知识库
                                    └─ 4. 未来检索时调出来
class KnowledgeAgent:
    def observe(self, conversation):
        # 1. 提取关键信息
        memories = self.extract(conversation)

        # 3. 存入
        for mem in memories:
            self.vector_db.add(mem)

    def augment(self, query):
        # 4. 检索相关 context
        relevant = self.vector_db.search(query, top_k=3)
        return relevant

好处:主 Agent 不用关心"记忆管理"——有一个专门的 Agent 负责观察、提取、存储。

优化技巧:


七、Microsoft Agent Framework 中的记忆#

Memory for AI Agents 提到了一个好消息——MAF 已经内置记忆抽象:

from agent_framework import ChatAgent, ChatMessageStore
from agent_framework.mem0 import Mem0Provider

# 短期记忆:AgentSession(runtime,session 内)
session = agent.create_session()

# 长期记忆:Persistent Message Store(数据库)
def create_message_store():
    return ChatMessageStore()

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    chat_message_store_factory=create_message_store  # 跨 session 持久化
)

# 动态记忆:Mem0 外部服务(上下文注入)
memory_provider = Mem0Provider(
    api_key="...",
    user_id="ben"
)

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    context_providers=memory_provider  # 自动注入相关记忆到 context
)

八、动手:一个完整的记忆 Agent 示例#

class MemoryEnabledAgent:
    def __init__(self, user_id):
        self.user_id = user_id
        self.memory = Memory()  # Mem0
        self.short_term = []    # 当前 session

    def chat(self, user_input: str) -> str:
        # 1. 检索长期记忆
        long_term = self.memory.search(user_input, user_id=self.user_id)

        # 2. 拼接完整 context
        context = long_term + self.short_term + [
            {"role": "user", "content": user_input}
        ]

        # 3. LLM 推理
        response = llm.complete(context)

        # 4. 更新短期记忆
        self.short_term.append({"role": "user", "content": user_input})
        self.short_term.append({"role": "assistant", "content": response})

        # 5. 异步提取长期记忆
        self.extract_long_term(user_input, response)

        # 6. 压缩短期记忆
        if len(self.short_term) > 20:
            self.short_term = self.compress(self.short_term)

        return response

    def extract_long_term(self, user_msg, agent_msg):
        """异步调用:分析对话,提取值得长期保存的信息"""
        # 实际生产用专门的提取 Agent
        # 这里简化
        if "不吃辣" in user_msg or "过敏" in user_msg:
            self.memory.add(
                [{"role": "user", "content": user_msg}],
                user_id=self.user_id
            )

九、关键要点回顾#

记忆类型用途实现
Working当前任务context window
Short-Term本对话LangGraph thread
Long-Term跨会话偏好Mem0 / Cognee / Azure AI Search
PersonaAgent 人设system prompt
Episodic过去行动日志数据库
Entity实体信息知识图谱
Structured RAG结构化数据Azure AI Search

记忆的本质 = 选择性遗忘——不是什么都记,而是有策略地保留。


十、参考资源#


十一、下一课预告#

L16 Microsoft Agent Framework 深入:微软官方的统一 SDK——一个框架搞定 Sequential、Concurrent、Group Chat、Handoff、Magnetic 五种多 Agent 编排模式。

为什么重要:MAF 是企业级 Agent 的"标准答案"——掌握它就掌握了微软生态的 Agent 开发。

自测 · 检验是否真的掌握了

1. L14 的 Context Engineering 与 L15 的 Agent 记忆,最本质的边界差异在哪里?

L14 优化的是这一次请求里送给模型的内容怎么排、怎么塞,属于单次调用的上下文编排问题。L15 解决的是跨会话的信息如何存下来、如何按需取回来,核心是持久化与检索机制。把所有历史塞进 system prompt 既撑爆上下文窗口,也做不到跨 session 保留,因此那仍然只是上下文而不是记忆。

2. 在 LangGraph 中实现短期记忆(当前会话内延续上下文),正确的做法是什么?

LangGraph 用 checkpointer 保存每个 thread 的状态,同一个 thread_id 再次 invoke 时即可延续上文,这正是短期记忆的标准实现。向量库加嵌入检索属于长期记忆的路径,用来做跨会话的语义召回。摘要压缩是上下文过长时的裁剪手段,解决的是长度问题而不是跨轮次状态保存问题。

3. Mem0 这类记忆库的核心两阶段 pipeline(Extraction + Update)解决了什么问题?

Mem0 先用 LLM 从对话中抽取值得保留的事实,再由 LLM 决定这些事实是新增、修改还是覆盖已有记忆,从而避免同一条信息被反复写成多条矛盾记录。纯规则匹配无法处理口语化的隐含偏好,而只做抽取不做更新则会让记忆库不断膨胀并出现冲突。记忆的本质是有策略地保留与遗忘,而不是把对话全量存档。