用过 LangChain Memory 的都知道,那玩意儿一上生产就翻车——DeepAgents 直接换了思路
LangChain 老版本里的 Memory 模块,相信大多数人都用过:ConversationBufferMemory、ConversationSummaryMemory、VectorStoreRetrieverMemory……
我自己用过最离谱的一次:上线一周后用户量上来,发现 ConversationBufferMemory 在多用户并发下串了——A 用户的偏好被 B 用户读到了。补补丁补到第三轮,最后整段 Memory 模块全删,自己用 Redis 重写。
LangGraph 出来后好一些:MemorySaver / Checkpointer 把短期记忆做成了 thread 级别。但长期记忆——跨 thread、跨用户、能学习、能更新——还是要自己接 Store、自己设计 namespace、自己写读写时机。
直到我看 DeepAgents 的 memory 文档,发现它把这件事换了个思路:
不再有"Memory 类"。Memory 就是文件,由 Agent 自己用
edit_file/read_file工具读写,存在哪、谁能看由 backend 控制。
这是 Day 6 的笔记,把这个新思路讲清楚。
阅读提示读完你能拿到三个东西:
- DeepAgents 的 Memory 三层架构:Working / Short-term / Long-term,分别由谁管
- 读路径和写路径的精确流转——什么时候灌入 prompt,什么时候触发
edit_file- 一段最小可运行代码:让 Agent 跨 thread 记住用户偏好 全文约 11 分钟。
一、全局地图:Day 6 在哪一层
12 天计划已经走到第二阶段(核心模块)的中段:
- Day 4 讲了 Agent 怎么定义
- Day 5 讲了工具怎么注册
- Day 6(本篇)讲 Agent 怎么记东西
- Day 7 讲工作流编排
- Day 8 讲多 Agent 协作
Memory 是 Agent 跟"无状态对话机器人"的分水岭。Day 6 之后,你的 Agent 开始有"长期身份"。
二、先把概念分清楚:DeepAgents 把 Memory 拆成三层
很多人讲 memory 总爱混在一起,DeepAgents 文档里其实分得很清楚(事实,参考 docs.langchain.com/oss/python/deepagents/memory):
图 1:三层 Memory,读路径(绿)和写路径(紫)走不同后端
L1 · Working Memory(工作记忆)
- 存活范围:单次
invoke()调用内 - 载体:LangGraph 的
state["messages"]、tool_calls、其它 state 字段 - 特点:随调用结束消失。受 LLM context 窗口直接约束
- 工程意义:相当于 RAM,速度最快但易失
这一层你不用配置,DeepAgents 自动管。Day 4 状态机里的 Reasoning / ToolExecuting 之间流转的就是 Working Memory。
L2 · Short-term Memory(短期记忆 / thread 内)
- 存活范围:同一
thread_id多次调用之间 - 载体:LangGraph Checkpointer(
MemorySaver/SqliteSaver/PostgresSaver) - 特点:本质上是一连串 checkpoint 快照,跟数据库的 WAL 很像
- 工程意义:相当于本地磁盘,会话内多轮对话可恢复
这一层等价于 LangChain 老版本的 ConversationBufferMemory,但**不再是"类实例属性"**,而是真正持久化下来的快照。多用户并发不会串。
L3 · Long-term Memory(长期记忆 / 跨 thread)
- 存活范围:跨 thread、跨会话、跨 Agent
- 载体:LangGraph Store(通过文件路径访问)
- 特点:filesystem-backed —— 用文件路径代替键值对
- 工程意义:相当于"用户数据库 / 知识库"
这是 DeepAgents 最不一样的地方:Long-term memory 不是 KV,是 filesystem。
三、Filesystem-backed Memory 是什么意思
字面意思:Agent 把"记忆"当作文件来读写,路径是字符串,内容是 markdown,由 backend 决定文件实际存在哪儿。
最常见的两个路径(来自官方示例):
/memories/AGENTS.md # 用户偏好、对话学到的事实/skills/<name>/SKILL.md # 可复用的"做事方法"(procedural memory)
这设计的关键点不是"用文件存储",而是:
Agent 用同一套文件读写工具(
read_file/edit_file/ls)就能既操作工作区文件、又操作长期记忆。 Memory 不再是一个独立的 API,而是 filesystem 的一个路径前缀。
读路径和写路径如下图:
图 2:写路径靠 edit_file 工具,读路径靠 MemoryMiddleware 在 before_model 注入 prompt
3.1 写路径
- Agent 在推理过程中决定"这事得记下来"
- 调用内置的
edit_file工具(这是FilesystemMiddleware提供的,参考 Day 4 默认中间件清单) - 工具调用进
CompositeBackend,按路径匹配路由:/memories/→StoreBackend StoreBackend用namespace(如(user_id,))解析后,调用store.put(ns, path, data)- 数据落盘
3.2 读路径
- 用户调用
agent.invoke(...) MemoryMiddleware的before_model钩子触发- 调用
Backend.get(path)拉取每个memory=配置的文件 - 把文件内容拼接到 system prompt 里(这个是关键——记忆不是 RAG 出来的,是直接灌进 prompt 的)
- LLM 推理时已经看见了
注意一个判断:DeepAgents 的默认 memory 模式是**“启动时全量灌入”**,不是"按需检索"。 适合记忆条目少、内容稳定的场景。如果你要存十万条历史,得用别的策略(看官方 episodic memory 那一节)。
四、最小实验:让 Agent 跨 thread 记住偏好
这段代码我自己跑通了,可以直接抄:
from langgraph.store.memory import InMemoryStorefrom deepagents import create_deep_agentfrom deepagents.backends import CompositeBackend, StateBackend, StoreBackendfrom deepagents.backends.utils import create_file_datastore = InMemoryStore() # 生产换 PostgresStore / 平台 store# Step 1: 预先种一份"用户偏好"store.put( ("user-alice",), # namespace "/memories/preferences.md", # path create_file_data("""## Preferences- Likes concise bullet points- Prefers Python examples"""),)# Step 2: 创建 Agent,告诉它去 /memories/preferences.md 找偏好agent = create_deep_agent( model="openai:gpt-4o", memory=["/memories/preferences.md"], backend=lambda rt: CompositeBackend( default=StateBackend(rt), routes={ "/memories/": StoreBackend( rt, namespace=lambda rt: (rt.server_info.user.identity,), ), }, ), store=store,)# Step 3: 跑两次,分别在不同 threadimport uuidconfig1 = {"configurable": {"thread_id": str(uuid.uuid4())}}agent.invoke({"messages": [{"role": "user", "content": "How do I read CSV?"}]}, config=config1)config2 = {"configurable": {"thread_id": str(uuid.uuid4())}}agent.invoke({"messages": [{"role": "user", "content": "How do I sort a list?"}]}, config=config2)
观察什么:
- 两次
invoke用了**不同的thread_id**(短期记忆完全不通) - 但两次回答都按 Alice 的偏好给的——简洁、Python 示例
- 这就是 long-term memory 在起作用
4.1 让 Agent 自己更新偏好
把 system_prompt 加一句"用户告诉你偏好就更新到 memory 文件",再跑:
agent.invoke( {"messages": [{"role": "user", "content": "From now on, give me TypeScript examples instead."}]}, config={"configurable": {"thread_id": str(uuid.uuid4())}},)
跑完之后看 store.get(("user-alice",), "/memories/preferences.md"),会发现内容已经被 Agent 用 edit_file 改过——偏好从 Python 换成了 TypeScript。事实:这就是文档说的 “hot path”(在对话中实时更新)。
五、和 LangChain Memory 模块的关键差异
我做了一个对比表,从工程视角看:
| 维度 | LangChain Memory(旧) | LangGraph Checkpointer | DeepAgents(filesystem) |
|---|---|---|---|
| 抽象 | 一堆 XxxMemory 类 |
thread 状态快照 | 文件 + backend |
| 短期记忆 | 类实例字段,并发不安全 | 内置,安全 | 内置,安全 |
| 长期记忆 | 要自己挑 store 子类 | 要接 BaseStore |
配置 backend 路由即可 |
| 多用户隔离 | 自己写 key 拼接 | 自己设 namespace | 配置 namespace=lambda rt: (user_id,) |
| 跨用户共享(org 策略) | 没有官方方案 | 自己写 | 配置 (org_id,) namespace |
| Agent 能否自己更新 | 否(外部代码改) | 否 | 是 (用 edit_file 工具) |
| 读写时机 | 框架隐式管 | 显式 reducer | 启动灌入 / on-demand |
| 调试 | 很难(黑盒) | 中等 | 每次 edit 都是一个 tool call ,trace 里能看 |
最关键的判断:
DeepAgents 把"记忆 ≠ 工具"这件事颠倒过来了——记忆就是工具能读写的文件。 所以 Memory 不再需要单独学一套 API,你学过的
edit_file/read_file工具就够。
这是它和 LangChain 老 Memory 模块本质上的差别。
六、踩坑记录
| 现象 | 原因 | 解决 |
|---|---|---|
| 记忆没生效,Agent 完全不知道用户偏好 | 没传 memory= 参数;或路径前缀和 backend route 不匹配 |
检查 memory=["/memories/..."] 和 routes={"/memories/": ...} 路径前缀一致 |
| 多用户串了 | namespace 写死了 ("default",) |
改成 lambda rt: (rt.server_info.user.identity,) |
Agent 不主动调 edit_file 更新记忆 |
system_prompt 没明确告诉它"什么时候更新" | 在 prompt 里加:“如果用户告诉你偏好,调 edit_file 更新 /memories/AGENTS.md” |
跑测试时 InMemoryStore 重启就没了 |
InMemoryStore 顾名思义只在内存 |
生产用 PostgresStore 或 LangSmith 平台 store |
| 同时多个 thread 写同一文件冲突 | 并发 last-write-wins | 用 background consolidation,或拆成多个 topic 文件 |
Agent 把 /policies/ 也改了 |
没设 read-only | 用 permissions= 参数 deny 写入特定路径 |
一个我自己撞到的细节
第一次跑示例时,我以为 memory=["/memories/AGENTS.md"] 是"创建一个空文件"——不是。如果 store 里没有这个文件,agent 启动时就找不到,得提前 store.put 一份初始内容(或者直接启动后让 Agent 用第一次对话写出来)。
文档示例里的 store.put(...) 一行不是装饰,是必须步骤。
七、什么时候不该用 DeepAgents 的 filesystem memory
诚实说:
- 记忆条目超过几百 KB:默认是启动时全量灌入 prompt,超过 context 窗口就崩
- 强结构化检索需求:比如"找出过去 30 天和支付相关的所有对话" → 文件查不动,得用 episodic memory + thread search(参考文档 episodic 那一节)
- 要做 RAG 风格的语义检索:DeepAgents 默认不是 vector retrieval,要自己用
Store的 vector search 接口 - 需要严格的事务性更新:filesystem 是 last-write-wins 的,不适合金融级一致性
适合:
- 用户偏好、Agent 自我提升、组织级策略
- “可读 markdown” 形态的知识,方便人审阅
- 需要 Agent 自主更新、跨会话演化的场景
八、Day 6 一句话结论
LangChain 的 Memory 是一堆类,DeepAgents 的 Memory 是一组文件。 类被框架隐式管,文件被 Agent 显式管——更可控、更可审计、更可调试。
判断:你是不是希望 Agent 自己决定记什么?是 → DeepAgents filesystem memory;不是 → LangGraph Checkpointer + 自定义 Store 也够。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

更多推荐

所有评论(0)