《LangChain 记忆机制完全指南:从短期记忆到长期记忆的实战》

你是否遇到过这样的情况?和 AI 聊完天,关闭窗口后再打开,AI 就完全不认识你了,问什么都得从头解释。这就像鱼的记忆一样——只有 7 秒。

但如果你有一个”私人助理”,即使过了一个月,它还记得你”喜欢吃披萨”、”住在上海”、”喜欢蓝色”——那该有多好!

这就是记忆机制要解决的问题。在 LangChain(特别是 LangGraph)中,我们可以轻松实现这两种记忆:短期记忆长期记忆

项目地址langchain_memory_demo —— 一个演示 LangGraph 记忆机制的入门项目,建议边读文章边对照代码!


1. 什么是记忆机制?

想象一下你在和 AI 聊天,有两种不同的记忆方式:

短期记忆 📝

就像人的”短期记忆”,只记得当前对话的内容:

  • 关闭对话框再打开,AI 就忘了之前聊过什么
  • 需要通过”会话ID”(thread_id)来恢复之前的对话
  • 适合:当前会话的多轮对话

长期记忆 🧠

就像人的”长期记忆”,AI 会记住你的偏好:

  • 即使关闭程序再打开,AI 仍然记得你”喜欢吃披萨”
  • 就像一个私人助理,了解你的习惯和偏好
  • 适合:记住用户偏好、历史记录

两者对比

特性 短期记忆 长期记忆
存储方式 内存 ChromaDB 向量数据库
持久化 ❌ 进程结束丢失 ✅ 进程重启后保留
用途 多轮对话 个性化推荐、用户画像
实现 InMemorySaver ChromaDB

2. 核心概念解析

2.1 LLM vs Embedding

在学习记忆机制之前,我们需要理解两个核心概念:

  • LLM(推理模型):像大脑,负责”思考”和”回答问题”
  • Embedding(向量化):像眼睛,负责”理解”文字的”含义”
1
2
3
4
5
"我喜欢吃披萨" → Embedding → [0.12, -0.34, 0.56, ...]

"我想吃东西" → Embedding → [0.11, -0.35, 0.55, ...]

相似度高!→ 检索到记忆

2.2 thread_id

就像每个微信会话有一个独立的聊天记录,thread_id 用来区分不同的会话:

1
2
3
4
config = {"configurable": {"thread_id": "session_1"}}

# 同一个 thread_id,对话历史会保留
result = agent.invoke({"messages": [HumanMessage("你好")]}, config)

3. 短期记忆实现

短期记忆使用 LangGraph 的 InMemorySaver(内存检查点)来实现。

3.1 核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph, START
from langchain_core.messages import HumanMessage

# 1. 创建内存检查点保存器
short_term_checkpointer = InMemorySaver()

# 2. 定义状态
class ShortMemoryState(TypedDict):
messages: Annotated[list[AnyMessage], operator.add]

# 3. 定义模型调用节点
def call_model(state: ShortMemoryState):
response = model.invoke(state["messages"])
return {"messages": [response]}

# 4. 构建工作流
short_memory_builder = StateGraph(ShortMemoryState)
short_memory_builder.add_node(call_model)
short_memory_builder.add_edge(START, "call_model")

# 5. 编译 Agent,传入检查点保存器
short_memory_agent = short_memory_builder.compile(checkpointer=short_term_checkpointer)

3.2 如何使用

1
2
3
4
5
6
7
8
9
10
11
12
# 开始新对话
config = {"configurable": {"thread_id": "session_1"}}
result = short_memory_agent.invoke(
{"messages": [HumanMessage(content="你好,我叫 Bob")]},
config
)

# 同一个 session 继续对话,AI 记得你叫 Bob
result = short_memory_agent.invoke(
{"messages": [HumanMessage(content="我叫什么名字?")]},
config
)

3.3 工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌─────────────────────────────────────────────────────────┐
│ 短期记忆工作流程 │
├─────────────────────────────────────────────────────────┤
│ │
│ 用户: "你好,我叫 Bob" │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ call_model │ → 调用 LLM 生成回复 │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ InMemorySaver │ → 自动保存对话状态到内存 │
│ │ thread_id=xxx │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ 用户: "我叫什么?" │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 从内存恢复历史 │ → 读取 thread_id 对应的对话历史 │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ LLM: "你叫 Bob" │
│ │
└─────────────────────────────────────────────────────────┘

3.4 特点总结

特点 说明
✅ 优点 速度快,零配置
❌ 缺点 进程结束数据丢失
适用场景 当前会话的多轮对话

4. 长期记忆实现

长期记忆使用 ChromaDB(向量数据库)来实现,支持语义搜索和持久化存储。

4.1 核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from pathlib import Path

# 1. 创建 Embedding 模型(本地,无需 API Key)
embedding_model = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)

# 2. 创建 ChromaDB 向量数据库
chroma_path = Path(__file__).parent / "chroma_db"
vectorstore = Chroma(
persist_directory=str(chroma_path),
embedding_function=embedding_model,
)

# 3. 保存记忆
def save_memory(user_id: str, memory_key: str, text: str):
vectorstore.add_texts(texts=[text], ids=[memory_key])

# 4. 检索记忆(语义搜索)
def retrieve_memories(user_id: str, query: str, limit: int = 2) -> str:
docs = vectorstore.similarity_search(query, k=limit)
memories = "\n".join(doc.page_content for doc in docs)
return f"## 用户记忆\n{memories}" if memories else ""

4.2 如何使用

1
2
3
4
5
6
7
8
9
10
11
# 保存记忆
save_memory("user_123", "memory_1", "我喜欢吃披萨")
save_memory("user_123", "memory_2", "我住在上海")

# 对话时检索记忆
result = long_memory_agent.invoke(
{"messages": [HumanMessage(content="我饿了想吃东西")]},
)

# AI 会自动检索到 "我喜欢吃披萨" 这条记忆
# 回复: "要不要点个披萨?"

4.3 工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌─────────────────────────────────────────────────────────┐
│ 长期记忆工作流程 │
├─────────────────────────────────────────────────────────┤
│ │
│ 步骤1: 保存记忆 │
│ ┌─────────────────┐ │
│ │ "我喜欢吃披萨" │ → Embedding → [0.12, -0.34, ...] │
│ └────────┬────────┘ ↓ │
│ │ ChromaDB 存储 │
│ ▼ │
│ ┌─────────────────┐ │
│ │ ID: memory_1 │ │
│ │ 向量: [0.12...]│ │
│ │ 原文: 我喜欢吃披萨 │
│ └─────────────────┘ │
│ │
│ 步骤2: 检索记忆 │
│ 用户: "我饿了" │
│ │ │
│ ▼ │
│ "我饿了" → Embedding → [0.11, -0.33, ...] │
│ │ │
│ ▼ │
│ ChromaDB 语义搜索 → 找到最相似的记忆 │
│ │ │
│ ▼ │
│ 找到: "我喜欢吃披萨" (相似度: 0.92) │
│ │
│ 步骤3: 生成回复 │
│ System: "## 用户记忆\n我喜欢吃披萨" │
│ LLM: "要不要点个披萨?" │
│ │
└─────────────────────────────────────────────────────────┘

4.4 特点总结

特点 说明
✅ 优点 持久化存储,支持语义搜索
❌ 缺点 首次加载较慢(需要初始化 Embedding 模型)
适用场景 个性化推荐、用户画像、跨会话记忆

5. 实战演示

5.1 项目结构

1
2
3
4
5
6
7
8
langchain_memory_demo/
├── main.py # 主入口,交互式演示
├── src/agent/
│ ├── model.py # 模型配置(LLM + Embedding)
│ ├── state.py # Agent 状态定义
│ └── memory/
│ ├── short_memory.py # 短期记忆实现
│ └── long_memory.py # 长期记忆实现

5.2 运行演示

1
2
3
4
5
6
7
8
9
# 克隆项目
git clone https://github.com/liupx/langchain_memory_demo
cd langchain_memory_demo

# 安装依赖
uv sync

# 运行
uv run python main.py

运行后会看到交互式菜单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
╔══════════════════════════════════════════════════════════════╗
║ 🎯 LangGraph 记忆机制演示 🎯 ║
║ 短期记忆 vs 长期记忆 ║
╚══════════════════════════════════════════════════════════════╝

📋 请选择功能:
1. 🎯 短期记忆 - 多轮对话演示
2. 🧠 长期记忆 - 语义搜索演示
3. ⚙️ 自定义记忆 - 添加自己的记忆
4. 🔍 查看短期记忆会话列表
5. 🔍 查看长期记忆内容
6. 🗑️ 清空短期记忆
7. 🧹 清空长期记忆
0. 🚪 退出程序

5.3 短期记忆演示

1
2
3
4
5
6
7
8
9
10
11
12
13
🎯 短期记忆模式
请告诉我你的名字:小明

🤖: 你好小明!很高兴认识你。

👤 你:我喜欢什么?
🤖: 你还没有告诉我你喜欢什么哦。

👤 你:我喜欢打篮球
🤖: 好的,我记住你喜欢打篮球了!

👤 你:我刚才说什么?
🤖: 你刚才说你喜欢打篮球。

5.4 长期记忆演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
🧠 长期记忆模式
请添加你的记忆(输入格式:记忆 你的内容)
添加记忆:我喜欢吃火锅
✅ 已保存:我喜欢吃火锅
添加记忆:我喜欢打篮球
✅ 已保存:我喜欢打篮球
添加记忆:完成

🎤 开始对话(AI 会根据记忆回复):
👤 你:我饿了

📚 检索到的记忆:
## 用户记忆
我喜欢吃火锅

🤖: 想必你饿了吧?要不要吃火锅?

6. 技术栈总结

技术 用途
LangGraph Agent 工作流框架
DeepSeek API LLM 推理模型(对话)
langchain-huggingface + sentence-transformers 本地 Embedding 模型(向量化)
ChromaDB 向量数据库(长期记忆持久化)

7. 常见问题

Q: 为什么用本地 Embedding 而不是 API?

A: 本地模型免费、离线可用,适合学习和小项目。生产环境可以用 OpenAI/DeepSeek 的 Embedding API。

Q: 长期记忆数据保存在哪里?

A: 保存在 src/agent/memory/chroma_db/ 目录,进程重启后不会丢失。

Q: 如何选择短期记忆还是长期记忆?

A:

  • 需要多轮对话、会话续接 → 短期记忆
  • 需要记住用户偏好、跨会话记忆 → 长期记忆
  • 两者可以同时使用!

Q: 如何扩展更多功能?

A: 可以添加:

  • 工具调用(Tools)
  • 多模态支持
  • 更复杂的记忆策略(如记忆分级、遗忘机制)

8. 总结

通过本文,我们学习了 LangChain/LangGraph 中的两种记忆机制:

记忆类型 实现方式 特点 适用场景
短期记忆 InMemorySaver 速度快,进程结束丢失 多轮对话
长期记忆 ChromaDB 持久化,语义搜索 用户画像、个性化推荐

核心要点

  1. 短期记忆通过 thread_id 区分不同会话
  2. 长期记忆通过 Embedding 实现语义搜索
  3. 两者可以结合使用,提供更好的用户体验

参考资源


关于作者:本文基于 langchain_memory_demo 项目编写,这是一个适合理解 LangGraph 记忆机制的实战入门项目。欢迎 Star 和 Fork!