L15 代理记忆:让 Agent 不再是"金鱼脑"
课程目标:理解 Agent 记忆的七大类型,掌握短期/长期记忆的实现路径,能用 Mem0 或 Cognee 给 Agent 装上"持续学习"的能力。
零、L14 vs L15:先搞清楚边界#
L14 和 L15 是学生最常混淆的两节课——它们都和"LLM 该看到什么信息"相关,关注点却完全不同。先把边界划清楚,再看后面七大类型。
0.1 一句话区别#
| L14 Context Engineering | L15 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 介绍] 列出四大价值:
反思(Reflective):从过去的行动中学习
互动(Interactive):维持对话的连贯性
主动(Proactive & Reactive):基于历史预测需求
自主(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
Extraction:LLM 总结对话历史,提取新记忆
Update:LLM 决定添加/修改/删除哪些记忆
5.3 长期记忆:Cognee 知识图谱#
另一种实现——用知识图谱表达实体间的关系:
import cognee
# 把文本喂给 Cognee
cognee.add("Ben 喜欢滑雪,但避开高级道。他计划 12 月去 Aspen。")
# 构建知识图谱
await cognee.cognify()
# 查询
result = await cognee.search("Ben 喜欢什么运动?")
# → "Ben 喜欢滑雪(来自 Aspen 计划)"
Cognee 的优势:双存储架构(向量 + 图谱)——既能相似度搜索,也能理解实体关系。
5.4 后端存储:Azure AI Search#
生产环境用 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 负责观察、提取、存储。
优化技巧:
用更便宜的小模型做提取(省钱)
长期不用的记忆移到"冷存储"(如便宜的 blob)
七、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 |
| Persona | Agent 人设 | system prompt |
| Episodic | 过去行动日志 | 数据库 |
| Entity | 实体信息 | 知识图谱 |
| Structured RAG | 结构化数据 | Azure AI Search |
记忆的本质 = 选择性遗忘——不是什么都记,而是有策略地保留。
十、参考资源#
课程章节:Memory for AI Agents
Mem0:https://mem0.ai/
Cognee:https://www.cognee.ai/
Azure AI Search:https://learn.microsoft.com/azure/search/
十一、下一课预告#
L16 Microsoft Agent Framework 深入:微软官方的统一 SDK——一个框架搞定 Sequential、Concurrent、Group Chat、Handoff、Magnetic 五种多 Agent 编排模式。
为什么重要:MAF 是企业级 Agent 的"标准答案"——掌握它就掌握了微软生态的 Agent 开发。
1. L14 的 Context Engineering 与 L15 的 Agent 记忆,最本质的边界差异在哪里?
2. 在 LangGraph 中实现短期记忆(当前会话内延续上下文),正确的做法是什么?
3. Mem0 这类记忆库的核心两阶段 pipeline(Extraction + Update)解决了什么问题?