Give Your AI Agent a Perfect Memory with Mem0 and OpenAI

Akram Chauhan
Akram Chauhan
11 min read322 views
Give Your AI Agent a Perfect Memory with Mem0 and OpenAI

Ever feel like you’re having the same conversation with your AI assistant over and over again? You tell it your preferences, what you’re working on, maybe even your dog’s name. The next day? Poof. It’s all gone. The AI is a clean slate, and you’re back to square one.

It’s one of the biggest frustrations in AI today. These incredibly powerful models can write poetry and code, but they often have the memory of a goldfish. They live in the moment, processing one request at a time without any real sense of history or continuity.

But what if we could change that? What if we could give our AI agents a persistent, long-term memory? A brain that remembers you, learns from your conversations, and uses that knowledge to give you truly personalized, context-aware responses.

That’s exactly what we’re going to build today. We're moving beyond simple chat history and creating a real memory layer. Using a fantastic open-source tool called Mem0, along with OpenAI and a local vector database called ChromaDB, we’ll build an AI that actually remembers.

Let’s get our hands dirty.

Getting Our Toolkit Ready

First things first, we need to set up our workshop. This just means installing a few Python libraries and getting our API key ready. Think of it as laying out all your tools on the workbench before you start building.

We’ll need mem0ai, the core library for memory, openai for the brains, rich for some nice-looking terminal output, and chromadb to store our memories locally.

You can install everything with one simple command:

pip install mem0ai openai rich chromadb -q

Next, we need to securely tell our code how to access OpenAI. We'll use a handy Python function to ask for your API key so it doesn't get saved in your code history.

import os
import getpass
from datetime import datetime

print("=" * 60)
print(" MEM0 Advanced Tutorial — API Key Setup")
print("=" * 60)

OPENAI_API_KEY = getpass.getpass("Enter your OpenAI API key: ")
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
print("\n API key set!\n")

With our key in place, we can initialize the main components. We’ll create an instance of the OpenAI client and, most importantly, our Memory object from Mem0.

from openai import OpenAI
from mem0 import Memory
from rich.console import Console
from rich import print as rprint

console = Console()
openai_client = OpenAI()

console.rule("[bold cyan]MODULE 1: Basic Memory Setup[/bold cyan]")

memory = Memory()

rprint(
    "[green]✓ Memory instance created with default config[/green]\n"
    " • LLM: gpt-4.1-nano (OpenAI)\n"
    " • Vector Store: ChromaDB (local)\n"
    " • Embedder: text-embedding-3-small"
)

Just like that, we have a memory system ready to go! By default, Mem0 sets itself up with a solid stack: a fast OpenAI model for processing, ChromaDB for local storage, and a powerful embedding model to understand the meaning behind our text.

Teaching Our AI About a User

Now for the fun part. A memory is useless if it’s empty, so let's start teaching our AI about a user. We’ll call her Alice.

Instead of just feeding it raw text, we’ll give it snippets of conversations. Mem0 is smart enough to listen in and pull out the important facts worth remembering.

Let's imagine a few chats Alice might have with her new assistant:

console.rule("[bold cyan]MODULE 2: Adding & Retrieving Memories[/bold cyan]")

USER_ID = "alice_tutorial"
print("\n Adding memories for user:", USER_ID)

conversations = [
    [
        {"role": "user", "content": "Hi! I'm Alice. I'm a software engineer who loves Python and machine learning."},
        {"role": "assistant", "content": "Nice to meet you Alice! Python and ML are great areas to be in."}
    ],
    [
        {"role": "user", "content": "I prefer dark mode in all my IDEs and I use VS Code as my main editor."},
        {"role": "assistant", "content": "Good to know! VS Code with dark mode is a popular combo."}
    ],
    [
        {"role": "user", "content": "I'm currently building a RAG pipeline for my company's internal docs. It's for a fintech startup."},
        {"role": "assistant", "content": "That's exciting! RAG pipelines are really valuable for enterprise use cases."}
    ],
    [
        {"role": "user", "content": "I have a dog named Max and I enjoy hiking on weekends."},
        {"role": "assistant", "content": "Max sounds lovely! Hiking is a great way to recharge."}
    ],
]

results = []
for i, convo in enumerate(conversations):
    result = memory.add(convo, user_id=USER_ID)
    extracted = result.get("results", [])
    for mem in extracted:
        results.append(mem)
    print(f" Conversation {i+1}: {len(extracted)} memory(ies) extracted")

print(f"\n Total memories stored: {len(results)}")

Look at that! We fed Mem0 four short conversations, and it automatically extracted and stored key facts about Alice. The user_id is crucial here—it’s like a label on a folder that ensures all of Alice’s memories are kept together.

Asking the AI What It Remembers

Okay, we’ve stored some memories. But how do we get them back out? This isn’t like a normal database where you need to know the exact keyword. We can ask questions in plain English. This is called "semantic search," and it’s a game-changer.

Let's quiz our AI about Alice:

console.rule("[bold cyan]MODULE 3: Semantic Search[/bold cyan]")

queries = [
    "What programming languages does the user prefer?",
    "What is Alice working on professionally?",
    "What are Alice's hobbies?",
    "What tools and IDE does Alice use?",
]

for query in queries:
    search_results = memory.search(query=query, user_id=USER_ID, limit=2)
    # ... (rich table formatting code omitted for brevity) ...
    # The output would show relevant memories for each query

When you run this, you'll see that for each question, Mem0 finds the most relevant memories it has stored. For "What are Alice's hobbies?", it will pull up the memory about her dog Max and hiking. It understands the meaning behind our questions, not just the words. Pretty cool, right?

Editing and Managing the AI's Memories

Sometimes, memories need to be updated. People change jobs, pick up new hobbies, or maybe the AI just misunderstood something. A good memory system needs to be manageable.

Mem0 gives us full control to Create, Read, Update, and Delete (CRUD) memories. Let's take a look at everything we've stored for Alice and then make a small update.

console.rule("[bold cyan]MODULE 4: CRUD Operations[/bold cyan]")

all_memories = memory.get_all(user_id=USER_ID)
memories_list = all_memories.get("results", [])

print(f"\n All memories for '{USER_ID}':")
for i, mem in enumerate(memories_list):
    print(f" [{i+1}] ID: {mem['id'][:8]}... → {mem['memory']}")

if memories_list:
    first_id = memories_list[0]["id"]
    original_text = memories_list[0]["memory"]
    print(f"\n Updating memory: '{original_text}'")
    memory.update(memory_id=first_id, data=original_text + " (confirmed)")
    updated = memory.get(memory_id=first_id)
    print(f" After update: '{updated['memory']}'")

Here, we list all of Alice's memories, grab the ID of the first one, and just add a little note to it. This shows how easy it is to keep the AI's knowledge base accurate and up-to-date.

The Payoff: A Conversation with Memory

This is the moment we've been building towards. Let's create a chat function that actually uses the memory layer.

Here’s the flow:

  1. When the user sends a message, we first search the memory for relevant facts.
  2. We inject those facts into a special system prompt for the AI.
  3. We let the AI generate a response, now armed with personal context.
  4. Finally, we save the new exchange back into memory, so the AI learns from every interaction.
console.rule("[bold cyan]MODULE 5: Memory-Augmented Chat[/bold cyan]")

def chat_with_memory(user_message: str, user_id: str, session_history: list) -> str:
    # 1. Search for relevant memories
    relevant = memory.search(query=user_message, user_id=user_id, limit=5)
    memory_context = "\n".join(
        f"- {r['memory']}" for r in relevant.get("results", [])
    ) or "No relevant memories found."

    # 2. Create a dynamic system prompt
    system_prompt = f"""You are a highly personalized AI assistant. You have access to long-term memories about this user.
RELEVANT USER MEMORIES:
{memory_context}
Use these memories to provide context-aware, personalized responses. Be natural — don't explicitly announce that you're using memories."""

    messages = [{"role": "system", "content": system_prompt}]
    messages.extend(session_history[-6:])
    messages.append({"role": "user", "content": user_message})

    # 3. Get the AI's response
    response = openai_client.chat.completions.create(
        model="gpt-4.1-nano-2025-04-14",
        messages=messages
    )
    assistant_response = response.choices[0].message.content

    # 4. Add the new conversation to memory
    exchange = [
        {"role": "user", "content": user_message},
        {"role": "assistant", "content": assistant_response}
    ]
    memory.add(exchange, user_id=user_id)
    
    session_history.append({"role": "user", "content": user_message})
    session_history.append({"role": "assistant", "content": assistant_response})
    
    return assistant_response

Now, let's test it out with a few questions for Alice:

session = []
demo_messages = [
    "Can you recommend a good IDE setup for me?",
    "What kind of project am I currently building at work?",
    "Suggest a weekend activity I might enjoy.",
]

print("\n Starting memory-augmented conversation with Alice...\n")
for msg in demo_messages:
    rprint(f"[bold yellow]User:[/bold yellow] {msg}")
    response = chat_with_memory(msg, USER_ID, session)
    rprint(f"[bold green]Assistant:[/bold green] {response}\n")

When you ask, "Can you recommend a good IDE setup for me?", the AI will remember Alice uses VS Code and prefers dark mode and might say something like, "Since you enjoy VS Code and prefer dark mode, you might like the 'One Dark Pro' theme..."

This is a world away from a generic, stateless response. It's personal. It's helpful. It's what an AI assistant should be.

Keeping Memories Separate: Multi-User Support

What if your application has more than one user? You can't have the AI mixing up Alice's preferences with Bob's. This is where that user_id we used earlier becomes so important. It acts as a firewall between different users' memories.

Let's quickly add another user, Bob, with completely different preferences.

console.rule("[bold cyan]MODULE 6: Multi-User Memory Isolation[/bold cyan]")

USER_BOB = "bob_tutorial"
bob_conversations = [
    [
        {"role": "user", "content": "I'm Bob, a data scientist specializing in computer vision and PyTorch."},
        {"role": "assistant", "content": "Great to meet you Bob!"}
    ],
    [
        {"role": "user", "content": "I prefer Jupyter notebooks over VS Code, and I use Vim keybindings."},
        {"role": "assistant", "content": "Classic setup for data science work!"}
    ],
]
for convo in bob_conversations:
    memory.add(convo, user_id=USER_BOB)

Now, if we ask the same question—"What programming tools does this user prefer?"—but specify the user_id for Alice and then for Bob, we get completely different, and correct, answers for each.

test_query = "What programming tools does this user prefer?"
alice_results = memory.search(query=test_query, user_id=USER_ID, limit=3)
bob_results = memory.search(query=test_query, user_id=USER_BOB, limit=3)

# The output will show VS Code for Alice and Jupyter for Bob

The memories are perfectly isolated. Alice has no idea Bob exists, and vice-versa. This is essential for building any real-world, multi-tenant application.

Going Deeper: Custom Configs, History, and Cleanup

We've only scratched the surface. Mem0 is incredibly flexible.

  • Custom Configuration: Don't like the default models or want to use a different vector database like Qdrant or Pinecone? No problem. You can define a custom configuration to swap out any component.
  • Memory History: You can easily pull a user's entire memory profile, complete with timestamps, to see how the AI's understanding of them has evolved over time.
  • Deletion: And of course, you can delete specific memories or wipe a user's entire history, which is crucial for privacy and data management.

So, What Did We Just Build?

Let's take a step back. In just a few lines of code, we've given an AI agent a sophisticated, long-term memory. We've built a system that can:

  • Automatically extract key facts from conversations.
  • Store those facts in a way that understands meaning.
  • Retrieve relevant memories using natural language.
  • Keep different users' memories completely separate.
  • Inject personal context into responses to create a truly personalized experience.

This is more than just a cool tech demo. It’s a fundamental shift in how we can build AI. By giving agents a memory, we turn them from amnesiac tools into continuous, learning companions. The potential for building smarter, more empathetic, and genuinely helpful AI is massive, and you now have the foundational skills to start exploring it.

Tags

AI OpenAI LLMs AI Engineering Vector Databases Software Development Persistent Memory Retrieval Augmented Generation (RAG) Conversational AI AI agents AI Assistants Human-AI interaction Long-Term Memory AI Mem0 Context-Aware AI

Stay Updated

Get the latest articles and insights delivered straight to your inbox.

We respect your privacy. Unsubscribe at any time.

Aicosoft

AI & Technology News, Insights & Innovation

AICOSOFT delivers cutting-edge AI news, technology breakthroughs, and innovation insights. Stay informed about artificial intelligence, machine learning, robotics, and the latest tech trends shaping tomorrow.

Connect With Us

© 2026 Aicosoft. All rights reserved.