短期记忆使Agent能够在单次会话中维持对话的连贯性,而长期记忆则赋予了Agent跨会话学习和积累知识的能力。这样Agent能够构建持久的用户画像,形成经验库,并持续优化自身行为,从而提供真正个性化、智能化的服务。
长期记忆介绍
长期记忆是一种用于存储用户特定信息或应用级数据的系统,其核心特点是跨越会话和线程共享。与短期记忆局限于单一线程(thread_id)不同,长期记忆中的数据可以被任何时间、在任何线程中召回。其存储范围(作用域)被定义在自定义的命名空间中,而非单个线程ID内

在LangChain框架中,长期记忆通过存储(Store)组件来实现,Store允许你将记忆保存为JSON文档,并通过命名空间(namespace)和键(Key)进行组织和管理,便于后续的检索、更新与删除。
- 命名空间(namespace):类似于文件夹,用于对记忆进行逻辑分组(例如,按应用场景划分)。
- 键(key):命名空间内每个文档的唯一标识符。
Store存储支持基本的put(写入)、get(读取)、delete(删除)、search(搜索)操作
示例:
from langgraph.store.memory import InMemoryStore
store = InMemoryStore()
namespace = ("user1", "perferences")
#添加记忆
store.put(namespace, "fruit", {"likes": ["苹果", "香蕉"], "dislike": ["橙子"]})
#获取记忆
memory = store.get(namespace, "fruit")
print(memory)
store.put(namespace, "chat", {"language": "中文", "emotion": "高兴"})
memory = store.get(namespace, "chat")
print(memory)
#搜索所有记忆
memories = store.search(namespace)
print(memories)
#更新记忆
store.put(namespace, "chat",{"language": "英文", "emotion": "happy"})
memory = store.get(namespace, "chat")
print(memory)
#删除记忆
store.delete(namespace, "chat")
memory = store.get(namespace, "chat")
print(memory)
Agent中使用长期记忆方式
长期记忆的核心作用是实现跨会话、跨节点的数据共享。在 LangChain 中,单个 Agent 通过将 Store注入到不同会话(thread_id)中,实现跨会话状态持久化。Agent中设置长期记忆的方式和短期记忆类似,长期记忆可以存在内存或者数据库中
from langchain.agents import AgentState, create_agent
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.prebuilt import ToolRuntime
from langgraph.store.memory import InMemoryStore
from agent.my_llm import llm
class CustomerAgentState(AgentState):
user_id: str #用户唯一标识
store = InMemoryStore()
store.put(("users",), 123, {"name":"张三", "age": 28, "hobby": "旅游、滑雪、喝茶"})
store.put(("users",), 124, {"name":"李四", "age": 32, "hobby": "编程、阅读、电影"})
@tool
def get_user_info(runtime: ToolRuntime):
"""获取用户信息"""
user_id = runtime.state["user_id"]
store = runtime.store
if user_id:
item = store.get(("users",),user_id)
info = item.value
return f"姓名: {info['name']}, 年龄: {info['age']}岁, 爱好: {info['hobby']}"
return "用户不存在"
agent = create_agent(
model=llm,
tools=[get_user_info],
checkpointer= InMemorySaver(),
store=store,
state_schema=CustomerAgentState
)
# 使用相同thread_id维持对话上下文
config = {"configurable": {"thread_id": "123abc"}}
#对话
while True:
question = input("用户:")
if question != 'q' and question != 'quit':
resp = agent.invoke( input={"messages":[HumanMessage(content=question)], "user_id":123}, config=config)
print("AI:"+resp["messages"][-1].content)
else:
break
print("="*20)
#获取agent 记忆状态
state = agent.get_state(config)
print(type(state))
print(state)
config = {"configurable": {"thread_id": "124abc"}}
while True:
question = input("用户:")
if question != 'q' and question != 'quit':
resp = agent.invoke( input={"messages":[HumanMessage(content=question)], "user_id":124}, config=config)
print("AI:"+resp["messages"][-1].content)
else:
break
print("="*20)
#获取agent 记忆状态
state = agent.get_state(config)
print(type(state))
print(state)
Agent创建中通过Store参数指定长期记忆对象,使用长期记忆时,可以同时使用短期记忆(checkpointer指定),也可以不使用短期记忆,但一般两者会同时使用
使用数据库存储长期记忆,代码大体相同,大致如下:
# 配置 MySQL 连接 D
B_URI = "mysql+pymysql://root:123456@localhost:3306/langchain_db?charset=utf8mb4" with (
PyMySQLSaver.from_conn_string(DB_URI) as checkpointer,
PyMySQLStore.from_conn_string(DB_URI) as store
):
# 自动创建checkpointer数据库表(首次运行)
checkpointer.setup()
# 2. 自动创建store数据库表(首次运行)
store.setup()
"""其它代码和案例1相同 此处省略......"""
长期记忆的核心使用场景是在工具中进行读写操作。LangChain通过ToolRuntime将store和context注入到工具函数中,使工具能够访问和修改长期记忆。如下案例中通过工具使用长期记忆记录用户偏好。
import uuid
from typing import Literal
from langchain.agents import create_agent
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.prebuilt import ToolRuntime
from langgraph.store.memory import InMemoryStore
from pydantic import BaseModel, Field
from agent.my_llm import llm
class UserContext(BaseModel):
user_id: str
#定义工具输入的类型
class UserPreference(BaseModel):
category: Literal["color", "food", "music"] = Field(description="用户偏好类别必须是color,food,music中的一个")
preference: str = Field(description="具体偏好内容,如'红色'、'中国美食'等")
store = InMemoryStore()
checkpointer = InMemorySaver()
@tool(args_schema=UserPreference)
def save_user_preference(category: str, preference: str, runtime: ToolRuntime) -> str:
"""保存用户偏好到长期记忆"""
user_id = runtime.context.user_id
namespace = (user_id, "preferences")
memory_id = str(uuid.uuid4())
memory_value = {
"category": category,
"preference": preference
}
runtime.store.put(namespace, memory_id, memory_value)
return f"已成功保存你的{category}偏好:{preference}"
@tool
def get_user_preferences(runtime: ToolRuntime) -> str:
"""从长期记忆中获取用户特定类别的所有偏好"""
user_id = runtime.context.user_id
namespace = (user_id, "preferences")
memories = runtime.store.search(namespace)
if not memories:
return f"您还没有保存过偏好"
print("memories:", memories)
preferences_list = []
for mem in memories:
pref = mem.value
preferences_list.append(f"- 种类:{pref['category']},偏好:{pref['preference']}")
return f"你的偏好有: \n" + "\n".join(preferences_list)
agent = create_agent(
model=llm,
tools=[save_user_preference, get_user_preferences],
checkpointer=checkpointer,
store=store,
context_schema = UserContext
)
# 使用相同thread_id维持对话上下文
config = {"configurable": {"thread_id": "123abc"}}
#对话
while True:
question = input("用户:")
if question != 'q' and question != 'quit':
resp = agent.invoke(input={"messages":[HumanMessage(content=question)]}, context=UserContext(user_id='123456'), config=config)
print("AI:"+resp["messages"][-1].content)
else:
break
print("="*20)
#获取agent 记忆状态
state = agent.get_state(config)
print(type(state))
print(state)
短期记忆和长期记忆区别总结
如下是短期记忆和长期记忆区别:
| 对比维度 | 短期记忆(Short-term Memory) | 长期记忆(Long-term Memory) |
|---|---|---|
| 作用域 | 线程/会话范围记忆 (Thread-scoped)。与单个会话线程 (thread_id) 绑定。 | 跨线程/会话记忆。存储在自定义命名空间 (namespace) 中,可被多个线程共享。 |
| 核心目的 | 保证单次对话的连贯性和上下文感知。 | 实现跨对话的个性化、知识积累和持续学习。 |
| 主要存储内容 | 对话的原始历史 (messages列表) 以及当前会话的状态数据。 | 从交互中提炼的结构化知识(如用户事实、行为经验、优化规则)。 |
| 管理组件 | 检查点 (Checkpointer),如 InMemorySaver、PyMySQLSaver。 | 存储 (Store),如 InMemoryStore、PostgresStore。 |
| 生命周期 | 随线程的创建而开始,随线程的销毁(或超时清理)而结束。 | 独立于任何特定线程,除非被显式删除,否则永久或长期存在。 |
| 访问方式 | 自动管理。Agent的状态在每个步骤后自动持久化到检查点,并在下次恢复。 | 手动控制。必须在工具(Tool) 或自定义逻辑中,通过代码显式地调用 store.put()或 store.get()。 |
| 典型应用场景 | 维持聊天上下文,让Agent记得用户在当前对话中刚说过的话。 | 记住用户的身份、偏好、历史行为。 |