Building Personalized Long‑Term Memory for AI Agents with Mem0 and LangGraph
This tutorial explains why AI agents need durable, personalized long‑term memory, introduces the open‑source Mem0 solution, shows how Mem0 works with LLMs and vector stores, and provides step‑by‑step code to integrate Mem0 into a LangGraph workflow for adaptive, user‑specific interactions.
Why Long‑Term Memory Matters for AI Agents
AI agents require memory to extract, store, and later retrieve important information from conversations. Short‑term memory caches the current context, while long‑term memory provides persistent, fast retrieval across sessions, users, and even different applications, enabling truly personalized experiences.
Mem0: An Open‑Source Long‑Term Memory Solution
Mem0 is a popular open‑source library that adds a dedicated memory layer for LLM‑based applications. It offers APIs for managing memory, leverages LLMs and embedding models to generate and update memories, and relies on a vector or graph database for storage and semantic search.
How Mem0 Works
Mem0 provides a simple memory‑management API. When a user interacts, Mem0 uses an LLM to extract factual snippets, stores them as embeddings in a vector store (e.g., Chroma), and performs semantic search to retrieve the most relevant memories for the current query. The backend can be a vector database or a graph database.
Creating a Mem0 Memory Object
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
# Personalized long‑term memory using a Chroma vector store
mem0 = Memory.from_config({
"version": "v1.1",
"llm": {
"provider": "openai",
"config": {"model": "gpt-4o-mini"}
},
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "chat_memory",
"path": "./db"
}
}
})Building a LangGraph Workflow with Mem0
The workflow defines a state containing the message list and a mem0_user_id to isolate memories per user. Before the LLM generates a response, the workflow searches Mem0 for relevant memories, assembles them into a system message, and then calls the LLM. After each turn, the new interaction is added back to Mem0.
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"]
# Retrieve personalized memories
memories = mem0.search(messages[-1].content, user_id=user_id)["results"]
context = "Relevant past information:
"
for memory in memories:
context += f"- {memory['memory']}
"
system_message = SystemMessage(content=f"You are a helpful assistant. Use the following context to personalize your reply.
{context}")
full_messages = [system_message] + messages
llm = ChatOpenAI(model="gpt-4o-mini").bind_tools(tools)
response = llm.invoke(full_messages)
# Store the interaction
mem0.add(f"User: {messages[-1].content}
Assistant: {response.content}", user_id=user_id)
return {"messages": [response]}
def should_continue(state):
last_message = state["messages"][-1]
return "end" if not last_message.tool_calls else "continue"
workflow = StateGraph(State)
workflow.add_node("llm", chatbot)
workflow.add_node("search", tool_node)
workflow.set_entry_point("llm")
workflow.add_conditional_edges("llm", should_continue, {"continue": "search", "end": END})
workflow.add_edge("search", "llm")
graph = workflow.compile()Testing the Agent’s Memory
A simple REPL demonstrates that after a few interactions the agent remembers user preferences (e.g., love of football, dislike of flying) across restarts when the same mem0_user_id is used.
if __name__ == "__main__":
print("AI: Hello! How can I help you?")
mem0_user_id = "testuser"
while True:
user_input = 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)Conclusion
By integrating Mem0, developers can quickly add durable, adaptive memory to AI agents, enabling personalized recommendations, customer support, personal assistants, and more. The combination of Mem0’s LLM‑driven memory extraction, vector‑store retrieval, and LangGraph’s flexible workflow makes building truly personalized AI applications straightforward.
AI Large Model Application Practice
Focused on deep research and development of large-model applications. Authors of "RAG Application Development and Optimization Based on Large Models" and "MCP Principles Unveiled and Development Guide". Primarily B2B, with B2C as a supplement.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
