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.

AI Large Model Application Practice
AI Large Model Application Practice
AI Large Model Application Practice
Building Personalized Long‑Term Memory for AI Agents with Mem0 and LangGraph

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.

Mem0 architecture diagram
Mem0 architecture diagram

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.

personalizationLLMLangGraphAI memoryMem0
AI Large Model Application Practice
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.