基于 LangGraph 与 Mem0 实现 AI Agent 的长期记忆与个性化体验
AI Agent(智能体)的记忆能力被视为构建高级人工智能应用的基础。它负责提取、存储会话中的重要信息,并支持后续的检索与使用。记忆通常分为短期记忆与长期记忆:短期记忆用于缓存单次会话的上下文与推理过程;而长期记忆则为 AI 智能体提供了持久的重要信息存储与快速检索能力,使其能够跨越多次交互记住用户偏好。
目前,无论是 LangChain、LlamaIndex 等底层 LLM 框架,还是低代码平台,在短期记忆(Context Window/Session History)方面已有相对完善的解决方案。但在长期记忆能力的实现上,特别是更智能的个性化记忆能力,往往存在不足。传统的 RAG(检索增强生成)方案侧重于知识库检索,而非用户个人历史的动态记忆管理。
本文介绍一种广受欢迎的 AI 记忆开源解决方案:Mem0。Mem0 是一个专为基于 LLM 的 AI 应用设计的独立记忆层,旨在解决跨应用、跨会话的持久化、智能化记忆问题。
一、AI 应用需要怎样的长期记忆
在实际应用场景中,我们希望 AI 应用能够提供一种更个性化的人工智能体验。随着时间推移,AI 应能记住每个使用者的独特信息,包括个人资料、专业细节、偏好、个人计划、习惯等,并在未来的交互中轻松检索这些信息,从而实现更具针对性的服务。
典型的应用场景包括:
- 个性化的 AI 学习助手:记住不同学员的学习特点、薄弱环节与习惯,提供定制化的教学路径。
- 个性化的 AI 客户服务:根据客户的历史交互记录、购买偏好与投诉历史,提供更智能的服务响应。
- 个性化的 AI 个人助理:根据个人日程偏好、沟通风格与生活习惯,提供更有吸引力的日程管理与建议。
- 个性化的 AI 医疗咨询:根据咨询者的既往病史、用药记录与过敏信息,辅助医生或系统做出更精准的健康建议。
这些需求的核心在于信息需要在跨越多用户、多次会话、甚至多个 AI 应用时保留与高效检索。
此外,参考人类的记忆机制,理想的 AI 长期记忆还应具备以下特性:
- 智能记忆提取:并非简单存储对话历史,而是通过 LLM 理解语义,提取重要事实与关联信息。例如,从旅游规划对话中识别客户偏好的酒店类型、出行频率及预算范围。
- 自适应学习:随着用户不断使用,系统能持续提高个性化信息的丰富性与准确性。例如,在多次对话中逐步完善对客户职业背景与兴趣爱好的画像。
- 动态更新与遗忘:根据新的交互信息动态更新记忆内容,同时及时遗忘过时信息。例如,当识别到使用者工作发生变动时,自动更新之前的职业记忆。
- 精准的检索与响应:优先召回最近且最相关的记忆信息,确保上下文的时效性。例如,回忆客户最近的用餐爱好进行推荐,而非半年前的偏好。
以上这些能力要求,正是 Mem0 已经具备的核心特性。
二、Mem0 的工作原理与架构
简单来说,Mem0 就是为基于 LLM 的 AI 应用而设计的独立记忆层。它通过 API 帮助 AI 应用实现跨应用的持久、智能、自适应与动态的长期记忆与回忆能力。
核心构成
Mem0 的主要工作流程依赖于以下几个关键组件:
- 记忆管理 API:提供简单的接口(如
add, search, update)集成到现有应用中。
- LLM 与嵌入模型:利用大语言模型进行智能的信息提取、摘要与更新;利用嵌入模型将记忆转化为向量表示。
- 向量数据库或图数据库:作为后端存储,组织、存储与检索记忆向量。支持 Chroma、Pinecone、Weaviate 等多种存储后端。
处理流程
以添加记忆(add 方法)为例,其核心处理过程如下:
- 输入接收:接收原始对话文本或事件描述。
- LLM 提取:调用 LLM 分析输入,提取关键事实(Facts),过滤噪音,判断是否需要更新现有记忆。
- 向量化:将提取出的记忆事实转换为向量。
- 存储:将向量存入向量数据库,并关联用户 ID(User ID)。
- 合并与去重:如果新信息与旧记忆冲突,LLM 会协助决定是覆盖、合并还是忽略。
由于借助了 LLM 进行语义理解,提示词(Prompt)的设计至关重要。开发者可以在创建 Memory 对象时,设置 custom_prompt 参数来定制记忆提取的逻辑,例如指定只提取特定类型的偏好信息。
三、用 LangGraph + Mem0 创建个性化体验的 AI Agent
LangGraph 是 LangChain 推出的用于构建有状态多智能体应用(Stateful Multi-Agent Applications)的库。结合 Mem0,我们可以创建一个具有强大长期记忆能力的 Agent。
1. 环境准备
首先安装必要的依赖包:
pip install mem0 langgraph langchain-openai langchain-community chromadb tavily-python
2. 初始化 Mem0 记忆对象
我们需要配置 Mem0 使用 OpenAI 作为 LLM 提供商,Chroma 作为向量数据库。OpenAI Key 需配置在环境变量中。
from mem0 import Memory
from typing import Annotated, TypedDict, List
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.prebuilt import ToolNode
import os
mem0 = Memory.from_config({
"version": "v1.1",
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4o-mini",
"api_key": os.getenv("OPENAI_API_KEY")
}
},
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "chat_memory",
"path": "./db",
}
}
})
3. 定义 LangGraph 状态与工作流
为了区分不同用户的记忆,必须在 State 中保留一个 mem0_user_id。这是实现多用户隔离的关键。
class State(TypedDict):
messages: Annotated[List[HumanMessage | AIMessage], add_messages]
mem0_user_id: str
tools = [TavilySearchResults(max_results=1)]
tool_node = ToolNode(tools)
def chatbot(state: State):
messages = state["messages"]
user_id = state["mem0_user_id"]
memories = mem0.search(messages[-1].content, user_id=user_id)["results"]
context = "历史对话中的相关信息有:\n"
for memory in memories:
context += f"- {memory['memory']}\n"
system_message = SystemMessage(
content=f"你是一个乐于助人的客户支持助手。利用所提供的上下文来个性化你的回复,并会记住用户的偏好和过去的交互。\n{context}"
)
full_messages = [system_message] + messages
llm = ChatOpenAI(model="gpt-4o-mini").bind_tools(tools)
response = llm.invoke(full_messages)
conversation_text = f"User: {messages[-1].content}\nAssistant: {response.content}"
mem0.add(conversation_text, user_id=user_id)
return {"messages": [response]}
():
messages = state[]
last_message = messages[-]
last_message.tool_calls:
:
workflow = StateGraph(State)
workflow.add_node(, chatbot)
workflow.add_node(, tool_node)
workflow.set_entry_point()
workflow.add_conditional_edges(
,
should_continue,
{
: ,
: END,
},
)
workflow.add_edge(, )
graph = workflow.()
4. 测试 Agent 的记忆能力
编写测试脚本模拟多轮对话,验证记忆是否被正确保存和检索。
if __name__ == "__main__":
print("AI: 你好!有什么可以帮助你?")
mem0_user_id = "testuser_001"
while True:
user_input = input("输入:")
if user_input.lower() in ['quit', 'exit', 'bye']:
break
config = {"configurable": {"thread_id": mem0_user_id}}
state = {
"messages": [HumanMessage(content=user_input)],
"mem0_user_id": mem0_user_id
}
response = graph.invoke(state, config)
print("AI:", response["messages"][-1].content)
5. 效果验证
运行上述代码,我们可以观察到以下行为:
- 首次交互:用户告知 AI 自己最近爱看足球、不喜欢坐飞机、对历史文化名城感兴趣。
- 记忆存储:Agent 将这些信息通过 Mem0 存入向量数据库。
- 重启会话:退出程序并重新运行,再次输入相同用户 ID。
- 记忆检索:AI 能够主动提及之前用户提到的足球爱好,并据此推荐相关活动。
- 个性化规划:当用户请求旅行建议时,AI 会自动避开飞机选项,并推荐历史文化名城,无需用户重复说明偏好。
注意:Agent 的记忆是与 user_id 绑定的。如果更换 user_id,系统将视为新用户,不会获得之前的记忆信息,从而开始创建新的用户记忆。这保证了数据隐私和多租户隔离。
四、进阶优化与最佳实践
在实际生产环境中部署此类系统时,还需考虑以下因素以提升稳定性和性能。
1. 记忆更新策略
Mem0 默认会根据新输入动态更新记忆。但在某些场景下,可能需要更精细的控制。例如,对于敏感信息(如密码、身份证号),不应被提取为记忆。可以通过自定义 Prompt 限制提取范围,或在 add 方法前增加数据清洗步骤。
2. 检索优化
在 chatbot 节点中,我们直接调用了 mem0.search。为了提高检索准确率,可以参考 RAG(检索增强生成)的优化技巧:
- 混合检索:结合关键词检索与向量检索。
- 重排序(Rerank):对检索到的记忆片段进行相关性打分排序,仅取 Top-K 个放入 Context。
- 查询改写:在搜索前,利用 LLM 将用户当前问题改写为更适合检索的陈述句。
3. 成本控制
每次对话都调用 LLM 进行记忆提取和检索会增加 Token 消耗。建议:
- 使用小模型(如 gpt-4o-mini)处理记忆任务。
- 降低记忆检索的频率,例如每 N 次对话才检索一次。
- 定期清理过期记忆,减少向量库体积。
4. 错误处理
网络波动或 API 超时可能导致记忆写入失败。建议在 mem0.add 周围包裹 try-except 块,确保即使记忆写入失败,主对话流程仍能正常进行,避免阻塞用户体验。
五、总结
借助 Mem0,你可以快速地给自己的 AI 应用与智能体添加额外的持久记忆体,以记住用户偏好、曾经的互动、任务的进度等,从而构建自适应的学习与记忆能力,实现完全个性化的 AI 应用体验。这在个人助理、客户服务、智能咨询、企业生产力应用等领域都可以有广泛的应用。
相比于传统的 Session 管理,Mem0 提供了一种更语义化、更持久的记忆方式。结合 LangGraph 的状态管理机制,开发者可以构建出既具备复杂逻辑处理能力,又拥有'人情味'的智能体系统。未来,随着多模态记忆支持的完善,AI Agent 的记忆能力将更加接近人类,为下一代人机交互奠定坚实基础。