[docs] Essential cookbook added and overall revamp to the structure of cookbooks (#3668)

This commit is contained in:
Parth Sharma
2025-10-27 00:19:29 +05:30
committed by GitHub
parent 2c18355dd2
commit 7be32641c7
46 changed files with 3356 additions and 226 deletions
+125
View File
@@ -0,0 +1,125 @@
---
title: AI Tutor with Mem0
description: "Keep student progress and preferences persistent across tutoring sessions."
---
You can create a personalized AI Tutor using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
## Overview
The Personalized AI Tutor leverages Mem0 to retain information across interactions, enabling a tailored learning experience. By integrating with OpenAI's GPT-4 model, the tutor can provide detailed and context-aware responses to user queries.
## Setup
Before you begin, ensure you have the required dependencies installed. You can install the necessary packages using pip:
```bash
pip install openai mem0ai
```
## Full Code Example
Below is the complete code to create and interact with a Personalized AI Tutor using Mem0:
```python
import os
from openai import OpenAI
from mem0 import Memory
# Set the OpenAI API key
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
# Initialize the OpenAI client
client = OpenAI()
class PersonalAITutor:
def __init__(self):
"""
Initialize the PersonalAITutor with memory configuration and OpenAI client.
"""
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333,
}
},
}
self.memory = Memory.from_config(config)
self.client = client
self.app_id = "app-1"
def ask(self, question, user_id=None):
"""
Ask a question to the AI and store the relevant facts in memory
:param question: The question to ask the AI.
:param user_id: Optional user ID to associate with the memory.
"""
# Start a streaming response request to the AI
response = self.client.responses.create(
model="gpt-4.1-nano-2025-04-14",
instructions="You are a personal AI Tutor.",
input=question,
stream=True
)
# Store the question in memory
self.memory.add(question, user_id=user_id, metadata={"app_id": self.app_id})
# Print the response from the AI in real-time
for event in response:
if event.type == "response.output_text.delta":
print(event.delta, end="")
def get_memories(self, user_id=None):
"""
Retrieve all memories associated with the given user ID.
:param user_id: Optional user ID to filter memories.
:return: List of memories.
"""
return self.memory.get_all(user_id=user_id)
# Instantiate the PersonalAITutor
ai_tutor = PersonalAITutor()
# Define a user ID
user_id = "john_doe"
# Ask a question
ai_tutor.ask("I am learning introduction to CS. What is queue? Briefly explain.", user_id=user_id)
```
### Fetching Memories
You can fetch all the memories at any point in time using the following code:
```python
memories = ai_tutor.get_memories(user_id=user_id)
for m in memories['results']:
print(m['memory'])
```
## Key Points
- **Initialization**: The PersonalAITutor class is initialized with the necessary memory configuration and OpenAI client setup
- **Asking Questions**: The ask method sends a question to the AI and stores the relevant information in memory
- **Retrieving Memories**: The get_memories method fetches all stored memories associated with a user
## Conclusion
As the conversation progresses, Mem0's memory automatically updates based on the interactions, providing a continuously improving personalized learning experience. This setup ensures that the AI Tutor can offer contextually relevant and accurate responses, enhancing the overall educational process.
---
<CardGroup cols={2}>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Learn the foundations of memory-powered companions with production-ready patterns.
</Card>
<Card title="Travel Assistant with Mem0" icon="plane" href="/cookbooks/companions/travel-assistant">
Build a travel companion that remembers preferences and past conversations.
</Card>
</CardGroup>
@@ -0,0 +1,83 @@
---
title: Local Companion with Mem0 and Ollama
description: "Run Mem0 end-to-end on your machine using Ollama-powered LLMs and embedders."
---
Mem0 can be utilized entirely locally by leveraging Ollama for both the embedding model and the language model (LLM). This guide will walk you through the necessary steps and provide the complete code to get you started.
## Overview
By using Ollama, you can run Mem0 locally, which allows for greater control over your data and models. This setup uses Ollama for both the embedding model and the language model, providing a fully local solution.
## Setup
Before you begin, ensure you have Mem0 and Ollama installed and properly configured on your local machine.
## Full Code Example
Below is the complete code to set up and use Mem0 locally with Ollama:
```python
from mem0 import Memory
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"collection_name": "test",
"host": "localhost",
"port": 6333,
"embedding_model_dims": 768, # Change this according to your local model's dimensions
},
},
"llm": {
"provider": "ollama",
"config": {
"model": "llama3.1:latest",
"temperature": 0,
"max_tokens": 2000,
"ollama_base_url": "http://localhost:11434", # Ensure this URL is correct
},
},
"embedder": {
"provider": "ollama",
"config": {
"model": "nomic-embed-text:latest",
# Alternatively, you can use "snowflake-arctic-embed:latest"
"ollama_base_url": "http://localhost:11434",
},
},
}
# Initialize Memory with the configuration
m = Memory.from_config(config)
# Add a memory
m.add("I'm visiting Paris", user_id="john")
# Retrieve memories
memories = m.get_all(user_id="john")
```
## Key Points
- **Configuration**: The setup involves configuring the vector store, language model, and embedding model to use local resources
- **Vector Store**: Qdrant is used as the vector store, running on localhost
- **Language Model**: Ollama is used as the LLM provider, with the `llama3.1:latest` model
- **Embedding Model**: Ollama is also used for embeddings, with the `nomic-embed-text:latest` model
## Conclusion
This local setup of Mem0 using Ollama provides a fully self-contained solution for memory management and AI interactions. It allows for greater control over your data and models while still leveraging the powerful capabilities of Mem0.
---
<CardGroup cols={2}>
<Card title="Configure Open Source" icon="gear" href="/open-source/configuration">
Explore advanced configuration options for vector stores, LLMs, and embedders.
</Card>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Learn core companion patterns that work with any LLM provider.
</Card>
</CardGroup>
@@ -0,0 +1,139 @@
---
title: Node.js Companion with Mem0
description: "Build a JavaScript fitness coach that remembers user goals run after run."
---
You can create a personalized AI Companion using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
## Overview
The Personalized AI Companion leverages Mem0 to retain information across interactions, enabling a tailored learning experience. It creates memories for each user interaction and integrates with OpenAI's GPT models to provide detailed and context-aware responses to user queries.
## Setup
Before you begin, ensure you have Node.js installed and create a new project. Install the required dependencies using npm:
```bash
npm install openai mem0ai
```
## Full Code Example
Below is the complete code to create and interact with an AI Companion using Mem0:
```javascript
import { OpenAI } from 'openai';
import { Memory } from 'mem0ai/oss';
import * as readline from 'readline';
const openaiClient = new OpenAI();
const memory = new Memory();
async function chatWithMemories(message, userId = "default_user") {
const relevantMemories = await memory.search(message, { userId: userId });
const memoriesStr = relevantMemories.results
.map(entry => `- ${entry.memory}`)
.join('\n');
const systemPrompt = `You are a helpful AI. Answer the question based on query and memories.
User Memories:
${memoriesStr}`;
const messages = [
{ role: "system", content: systemPrompt },
{ role: "user", content: message }
];
const response = await openaiClient.chat.completions.create({
model: "gpt-4.1-nano-2025-04-14",
messages: messages
});
const assistantResponse = response.choices[0].message.content || "";
messages.push({ role: "assistant", content: assistantResponse });
await memory.add(messages, { userId: userId });
return assistantResponse;
}
async function main() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
console.log("Chat with AI (type 'exit' to quit)");
const askQuestion = () => {
return new Promise((resolve) => {
rl.question("You: ", (input) => {
resolve(input.trim());
});
});
};
try {
while (true) {
const userInput = await askQuestion();
if (userInput.toLowerCase() === 'exit') {
console.log("Goodbye!");
rl.close();
break;
}
const response = await chatWithMemories(userInput, "sample_user");
console.log(`AI: ${response}`);
}
} catch (error) {
console.error("An error occurred:", error);
rl.close();
}
}
main().catch(console.error);
```
### Key Components
1. **Initialization**
- The code initializes both OpenAI and Mem0 Memory clients
- Uses Node.js's built-in readline module for command-line interaction
2. **Memory Management (chatWithMemories function)**
- Retrieves relevant memories using Mem0's search functionality
- Constructs a system prompt that includes past memories
- Makes API calls to OpenAI for generating responses
- Stores new interactions in memory
3. **Interactive Chat Interface (main function)**
- Creates a command-line interface for user interaction
- Handles user input and displays AI responses
- Includes graceful exit functionality
### Environment Setup
Make sure to set up your environment variables:
```bash
export OPENAI_API_KEY=your_api_key
```
### Conclusion
This implementation demonstrates how to create an AI Companion that maintains context across conversations using Mem0's memory capabilities. The system automatically stores and retrieves relevant information, creating a more personalized and context-aware interaction experience.
As users interact with the system, Mem0's memory system continuously learns and adapts, making future responses more relevant and personalized. This setup is ideal for creating long-term learning AI assistants that can maintain context and provide increasingly personalized responses over time.
---
<CardGroup cols={2}>
<Card title="Build AI with Personality" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Separate user and agent memories to keep your companion's personality consistent.
</Card>
<Card title="Quickstart Demo with Mem0" icon="rocket" href="/cookbooks/companions/quickstart-demo">
Run the full showcase app to see memory-powered companions in action.
</Card>
</CardGroup>
@@ -0,0 +1,80 @@
---
title: Quickstart Demo with Mem0
description: "Spin up the showcase companion app to see Mem0 memories in action."
---
You can create a personalized AI Companion using Mem0. This guide will walk you through the necessary steps and provide the complete setup instructions to get you started.
<video
autoPlay
muted
loop
playsInline
className="w-full aspect-video rounded-lg"
src="https://github.com/user-attachments/assets/cebc4f8e-bdb9-4837-868d-13c5ab7bb433"
></video>
You can try the [Mem0 Demo](https://mem0-4vmi.vercel.app) live here.
## Overview
The Personalized AI Companion leverages Mem0 to retain information across interactions, enabling a tailored learning experience. It creates memories for each user interaction and integrates with OpenAI's GPT models to provide detailed and context-aware responses to user queries.
## Setup
Before you begin, follow these steps to set up the demo application:
1. Clone the Mem0 repository:
```bash
git clone https://github.com/mem0ai/mem0.git
```
2. Navigate to the demo application folder:
```bash
cd mem0/examples/mem0-demo
```
3. Install dependencies:
```bash
pnpm install
```
4. Set up environment variables by creating a `.env` file in the project root with the following content:
```bash
OPENAI_API_KEY=your_openai_api_key
MEM0_API_KEY=your_mem0_api_key
```
You can obtain your `MEM0_API_KEY` by signing up at [Mem0 API Dashboard](https://app.mem0.ai/dashboard/api-keys).
5. Start the development server:
```bash
pnpm run dev
```
## Enhancing the Next.js Application
Once the demo is running, you can customize and enhance the Next.js application by modifying the components in the `mem0-demo` folder. Consider:
- Adding new memory features to improve contextual retention
- Customizing the UI to better suit your application needs
- Integrating additional APIs or third-party services to extend functionality
## Full Code
You can find the complete source code for this demo on GitHub:
[Mem0 Demo GitHub](https://github.com/mem0ai/mem0/tree/main/examples/mem0-demo)
## Conclusion
This setup demonstrates how to build an AI Companion that maintains memory across interactions using Mem0. The system continuously adapts to user interactions, making future responses more relevant and personalized. Experiment with the application and enhance it further to suit your use case!
---
<CardGroup cols={2}>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Deep dive into production patterns for fitness coaches, tutors, and assistants.
</Card>
<Card title="Node.js Companion with Mem0" icon="code" href="/cookbooks/companions/nodejs-companion">
Implement a command-line companion using the Node.js SDK.
</Card>
</CardGroup>
@@ -0,0 +1,214 @@
---
title: Travel Assistant with Mem0
description: "Plan itineraries that remember traveler preferences across trips."
---
Create a personalized AI Travel Assistant using Mem0. This guide provides step-by-step instructions and the complete code to get you started.
## Overview
The Personalized AI Travel Assistant uses Mem0 to store and retrieve information across interactions, enabling a tailored travel planning experience. It integrates with OpenAI's GPT-4 model to provide detailed and context-aware responses to user queries.
## Setup
Install the required dependencies using pip:
```bash
pip install openai mem0ai
```
## Full Code Example
Here's the complete code to create and interact with a Personalized AI Travel Assistant using Mem0:
<CodeGroup>
```python After v1.1
import os
from openai import OpenAI
from mem0 import Memory
# Set the OpenAI API key
os.environ['OPENAI_API_KEY'] = "sk-xxx"
config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"temperature": 0.1,
"max_tokens": 2000,
}
},
"embedder": {
"provider": "openai",
"config": {
"model": "text-embedding-3-large"
}
},
"vector_store": {
"provider": "qdrant",
"config": {
"collection_name": "test",
"embedding_model_dims": 3072,
}
},
"version": "v1.1",
}
class PersonalTravelAssistant:
def __init__(self):
self.client = OpenAI()
self.memory = Memory.from_config(config)
self.messages = [{"role": "system", "content": "You are a personal AI Assistant."}]
def ask_question(self, question, user_id):
# Fetch previous related memories
previous_memories = self.search_memories(question, user_id=user_id)
# Build the prompt
system_message = "You are a personal AI Assistant."
if previous_memories:
prompt = f"{system_message}\n\nUser input: {question}\nPrevious memories: {', '.join(previous_memories)}"
else:
prompt = f"{system_message}\n\nUser input: {question}"
# Generate response using Responses API
response = self.client.responses.create(
model="gpt-4.1-nano-2025-04-14",
input=prompt
)
# Extract answer from the response
answer = response.output[0].content[0].text
# Store the question in memory
self.memory.add(question, user_id=user_id)
return answer
def get_memories(self, user_id):
memories = self.memory.get_all(user_id=user_id)
return [m['memory'] for m in memories['results']]
def search_memories(self, query, user_id):
memories = self.memory.search(query, user_id=user_id)
return [m['memory'] for m in memories['results']]
# Usage example
user_id = "traveler_123"
ai_assistant = PersonalTravelAssistant()
def main():
while True:
question = input("Question: ")
if question.lower() in ['q', 'exit']:
print("Exiting...")
break
answer = ai_assistant.ask_question(question, user_id=user_id)
print(f"Answer: {answer}")
memories = ai_assistant.get_memories(user_id=user_id)
print("Memories:")
for memory in memories:
print(f"- {memory}")
print("-----")
if __name__ == "__main__":
main()
```
```python Before v1.1
import os
from openai import OpenAI
from mem0 import Memory
# Set the OpenAI API key
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
class PersonalTravelAssistant:
def __init__(self):
self.client = OpenAI()
self.memory = Memory()
self.messages = [{"role": "system", "content": "You are a personal AI Assistant."}]
def ask_question(self, question, user_id):
# Fetch previous related memories
previous_memories = self.search_memories(question, user_id=user_id)
prompt = question
if previous_memories:
prompt = f"User input: {question}\n Previous memories: {previous_memories}"
self.messages.append({"role": "user", "content": prompt})
# Generate response using gpt-4.1-nano
response = self.client.chat.completions.create(
model="gpt-4.1-nano-2025-04-14"2025-04-14",
messages=self.messages
)
answer = response.choices[0].message.content
self.messages.append({"role": "assistant", "content": answer})
# Store the question in memory
self.memory.add(question, user_id=user_id)
return answer
def get_memories(self, user_id):
memories = self.memory.get_all(user_id=user_id)
return [m['memory'] for m in memories.get('results', [])]
def search_memories(self, query, user_id):
memories = self.memory.search(query, user_id=user_id)
return [m['memory'] for m in memories.get('results', [])]
# Usage example
user_id = "traveler_123"
ai_assistant = PersonalTravelAssistant()
def main():
while True:
question = input("Question: ")
if question.lower() in ['q', 'exit']:
print("Exiting...")
break
answer = ai_assistant.ask_question(question, user_id=user_id)
print(f"Answer: {answer}")
memories = ai_assistant.get_memories(user_id=user_id)
print("Memories:")
for memory in memories:
print(f"- {memory}")
print("-----")
if __name__ == "__main__":
main()
```
</CodeGroup>
## Key Components
- **Initialization**: The `PersonalTravelAssistant` class is initialized with the OpenAI client and Mem0 memory setup.
- **Asking Questions**: The `ask_question` method sends a question to the AI, incorporates previous memories, and stores new information.
- **Memory Management**: The `get_memories` and search_memories methods handle retrieval and searching of stored memories.
## Usage
1. Set your OpenAI API key in the environment variable.
2. Instantiate the `PersonalTravelAssistant`.
3. Use the `main()` function to interact with the assistant in a loop.
## Conclusion
This Personalized AI Travel Assistant leverages Mem0's memory capabilities to provide context-aware responses. As you interact with it, the assistant learns and improves, offering increasingly personalized travel advice and information.
---
<CardGroup cols={2}>
<Card title="Tag and Organize Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories">
Use categories to organize travel preferences, destinations, and user context.
</Card>
<Card title="AI Tutor with Mem0" icon="graduation-cap" href="/cookbooks/companions/ai-tutor">
Build an educational companion that remembers learning progress and preferences.
</Card>
</CardGroup>
@@ -0,0 +1,548 @@
---
title: Voice Companion with Mem0 and OpenAI
description: "Pair the OpenAI Agents SDK with Mem0 to build a voice assistant that remembers."
---
This guide demonstrates how to combine OpenAI's Agents SDK for voice applications with Mem0's memory capabilities to create a voice assistant that remembers user preferences and past interactions.
## Prerequisites
Before you begin, make sure you have:
1. Installed OpenAI Agents SDK with voice dependencies:
```bash
pip install 'openai-agents[voice]'
```
2. Installed Mem0 SDK:
```bash
pip install mem0ai
```
3. Installed other required dependencies:
```bash
pip install numpy sounddevice pydantic
```
4. Set up your API keys:
- OpenAI API key for the Agents SDK
- Mem0 API key from the Mem0 Platform
## Code Breakdown
Let's break down the key components of this implementation:
### 1. Setting Up Dependencies and Environment
```python
# OpenAI Agents SDK imports
from agents import (
Agent,
function_tool
)
from agents.voice import (
AudioInput,
SingleAgentVoiceWorkflow,
VoicePipeline
)
from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
# Mem0 imports
from mem0 import AsyncMemoryClient
# Set up API keys (replace with your actual keys)
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
# Define a global user ID for simplicity
USER_ID = "voice_user"
# Initialize Mem0 client
mem0_client = AsyncMemoryClient()
```
This section handles:
- Importing required modules from OpenAI Agents SDK and Mem0
- Setting up environment variables for API keys
- Defining a simple user identification system (using a global variable)
- Initializing the Mem0 client that will handle memory operations
### 2. Memory Tools with Function Decorators
The `@function_tool` decorator transforms Python functions into callable tools for the OpenAI agent. Here are the key memory tools:
#### Storing User Memories
```python
import logging
# Set up logging at the top of your file
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
force=True
)
logger = logging.getLogger("memory_voice_agent")
# Then use logger in your function tools
@function_tool
async def save_memories(
memory: str
) -> str:
"""Store a user memory in memory."""
# This will be visible in your console
logger.debug(f"Saving memory: {memory} for user {USER_ID}")
# Store the preference in Mem0
memory_content = f"User memory - {memory}"
await mem0_client.add(
memory_content,
user_id=USER_ID,
)
return f"I've saved your memory: {memory}"
```
This function:
- Takes a memory string
- Creates a formatted memory string
- Stores it in Mem0 using the `add()` method
- Includes metadata to categorize the memory for easier retrieval
- Returns a confirmation message that the agent will speak
#### Finding Relevant Memories
```python
@function_tool
async def search_memories(
query: str
) -> str:
"""
Find memories relevant to the current conversation.
Args:
query: The search query to find relevant memories
"""
print(f"Finding memories related to: {query}")
results = await mem0_client.search(
query,
user_id=USER_ID,
limit=5,
threshold=0.7, # Higher threshold for more relevant results
)
# Format and return the results
if not results.get('results', []):
return "I don't have any relevant memories about this topic."
memories = [f"• {result['memory']}" for result in results.get('results', [])]
return "Here's what I remember that might be relevant:\n" + "\n".join(memories)
```
This tool:
- Takes a search query string
- Passes it to Mem0's semantic search to find related memories
- Sets a threshold for relevance to ensure quality results
- Returns a formatted list of relevant memories or a default message
### 3. Creating the Voice Agent
```python
def create_memory_voice_agent():
# Create the agent with memory-enabled tools
agent = Agent(
name="Memory Assistant",
instructions=prompt_with_handoff_instructions(
"""You're speaking to a human, so be polite and concise.
Always respond in clear, natural English.
You have the ability to remember information about the user.
Use the save_memories tool when the user shares an important information worth remembering.
Use the search_memories tool when you need context from past conversations or user asks you to recall something.
""",
),
model="gpt-4.1-nano-2025-04-14",
tools=[save_memories, search_memories],
)
return agent
```
This function:
- Creates an OpenAI Agent with specific instructions
- Configures it to use gpt-4.1-nano (you can use other models)
- Registers the memory-related tools with the agent
- Uses `prompt_with_handoff_instructions` to include standard voice agent behaviors
### 4. Microphone Recording Functionality
```python
async def record_from_microphone(duration=5, samplerate=24000):
"""Record audio from the microphone for a specified duration."""
print(f"Recording for {duration} seconds...")
# Create a buffer to store the recorded audio
frames = []
# Callback function to store audio data
def callback(indata, frames_count, time_info, status):
frames.append(indata.copy())
# Start recording
with sd.InputStream(samplerate=samplerate, channels=1, callback=callback, dtype=np.int16):
await asyncio.sleep(duration)
# Combine all frames into a single numpy array
audio_data = np.concatenate(frames)
return audio_data
```
This function:
- Creates a simple asynchronous microphone recording function
- Uses the sounddevice library to capture audio input
- Stores frames in a buffer during recording
- Combines frames into a single numpy array when complete
- Returns the audio data for processing
### 5. Main Loop and Voice Processing
```python
async def main():
# Create the agent
agent = create_memory_voice_agent()
# Set up the voice pipeline
pipeline = VoicePipeline(
workflow=SingleAgentVoiceWorkflow(agent)
)
# Configure TTS settings
pipeline.config.tts_settings.voice = "alloy"
pipeline.config.tts_settings.speed = 1.0
try:
while True:
# Get user input
print("\nPress Enter to start recording (or 'q' to quit)...")
user_input = input()
if user_input.lower() == 'q':
break
# Record and process audio
audio_data = await record_from_microphone(duration=5)
audio_input = AudioInput(buffer=audio_data)
result = await pipeline.run(audio_input)
# Play response and handle events
player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16)
player.start()
agent_response = ""
print("\nAgent response:")
async for event in result.stream():
if event.type == "voice_stream_event_audio":
player.write(event.data)
elif event.type == "voice_stream_event_content":
content = event.data
agent_response += content
print(content, end="", flush=True)
# Save the agent's response to memory
if agent_response:
try:
await mem0_client.add(
f"Agent response: {agent_response}",
user_id=USER_ID,
metadata={"type": "agent_response"}
)
except Exception as e:
print(f"Failed to store memory: {e}")
except KeyboardInterrupt:
print("\nExiting...")
```
This main function orchestrates the entire process:
1. Creates the memory-enabled voice agent
2. Sets up the voice pipeline with TTS settings
3. Implements an interactive loop for recording and processing voice input
4. Handles streaming of response events (both audio and text)
5. Automatically saves the agent's responses to memory
6. Includes proper error handling and exit mechanisms
## Create a Memory-Enabled Voice Agent
Now that we've explained each component, here's the complete implementation that combines OpenAI Agents SDK for voice with Mem0's memory capabilities:
```python
import asyncio
import os
import logging
from typing import Optional, List, Dict, Any
import numpy as np
import sounddevice as sd
from pydantic import BaseModel
# OpenAI Agents SDK imports
from agents import (
Agent,
function_tool
)
from agents.voice import (
AudioInput,
SingleAgentVoiceWorkflow,
VoicePipeline
)
from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
# Mem0 imports
from mem0 import AsyncMemoryClient
# Set up API keys (replace with your actual keys)
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
# Define a global user ID for simplicity
USER_ID = "voice_user"
# Initialize Mem0 client
mem0_client = AsyncMemoryClient()
# Create tools that utilize Mem0's memory
@function_tool
async def save_memories(
memory: str
) -> str:
"""
Store a user memory in memory.
Args:
memory: The memory to save
"""
print(f"Saving memory: {memory} for user {USER_ID}")
# Store the preference in Mem0
memory_content = f"User memory - {memory}"
await mem0_client.add(
memory_content,
user_id=USER_ID,
)
return f"I've saved your memory: {memory}"
@function_tool
async def search_memories(
query: str
) -> str:
"""
Find memories relevant to the current conversation.
Args:
query: The search query to find relevant memories
"""
print(f"Finding memories related to: {query}")
results = await mem0_client.search(
query,
user_id=USER_ID,
limit=5,
threshold=0.7, # Higher threshold for more relevant results
)
# Format and return the results
if not results.get('results', []):
return "I don't have any relevant memories about this topic."
memories = [f"• {result['memory']}" for result in results.get('results', [])]
return "Here's what I remember that might be relevant:\n" + "\n".join(memories)
# Create the agent with memory-enabled tools
def create_memory_voice_agent():
# Create the agent with memory-enabled tools
agent = Agent(
name="Memory Assistant",
instructions=prompt_with_handoff_instructions(
"""You're speaking to a human, so be polite and concise.
Always respond in clear, natural English.
You have the ability to remember information about the user.
Use the save_memories tool when the user shares an important information worth remembering.
Use the search_memories tool when you need context from past conversations or user asks you to recall something.
""",
),
model="gpt-4.1-nano-2025-04-14",
tools=[save_memories, search_memories],
)
return agent
async def record_from_microphone(duration=5, samplerate=24000):
"""Record audio from the microphone for a specified duration."""
print(f"Recording for {duration} seconds...")
# Create a buffer to store the recorded audio
frames = []
# Callback function to store audio data
def callback(indata, frames_count, time_info, status):
frames.append(indata.copy())
# Start recording
with sd.InputStream(samplerate=samplerate, channels=1, callback=callback, dtype=np.int16):
await asyncio.sleep(duration)
# Combine all frames into a single numpy array
audio_data = np.concatenate(frames)
return audio_data
async def main():
print("Starting Memory Voice Agent")
# Create the agent and context
agent = create_memory_voice_agent()
# Set up the voice pipeline
pipeline = VoicePipeline(
workflow=SingleAgentVoiceWorkflow(agent)
)
# Configure TTS settings
pipeline.config.tts_settings.voice = "alloy"
pipeline.config.tts_settings.speed = 1.0
try:
while True:
# Get user input
print("\nPress Enter to start recording (or 'q' to quit)...")
user_input = input()
if user_input.lower() == 'q':
break
# Record and process audio
audio_data = await record_from_microphone(duration=5)
audio_input = AudioInput(buffer=audio_data)
print("Processing your request...")
# Process the audio input
result = await pipeline.run(audio_input)
# Create an audio player
player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16)
player.start()
# Store the agent's response for adding to memory
agent_response = ""
print("\nAgent response:")
# Play the audio stream as it comes in
async for event in result.stream():
if event.type == "voice_stream_event_audio":
player.write(event.data)
elif event.type == "voice_stream_event_content":
# Accumulate and print the text response
content = event.data
agent_response += content
print(content, end="", flush=True)
print("\n")
# Example of saving the conversation to Mem0 after completion
if agent_response:
try:
await mem0_client.add(
f"Agent response: {agent_response}",
user_id=USER_ID,
metadata={"type": "agent_response"}
)
except Exception as e:
print(f"Failed to store memory: {e}")
except KeyboardInterrupt:
print("\nExiting...")
if __name__ == "__main__":
asyncio.run(main())
```
## Key Features of This Implementation
This implementation offers several key features:
1. **Simplified User Management**: Uses a global `USER_ID` variable for simplicity, but can be extended to manage multiple users.
2. **Real Microphone Input**: Includes a `record_from_microphone()` function that captures actual voice input from your microphone.
3. **Interactive Voice Loop**: Implements a continuous interaction loop, allowing for multiple back-and-forth exchanges.
4. **Memory Management Tools**:
- `save_memories`: Stores user memories in Mem0
- `search_memories`: Searches for relevant past information
5. **Voice Configuration**: Demonstrates how to configure TTS settings for the voice response.
## Running the Example
To run this example:
1. Replace the placeholder API keys with your actual keys
2. Make sure your microphone is properly connected
3. Run the script with Python 3.8 or newer
4. Press Enter to start recording, then speak your request
5. Press 'q' to quit the application
The agent will listen to your request, process it through the OpenAI model, utilize Mem0 for memory operations as needed, and respond both through text output and voice speech.
## Best Practices for Voice Agents with Memory
1. **Optimizing Memory for Voice**: Keep memories concise and relevant for voice responses.
2. **Forgetting Mechanism**: Implement a way to delete or expire memories that are no longer relevant.
3. **Context Preservation**: Store enough context with each memory to make retrieval effective.
4. **Error Handling**: Implement robust error handling for memory operations, as voice interactions should continue smoothly even if memory operations fail.
## Conclusion
By combining OpenAI's Agents SDK with Mem0's memory capabilities, you can create voice agents that maintain persistent memory of user preferences and past interactions. This significantly enhances the user experience by making conversations more natural and personalized.
As you build your voice application, experiment with different memory strategies and filtering approaches to find the optimal balance between comprehensive memory and efficient retrieval for your specific use case.
## Debugging Function Tools
When working with the OpenAI Agents SDK, you might notice that regular `print()` statements inside `@function_tool` decorated functions don't appear in your console output. This is because the Agents SDK captures and redirects standard output when executing these functions.
To effectively debug your function tools, use Python's `logging` module instead:
```python
import logging
# Set up logging at the top of your file
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
force=True
)
logger = logging.getLogger("memory_voice_agent")
# Then use logger in your function tools
@function_tool
async def save_memories(
memory: str
) -> str:
"""Store a user memory in memory."""
# This will be visible in your console
logger.debug(f"Saving memory: {memory} for user {USER_ID}")
# Rest of your function...
```
---
<CardGroup cols={2}>
<Card title="Multimodal Support" icon="image" href="/platform/features/multimodal-support">
Learn how to add vision and audio memory alongside voice interactions.
</Card>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Master the core patterns for building memory-powered companions.
</Card>
</CardGroup>
@@ -0,0 +1,68 @@
---
title: YouTube Research with Mem0
description: "Layer personalized context over any video using the Mem0 YouTube assistant."
---
Enhance your YouTube experience with Mem0's YouTube Assistant, a Chrome extension that brings AI-powered chat directly to your YouTube videos. Get instant, personalized answers about video content while leveraging your own knowledge and memories, all without leaving the page.
## Features
- **Contextual AI Chat**: Ask questions about videos you're watching
- **Seamless Integration**: Chat interface sits alongside YouTube's native UI
- **Memory Integration**: Personalized responses based on your knowledge through Mem0
- **Real-Time Memory**: Memories are updated in real-time based on your interactions
## Demo Video
<video
autoPlay
muted
loop
playsInline
width="700"
height="400"
src="https://github.com/user-attachments/assets/c0334ccd-311b-4dd7-8034-ef88204fc751"
></video>
## Installation
This extension is not available on the Chrome Web Store yet. You can install it manually using below method:
### Manual Installation (Developer Mode)
1. **Download the Extension**: Clone or download the extension files from the [Mem0 GitHub repository](https://github.com/mem0ai/mem0/tree/main/examples)
2. **Build**: Run `npm install` followed by `npm run build` to install the dependencies and build the extension
3. **Access Chrome Extensions**: Open Google Chrome and navigate to `chrome://extensions`
4. **Enable Developer Mode**: Toggle the "Developer mode" switch in the top right corner
5. **Load Unpacked Extension**: Click "Load unpacked" and select the directory containing the extension files
6. **Confirm Installation**: The Mem0 YouTube Assistant Extension should now appear in your Chrome toolbar
## Setup
1. **Configure API Settings**: Click the extension icon and enter your OpenAI API key (required to use the extension)
2. **Customize Settings**: Configure additional settings such as model, temperature, and memory settings
3. **Navigate to YouTube**: Start using the assistant on any YouTube video
4. **Memories**: Enter your Mem0 API key to enable personalized responses, and feed initial memories from settings
## Example Prompts
- "Can you summarize the main points of this video?"
- "Explain the concept they just mentioned"
- "How does this relate to what I already know?"
- "What are some practical applications of this topic related to my work?"
## Privacy and Data Security
Your API keys are stored locally in your browser. Your messages are sent to the Mem0 API for extracting and retrieving memories. Mem0 is committed to ensuring your data's privacy and security.
---
<CardGroup cols={2}>
<Card title="Tag and Organize Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories">
Categorize video insights to build a searchable research knowledge base.
</Card>
<Card title="Deep Research with Mem0" icon="magnifying-glass" href="/cookbooks/operations/deep-research">
Combine memory with search tools to conduct comprehensive research projects.
</Card>
</CardGroup>
@@ -0,0 +1,525 @@
---
title: Build a Mem0 Companion
description: "Spin up a fitness coach that remembers goals, adapts tone, and keeps sessions personal."
---
Essentially, creating a companion out of LLMs is as simple as a loop. But these loops work great for one type of character without personalization and fall short as soon as you restart the chat.
Problem: LLMs are stateless. GPT doesn't remember conversations. You could stuff everything inside the context window, but that becomes slow, expensive, and breaks at scale.
The solution: Mem0. It extracts and stores what matters from conversations, then retrieves it when needed. Your companion remembers user preferences, past events, and history.
In this cookbook we'll build a **fitness companion** that:
- Remembers user goals across sessions
- Recalls past workouts and progress
- Adapts its personality based on user preferences
- Handles both short-term context (today's chat) and long-term memory (months of history)
By the end, you'll have a working fitness companion and know how to handle common production challenges.
---
## The Basic Loop with Memory
Max wants to train for a marathon. He starts chatting with Ray, an AI running coach.
```python
from openai import OpenAI
from mem0 import MemoryClient
openai_client = OpenAI(api_key="your-openai-key")
mem0_client = MemoryClient(api_key="your-mem0-key")
def chat(user_input, user_id):
# Retrieve relevant memories
memories = mem0_client.search(user_input, user_id=user_id, limit=5)
context = "\\n".join(m["memory"] for m in memories["results"])
# Call LLM with memory context
response = openai_client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": f"You're Ray, a running coach. Memories:\\n{context}"},
{"role": "user", "content": user_input}
]
).choices[0].message.content
# Store the exchange
mem0_client.add([
{"role": "user", "content": user_input},
{"role": "assistant", "content": response}
], user_id=user_id)
return response
```
**Session 1:**
```python
chat("I want to run a marathon in under 4 hours", user_id="max")
# Output: "That's a solid goal. What's your current weekly mileage?"
# Stored in Mem0: "Max wants to run sub-4 marathon"
```
**Session 2 (next day, app restarted):**
```python
chat("What should I focus on today?", user_id="max")
# Output: "Based on your sub-4 marathon goal, let's work on building your aerobic base..."
```
<Info>
Ray remembers Max's goal across sessions. The app restarted, but the memory persisted. This is the core pattern: retrieve memories, pass them as context, store new exchanges.
</Info>
Ray remembers. Restart the app, and the goal persists. From here on, we'll focus on just the Mem0 API calls.
---
## Organizing Memory by Type
### Separating Temporary from Permanent
Max mentions his knee hurts. That's different from his marathon goal - one is temporary, the other is long-term.
**Categories vs Metadata:**
- **Categories**: AI-assigned by Mem0 based on content (you can't force them)
- **Metadata**: Manually set by you for forced tagging
Define custom categories at the project level. Mem0 will automatically tag memories with relevant categories based on content:
```python
mem0_client.project.update(custom_categories=[
{"goals": "Race targets and training objectives"},
{"constraints": "Injuries, limitations, recovery needs"},
{"preferences": "Training style, surfaces, schedules"}
])
```
<Note>
**Categories vs Metadata:** Categories are AI-assigned by Mem0 based on content semantics. You define the palette, Mem0 picks which ones apply. If you need guaranteed tagging, use `metadata` instead.
</Note>
Now when you add memories, Mem0 automatically assigns the appropriate categories:
```python
# Add goal - Mem0 automatically tags it as "goals"
mem0_client.add(
[{"role": "user", "content": "Sub-4 marathon is my A-race"}],
user_id="max"
)
# Add constraint - Mem0 automatically tags it as "constraints"
mem0_client.add(
[{"role": "user", "content": "My right knee flares up on downhills"}],
user_id="max"
)
```
Mem0 reads the content and intelligently picks which categories apply. You define the palette, it handles the tagging.
**Important:** You cannot force specific categories. Mem0's platform decides which categories are relevant based on content. If you need to force-tag something, use `metadata` instead:
```python
# Force tag using metadata (not categories)
mem0_client.add(
[{"role": "user", "content": "Some workout note"}],
user_id="max",
metadata={"workout_type": "speed", "forced_tag": "custom_label"}
)
```
### Filtering by Category
Retrieve just constraints for workout planning:
```python
constraints = mem0_client.search(
"injury concerns",
user_id="max",
filters={"categories": {"in": ["constraints"]}}
)
print([m["memory"] for m in constraints["results"]])
# Output: ["Max's right knee flares up on downhills"]
```
Ray can plan workouts that avoid aggravating Max's knee, without pulling in race goals or other unrelated memories.
---
## Filtering What Gets Stored
### The Problem
Run the basic loop for a week and check what's stored:
```python
memories = mem0_client.get_all(user_id="max")
print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "hey", "lol ok", "cool thanks", "gtg bye"]
```
<Warning>
Without filters, Mem0 stores everything—greetings, filler, and casual chat. This pollutes retrieval: instead of pulling "marathon goal," you get "lol ok." Set custom instructions to keep memory clean.
</Warning>
Noise. Greetings and filler clutter the memory.
### Custom Instructions
Tell Mem0 what matters:
```python
mem0_client.project.update(custom_instructions="""
Extract from running coach conversations:
- Training goals and race targets
- Physical constraints or injuries
- Training preferences (time of day, surfaces, weather)
- Progress milestones
Exclude:
- Greetings and filler
- Casual chatter
- Hypotheticals unless planning related
""")
```
Now chat again:
```python
chat("hey how's it going", user_id="max")
chat("I prefer trail running over roads", user_id="max")
memories = mem0_client.get_all(user_id="max")
print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "Max prefers trail running over roads"]
```
<Info>
**Expected output:** Only 2 memories stored—the marathon goal and trail preference. The greeting "hey how's it going" was filtered out automatically. Custom instructions are working.
</Info>
Only meaningful facts. Filler gets dropped automatically.
---
---
## Agent Memory for Personality
### Why Agents Need Memory Too
Max prefers direct feedback, not motivational fluff. Ray needs to remember how to communicate - that's agent memory, separate from user memory.
Store agent personality:
```python
mem0_client.add(
[{"role": "system", "content": "Max wants direct, data-driven feedback. Skip motivational language."}],
agent_id="ray_coach"
)
```
Retrieve agent style alongside user memories:
```python
# Get coach personality
agent_memories = mem0_client.search("coaching style", agent_id="ray_coach")
# Output: ["Max wants direct, data-driven feedback. Skip motivational language."]
# Store conversations with agent_id
mem0_client.add([
{"role": "user", "content": "How'd my run look today?"},
{"role": "assistant", "content": "Pace was 8:15/mile. Heart rate 152, zone 2."}
], user_id="max", agent_id="ray_coach")
```
<Info>
**Expected behavior:** Ray's responses are now data-driven and direct. The agent memory stored the coaching style preference, so future responses adapt automatically without Max having to repeat his preference.
</Info>
No "Great job!" or "Keep it up!" - just data. Ray adapts to Max's preference.
---
## Managing Short-Term Context
### When to Store in Mem0
Don't send every single message to Mem0. Keep recent context in memory, let Mem0 handle the important long-term facts.
```python
# Store only meaningful exchanges in Mem0
mem0_client.add([
{"role": "user", "content": "I want to run a marathon"},
{"role": "assistant", "content": "Let's build a training plan"}
], user_id="max")
# Skip storing filler
# "hey" → don't store
# "cool thanks" → don't store
# Or rely on custom_instructions to filter automatically
```
Last 10 messages in your app's buffer. Important facts in Mem0. Faster, cheaper, still works.
---
## Time-Bound Memories
### Auto-Expiring Facts
Max tweaks his ankle. It'll heal in two weeks - the memory should expire too.
```python
from datetime import datetime, timedelta
expiration = (datetime.now() + timedelta(days=14)).strftime("%Y-%m-%d")
mem0_client.add(
[{"role": "user", "content": "Rolled my left ankle, needs rest"}],
user_id="max",
expiration_date=expiration
)
```
In 14 days, this memory disappears automatically. Ray stops asking about the ankle.
---
## Putting It All Together
Here's the Mem0 setup combining everything:
```python
from mem0 import MemoryClient
from datetime import datetime, timedelta
mem0_client = MemoryClient(api_key="your-mem0-key")
# Configure memory filtering and categories
mem0_client.project.update(
custom_instructions="""
Extract: goals, constraints, preferences, progress
Exclude: greetings, filler, casual chat
""",
custom_categories=[
{"name": "goals", "description": "Training targets"},
{"name": "constraints", "description": "Injuries and limitations"},
{"name": "preferences", "description": "Training style"}
]
)
```
**Week 1 - Store goals and preferences:**
```python
mem0_client.add([
{"role": "user", "content": "I want to run a sub-4 marathon"},
{"role": "assistant", "content": "Got it. Let's build a training plan."}
], user_id="max", agent_id="ray", categories=["goals"])
mem0_client.add([
{"role": "user", "content": "I prefer trail running over roads"}
], user_id="max", categories=["preferences"])
```
**Week 3 - Temporary injury with expiration:**
```python
expiration = (datetime.now() + timedelta(days=14)).strftime("%Y-%m-%d")
mem0_client.add(
[{"role": "user", "content": "Rolled ankle, need light workouts"}],
user_id="max",
categories=["constraints"],
expiration_date=expiration
)
```
**Retrieve for context:**
```python
memories = mem0_client.search("training plan", user_id="max", limit=5)
# Gets: marathon goal, trail preference, ankle injury (if still valid)
```
Ray remembers goals, preferences, and personality. Handles temporary injuries. Works across sessions.
---
## Common Production Patterns
### Episodic Stories with run_id
Training for Boston is different from training for New York. Separate the memory threads:
```python
mem0_client.add(messages, user_id="max", run_id="boston-2025")
mem0_client.add(messages, user_id="max", run_id="nyc-2025")
# Retrieve only Boston memories
boston_memories = mem0_client.search(
"training plan",
user_id="max",
run_id="boston-2025"
)
```
Each race gets its own episodic boundary. No cross-contamination.
### Importing Historical Data
Max has 6 months of training logs to backfill:
```python
old_logs = [
[{"role": "user", "content": "Completed 20-mile long run"}],
[{"role": "user", "content": "Hit 8:00 pace on tempo run"}],
]
for log in old_logs:
mem0_client.add(log, user_id="max")
```
### Handling Contradictions
Max changes his goal from sub-4 to sub-3:45:
```python
# Find the old memory
memories = mem0_client.get_all(user_id="max")
goal_memory = [m for m in memories["results"] if "sub-4" in m["memory"]][0]
# Update it
mem0_client.update(goal_memory["id"], "Max wants to run sub-3:45 marathon")
```
Update instead of creating duplicates.
### Multiple Agents
Max works with Ray for running and Jordan for strength training:
```python
chat("easy run today", user_id="max", agent_id="ray")
chat("leg day workout", user_id="max", agent_id="jordan")
```
Each coach maintains separate personality memory while sharing user context.
### Filtering by Date
Prioritize recent training over old data:
```python
recent = mem0_client.search(
"training progress",
user_id="max",
filters={"created_at": {"gte": "2025-10-01"}}
)
```
### Metadata Tagging
Tag workouts by type:
```python
mem0_client.add(
[{"role": "user", "content": "10x400m intervals"}],
user_id="max",
metadata={"workout_type": "speed", "intensity": "high"}
)
# Later, find all speed workouts
speed_sessions = mem0_client.search(
"speed work",
user_id="max",
filters={"metadata": {"workout_type": "speed"}}
)
```
### Pruning Old Memories
Delete irrelevant memories:
```python
mem0_client.delete(memory_id="mem_xyz")
# Or clear an entire run_id
mem0_client.delete_all(user_id="max", run_id="old-training-cycle")
```
---
## What You Built
A companion that:
- **Persists across sessions** - Mem0 storage
- **Filters noise** - custom instructions
- **Organizes by type** - categories
- **Adapts personality** - **`agent_id`**
- **Stays fast** - short-term buffer
- **Handles temporal facts** - expiration
- **Scales to production** - batching, metadata, pruning
This pattern works for any companion: fitness coaches, tutors, roleplay characters, therapy bots, creative writing partners.
---
<Tip>
Start with 2-3 categories max (e.g., goals, constraints, preferences). More categories dilute tagging accuracy. You can always add more later after seeing what Mem0 extracts.
</Tip>
---
## Production Checklist
Before launching:
- Set custom instructions for your domain
- Define 2-3 categories (goals, constraints, preferences)
- Add expiration strategy for time-bound facts
- Implement error handling for API calls
- Monitor memory quality in Mem0 dashboard
- Clear test data from production project
---
<CardGroup cols={2}>
<Card title="Build AI with Personality" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Separate user and agent memories so companions stay consistent across sessions.
</Card>
<Card title="Tag Support Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories">
Organize customer context to keep assistants responsive at scale.
</Card>
</CardGroup>
@@ -0,0 +1,603 @@
---
title: Scope User vs Agent Memories
description: "Use **user_id** and **agent_id** to balance personalization with consistent assistant behavior."
---
# Build AI with Distinct Personalities
While building memory systems for AI apps, you need to juggle between agent and user memories. The user delivers information from their side, but there's often value inside the agent's responses as well.
Unlike other memory APIs, we built one that allows you the flexibility to store memory from all sources. User and agent memories in Mem0 are handled by:
- **user_id** - Memories about specific users
- **agent_id** - Memories from the agent itself
In this guide, you'll see how these parameters work together, along with practical examples to help you build a fitness coach that remembers user workouts while maintaining a consistent coaching personality.
---
## User Memories
Let's start by tracking individual user workouts. We'll use **`user_id`** to keep each person's data separate.
```python
from openai import OpenAI
from mem0 import MemoryClient
import os
openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
mem0_client = MemoryClient()
# Sarah logs her workout
mem0_client.add(
"Completed 5K run in 28 minutes - felt great!",
user_id="sarah"
)
# Mike logs his workout
mem0_client.add(
"Bench press: 185 lbs x 10 reps, 3 sets",
user_id="mike"
)
```
Now when we coach Sarah, we retrieve only her workout history:
```python
# Get Sarah's workout history
sarah_history = mem0_client.search(
"What exercises has Sarah done recently?",
filters={"user_id": "sarah"}
)
# Generate coaching advice
response = openai_client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You're a supportive fitness coach."},
{"role": "user", "content": f"Based on this history: {sarah_history}, suggest the next workout."}
]
)
print(response.choices[0].message.content)
```
**Output:**
```
Great job on that 5K! Your endurance is building nicely. Let's add some
strength work to complement your running. Try 3 sets of bodyweight squats
(15 reps each) to strengthen your legs and improve your running power.
```
<Info>
**Expected output:** Sarah gets running advice based on her 5K, not Mike's bench press data. The **`user_id`** filter ensures memories are isolated—each user only sees their own workout history.
</Info>
This works perfectly! Each user has private workout history, and Sarah never sees Mike's data.
---
## Adding Coach Personality
Our fitness coach needs a consistent personality - supportive, motivational, and celebrates small wins. Let's see what happens if we try storing this with **`user_id`**:
```python
# Adding coach personality for Sarah
mem0_client.add(
"I'm a supportive fitness coach who celebrates every achievement and uses athlete-focused language",
user_id="sarah"
)
# Adding the same personality for Mike
mem0_client.add(
"I'm a supportive fitness coach who celebrates every achievement and uses athlete-focused language",
user_id="mike"
)
# For 1,000 users, we'd repeat this 1,000 times...
```
This approach has some limitations:
1. **Duplication**: We're storing the same coaching personality 1,000 times for 1,000 users
2. **Hard to update**: Want to change the coaching style? Update 1,000 memories
3. **Mixed with user data**: Coach personality and user workouts are stored together, making queries complex
<Warning>
Storing agent personality with **`user_id`** doesn't scale. For 10,000 users, you'd duplicate the same personality 10,000 times. Updating the coaching style means updating 10,000 separate memories. This wastes storage and makes maintenance impossible.
</Warning>
What if the coach could have a personality that's shared across all users?
---
## Agent Memories
Here's where **`agent_id`** comes in. We can store the coach's personality once and share it across all users:
```python
# Store coach personality ONCE with agent_id
mem0_client.add(
"I'm FitCoach - a supportive fitness coach who celebrates every achievement. "
"I use motivational language, focus on progress over perfection, and help users build sustainable habits.",
agent_id="fitcoach_v1"
)
# Sarah's workout (still private)
mem0_client.add(
"Completed 5K run in 28 minutes",
user_id="sarah"
)
# Mike's workout (still private)
mem0_client.add(
"Bench press: 185 lbs x 10 reps, 3 sets",
user_id="mike"
)
```
Now when coaching Sarah, we retrieve both the agent's personality AND her workout history:
```python
# Get both coach personality and Sarah's workouts
coaching_context = mem0_client.search(
"coaching context for Sarah",
filters={
"OR": [
{"agent_id": "fitcoach_v1"}, # Coach personality
{"user_id": "sarah"} # Sarah's workout history
]
}
)
# Generate personalized coaching
response = openai_client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": str(coaching_context)},
{"role": "user", "content": "What should I focus on in my next workout?"}
]
)
print(response.choices[0].message.content)
```
**Output:**
```
Amazing work on that 5K! 🎉 You're crushing your running goals!
Now let's build some complementary strength. I recommend adding bodyweight
squats to your routine - they'll make you an even stronger runner. Start
with 3 sets of 15 reps, and remember: progress over perfection!
```
Notice how the response has the motivational tone (from **`agent_id`**) combined with personalized advice based on Sarah's 5K run (from **`user_id`**).
The coach personality is now:
- ✅ Stored once, shared by all users
- ✅ Easy to update (change one memory, affects all users)
- ✅ Cleanly separated from user workout data
<Info>
**Expected behavior:** The response combines the motivational tone (from **`agent_id`**) with Sarah's specific 5K progress (from **`user_id`**). One agent personality, infinite users—update the agent once, and all users get the new coaching style.
</Info>
---
## Combining Both: Relationship Memories
There's a third type of memory - one that captures the relationship between a specific user and the coach. To store these, use `metadata` to track which agent the relationship is with:
```python
# Coach personality (shared across all users)
mem0_client.add(
"I'm FitCoach - supportive and motivational",
agent_id="fitcoach_v1"
)
# Sarah's workout data (private to Sarah)
mem0_client.add(
"Goal: Run a half marathon by June. Currently runs 5K comfortably.",
user_id="sarah"
)
# Sarah-Coach relationship (stored as user memory with agent context in metadata)
mem0_client.add(
"Sarah and I have an inside joke: 'No pain, no protein shake!' "
"She responds best to gentle encouragement after tough workouts.",
user_id="sarah",
metadata={"agent_id": "fitcoach_v1", "type": "relationship"}
)
# Mike-Coach relationship (different from Sarah's)
mem0_client.add(
"Mike prefers data-driven feedback with specific numbers and percentages. "
"Less motivational talk, more concrete metrics.",
user_id="mike",
metadata={"agent_id": "fitcoach_v1", "type": "relationship"}
)
```
Now when coaching Sarah, retrieve her data including relationship with this specific coach:
```python
# Get Sarah's memories including relationship with fitcoach_v1
sarah_context = mem0_client.search(
"How should I coach Sarah today?",
user_id="sarah",
filters={"metadata": {"agent_id": "fitcoach_v1"}}
)
# Get coach personality
coach_personality = mem0_client.search(
"coaching personality",
agent_id="fitcoach_v1"
)
# Combine both contexts
full_context = str(coach_personality) + "\\n" + str(sarah_context)
response = openai_client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": full_context},
{"role": "user", "content": "Just finished today's workout!"}
]
)
print(response.choices[0].message.content)
```
**Output:**
```
Awesome work today! 💪 No pain, no protein shake, right? 😄
You're making real progress toward that half marathon goal. Keep this
momentum going - your consistency is your superpower!
```
When coaching Mike with the same approach:
```python
# Get Mike's memories including relationship with fitcoach_v1
mike_context = mem0_client.search(
"How should I coach Mike today?",
user_id="mike",
filters={"metadata": {"agent_id": "fitcoach_v1"}}
)
coach_personality = mem0_client.search(
"coaching personality",
agent_id="fitcoach_v1"
)
full_context = str(coach_personality) + "\\n" + str(mike_context)
# ... same coaching code ...
```
**Output:**
```
Solid session. Your bench press shows 8% improvement over last week
(171 lbs avg to 185 lbs). Target: 200 lbs by end of month.
On track at current rate (+3.2% weekly).
```
Same coach, completely different experience based on each user's relationship preferences stored in metadata.
<Note>
**Relationship memories** are stored with **`user_id`** (they're private to each user) but include `agent_id` in metadata to track which agent the relationship is with. This lets you retrieve the user's preferences for how this specific agent should interact with them.
</Note>
---
## Putting It All Together
Here's a complete example showing all three memory layers working together:
```python
from openai import OpenAI
from mem0 import MemoryClient
import os
# Initialize clients
openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
mem0_client = MemoryClient()
# Layer 1: Agent personality (shared)
mem0_client.add(
"I'm FitCoach - supportive, motivational, celebrates small wins",
agent_id="fitcoach_v1",
metadata={"type": "personality"}
)
# Layer 2: User profile (private)
mem0_client.add(
"Sarah's goal: Run half marathon by June. Currently comfortable at 5K distance.",
user_id="sarah",
metadata={"type": "profile"}
)
# Layer 3: Relationship (stored as user memory with agent context in metadata)
mem0_client.add(
"Sarah responds best to encouragement. Inside joke: 'No pain, no protein shake!'",
user_id="sarah",
metadata={"agent_id": "fitcoach_v1", "type": "relationship"}
)
# Log today's workout
mem0_client.add(
"Completed 8K run in 45 minutes - new personal record!",
user_id="sarah",
metadata={"type": "workout", "date": "2025-01-23"}
)
# Generate coaching response
# Get Sarah's context (includes all her memories)
sarah_context = mem0_client.search(
"Generate coaching advice for Sarah",
user_id="sarah"
)
# Get coach personality
coach_personality = mem0_client.search(
"coaching personality",
agent_id="fitcoach_v1"
)
# Combine contexts
full_context = str(coach_personality) + "\\n" + str(sarah_context)
response = openai_client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": full_context},
{"role": "user", "content": "Just finished my run today!"}
]
)
print(response.choices[0].message.content)
```
**Output:**
```
🎉 YES! 8K is a HUGE milestone! You just crushed your previous distance!
Remember when you could barely do 5K? Look at you now! That half marathon
in June is looking more achievable every single day. No pain, no protein
shake - and today, you EARNED that shake! 💪
Next week, let's aim for 9K. You're ready for it!
```
The response combines:
- ✅ Motivational tone (agent personality)
- ✅ Specific goal reference (Sarah's profile)
- ✅ Inside joke (relationship memory)
- ✅ Progress tracking (workout history)
---
![image.png](building_ai_with_personality%20295f22c70c908182affdfc87ec79f2db/image.png)
**Three memory layers:**
1. **Agent memories** (blue) - Shared personality and capabilities
2. **User memories** (red) - Private workout data and goals
3. **Relationship memories** (purple) - User memories with agent context stored in metadata
---
## When to Use What
### Use **`user_id`** only (most apps)
**Best for:** Apps that just need to track user-specific data without AI personality
**Examples:**
- Todo lists
- Note-taking apps
- Personal finance trackers
- Support ticket history
```python
mem0_client.add(
"Bought groceries for $127.43",
user_id="sarah"
)
```
---
### Use **`agent_id`** only (rare)
**Best for:** AI tools that work the same for everyone, no user-specific data
**Examples:**
- Calculator bots
- Language translators
- Company policy assistants (same policies for all)
```python
mem0_client.add(
"I can calculate: arithmetic, algebra, basic calculus. I cannot solve differential equations.",
agent_id="calculator_v1"
)
```
---
### Use both **`user_id`** and **`agent_id`** (AI with personality)
**Best for:** AI agents with persistent personalities that remember individual users
**Examples:**
- Fitness coaches (this guide!)
- Educational tutors
- AI companions
- Therapy/mental health bots
- Game NPCs with character development
```python
# Agent personality (shared across all users)
mem0_client.add(
"Coaching personality and style",
agent_id="agent_name"
)
# User data (private)
mem0_client.add(
"User's goals and progress",
user_id="user_name"
)
# Relationship (user memory with agent context in metadata)
mem0_client.add(
"User's relationship with this specific agent",
user_id="user_name",
metadata={"agent_id": "agent_name", "type": "relationship"}
)
```
---
<Tip>
**When to combine user_id + agent_id:** Use both when your AI has a consistent personality that should work the same for everyone (agent_id), while also tracking individual user data (user_id). Most personal AI assistants, coaches, and tutors fit this pattern.
</Tip>
---
## Best Practices
### 1. Use clear naming conventions
```python
# Good: Descriptive and versioned
agent_id="fitcoach_v1"
user_id="sarah_123"
# Bad: Generic and unclear
agent_id="agent1"
user_id="user_abc"
```
### 2. Tag memories with metadata
```python
# For relationship memories, store agent context in metadata
mem0_client.add(
content,
user_id="sarah",
metadata={
"agent_id": "fitcoach_v1",
"type": "relationship",
"version": "v1"
}
)
```
### 3. Test data isolation
Ensure users never see each other's data:
```python
# Get Mike's memories
mike_memories = mem0_client.get_all(filters={"user_id": "mike"})
# Get Sarah's memories
sarah_memories = mem0_client.get_all(filters={"user_id": "sarah"})
# Verify no overlap
assert len(set(mike_memories) & set(sarah_memories)) == 0, "Data leak detected!"
```
### 4. Version your agents
Allows A/B testing different coaching styles:
```python
# Version 1: Gentle and encouraging
mem0_client.add(
"I'm supportive and celebrate small wins",
agent_id="fitcoach_v1"
)
# Version 2: Data-driven and metric-focused
mem0_client.add(
"I provide concrete metrics and percentage improvements",
agent_id="fitcoach_v2"
)
# Assign users to different versions by storing version in metadata
mem0_client.add(
"Sarah's workout preferences and relationship with coach",
user_id="sarah",
metadata={"agent_id": "fitcoach_v1"}
)
mem0_client.add(
"Mike's workout preferences and relationship with coach",
user_id="mike",
metadata={"agent_id": "fitcoach_v2"}
)
```
---
## What You Built
A fitness coach with three-layer memory architecture:
- **Agent personality (agent_id)** - Shared coaching style across all users, updated once
- **User profiles (user_id)** - Private workout history, goals, and progress for each person
- **Relationship memories (user_id + metadata)** - Personalized interaction preferences per user-agent pair
- **Data isolation** - Sarah never sees Mike's workouts, guaranteed by user_id filtering
This pattern scales from 10 to 10,000 users without duplicating agent personality.
---
## Summary
With Mem0's **`user_id`** and **`agent_id`** parameters, you can build AI agents that maintain consistent personalities across all users while remembering individual user data privately. Store relationship preferences with **`user_id`** and track agent context in metadata.
Most apps only need **`user_id`**. Add **`agent_id`** when your AI needs a consistent personality that evolves independently from user data—fitness coaches, tutors, therapy bots, and game NPCs all fit this pattern.
<CardGroup cols={2}>
<Card title="Control What Gets Stored" icon="filter" href="/cookbooks/essentials/controlling-memory-ingestion">
Filter low-signal conversations before they pollute long-term memory.
</Card>
<Card title="Organize Support Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories">
Categorize customer context so teams can retrieve the right facts fast.
</Card>
</CardGroup>
Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

@@ -0,0 +1,361 @@
---
title: Choose Vector vs Graph Memory
description: "Blend vector search with graph relationships to answer multi-hop questions."
---
Most AI agents use vector stores for RAG operations - they work great for semantic search and retrieving relevant context. But there's a gap when queries require understanding connections between entities.
Mem0 brings graph memory into the picture to fill this gap. In this cookbook, we'll create a company knowledge base with Mem0, using both vector and graph stores. You'll learn when each one helps along the way.
---
## Vector and Graph Stores
When you add a memory to Mem0, it goes into a **vector store** by default. Vector stores are excellent at semantic search - finding memories that match the meaning of your query.
**Graph stores** work differently. They extract **entities** (people, projects, teams) and **relationships between them** (works_with, reports_to, member_of). This lets you answer questions that need connecting information across multiple memories.
We will go through examples in this cookbook while building a company's knowledge base along the way.
---
## Starting Simple
Since we're building a company knowledge base, let's add some employee information:
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
# Add employee info
client.add("Emma is a software engineer in Seattle", user_id="company_kb")
client.add("David is a product manager in Austin", user_id="company_kb")
```
Now let's search for Emma's role:
```python
results = client.search("What does Emma do?", filters={"user_id": "company_kb"})
print(results['results'][0]['memory'])
```
**Output:**
```
Emma is a software engineer in Seattle
```
<Info>
**Expected output:** Vector search returned Emma's role instantly. When queries ask for facts directly stored in one memory, vector semantic search is perfect—fast and accurate.
</Info>
This works perfectly. Vector search found the memory that semantically matches "What does Emma do?" and returned Emma's role.
---
## Adding Team Structure
Let's add some information about how the team works together:
```python
client.add("Emma works with David on the mobile app redesign", user_id="company_kb")
client.add("David reports to Rachel, who manages the design team", user_id="company_kb")
```
Now we have two pieces of information stored:
1. Emma works with David
2. David reports to Rachel
Let's try asking something that needs both pieces:
```python
results = client.search(
"Who is Emma's teammate's manager?",
filters={"user_id": "company_kb"}
)
for r in results['results']:
print(r['memory'])
```
**Output:**
```
Emma works with David on the mobile app redesign
David reports to Rachel, who manages the design team
```
Vector search returned both memories, but it didn't connect them. You'd need to manually figure out:
- Emma's teammate is David (from memory 1)
- David's manager is Rachel (from memory 2)
- So the answer is Rachel
<Warning>
Vector search can't traverse relationships. It returns relevant memories, but you must connect the dots manually. For "Who is Emma's teammate's manager?", vector search gives you the pieces—not the answer. This breaks down as queries get more complex (3+ hops).
</Warning>
---
## Enter Graph Memory
Let's add the same information with graph memory enabled:
```python
client.add(
"Emma works with David on the mobile app redesign",
user_id="company_kb",
enable_graph=True
)
client.add(
"David reports to Rachel, who manages the design team",
user_id="company_kb",
enable_graph=True
)
```
When you set `enable_graph=True`, Mem0 extracts entities and relationships:
- `emma --[works_with]--> david`
- `david --[reports_to]--> rachel`
- `rachel --[manages]--> design_team`
Now the same query works differently:
```python
results = client.search(
"Who is Emma's teammate's manager?",
filters={"user_id": "company_kb"},
enable_graph=True
)
print(results['results'][0]['memory'])
print("\\nRelationships found:")
for rel in results.get('relations', []):
print(f" {rel['source']}, {rel['target']} ({rel['relationship']})")
```
**Output:**
```
David reports to Rachel, who manages the design team
Relationships found:
emma, david (works_with)
david, rachel (reports_to)
```
<Info>
**Expected behavior:** Graph memory returns the direct answer—"David reports to Rachel"—plus the relationship chain that got there. No manual connecting needed. The graph traversed: Emma → works_with → David → reports_to → Rachel.
</Info>
Graph memory traversed the relationships automatically: Emma works with David, David reports to Rachel, so Rachel is the answer.
---
## How It Connects
Here's what the graph looks like behind the scenes:
```mermaid
graph LR
Emma[Emma] -->|works_with| David[David]
David -->|reports_to| Rachel[Rachel]
Rachel -->|manages| DesignTeam[Design Team]
David -->|works_on| MobileApp[Mobile App]
Emma -->|works_on| MobileApp
```
Graph memory lets you discover relations and memories which are tricky to do with direct vector stores.
Vector search would need the exact words in your query to match. Graph memory follows the connections.
---
## When to Use Each
Use **vector store** (default) when:
- Searching documents by semantic similarity
- Looking up facts that don't need relationships
- Building FAQs or knowledge bases where each item stands alone
Use **graph memory** when:
- Tracking organizational hierarchies (who reports to whom)
- Understanding project teams (who collaborates with whom)
- Building CRMs (which contacts connect to which companies)
- Product recommendations (what items are bought together)
For our company knowledge base, we'll use both:
- Vector for individual facts: "Emma specializes in React"
- Graph for relationships: "Emma works with David"
---
## Putting It Together
Let's build a small company knowledge base with both approaches:
```python
# Facts about individuals - vector store is fine
client.add("Emma specializes in React and TypeScript", user_id="company_kb")
client.add("David has 5 years of product management experience", user_id="company_kb")
# Relationships - use graph memory
client.add(
"Emma and David work together on the mobile app",
user_id="company_kb",
enable_graph=True
)
client.add(
"David reports to Rachel",
user_id="company_kb",
enable_graph=True
)
client.add(
"Rachel runs weekly team syncs every Tuesday",
user_id="company_kb",
enable_graph=True
)
```
Now we can ask different types of questions:
```python
# Direct fact - vector search
results = client.search("What are Emma's skills?", filters={"user_id": "company_kb"})
print(results['results'][0]['memory'])
```
**Output:**
```
Emma specializes in React and TypeScript
```
```python
# Multi-hop relationship - graph search
results = client.search(
"What meetings does Emma's project manager's boss run?",
filters={"user_id": "company_kb"},
enable_graph=True
)
print(results['results'][0]['memory'])
```
**Output:**
```
Rachel runs weekly team syncs every Tuesday
```
Graph memory connected: Emma works with David, David reports to Rachel, Rachel runs team syncs.
<Tip>
Enable graph memory when your queries need multi-hop traversal: org charts (who reports to whom), project teams (who collaborates), CRMs (which contacts connect to companies). For single-fact lookups, stick with vector search—it's faster and cheaper.
</Tip>
---
## The Tradeoff
Graph memory adds processing time and cost. When you call `client.add()` with `enable_graph=True`, Mem0 makes extra LLM calls to extract entities and relationships.
<Note>
**Cost consideration:** Graph memory extraction adds ~2-3 extra LLM calls per `add()` operation to identify entities and relationships. Use it selectively—enable graph for organizational structure and long-term relationships, skip it for temporary notes and simple facts.
</Note>
Use graph memory when the relationship traversal adds real value. For most use cases, vector search is sufficient and faster.
```python
# Long-term organizational structure - worth using graph
client.add(
"Emma mentors two junior engineers on the frontend team",
user_id="company_kb",
enable_graph=True
)
# Temporary notes - skip graph, not worth the cost
client.add(
"Emma is out sick today",
user_id="company_kb",
run_id="daily_notes"
)
```
---
## Enabling Graph Memory
You can enable graph memory in two ways:
**Per-call** (recommended to start):
```python
client.add("Emma works with David", user_id="company_kb", enable_graph=True)
client.search("team structure", filters={"user_id": "company_kb"}, enable_graph=True)
```
**Project-wide** (if most of your data has relationships):
```python
client.project.update(enable_graph=True)
# Now every add uses graph automatically
client.add("Emma mentors Jordan", user_id="company_kb")
```
---
## What You Built
A hybrid company knowledge base that combines both architectures:
- **Vector search** - Fast semantic lookups for individual facts (Emma's skills, David's experience)
- **Graph memory** - Multi-hop relationship traversal (Emma's teammate's manager, project hierarchies)
- **Selective enablement** - Graph only for long-term organizational structure, vector for everything else
- **Cost optimization** - Skip graph extraction for temporary notes and simple facts
This pattern scales from 10-person startups to enterprise org charts with thousands of employees.
---
## Summary
Vector stores handle most memory operations efficiently—semantic search works great for finding relevant information. Add graph memory when your queries need to understand how entities connect across multiple hops.
The key is knowing which tool fits your query pattern: direct questions work with vectors, multi-hop relationship queries need graphs.
<CardGroup cols={2}>
<Card title="Build AI with Personality" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Scope memories across user and agent IDs to balance personalization and reuse.
</Card>
<Card title="Export Everything Safely" icon="download" href="/cookbooks/essentials/exporting-memories">
Learn how to migrate or audit stored memories with structured exports.
</Card>
</CardGroup>
@@ -0,0 +1,508 @@
---
title: Control Memory Ingestion
description: "Filter speculation, enforce formats, and gate low-confidence data before it persists."
---
AI assistants plugged with memory systems face a problem - they often store everything. Not every conversation needs to be remembered, and not every detail should go to the memory store. Without proper controls, memory systems accumulate unreliable data.
Mem0 lets you control your memory ingestion pipeline. In this cookbook, we'll demonstrate these controls using a medical assistant example - showing how to filter unwanted data, enforce data formats, and implement confidence-based storage.
---
## Overview
Without controls, everything gets stored - speculation, low-confidence data, and information that shouldn't persist. This uncontrolled ingestion leads to cluttered memory and retrieval failures.
Mem0 provides **three tools to control** what gets stored:
1. **Custom instructions** define what to remember and what to ignore.
2. **Confidence thresholds** ensure only verified facts persist.
3. **Memory updates** let you change information without creating duplicates.
In this tutorial, we will:
- Filter speculative statements with custom instructions
- Configure confidence thresholds for fact verification
- Update stored information without duplication
- Build a complete ingestion pipeline
---
## Setup
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
```
<Note>
Replace `your-api-key` with your actual Mem0 API key from the [dashboard](https://app.mem0.ai). Without proper API authentication, memory operations will fail.
</Note>
---
## The Problem
Uncontrolled ingestion stores everything, including speculation:
```python
# Patient mentions speculation
messages = [{"role": "user", "content": "I think I might be allergic to penicillin"}]
client.add(messages, user_id="patient_123")
# Check what got stored
results = client.search("patient allergies", filters={"user_id": "patient_123"})
print(results['results'][0]['memory'])
```
**Output:**
```
Patient is allergic to penicillin
```
<Warning>
Without custom instructions, AI assistants treat speculation as confirmed facts. "I think I might be allergic" becomes "Patient is allergic"—a dangerous transformation in sensitive domains like healthcare, legal, or financial services.
</Warning>
The speculation became a confirmed fact. Let's add controls.
---
## Custom Instructions
Custom instructions tell Mem0 what to store and what to ignore.
```python
instructions = """
Only store CONFIRMED medical facts.
Store:
- Confirmed diagnoses from doctors
- Known allergies with documented reactions
- Current medications being taken
Ignore:
- Speculation (words like "might", "maybe", "I think")
- Unverified symptoms
- Casual mentions without confirmation
"""
client.project.update(custom_instructions=instructions)
# Same speculative statement
messages = [{"role": "user", "content": "I think I might be allergic to penicillin"}]
client.add(messages, user_id="patient_123")
# Check what got stored
results = client.get_all(filters={"user_id": "patient_123"})
print(f"Memories stored: {len(results['results'])}")
```
**Output:**
```
Memories stored: 0
```
<Info>
**Expected output:** Zero memories stored. The speculative statement "I think I might be allergic" was filtered out before reaching storage. Custom instructions are actively blocking unreliable data.
</Info>
The speculation was filtered out.
---
## Designing Custom Instructions
When designing instructions, consider the trade-off between precision and recall:
**Too restrictive:** You'll miss important information (false negatives)
```python
# Too strict - filters out useful context
"""
Only store information if explicitly stated by a doctor with full name,
date, time, and medical license number.
"""
```
**Too permissive:** You'll store unreliable data (false positives)
```python
# Too loose - stores speculation as fact
"""
Store any health-related information mentioned.
"""
```
**Balanced approach:**
```python
# Clear categories with examples
"""
Store CONFIRMED facts:
- Diagnoses: "Dr. Smith diagnosed hypertension on March 15th"
- Allergies: "Patient had hives reaction to penicillin"
- Medications: "Taking Lisinopril 10mg daily"
Ignore SPECULATION:
- "I think I might have..."
- "Maybe it's..."
- "Could be related to..."
"""
```
<Tip>
Start with strict instructions (only store confirmed facts), then relax them based on your use case. It's easier to allow more data than to clean up polluted memory. Test with sample conversations before deploying to production.
</Tip>
Start with clear categories and iterate based on retrieval quality.
---
## Confidence Thresholds
Mem0 assigns confidence scores to extracted memories. Use these to filter low-quality data.
### Setting Thresholds
Setting the right confidence threshold depends on your application:
- **High-stakes domains** (medical, legal): Require 0.8+ confidence
- **General assistants**: 0.6+ confidence is often sufficient
- **Exploratory systems**: Lower thresholds (0.4+) capture more data
Test your pipeline with multiple input examples and threshold combinations to find what works for your use case.
```python
# Configure stricter instructions
client.project.update(
custom_instructions="""
Only extract memories with HIGH confidence.
Require specific details (dates, dosages, doctor names) for medical facts.
Skip vague or uncertain statements.
"""
)
# Test with uncertain statement
messages = [{"role": "user", "content": "The doctor mentioned something about my blood pressure"}]
result1 = client.add(messages, user_id="patient_123")
# Test with confirmed fact
messages = [{"role": "user", "content": "Dr. Smith diagnosed me with hypertension on March 15th"}]
result2 = client.add(messages, user_id="patient_123")
print("Vague statement stored:", len(result1['results']) > 0)
print("Confirmed fact stored:", len(result2['results']) > 0)
```
**Output:**
```
Vague statement stored: False
Confirmed fact stored: True
```
<Info icon="check">
**Expected behavior:** Low-confidence extractions are now filtered out automatically. Only verified facts with specific details (names, dates, dosages) persist in memory. The confidence threshold is working.
</Info>
The vague statement was filtered for low confidence. The confirmed fact with specific details was stored.
---
## Filtering Sensitive Information
Custom instructions can prevent storing personal identifiers:
```python
client.project.update(
custom_instructions="""
Medical memory rules:
STORE:
- Confirmed diagnoses
- Verified allergies
- Current medications
NEVER STORE:
- Social Security Numbers
- Insurance policy numbers
- Credit card information
- Full addresses
- Phone numbers
Replace identifiers with generic references if mentioned.
"""
)
# Test with PII
messages = [
{"role": "user", "content": "My SSN is 123-45-6789 and I'm allergic to penicillin"}
]
client.add(messages, user_id="patient_123")
# Check what was stored
results = client.get_all(filters={"user_id": "patient_123"})
for result in results['results']:
print(result['memory'])
```
**Output:**
```
Patient is allergic to penicillin
```
The SSN was filtered out, but the allergy was stored.
---
## Updating Memories
When information changes, update existing memories instead of creating duplicates.
```python
# Initial allergy stored
result = client.add(
[{"role": "user", "content": "Patient confirmed allergy to penicillin with documented hives reaction"}],
user_id="patient_123"
)
memory_id = result['results'][0]['id']
print(f"Stored memory: {memory_id}")
# Later, patient gets retested - allergy was false positive
client.update(
memory_id=memory_id,
text="Patient tested negative for penicillin allergy on April 2nd, 2025. Previous allergy was false positive.",
metadata={"verified": True, "updated_date": "2025-04-02"}
)
# Retrieve the updated memory
updated = client.get(memory_id)
print(f"\\nUpdated memory: {updated['memory']}")
print(f"Metadata: {updated['metadata']}")
```
**Output:**
```
Stored memory: mem_abc123
Updated memory: Patient tested negative for penicillin allergy on April 2nd, 2025. Previous allergy was false positive.
Metadata: {'verified': True, 'updated_date': '2025-04-02'}
```
### Benefits of Updating
**Preserves history:**
- `created_at` shows when the memory was first stored
- `updated_at` shows when it was modified
- Audit trail for compliance
**Avoids conflicts:**
- No duplicate or contradicting memories
- Single source of truth for each fact
**Maintains relationships:**
- If using graph memory, connections to other entities persist
---
## Update vs Delete
When should you update vs delete?
### Update when:
- Information changes but remains relevant
- You need audit history
- The memory has relationships to other data
```python
# Medication dosage changed
client.update(
memory_id=med_id,
text="Taking Lisinopril 20mg daily (increased from 10mg on March 1st)"
)
```
### Delete when:
- Information was completely wrong
- Memory is no longer relevant
- Duplicate entry
```python
# Duplicate entry
client.delete(memory_id)
```
---
## Putting It Together
Here's a complete ingestion pipeline with all controls:
```python
from mem0 import MemoryClient
import os
# Initialize client
client = MemoryClient(api_key=os.getenv("MEM0_API_KEY"))
# Configure custom instructions
client.project.update(
custom_instructions="""
Medical memory assistant rules:
STORE:
- Confirmed diagnoses (with doctor name and date)
- Verified allergies (with reaction details)
- Current medications (with dosage)
IGNORE:
- Speculation (might, maybe, possibly)
- Unverified symptoms
- Personal identifiers (SSN, insurance numbers)
CONFIDENCE:
Require high confidence. Reject vague or uncertain statements.
Require specific details: names, dates, dosages.
"""
)
# Helper function for safe ingestion
def add_medical_memory(content, user_id, metadata=None):
"""Add memory with automatic filtering."""
result = client.add(
[{"role": "user", "content": content}],
user_id=user_id,
metadata=metadata or {}
)
if result['results']:
print(f"✓ Stored: {result['results'][0]['memory']}")
else:
print(f"✗ Filtered: {content}")
return result
# Test cases
print("Testing ingestion pipeline:\\n")
test_cases = [
"I think I might be allergic to penicillin",
"Dr. Johnson confirmed penicillin allergy on Jan 15th with hives reaction",
"Patient SSN is 123-45-6789",
"Currently taking Lisinopril 10mg daily for hypertension",
"Feeling tired lately",
"Dr. Martinez diagnosed Type 2 diabetes on February 3rd, 2025"
]
for content in test_cases:
add_medical_memory(content, user_id="patient_123")
print()
```
**Output:**
```
Testing ingestion pipeline:
✗ Filtered: I think I might be allergic to penicillin
✓ Stored: Patient has confirmed penicillin allergy diagnosed by Dr. Johnson on January 15th with hives reaction
✗ Filtered: Patient SSN is 123-45-6789
✓ Stored: Patient is currently taking Lisinopril 10mg daily for hypertension
✗ Filtered: Feeling tired lately
✓ Stored: Patient diagnosed with Type 2 diabetes by Dr. Martinez on February 3rd, 2025
```
---
## Per-Call Instructions
You can override project-level instructions for specific conversations:
First define custom instructions
```python
custom_instructions="""Emergency intake mode:Store ALL symptoms and observations immediately.
Flag for later review and verification."""
```
```python
# Emergency intake - store everything temporarily
emergency_messages = [
{"role": "user", "content": "Patient arrived with chest pain and shortness of breath"}
]
client.add(
emergency_messages,
user_id="patient_456",
custom_instructions=custom_instructions,
metadata={"type": "emergency", "review_required": True}
)
```
This is useful for:
- Different conversation types (emergency vs routine)
- Channel-specific rules (phone vs in-person)
- Temporary data collection that needs review
---
## What You Built
You now have a medical assistant with production-grade memory controls:
- **Custom instructions** - Filter speculation and enforce confirmed facts only
- **Confidence thresholds** - Gate extractions below 0.7 confidence score
- **Memory updates** - Modify stored information without creating duplicates
- **Per-call instructions** - Apply temporary rules for specific conversations
- **PII filtering** - Block sensitive data (SSNs, insurance numbers) automatically
These controls prevent retrieval failures and ensure your AI assistant works with reliable, verified information.
---
## Summary
Start with conservative filters (only store confirmed facts) and iterate based on your application's needs. Combine custom instructions with confidence thresholds for the most reliable memory ingestion pipeline.
<CardGroup cols={2}>
<Card title="Expire Short-Term Data" icon="timer" href="/cookbooks/essentials/memory-expiration-short-and-long-term">
Automatically clean up session context before it clutters retrieval.
</Card>
<Card title="Choose Your Memory Architecture" icon="sitemap" href="/cookbooks/essentials/choosing-memory-architecture-vector-vs-graph">
Learn when to layer graph memory alongside vectors for multi-hop queries.
</Card>
</CardGroup>
@@ -0,0 +1,289 @@
---
title: Export Stored Memories
description: "Retrieve, review, and migrate user memories with structured exports."
---
Mem0 is a dynamic memory store that gives you full control over your data. Along with storing memories, it gives you the ability to retrieve, export, and migrate your data whenever you need.
This cookbook shows you how to retrieve and export your data for inspection, migration, or compliance.
---
## Setup
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
```
<Note>
Your API key needs export permissions to download memory data. Check your project settings on the [dashboard](https://app.mem0.ai) if export operations fail with authentication errors.
</Note>
Let's add some sample memories to work with:
```python
# Dev's work history
client.add(
"Dev works at TechCorp as a senior engineer",
user_id="dev",
metadata={"type": "professional"}
)
# Arjun's preferences
client.add(
"Arjun prefers morning meetings and async communication",
user_id="arjun",
metadata={"type": "preference"}
)
# Carl's project notes
client.add(
"Carl is leading the API redesign project, targeting Q2 launch",
user_id="carl",
metadata={"type": "project"}
)
```
---
## Getting All Memories
Use `get_all()` with filters to retrieve everything for a specific user:
```python
dev_memories = client.get_all(
filters={"user_id": "dev"},
page_size=50
)
print(f"Total memories: {dev_memories['count']}")
print(f"First memory: {dev_memories['results'][0]['memory']}")
```
**Output:**
```
Total memories: 1
First memory: Dev works at TechCorp as a senior engineer
```
<Info>
**Expected output:** `get_all()` retrieved Dev's complete memory record. This method returns everything matching your filters—no semantic search, no ranking, just raw retrieval. Perfect for exports and audits.
</Info>
You can filter by metadata to get specific types:
```python
carl_projects = client.get_all(
filters={
"AND": [
{"user_id": "carl"},
{"metadata": {"type": "project"}}
]
}
)
for memory in carl_projects['results']:
print(memory['memory'])
```
**Output:**
```
Carl is leading the API redesign project, targeting Q2 launch
```
---
## Searching Memories
When you need semantic search instead of retrieving everything, use `search()`:
```python
results = client.search(
query="What does Dev do for work?",
filters={"user_id": "dev"},
top_k=5
)
for result in results['results']:
print(f"{result['memory']} (score: {result['score']:.2f})")
```
**Output:**
```
Dev works at TechCorp as a senior engineer (score: 0.89)
```
Search works across all memory fields and ranks by relevance. Use it when you have a specific question, use `get_all()` when you need everything.
---
## Exporting to Structured Format
For migrations or compliance, you can export memories into a structured schema using Pydantic-style JSON schemas.
### Step 1: Define the schema
```python
professional_profile_schema = {
"properties": {
"full_name": {
"type": "string",
"description": "The person's full name"
},
"current_role": {
"type": "string",
"description": "Current job title or role"
},
"company": {
"type": "string",
"description": "Current employer"
}
},
"title": "ProfessionalProfile",
"type": "object"
}
```
### Step 2: Create export job
```python
export_job = client.create_memory_export(
schema=professional_profile_schema,
filters={"user_id": "dev"}
)
print(f"Export ID: {export_job['id']}")
print(f"Status: {export_job['status']}")
```
**Output:**
```
Export ID: exp_abc123
Status: processing
```
<Info>
**Export initiated:** Status is "processing". Large exports may take a few seconds. Poll with `get_memory_export()` until status changes to "completed" before downloading data.
</Info>
### Step 3: Download the export
```python
# Get by ID
export_data = client.get_memory_export(
memory_export_id=export_job['id']
)
print(export_data['data'])
```
**Output:**
```json
{
"full_name": "Dev",
"current_role": "senior engineer",
"company": "TechCorp"
}
```
You can also retrieve exports by filters:
```python
# Get latest export matching filters
export_by_filters = client.get_memory_export(
filters={"user_id": "dev"}
)
print(export_by_filters['data'])
```
---
## Adding Export Instructions
Guide how Mem0 resolves conflicts or formats the export:
```python
export_with_instructions = client.create_memory_export(
schema=professional_profile_schema,
filters={"user_id": "arjun"},
export_instructions="""
1. Use the most recent information if there are conflicts
2. Only include confirmed facts, not speculation
3. Return null for missing fields rather than guessing
"""
)
```
<Tip>
Always check export status before downloading. Call `get_memory_export()` in a loop with a short delay until `status == "completed"`. Attempting to download while still processing returns incomplete data.
</Tip>
---
## Platform Export
You can also export memories directly from the Mem0 platform UI:
1. Navigate to **Memory Exports** in your project dashboard
2. Click **Create Export**
3. Select your filters and schema
4. Download the completed export as JSON
This is useful for one-off exports or manual data reviews.
<Warning>
Exported data expires after 7 days. Download and store exports locally if you need long-term archives. After expiration, you'll need to recreate the export job.
</Warning>
---
## What You Built
A complete memory export system with multiple retrieval methods:
- **Bulk retrieval (get_all)** - Fetch all memories matching filters for comprehensive audits
- **Semantic search** - Query-based lookups with relevance scoring
- **Structured exports** - Pydantic-schema exports for migrations and compliance
- **Export instructions** - Guide conflict resolution and data formatting
- **Platform UI exports** - One-off manual downloads via dashboard
This covers data portability, GDPR compliance, system migrations, and manual reviews.
---
## Summary
Use **`get_all()`** for bulk retrieval, **`search()`** for specific questions, and **`create_memory_export()`** for structured data exports with custom schemas. Remember exports expire after 7 days—download them locally for long-term archives.
<CardGroup cols={2}>
<Card title="Expire Short-Term Data" icon="timer" href="/cookbooks/essentials/memory-expiration-short-and-long-term">
Keep exports lean by clearing session context before you archive it.
</Card>
<Card title="Control Memory Ingestion" icon="filter" href="/cookbooks/essentials/controlling-memory-ingestion">
Ensure only verified insights make it into your export pipeline.
</Card>
</CardGroup>
@@ -0,0 +1,277 @@
---
title: Set Memory Expiration
description: "Define short-term versus long-term retention so the store stays fresh."
---
While building memory systems, we realized their size grows fast. Session notes, temporary context, chat history - everything starts accumulating and bogging down the system. This pollutes search results and increase storage costs. Not every memory needs to persist forever.
In this cookbook, we'll go through how to use short-term vs long-term memories and see where it's best to use them.
---
## Overview
By default, Mem0 memories persist forever. This works for user preferences and core facts, but temporary data should expire automatically.
In this tutorial, we will:
- Understand default (permanent) memory behavior
- Add expiration dates for temporary memories
- Decide what should be temporary vs permanent
---
## Setup
```python
from mem0 import MemoryClient
from datetime import datetime, timedelta
client = MemoryClient(api_key="your-api-key")
```
<Note>
Import `datetime` and `timedelta` to calculate expiration dates. Without these imports, you'll need to manually format ISO timestamps—error-prone and harder to read.
</Note>
---
## Default Behavior: Everything Persists
By default, all memories persist forever:
```python
# Store user preference
client.add("User prefers dark mode", user_id="sarah")
# Store session context
client.add("Currently browsing electronics category", user_id="sarah")
# 6 months later - both still exist
results = client.get_all(filters={"user_id": "sarah"})
print(f"Total memories: {len(results['results'])}")
```
**Output:**
```
Total memories: 2
```
Both the preference and session context persist. The preference is useful, but the 6-month-old session context is not.
---
## The Problem: Memory Bloat
Without expiration, memories accumulate forever. Session notes from weeks ago mix with current preferences. Storage grows, search results get polluted with irrelevant old context, and retrieval quality degrades.
<Warning>
Memory bloat degrades search quality. When "User prefers dark mode" competes with "Currently browsing electronics" from 6 months ago, semantic search returns stale session data instead of actual preferences. Old memories pollute retrieval.
</Warning>
---
## Short-Term Memories: Adding Expiration
Set `expiration_date` to make memories temporary:
```python
from datetime import datetime, timedelta
# Session context - expires in 7 days
expires_at = (datetime.now() + timedelta(days=7)).isoformat()
client.add(
"Currently browsing electronics category",
user_id="sarah",
expiration_date=expires_at
)
# User preference - no expiration, persists forever
client.add(
"User prefers dark mode",
user_id="sarah"
)
```
<Info icon="check">
**Expected behavior:** After 7 days, the session context automatically disappears—no cron jobs, no manual cleanup. The preference persists forever. Mem0 handles expiration transparently.
</Info>
Memories with `expiration_date` are automatically removed after expiring. No cleanup job needed - Mem0 handles it.
<Tip>
Start conservative with short expiration windows (7 days), then extend them based on usage patterns. It's easier to increase retention than to clean up over-retained stale data. Monitor search quality to find the right balance.
</Tip>
---
## When to Use Each
### Permanent Memories (no expiration_date):
**Use for:**
- User preferences and settings
- Account information
- Important facts and milestones
- Historical data that matters long-term
```python
client.add("User prefers email notifications", user_id="sarah")
client.add("User's birthday is March 15th", user_id="sarah")
client.add("User completed onboarding on Jan 5th", user_id="sarah")
```
### Temporary Memories (with expiration_date):
**Use for:**
- Session context (current page, browsing history)
- Temporary reminders
- Recent chat history
- Cached data
```python
expires_7d = (datetime.now() + timedelta(days=7)).isoformat()
client.add(
"Currently viewing product ABC123",
user_id="sarah",
expiration_date=expires_7d
)
client.add(
"Asked about return policy",
user_id="sarah",
expiration_date=expires_7d
)
```
---
## Setting Different Expiration Periods
Different data needs different lifetimes:
```python
# Session context - 7 days
expires_7d = (datetime.now() + timedelta(days=7)).isoformat()
client.add("Browsing electronics", user_id="sarah", expiration_date=expires_7d)
# Recent chat - 30 days
expires_30d = (datetime.now() + timedelta(days=30)).isoformat()
client.add("User asked about warranty", user_id="sarah", expiration_date=expires_30d)
# Important preference - no expiration
client.add("User prefers dark mode", user_id="sarah")
```
---
## Using Metadata to Track Memory Types
Tag memories to make filtering easier:
```python
expires_7d = (datetime.now() + timedelta(days=7)).isoformat()
# Tag session context
client.add(
"Browsing electronics",
user_id="sarah",
expiration_date=expires_7d,
metadata={"type": "session"}
)
# Tag preference
client.add(
"User prefers dark mode",
user_id="sarah",
metadata={"type": "preference"}
)
# Query only preferences
preferences = client.get_all(
filters={
"AND": [
{"user_id": "sarah"},
{"metadata": {"type": "preference"}}
]
}
)
```
---
## Checking Expiration Status
See which memories will expire and when:
```python
results = client.get_all(filters={"user_id": "sarah"})
for memory in results['results']:
exp_date = memory.get('expiration_date')
if exp_date:
print(f"Temporary: {memory['memory']}")
print(f" Expires: {exp_date}\\n")
else:
print(f"Permanent: {memory['memory']}\\n")
```
**Output:**
```
Temporary: Browsing electronics
Expires: 2025-11-01T10:30:00Z
Temporary: Viewed MacBook Pro and Dell XPS
Expires: 2025-11-01T10:30:00Z
Permanent: User prefers dark mode
Permanent: User prefers email notifications
```
---
## What You Built
A self-cleaning memory system with automatic retention policies:
- **Automatic expiration** - Memories self-destruct after defined periods, no cron jobs needed
- **Tiered retention** - 7-day session context, 30-day chat history, permanent preferences
- **Metadata tagging** - Classify memories by type (session, preference, chat) for filtered retrieval
- **Expiration tracking** - Check which memories will expire and when using `get_all()`
This pattern keeps storage costs low and search quality high as your memory store scales.
---
## Summary
Memory expiration keeps storage clean and search results relevant. Use **`expiration_date`** for temporary data (session context, recent chats), skip it for permanent facts (preferences, account info). Mem0 handles cleanup automatically—no background jobs required.
Start by identifying what's temporary versus permanent, then set conservative expiration windows and adjust based on retrieval quality.
<CardGroup cols={2}>
<Card title="Control Memory Ingestion" icon="filter" href="/cookbooks/essentials/controlling-memory-ingestion">
Pair expirations with ingestion rules so only trusted context persists.
</Card>
<Card title="Export Memories Safely" icon="download" href="/cookbooks/essentials/exporting-memories">
Build compliant archives once your retention windows are dialed in.
</Card>
</CardGroup>
@@ -0,0 +1,251 @@
---
title: Tag and Organize Memories
description: "Let Mem0 auto-categorize support data so teams retrieve the right facts fast."
---
When you have large volumes of memory data, sorting it during post-processing becomes difficult. What if your memory store understood the importance of creating tags and buckets without a lot of effort?
Mem0 handles this for you by providing the flexibility to organize memories with custom categories. This cookbook shows you how to tag and organize memories for a customer support platform.
---
## Setup
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
```
<Note>
Define custom categories at the **project level** with `client.project.update()` before adding memories. Categories apply to all future memories—Mem0 auto-assigns them based on content semantics.
</Note>
---
## The Problem
Without categories, all memories sit in one undifferentiated bucket. Support agents waste time searching through everything to find billing issues, account details, or past tickets.
Let's see what happens without organization:
```python
# Joseph (support agent) stores various customer interactions
client.add(
"Maria called about her account password reset",
user_id="maria",
)
client.add(
"Maria was charged twice for last month's subscription",
user_id="maria",
)
client.add(
"Maria wants to upgrade to the premium plan",
user_id="maria",
)
# Now try to find just billing issues
all_memories = client.get_all(filters={"user_id": "maria"})
print(f"Total memories: {len(all_memories['results'])}")
for memory in all_memories['results']:
print(f"- {memory['memory']}")
```
**Output:**
```
Total memories: 3
- Maria called about her account password reset
- Maria was charged twice for last month's subscription
- Maria wants to upgrade to the premium plan
```
<Warning>
Without categories, agents waste time reading through everything. For a customer with 100 memories, finding one billing issue means scanning all 100. Categories let you filter to exactly what you need—billing issues only, no password resets or feedback mixed in.
</Warning>
Everything is mixed together. Support agents have to read through all memories to find what they need.
---
## Custom Categories
Define categories that match how your support team thinks about customer issues:
```python
custom_categories = [
{"support_tickets": "Customer issues and resolutions"},
{"account_info": "Account details and preferences"},
{"billing": "Payment history and billing questions"},
{"product_feedback": "Feature requests and feedback"},
]
client.project.update(custom_categories=custom_categories)
```
<Tip>
Start with 3-5 clear categories that match how your team thinks. Too many categories dilute auto-tagging accuracy. Add more later if needed—it's easier to expand than to fix over-complicated classification.
</Tip>
These categories are now available project-wide. Every memory can be tagged with one or more categories.
---
## Tagging Memories
Once categories are defined at the project level, Mem0 automatically assigns them based on content:
```python
# Billing issue - automatically tagged as "billing"
client.add(
"Maria was charged twice for last month's subscription",
user_id="maria",
metadata={"priority": "high", "source": "phone_call"}
)
# Account update - automatically tagged as "account_info"
client.add(
"Maria changed her email to maria.new@example.com",
user_id="maria",
metadata={"source": "web_portal"}
)
# Product feedback - automatically tagged as "product_feedback"
client.add(
"Maria requested a dark mode feature for the dashboard",
user_id="maria",
metadata={"source": "chat"}
)
```
Mem0 reads the content and intelligently assigns the appropriate categories. You don't manually tag - the platform does it for you based on the category definitions.
---
## Retrieving by Category
Filter memories by category to find exactly what you need:
```python
# Joseph needs to pull all billing issues for audit
billing_issues = client.get_all(
filters={
"AND": [
{"user_id": "maria"},
{"categories": {"in": ["billing"]}}
]
}
)
print("Billing issues:")
for memory in billing_issues['results']:
print(f"- {memory['memory']}")
```
**Output:**
```
Billing issues:
- Maria was charged twice for last month's subscription
```
<Info icon="check">
**Expected output:** Only the billing issue returned—no password reset, no upgrade request. Category filtering worked. Joseph can audit billing without reading through unrelated support tickets.
</Info>
Only billing-related memories are returned. No need to filter through account updates or feedback.
You can also retrieve multiple categories:
```python
# Get both account info and billing
account_and_billing = client.get_all(
filters={
"AND": [
{"user_id": "maria"},
{"categories": {"in": ["account_info", "billing"]}}
]
}
)
for memory in account_and_billing['results']:
print(f"[{memory['categories'][0]}] {memory['memory']}")
```
**Output:**
```
[account_info] Maria changed her email to maria.new@example.com
[billing] Maria was charged twice for last month's subscription
```
---
## Updating Categories
Categories are automatically assigned based on content. To trigger re-categorization, update the memory content:
```python
# Find memories that need re-categorization
needs_update = client.get_all(
filters={
"AND": [
{"user_id": "maria"},
{"categories": {"in": ["misc"]}}
]
}
)
# Update memory content to trigger re-categorization
for memory in needs_update['results']:
client.update(
memory_id=memory['id'],
data=memory['memory'] # Re-process with current category definitions
)
```
When you update a memory, Mem0 re-analyzes it against your current category definitions. This is useful when you introduce new categories or refine category descriptions.
---
## What You Built
A customer support platform with intelligent memory organization:
- **Project-wide categories** - Support tickets, billing, account info, and product feedback auto-classified
- **Automatic tagging** - Mem0 assigns categories based on content semantics, no manual tagging
- **Filtered retrieval** - Pull only billing issues or only account updates using `categories: {in: [...]}`
- **Re-categorization** - Update memory content to trigger re-analysis against new category definitions
- **Multi-category support** - Memories can belong to multiple categories when appropriate
This pattern scales from 10 customers to 10,000 without degrading retrieval speed.
---
## Summary
Categories make retrieval faster and compliance easier. Define 3-5 clear categories with `client.project.update()`, let Mem0 auto-assign them based on content, then filter with `categories: {in: [...]}` to pull exactly what you need.
Instead of searching through everything, agents jump directly to the information type they need—billing issues, account details, or support tickets.
<CardGroup cols={2}>
<Card title="Control Memory Ingestion" icon="filter" href="/cookbooks/essentials/controlling-memory-ingestion">
Keep categories meaningful by filtering noise before it lands in storage.
</Card>
<Card title="Export Tagged Memories" icon="download" href="/cookbooks/essentials/exporting-memories">
Use categories to drive audits, migrations, and compliance reports.
</Card>
</CardGroup>
@@ -0,0 +1,70 @@
---
title: Chrome Extension with Mem0
description: "Add Mem0's universal memory layer to Chrome chat surfaces."
---
Enhance your AI interactions with Mem0, a Chrome extension that introduces a universal memory layer across platforms like ChatGPT, Claude, and Perplexity. Mem0 ensures seamless context sharing, making your AI experiences more personalized and efficient.
<Note>
We now support Grok! The Mem0 Chrome Extension has been updated to work with Grok, bringing the same powerful memory capabilities to your Grok conversations.
</Note>
## Features
- **Universal Memory Layer**: Share context seamlessly across ChatGPT, Claude, Perplexity, and Grok.
- **Smart Context Detection**: Automatically captures relevant information from your conversations.
- **Intelligent Memory Retrieval**: Surfaces pertinent memories at the right time.
- **One-Click Sync**: Easily synchronize with existing ChatGPT memories.
- **Memory Dashboard**: Manage all your memories in one centralized location.
## Installation
You can install the Mem0 Chrome Extension using one of the following methods:
### Method 1: Chrome Web Store Installation
1. **Download the Extension**: Open Google Chrome and navigate to the [Mem0 Chrome Extension page](https://chromewebstore.google.com/detail/mem0/onihkkbipkfeijkadecaafbgagkhglop?hl=en).
2. **Add to Chrome**: Click on the "Add to Chrome" button.
3. **Confirm Installation**: In the pop-up dialog, click "Add extension" to confirm. The Mem0 icon should now appear in your Chrome toolbar.
### Method 2: Manual Installation
1. **Download the Extension**: Clone or download the extension files from the [Mem0 Chrome Extension GitHub repository](https://github.com/mem0ai/mem0-chrome-extension).
2. **Access Chrome Extensions**: Open Google Chrome and navigate to `chrome://extensions`.
3. **Enable Developer Mode**: Toggle the "Developer mode" switch in the top right corner.
4. **Load Unpacked Extension**: Click "Load unpacked" and select the directory containing the extension files.
5. **Confirm Installation**: The Mem0 Chrome Extension should now appear in your Chrome toolbar.
## Usage
1. **Locate the Mem0 Icon**: After installation, find the Mem0 icon in your Chrome toolbar.
2. **Sign In**: Click the icon and sign in with your Google account.
3. **Interact with AI Assistants**:
- **ChatGPT and Perplexity**: Continue your conversations as usual; Mem0 operates seamlessly in the background.
- **Claude**: Click the Mem0 button or use the shortcut `Ctrl + M` to activate memory functions.
## Configuration
- **API Key**: Obtain your API key from the Mem0 Dashboard to connect the extension to the Mem0 API.
- **User ID**: This is your unique identifier in the Mem0 system. If not provided, it defaults to `chrome-extension-user`.
## Demo Video
<iframe width="700" height="400" src="https://www.youtube.com/embed/dqenCMMlfwQ?si=zhGVrkq6IS_0Jwyj" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
## Privacy and Data Security
Your messages are sent to the Mem0 API for extracting and retrieving memories. Mem0 is committed to ensuring your data's privacy and security.
---
<CardGroup cols={2}>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Learn the foundations of memory-powered assistants that work across platforms.
</Card>
<Card title="Multimodal Support" icon="image" href="/platform/features/multimodal-support">
Extend your browser interactions with vision and audio memory.
</Card>
</CardGroup>
@@ -0,0 +1,85 @@
---
title: Eliza OS Character with Mem0
description: "Bring persistent personality to Eliza OS agents using Mem0."
---
You can create a personalized Eliza OS Character using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
## Overview
ElizaOS is a powerful AI agent framework for autonomy and personality. It is a collection of tools that help you create a personalized AI agent.
## Setup
You can start by cloning the eliza-os repository:
```bash
git clone https://github.com/elizaOS/eliza.git
```
Change the directory to the eliza-os repository:
```bash
cd eliza
```
Install the dependencies:
```bash
pnpm install
```
Build the project:
```bash
pnpm build
```
## Setup ENVs
Create a `.env` file in the root of the project and add the following (you can use the `.env.example` file as a reference):
```bash
# Mem0 Configuration
MEM0_API_KEY= # Mem0 API Key (get from https://app.mem0.ai/dashboard/api-keys)
MEM0_USER_ID= # Default: eliza-os-user
MEM0_PROVIDER= # Default: openai
MEM0_PROVIDER_API_KEY= # API Key for the provider (OpenAI, Anthropic, etc.)
SMALL_MEM0_MODEL= # Default: gpt-4.1-nano
MEDIUM_MEM0_MODEL= # Default: gpt-4o
LARGE_MEM0_MODEL= # Default: gpt-4o
```
## Make the default character use Mem0
By default, there is a character called `eliza` that uses the Ollama model. You can make this character use Mem0 by changing the config in the `agent/src/defaultCharacter.ts` file.
```ts
modelProvider: ModelProviderName.MEM0,
```
This will make the character use Mem0 to generate responses.
## Run the project
```bash
pnpm start
```
## Conclusion
You have now created a personalized Eliza OS Character using Mem0. You can now start interacting with the character by running the project and talking to the character.
This is a simple example of how to use Mem0 to create a personalized AI agent. You can use this as a starting point to create your own AI agent.
---
<CardGroup cols={2}>
<Card title="Build AI with Personality" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Separate agent and user memories to maintain consistent character personalities.
</Card>
<Card title="AI Tutor with Mem0" icon="graduation-cap" href="/cookbooks/companions/ai-tutor">
Build another type of personalized companion with memory capabilities.
</Card>
</CardGroup>
@@ -0,0 +1,371 @@
---
title: LlamaIndex Multi-Agent with Mem0
description: "Share a persistent memory layer across collaborating LlamaIndex agents."
---
<Snippet file="blank-notif.mdx" />
Build an intelligent multi-agent learning system that uses Mem0 to maintain persistent memory across multiple specialized agents. This example demonstrates how to create a tutoring system where different agents collaborate while sharing a unified memory layer.
## Overview
This example showcases a **Multi-Agent Personal Learning System** that combines:
- **LlamaIndex AgentWorkflow** for multi-agent orchestration
- **Mem0** for persistent, shared memory across agents
- **Multiple agents** that collaborate on teaching tasks
The system consists of two agents:
- **TutorAgent**: Primary instructor for explanations and concept teaching
- **PracticeAgent**: Generates exercises and tracks learning progress
Both agents share the same memory context, enabling seamless collaboration and continuous learning from student interactions.
## Key Features
- **Persistent Memory**: Agents remember previous interactions across sessions
- **Multi-Agent Collaboration**: Agents can hand off tasks to each other
- **Personalized Learning**: Adapts to individual student needs and learning styles
- **Progress Tracking**: Monitors learning patterns and skill development
- **Memory-Driven Teaching**: References past struggles and successes
## Prerequisites
Install the required packages:
```bash
pip install llama-index-core llama-index-memory-mem0 openai python-dotenv
```
Set up your environment variables:
- `MEM0_API_KEY`: Your Mem0 Platform API key
- `OPENAI_API_KEY`: Your OpenAI API key
You can obtain your Mem0 Platform API key from the [Mem0 Platform](https://app.mem0.ai).
## Complete Implementation
```python
"""
Multi-Agent Personal Learning System: Mem0 + LlamaIndex AgentWorkflow Example
INSTALLATIONS:
!pip install llama-index-core llama-index-memory-mem0 openai
You need MEM0_API_KEY and OPENAI_API_KEY to run the example.
"""
import asyncio
from datetime import datetime
from dotenv import load_dotenv
# LlamaIndex imports
from llama_index.core.agent.workflow import AgentWorkflow, FunctionAgent
from llama_index.llms.openai import OpenAI
from llama_index.core.tools import FunctionTool
# Memory integration
from llama_index.memory.mem0 import Mem0Memory
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
load_dotenv()
class MultiAgentLearningSystem:
"""
Multi-Agent Architecture:
- TutorAgent: Main teaching and explanations
- PracticeAgent: Exercises and skill reinforcement
- Shared Memory: Both agents learn from student interactions
"""
def __init__(self, student_id: str):
self.student_id = student_id
self.llm = OpenAI(model="gpt-4.1-nano-2025-04-14", temperature=0.2)
# Memory context for this student
self.memory_context = {"user_id": student_id, "app": "learning_assistant"}
self.memory = Mem0Memory.from_client(
context=self.memory_context
)
self._setup_agents()
def _setup_agents(self):
"""Setup two agents that work together and share memory"""
# TOOLS
async def assess_understanding(topic: str, student_response: str) -> str:
"""Assess student's understanding of a topic and save insights"""
# Simulate assessment logic
if "confused" in student_response.lower() or "don't understand" in student_response.lower():
assessment = f"STRUGGLING with {topic}: {student_response}"
insight = f"Student needs more help with {topic}. Prefers step-by-step explanations."
elif "makes sense" in student_response.lower() or "got it" in student_response.lower():
assessment = f"UNDERSTANDS {topic}: {student_response}"
insight = f"Student grasped {topic} quickly. Can move to advanced concepts."
else:
assessment = f"PARTIAL understanding of {topic}: {student_response}"
insight = f"Student has basic understanding of {topic}. Needs reinforcement."
return f"Assessment: {assessment}\nInsight saved: {insight}"
async def track_progress(topic: str, success_rate: str) -> str:
"""Track learning progress and identify patterns"""
progress_note = f"Progress on {topic}: {success_rate} - {datetime.now().strftime('%Y-%m-%d')}"
return f"Progress tracked: {progress_note}"
# Convert to FunctionTools
tools = [
FunctionTool.from_defaults(async_fn=assess_understanding),
FunctionTool.from_defaults(async_fn=track_progress)
]
# AGENTS
# Tutor Agent - Main teaching and explanation
self.tutor_agent = FunctionAgent(
name="TutorAgent",
description="Primary instructor that explains concepts and adapts to student needs",
system_prompt="""
You are a patient, adaptive programming tutor. Your key strength is REMEMBERING and BUILDING on previous interactions.
Key Behaviors:
1. Always check what the student has learned before (use memory context)
2. Adapt explanations based on their preferred learning style
3. Reference previous struggles or successes
4. Build progressively on past lessons
5. Use assess_understanding to evaluate responses and save insights
MEMORY-DRIVEN TEACHING:
- "Last time you struggled with X, so let's approach Y differently..."
- "Since you prefer visual examples, here's a diagram..."
- "Building on the functions we covered yesterday..."
When student shows understanding, hand off to PracticeAgent for exercises.
""",
tools=tools,
llm=self.llm,
can_handoff_to=["PracticeAgent"]
)
# Practice Agent - Exercises and reinforcement
self.practice_agent = FunctionAgent(
name="PracticeAgent",
description="Creates practice exercises and tracks progress based on student's learning history",
system_prompt="""
You create personalized practice exercises based on the student's learning history and current level.
Key Behaviors:
1. Generate problems that match their skill level (from memory)
2. Focus on areas they've struggled with previously
3. Gradually increase difficulty based on their progress
4. Use track_progress to record their performance
5. Provide encouraging feedback that references their growth
MEMORY-DRIVEN PRACTICE:
- "Let's practice loops again since you wanted more examples..."
- "Here's a harder version of the problem you solved yesterday..."
- "You've improved a lot in functions, ready for the next level?"
After practice, can hand back to TutorAgent for concept review if needed.
""",
tools=tools,
llm=self.llm,
can_handoff_to=["TutorAgent"]
)
# Create the multi-agent workflow
self.workflow = AgentWorkflow(
agents=[self.tutor_agent, self.practice_agent],
root_agent=self.tutor_agent.name,
initial_state={
"current_topic": "",
"student_level": "beginner",
"learning_style": "unknown",
"session_goals": []
}
)
async def start_learning_session(self, topic: str, student_message: str = "") -> str:
"""
Start a learning session with multi-agent memory-aware teaching
"""
if student_message:
request = f"I want to learn about {topic}. {student_message}"
else:
request = f"I want to learn about {topic}."
# The magic happens here - multi-agent memory is automatically shared!
response = await self.workflow.run(
user_msg=request,
memory=self.memory
)
return str(response)
async def get_learning_history(self) -> str:
"""Show what the system remembers about this student"""
try:
# Search memory for learning patterns
memories = self.memory.search(
user_id=self.student_id,
query="learning machine learning"
)
if memories and memories.get('results'):
history = "\n".join(f"- {m['memory']}" for m in memories['results'])
return history
else:
return "No learning history found yet. Let's start building your profile!"
except Exception as e:
return f"Memory retrieval error: {str(e)}"
async def run_learning_agent():
learning_system = MultiAgentLearningSystem(student_id="Alexander")
# First session
print("Session 1:")
response = await learning_system.start_learning_session(
"Vision Language Models",
"I'm new to machine learning but I have good hold on Python and have 4 years of work experience.")
print(response)
# Second session - multi-agent memory will remember the first
print("\nSession 2:")
response2 = await learning_system.start_learning_session(
"Machine Learning", "what all did I cover so far?")
print(response2)
# Show what the multi-agent system remembers
print("\nLearning History:")
history = await learning_system.get_learning_history()
print(history)
if __name__ == "__main__":
"""Run the example"""
print("Multi-agent Learning System powered by LlamaIndex and Mem0")
async def main():
await run_learning_agent()
asyncio.run(main())
```
## How It Works
### 1. Memory Context Setup
```python
# Memory context for this student
self.memory_context = {"user_id": student_id, "app": "learning_assistant"}
self.memory = Mem0Memory.from_client(context=self.memory_context)
```
The memory context identifies the specific student and application, ensuring memory isolation and proper retrieval.
### 2. Agent Collaboration
```python
# Agents can hand off to each other
can_handoff_to=["PracticeAgent"] # TutorAgent can hand off to PracticeAgent
can_handoff_to=["TutorAgent"] # PracticeAgent can hand off back
```
Agents collaborate seamlessly, with the TutorAgent handling explanations and the PracticeAgent managing exercises.
### 3. Shared Memory
```python
# Both agents share the same memory instance
response = await self.workflow.run(
user_msg=request,
memory=self.memory # Shared across all agents
)
```
All agents in the workflow share the same memory context, enabling true collaborative learning.
### 4. Memory-Driven Interactions
The system prompts guide agents to:
- Reference previous learning sessions
- Adapt to discovered learning styles
- Build progressively on past lessons
- Track and respond to learning patterns
## Running the Example
```python
# Initialize the learning system
learning_system = MultiAgentLearningSystem(student_id="Alexander")
# Start a learning session
response = await learning_system.start_learning_session(
"Vision Language Models",
"I'm new to machine learning but I have good hold on Python and have 4 years of work experience."
)
# Continue learning in a new session (memory persists)
response2 = await learning_system.start_learning_session(
"Machine Learning",
"what all did I cover so far?"
)
# Check learning history
history = await learning_system.get_learning_history()
```
## Expected Output
The system will demonstrate memory-aware interactions:
```
Session 1:
I understand you want to learn about Vision Language Models and you mentioned you're new to machine learning but have a strong Python background with 4 years of experience. That's a great foundation to build on!
Let me start with an explanation tailored to your programming background...
[Agent provides explanation and may hand off to PracticeAgent for exercises]
Session 2:
Based on our previous session, I remember we covered Vision Language Models and I noted that you have a strong Python background with 4 years of experience. You mentioned being new to machine learning, so we started with foundational concepts...
[Agent references previous session and builds upon it]
```
## Key Benefits
1. **Persistent Learning**: Agents remember across sessions, creating continuity
2. **Collaborative Teaching**: Multiple specialized agents work together seamlessly
3. **Personalized Adaptation**: System learns and adapts to individual learning styles
4. **Scalable Architecture**: Easy to add more specialized agents
5. **Memory Efficiency**: Shared memory prevents duplication and ensures consistency
## Best Practices
1. **Clear Agent Roles**: Define specific responsibilities for each agent
2. **Memory Context**: Use descriptive context for memory isolation
3. **Handoff Strategy**: Design clear handoff criteria between agents
4. **Memory Hygiene**: Regularly review and clean memory for optimal performance
## Help & Resources
- [LlamaIndex Agent Workflows](https://docs.llamaindex.ai/en/stable/use_cases/agents/)
- [Mem0 Platform](https://app.mem0.ai/)
---
<CardGroup cols={2}>
<Card title="LlamaIndex ReAct with Mem0" icon="brain" href="/cookbooks/frameworks/llamaindex-react">
Start with single-agent patterns before scaling to multi-agent systems.
</Card>
<Card title="Build AI with Personality" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Learn how to scope memories across multiple agents and users.
</Card>
</CardGroup>
@@ -0,0 +1,199 @@
---
title: LlamaIndex ReAct with Mem0
description: "Teach a ReAct agent to store and recall context via Mem0."
---
Create a ReAct Agent with LlamaIndex which uses Mem0 as the memory store.
## Overview
A ReAct agent combines reasoning and action capabilities, making it versatile for tasks requiring both thought processes (reasoning) and interaction with tools or APIs (acting). Mem0 as memory enhances these capabilities by allowing the agent to store and retrieve contextual information from past interactions.
## Setup
```bash
pip install llama-index-core llama-index-memory-mem0
```
Initialize the LLM.
```python
import os
from llama_index.llms.openai import OpenAI
os.environ["OPENAI_API_KEY"] = "<your-openai-api-key>"
llm = OpenAI(model="gpt-4.1-nano-2025-04-14")
```
Initialize the Mem0 client. You can find your API key [here](https://app.mem0.ai/dashboard/api-keys). Read about Mem0 [Open Source](https://docs.mem0.ai/open-source/overview).
```python
os.environ["MEM0_API_KEY"] = "<your-mem0-api-key>"
from llama_index.memory.mem0 import Mem0Memory
context = {"user_id": "david"}
memory_from_client = Mem0Memory.from_client(
context=context,
api_key=os.environ["MEM0_API_KEY"],
search_msg_limit=4, # optional, default is 5
)
```
Create the tools. These tools will be used by the agent to perform actions.
```python
from llama_index.core.tools import FunctionTool
def call_fn(name: str):
"""Call the provided name.
Args:
name: str (Name of the person)
"""
return f"Calling... {name}"
def email_fn(name: str):
"""Email the provided name.
Args:
name: str (Name of the person)
"""
return f"Emailing... {name}"
def order_food(name: str, dish: str):
"""Order food for the provided name.
Args:
name: str (Name of the person)
dish: str (Name of the dish)
"""
return f"Ordering {dish} for {name}"
call_tool = FunctionTool.from_defaults(fn=call_fn)
email_tool = FunctionTool.from_defaults(fn=email_fn)
order_food_tool = FunctionTool.from_defaults(fn=order_food)
```
Initialize the agent with tools and memory.
```python
from llama_index.core.agent import FunctionCallingAgent
agent = FunctionCallingAgent.from_tools(
[call_tool, email_tool, order_food_tool],
llm=llm,
memory=memory_from_client, # or memory_from_config
verbose=True,
)
```
Start the chat.
<Note>The agent will use Mem0 to store the relevant memories from the chat.</Note>
**Input**
```python
response = agent.chat("Hi, My name is David")
print(response)
```
**Output**
```text
> Running step bf44a75a-a920-4cf3-944e-b6e6b5695043. Step input: Hi, My name is David
Added user message to memory: Hi, My name is David
=== LLM Response ===
Hello, David! How can I assist you today?
```
**Input**
```python
response = agent.chat("I love to eat pizza on weekends")
print(response)
```
**Output**
```text
> Running step 845783b0-b85b-487c-baee-8460ebe8b38d. Step input: I love to eat pizza on weekends
Added user message to memory: I love to eat pizza on weekends
=== LLM Response ===
Pizza is a great choice for the weekend! If you'd like, I can help you order some. Just let me know what kind of pizza you prefer!
```
**Input**
```python
response = agent.chat("My preferred way of communication is email")
print(response)
```
**Output**
```text
> Running step 345842f0-f8a0-42ea-a1b7-612265d72a92. Step input: My preferred way of communication is email
Added user message to memory: My preferred way of communication is email
=== LLM Response ===
Got it! If you need any assistance or have any requests, feel free to let me know, and I can communicate with you via email.
```
## Using the Agent Without Memory
**Input**
```python
agent = FunctionCallingAgent.from_tools(
[call_tool, email_tool, order_food_tool],
# memory is not provided
llm=llm,
verbose=True,
)
response = agent.chat("I am feeling hungry, order me something and send me the bill")
print(response)
```
**Output**
```text
> Running step e89eb75d-75e1-4dea-a8c8-5c3d4b77882d. Step input: I am feeling hungry, order me something and send me the bill
Added user message to memory: I am feeling hungry, order me something and send me the bill
=== LLM Response ===
Please let me know your name and the dish you'd like to order, and I'll take care of it for you!
```
<Note>The agent is not able to remember the past preferences the user shared in previous chats.</Note>
## Using the Agent With Memory
**Input**
```python
agent = FunctionCallingAgent.from_tools(
[call_tool, email_tool, order_food_tool],
llm=llm,
# memory is provided
memory=memory_from_client, # or memory_from_config
verbose=True,
)
response = agent.chat("I am feeling hungry, order me something and send me the bill")
print(response)
```
Output
```text
> Running step 5e473db9-3973-4cb1-a5fd-860be0ab0006. Step input: I am feeling hungry, order me something and send me the bill
Added user message to memory: I am feeling hungry, order me something and send me the bill
=== Calling Function ===
Calling function: order_food with args: {"name": "David", "dish": "pizza"}
=== Function Output ===
Ordering pizza for David
=== Calling Function ===
Calling function: email_fn with args: {"name": "David"}
=== Function Output ===
Emailing... David
> Running step 38080544-6b37-4bb2-aab2-7670100d926e. Step input: None
=== LLM Response ===
I've ordered a pizza for you, and the bill has been sent to your email. Enjoy your meal! If there's anything else you need, feel free to let me know.
```
<Note>The agent is able to remember the past preferences the user shared and use them to perform actions.</Note>
---
<CardGroup cols={2}>
<Card title="LlamaIndex Multiagent with Mem0" icon="users" href="/cookbooks/frameworks/llamaindex-multiagent">
Scale to multi-agent workflows with shared memory coordination.
</Card>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Master the core patterns for memory-powered agents across frameworks.
</Card>
</CardGroup>
@@ -0,0 +1,43 @@
---
title: Multimodal Retrieval with Mem0
description: "Store and recall visual context alongside text conversations."
---
Enhance your AI interactions with Mem0's multimodal capabilities. Mem0 now supports image understanding, allowing for richer context and more natural interactions across supported AI platforms.
> Experience the power of multimodal AI! Test out Mem0's image understanding capabilities at [multimodal-demo.mem0.ai](https://multimodal-demo.mem0.ai)
## Features
- **Image Understanding**: Share and discuss images with AI assistants while maintaining context
- **Smart Visual Context**: Automatically capture and reference visual elements in conversations
- **Cross-Modal Memory**: Link visual and textual information seamlessly in your memory layer
- **Cross-Session Recall**: Reference previously discussed visual content across different conversations
- **Seamless Integration**: Works naturally with existing chat interfaces for a smooth experience
## How It Works
1. **Upload Visual Content**: Simply drag and drop or paste images into your conversations
2. **Natural Interaction**: Discuss the visual content naturally with AI assistants
3. **Memory Integration**: Visual context is automatically stored and linked with your conversation history
4. **Persistent Recall**: Retrieve and reference past visual content effortlessly
## Demo Video
<iframe width="700" height="400" src="https://www.youtube.com/embed/2Md5AEFVpmg?si=rXXupn6CiDUPJsi3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
## Try It Out
Visit [multimodal-demo.mem0.ai](https://multimodal-demo.mem0.ai) to experience Mem0's multimodal capabilities firsthand. Upload images and see how Mem0 understands and remembers visual context across your conversations.
---
<CardGroup cols={2}>
<Card title="Multimodal Support" icon="image" href="/platform/features/multimodal-support">
Learn how to store and retrieve vision and audio memories in your apps.
</Card>
<Card title="Voice Companion with OpenAI" icon="microphone" href="/cookbooks/companions/voice-companion-openai">
Build voice-first companions that remember conversations.
</Card>
</CardGroup>
@@ -0,0 +1,238 @@
---
title: Agents SDK Tool with Mem0
description: "Expose Mem0 memories as callable tools inside OpenAI agent workflows."
---
Integrate Mem0's memory capabilities with OpenAI's Agents SDK to create AI agents with persistent memory. You can create agents that remember past conversations and use that context to provide better responses.
## Installation
First, install the required packages:
```bash
pip install mem0ai pydantic openai-agents
```
You'll also need a custom agents framework for this implementation.
## Setting Up Environment Variables
Store your Mem0 API key as an environment variable:
```bash
export MEM0_API_KEY="your_mem0_api_key"
```
Or in your Python script:
```python
import os
os.environ["MEM0_API_KEY"] = "your_mem0_api_key"
```
## Code Structure
The integration consists of three main components:
1. **Context Manager**: Defines user context for memory operations
2. **Memory Tools**: Functions to add, search, and retrieve memories
3. **Memory Agent**: An agent configured to use these memory tools
## Step-by-Step Implementation
### 1. Import Dependencies
```python
from __future__ import annotations
import os
import asyncio
from pydantic import BaseModel
try:
from mem0 import AsyncMemoryClient
except ImportError:
raise ImportError("mem0 is not installed. Please install it using 'pip install mem0ai'.")
from agents import (
Agent,
ItemHelpers,
MessageOutputItem,
RunContextWrapper,
Runner,
ToolCallItem,
ToolCallOutputItem,
TResponseInputItem,
function_tool,
)
```
### 2. Define Memory Context
```python
class Mem0Context(BaseModel):
user_id: str | None = None
```
### 3. Initialize the Mem0 Client
```python
client = AsyncMemoryClient(api_key=os.getenv("MEM0_API_KEY"))
```
### 4. Create Memory Tools
#### Add to Memory
```python
@function_tool
async def add_to_memory(
context: RunContextWrapper[Mem0Context],
content: str,
) -> str:
"""
Add a message to Mem0
Args:
content: The content to store in memory.
"""
messages = [{"role": "user", "content": content}]
user_id = context.context.user_id or "default_user"
await client.add(messages, user_id=user_id)
return f"Stored message: {content}"
```
#### Search Memory
```python
@function_tool
async def search_memory(
context: RunContextWrapper[Mem0Context],
query: str,
) -> str:
"""
Search for memories in Mem0
Args:
query: The search query.
"""
user_id = context.context.user_id or "default_user"
memories = await client.search(query, user_id=user_id)
results = '\n'.join([result["memory"] for result in memories["results"]])
return str(results)
```
#### Get All Memories
```python
@function_tool
async def get_all_memory(
context: RunContextWrapper[Mem0Context],
) -> str:
"""Retrieve all memories from Mem0"""
user_id = context.context.user_id or "default_user"
memories = await client.get_all(user_id=user_id)
results = '\n'.join([result["memory"] for result in memories["results"]])
return str(results)
```
### 5. Configure the Memory Agent
```python
memory_agent = Agent[Mem0Context](
name="Memory Assistant",
instructions="""You are a helpful assistant with memory capabilities. You can:
1. Store new information using add_to_memory
2. Search existing information using search_memory
3. Retrieve all stored information using get_all_memory
When users ask questions:
- If they want to store information, use add_to_memory
- If they're searching for specific information, use search_memory
- If they want to see everything stored, use get_all_memory""",
tools=[add_to_memory, search_memory, get_all_memory],
)
```
### 6. Implement the Main Runtime Loop
```python
async def main():
current_agent: Agent[Mem0Context] = memory_agent
input_items: list[TResponseInputItem] = []
context = Mem0Context()
while True:
user_input = input("Enter your message (or 'quit' to exit): ")
if user_input.lower() == 'quit':
break
input_items.append({"content": user_input, "role": "user"})
result = await Runner.run(current_agent, input_items, context=context)
for new_item in result.new_items:
agent_name = new_item.agent.name
if isinstance(new_item, MessageOutputItem):
print(f"{agent_name}: {ItemHelpers.text_message_output(new_item)}")
elif isinstance(new_item, ToolCallItem):
print(f"{agent_name}: Calling a tool")
elif isinstance(new_item, ToolCallOutputItem):
print(f"{agent_name}: Tool call output: {new_item.output}")
else:
print(f"{agent_name}: Skipping item: {new_item.__class__.__name__}")
input_items = result.to_input_list()
if __name__ == "__main__":
asyncio.run(main())
```
## Usage Examples
### Storing Information
```
User: Remember that my favorite color is blue
Agent: Calling a tool
Agent: Tool call output: Stored message: my favorite color is blue
Agent: I've stored that your favorite color is blue in my memory. I'll remember that for future conversations.
```
### Searching Memory
```
User: What's my favorite color?
Agent: Calling a tool
Agent: Tool call output: my favorite color is blue
Agent: Your favorite color is blue, based on what you've told me earlier.
```
### Retrieving All Memories
```
User: What do you know about me?
Agent: Calling a tool
Agent: Tool call output: favorite color is blue
my birthday is on March 15
Agent: Based on our previous conversations, I know that:
1. Your favorite color is blue
2. Your birthday is on March 15
```
## Advanced Configuration
### Custom User IDs
You can specify different user IDs to maintain separate memory stores for multiple users:
```python
context = Mem0Context(user_id="user123")
```
## Resources
- [Mem0 Documentation](https://docs.mem0.ai)
- [Mem0 Dashboard](https://app.mem0.ai/dashboard)
- [API Reference](https://docs.mem0.ai/api-reference)
---
<CardGroup cols={2}>
<Card title="OpenAI Tool Calls with Mem0" icon="wrench" href="/cookbooks/integrations/openai-tool-calls">
Extend OpenAI assistants with tool-based memory operations.
</Card>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Learn the core patterns for memory-powered agents with any SDK.
</Card>
</CardGroup>
+143
View File
@@ -0,0 +1,143 @@
---
title: AWS Bedrock with Mem0
description: "Pair Mem0 with AWS Bedrock, OpenSearch, and Neptune for a managed stack."
---
This example demonstrates how to configure and use the `mem0ai` SDK with **AWS Bedrock**, **OpenSearch Service (AOSS)**, and **AWS Neptune Analytics** for persistent memory capabilities in Python.
## Installation
Install the required dependencies to include the Amazon data stack, including **boto3**, **opensearch-py**, and **langchain-aws**:
```bash
pip install "mem0ai[graph,extras]"
```
## Environment Setup
Set your AWS environment variables:
```python
import os
# Set these in your environment or notebook
os.environ['AWS_REGION'] = 'us-west-2'
os.environ['AWS_ACCESS_KEY_ID'] = 'AK00000000000000000'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'AS00000000000000000'
# Confirm they are set
print(os.environ['AWS_REGION'])
print(os.environ['AWS_ACCESS_KEY_ID'])
print(os.environ['AWS_SECRET_ACCESS_KEY'])
```
## Configuration and Usage
This sets up Mem0 with:
- [AWS Bedrock for LLM](https://docs.mem0.ai/components/llms/models/aws_bedrock)
- [AWS Bedrock for embeddings](https://docs.mem0.ai/components/embedders/models/aws_bedrock#aws-bedrock)
- [OpenSearch as the vector store](https://docs.mem0.ai/components/vectordbs/dbs/opensearch)
- [Graph Memory guide](https://docs.mem0.ai/open-source/features/graph-memory)
```python
import boto3
from opensearchpy import RequestsHttpConnection, AWSV4SignerAuth
from mem0.memory.main import Memory
region = 'us-west-2'
service = 'aoss'
credentials = boto3.Session().get_credentials()
auth = AWSV4SignerAuth(credentials, region, service)
config = {
"embedder": {
"provider": "aws_bedrock",
"config": {
"model": "amazon.titan-embed-text-v2:0"
}
},
"llm": {
"provider": "aws_bedrock",
"config": {
"model": "us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"temperature": 0.1,
"max_tokens": 2000
}
},
"vector_store": {
"provider": "opensearch",
"config": {
"collection_name": "mem0",
"host": "your-opensearch-domain.us-west-2.es.amazonaws.com",
"port": 443,
"http_auth": auth,
"connection_class": RequestsHttpConnection,
"pool_maxsize": 20,
"use_ssl": True,
"verify_certs": True,
"embedding_model_dims": 1024,
}
},
"graph_store": {
"provider": "neptune",
"config": {
"endpoint": f"neptune-graph://my-graph-identifier",
},
},
}
# Initialize the memory system
m = Memory.from_config(config)
```
## Usage
Reference [Notebook example](https://github.com/mem0ai/mem0/blob/main/examples/graph-db-demo/neptune-example.ipynb)
### Add a memory
```python
messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about thriller movies? They can be quite engaging."},
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
]
# Store inferred memories (default behavior)
result = m.add(messages, user_id="alice", metadata={"category": "movie_recommendations"})
```
### Search a memory
```python
relevant_memories = m.search(query, user_id="alice")
```
### Get all memories
```python
all_memories = m.get_all(user_id="alice")
```
### Get a specific memory
```python
memory = m.get(memory_id)
```
## Conclusion
With Mem0 and AWS services like Bedrock, OpenSearch, and Neptune Analytics, you can build intelligent AI companions that remember, adapt, and personalize their responses over time. This makes them ideal for long-term assistants, tutors, or support bots with persistent memory and natural conversation abilities.
---
<CardGroup cols={2}>
<Card title="Neptune Analytics with Mem0" icon="database" href="/cookbooks/integrations/neptune-analytics">
Explore graph-based memory storage with AWS Neptune Analytics.
</Card>
<Card title="Graph Memory Features" icon="sitemap" href="/platform/features/graph-memory">
Learn how to leverage knowledge graphs for entity relationships.
</Card>
</CardGroup>
@@ -0,0 +1,301 @@
---
title: Healthcare Coach with Mem0 and Google ADK
description: "Guide patients with an assistant that remembers history across ADK sessions."
---
This example demonstrates how to build a healthcare assistant that remembers patient information across conversations using Google ADK and Mem0.
## Overview
The Healthcare Assistant helps patients by:
- Remembering their medical history and symptoms
- Providing general health information
- Scheduling appointment reminders
- Maintaining a personalized experience across conversations
By integrating Mem0's memory layer with Google ADK, the assistant maintains context about the patient without requiring them to repeat information.
## Setup
Before you begin, make sure you have:
Installed Google ADK and Mem0 SDK:
```bash
pip install google-adk mem0ai python-dotenv
```
## Code Breakdown
Let's get started and understand the different components required in building a healthcare assistant powered by memory
```python
# Import dependencies
import os
import asyncio
from google.adk.agents import Agent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
from mem0 import MemoryClient
from dotenv import load_dotenv
load_dotenv()
# Set up environment variables
# os.environ["GOOGLE_API_KEY"] = "your-google-api-key"
# os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
# Define a global user ID for simplicity
USER_ID = "Alex"
# Initialize Mem0 client
mem0 = MemoryClient()
```
## Define Memory Tools
First, we'll create tools that allow our agent to store and retrieve information using Mem0:
```python
def save_patient_info(information: str) -> dict:
"""Saves important patient information to memory."""
# Store in Mem0
response = mem0_client.add(
[{"role": "user", "content": information}],
user_id=USER_ID,
run_id="healthcare_session",
metadata={"type": "patient_information"}
)
def retrieve_patient_info(query: str) -> dict:
"""Retrieves relevant patient information from memory."""
# Search Mem0
results = mem0_client.search(
query,
user_id=USER_ID,
limit=5,
threshold=0.7 # Higher threshold for more relevant results
)
# Format and return the results
if results and len(results) > 0:
memories = [memory["memory"] for memory in results.get('results', [])]
return {
"status": "success",
"memories": memories,
"count": len(memories)
}
else:
return {
"status": "no_results",
"memories": [],
"count": 0
}
```
## Define Healthcare Tools
Next, we'll add tools specific to healthcare assistance:
```python
def schedule_appointment(date: str, time: str, reason: str) -> dict:
"""Schedules a doctor's appointment."""
# In a real app, this would connect to a scheduling system
appointment_id = f"APT-{hash(date + time) % 10000}"
return {
"status": "success",
"appointment_id": appointment_id,
"confirmation": f"Appointment scheduled for {date} at {time} for {reason}",
"message": "Please arrive 15 minutes early to complete paperwork."
}
```
## Create the Healthcare Assistant Agent
Now we'll create our main agent with all the tools:
```python
# Create the agent
healthcare_agent = Agent(
name="healthcare_assistant",
model="gemini-1.5-flash", # Using Gemini for healthcare assistant
description="Healthcare assistant that helps patients with health information and appointment scheduling.",
instruction="""You are a helpful Healthcare Assistant with memory capabilities.
Your primary responsibilities are to:
1. Remember patient information using the 'save_patient_info' tool when they share symptoms, conditions, or preferences.
2. Retrieve past patient information using the 'retrieve_patient_info' tool when relevant to the current conversation.
3. Help schedule appointments using the 'schedule_appointment' tool.
IMPORTANT GUIDELINES:
- Always be empathetic, professional, and helpful.
- Save important patient information like symptoms, conditions, allergies, and preferences.
- Check if you have relevant patient information before asking for details they may have shared previously.
- Make it clear you are not a doctor and cannot provide medical diagnosis or treatment.
- For serious symptoms, always recommend consulting a healthcare professional.
- Keep all patient information confidential.
""",
tools=[save_patient_info, retrieve_patient_info, schedule_appointment]
)
```
## Set Up Session and Runner
```python
# Set up Session Service and Runner
session_service = InMemorySessionService()
# Define constants for the conversation
APP_NAME = "healthcare_assistant_app"
USER_ID = "Alex"
SESSION_ID = "session_001"
# Create a session
session = session_service.create_session(
app_name=APP_NAME,
user_id=USER_ID,
session_id=SESSION_ID
)
# Create the runner
runner = Runner(
agent=healthcare_agent,
app_name=APP_NAME,
session_service=session_service
)
```
## Interact with the Healthcare Assistant
```python
# Function to interact with the agent
async def call_agent_async(query, runner, user_id, session_id):
"""Sends a query to the agent and returns the final response."""
print(f"\n>>> Patient: {query}")
# Format the user's message
content = types.Content(
role='user',
parts=[types.Part(text=query)]
)
# Set user_id for tools to access
save_patient_info.user_id = user_id
retrieve_patient_info.user_id = user_id
# Run the agent
async for event in runner.run_async(
user_id=user_id,
session_id=session_id,
new_message=content
):
if event.is_final_response():
if event.content and event.content.parts:
response = event.content.parts[0].text
print(f"<<< Assistant: {response}")
return response
return "No response received."
# Example conversation flow
async def run_conversation():
# First interaction - patient introduces themselves with key information
await call_agent_async(
"Hi, I'm Alex. I've been having headaches for the past week, and I have a penicillin allergy.",
runner=runner,
user_id=USER_ID,
session_id=SESSION_ID
)
# Request for health information
await call_agent_async(
"Can you tell me more about what might be causing my headaches?",
runner=runner,
user_id=USER_ID,
session_id=SESSION_ID
)
# Schedule an appointment
await call_agent_async(
"I think I should see a doctor. Can you help me schedule an appointment for next Monday at 2pm?",
runner=runner,
user_id=USER_ID,
session_id=SESSION_ID
)
# Test memory - should remember patient name, symptoms, and allergy
await call_agent_async(
"What medications should I avoid for my headaches?",
runner=runner,
user_id=USER_ID,
session_id=SESSION_ID
)
# Run the conversation example
if __name__ == "__main__":
asyncio.run(run_conversation())
```
## How It Works
This healthcare assistant demonstrates several key capabilities:
1. **Memory Storage**: When Alex mentions her headaches and penicillin allergy, the agent stores this information in Mem0 using the `save_patient_info` tool.
2. **Contextual Retrieval**: When Alex asks about headache causes, the agent uses the `retrieve_patient_info` tool to recall her specific situation.
3. **Memory Application**: When discussing medications, the agent remembers Alex's penicillin allergy without her needing to repeat it, providing safer and more personalized advice.
4. **Conversation Continuity**: The agent maintains context across the entire conversation session, creating a more natural and efficient interaction.
## Key Implementation Details
## User ID Management
Instead of passing the user ID as a parameter to the memory tools (which would require modifying the ADK's tool calling system), we attach it directly to the function object:
```python
# Set user_id for tools to access
save_patient_info.user_id = user_id
retrieve_patient_info.user_id = user_id
```
Inside the tool functions, we retrieve this attribute:
```python
# Get user_id from session state or use default
user_id = getattr(save_patient_info, 'user_id', 'default_user')
```
This approach allows our tools to maintain user context without complicating their parameter signatures.
## Mem0 Integration
The integration with Mem0 happens through two primary functions:
1. `mem0_client.add()` - Stores new information with appropriate metadata
2. `mem0_client.search()` - Retrieves relevant memories using semantic search
The `threshold` parameter in the search function ensures that only highly relevant memories are returned.
## Conclusion
This example demonstrates how to build a healthcare assistant with persistent memory using Google ADK and Mem0. The integration allows for a more personalized patient experience by maintaining context across conversation turns, which is particularly valuable in healthcare scenarios where continuity of information is crucial.
By storing and retrieving patient information intelligently, the assistant provides more relevant responses without requiring the patient to repeat their medical history, symptoms, or preferences.
---
<CardGroup cols={2}>
<Card title="Tag and Organize Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories">
Categorize patient data by symptoms, history, and visit context.
</Card>
<Card title="Support Inbox with Mem0" icon="headset" href="/cookbooks/operations/support-inbox">
Apply similar memory patterns to customer support workflows.
</Card>
</CardGroup>
@@ -0,0 +1,138 @@
---
title: Mastra Agent with Mem0
description: "Extend Mastra agents with persistent memories powered by Mem0."
---
In this example you'll learn how to use Mem0 to add long-term memory capabilities to [Mastra's agent](https://mastra.ai/) via tool-use. This memory integration can work alongside Mastra's [agent memory features](https://mastra.ai/docs/agents/01-agent-memory).
You can find the complete example code in the [Mastra repository](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-mem0).
## Overview
This guide will show you how to integrate Mem0 with Mastra to add long-term memory capabilities to your agents. We'll create tools that allow agents to save and retrieve memories using Mem0's API.
## Installation
**Install the Integration Package**
To install the Mem0 integration, run:
```bash
npm install @mastra/mem0
```
**Add the Integration to Your Project**
Create a new file for your integrations and import the integration:
```typescript integrations/index.ts
import { Mem0Integration } from "@mastra/mem0";
export const mem0 = new Mem0Integration({
config: {
apiKey: process.env.MEM0_API_KEY!,
userId: "alice",
},
});
```
**Use the Integration in Tools or Workflows**
You can now use the integration when defining tools for your agents or in workflows.
```typescript tools/index.ts
import { createTool } from "@mastra/core";
import { z } from "zod";
import { mem0 } from "../integrations";
export const mem0RememberTool = createTool({
id: "Mem0-remember",
description:
"Remember your agent memories that you've previously saved using the Mem0-memorize tool.",
inputSchema: z.object({
question: z
.string()
.describe("Question used to look up the answer in saved memories."),
}),
outputSchema: z.object({
answer: z.string().describe("Remembered answer"),
}),
execute: async ({ context }) => {
console.log(`Searching memory "${context.question}"`);
const memory = await mem0.searchMemory(context.question);
console.log(`\nFound memory "${memory}"\n`);
return {
answer: memory,
};
},
});
export const mem0MemorizeTool = createTool({
id: "Mem0-memorize",
description:
"Save information to mem0 so you can remember it later using the Mem0-remember tool.",
inputSchema: z.object({
statement: z.string().describe("A statement to save into memory"),
}),
execute: async ({ context }) => {
console.log(`\nCreating memory "${context.statement}"\n`);
// to reduce latency memories can be saved async without blocking tool execution
void mem0.createMemory(context.statement).then(() => {
console.log(`\nMemory "${context.statement}" saved.\n`);
});
return { success: true };
},
});
```
**Create a New Agent**
```typescript agents/index.ts
import { openai } from '@ai-sdk/openai';
import { Agent } from '@mastra/core/agent';
import { mem0MemorizeTool, mem0RememberTool } from '../tools';
export const mem0Agent = new Agent({
name: 'Mem0 Agent',
instructions: `
You are a helpful assistant that has the ability to memorize and remember facts using Mem0.
`,
model: openai('gpt-4.1-nano'),
tools: { mem0RememberTool, mem0MemorizeTool },
});
```
**Run the Agent**
```typescript index.ts
import { Mastra } from '@mastra/core/mastra';
import { createLogger } from '@mastra/core/logger';
import { mem0Agent } from './agents';
export const mastra = new Mastra({
agents: { mem0Agent },
logger: createLogger({
name: 'Mastra',
level: 'error',
}),
});
```
In the example above:
- We import the `@mastra/mem0` integration
- We define two tools that use the Mem0 API client to create new memories and recall previously saved memories
- The tool accepts `question` as an input and returns the memory as a string
---
<CardGroup cols={2}>
<Card title="Build AI with Personality" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Separate agent and user memories to maintain consistent personalities.
</Card>
<Card title="Agents SDK Tool with Mem0" icon="robot" href="/cookbooks/integrations/agents-sdk-tool">
Explore tool-calling patterns with the OpenAI Agents SDK.
</Card>
</CardGroup>
@@ -0,0 +1,133 @@
---
title: Neptune Analytics with Mem0
description: "Combine Mem0 graph memory with AWS Neptune Analytics and Bedrock."
---
This example demonstrates how to configure and use the `mem0ai` SDK with **AWS Bedrock** and **AWS Neptune Analytics** for persistent memory capabilities in Python.
## Installation
Install the required dependencies to include the Amazon data stack, including **boto3** and **langchain-aws**:
```bash
pip install "mem0ai[graph,extras]"
```
## Environment Setup
Set your AWS environment variables:
```python
import os
# Set these in your environment or notebook
os.environ['AWS_REGION'] = 'us-west-2'
os.environ['AWS_ACCESS_KEY_ID'] = 'AK00000000000000000'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'AS00000000000000000'
# Confirm they are set
print(os.environ['AWS_REGION'])
print(os.environ['AWS_ACCESS_KEY_ID'])
print(os.environ['AWS_SECRET_ACCESS_KEY'])
```
## Configuration and Usage
This sets up Mem0 with:
- [AWS Bedrock for LLM](https://docs.mem0.ai/components/llms/models/aws_bedrock)
- [AWS Bedrock for embeddings](https://docs.mem0.ai/components/embedders/models/aws_bedrock#aws-bedrock)
- [Neptune Analytics as the vector store](https://docs.mem0.ai/components/vectordbs/dbs/neptune_analytics)
- [Graph Memory guide](https://docs.mem0.ai/open-source/features/graph-memory).
```python
import boto3
from mem0.memory.main import Memory
region = 'us-west-2'
neptune_analytics_endpoint = 'neptune-graph://my-graph-identifier'
config = {
"embedder": {
"provider": "aws_bedrock",
"config": {
"model": "amazon.titan-embed-text-v2:0"
}
},
"llm": {
"provider": "aws_bedrock",
"config": {
"model": "us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"temperature": 0.1,
"max_tokens": 2000
}
},
"vector_store": {
"provider": "neptune",
"config": {
"collection_name": "mem0",
"endpoint": neptune_analytics_endpoint,
},
},
"graph_store": {
"provider": "neptune",
"config": {
"endpoint": neptune_analytics_endpoint,
},
},
}
# Initialize the memory system
m = Memory.from_config(config)
```
## Usage
Reference [Notebook example](https://github.com/mem0ai/mem0/blob/main/examples/graph-db-demo/neptune-example.ipynb)
#### Add a memory:
```python
messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
]
# Store inferred memories (default behavior)
result = m.add(messages, user_id="alice", metadata={"category": "movie_recommendations"})
```
#### Search a memory:
```python
relevant_memories = m.search(query, user_id="alice")
```
#### Get all memories:
```python
all_memories = m.get_all(user_id="alice")
```
#### Get a specific memory:
```python
memory = m.get(memory_id)
```
---
## Conclusion
With Mem0 and AWS services like Bedrock and Neptune Analytics, you can build intelligent AI companions that remember, adapt, and personalize their responses over time. This makes them ideal for long-term assistants, tutors, or support bots with persistent memory and natural conversation abilities.
---
<CardGroup cols={2}>
<Card title="AWS Bedrock with Mem0" icon="aws" href="/cookbooks/integrations/aws-bedrock">
Combine Neptune Analytics with AWS Bedrock for complete AWS stack.
</Card>
<Card title="Graph Memory Architecture" icon="sitemap" href="/cookbooks/essentials/choosing-memory-architecture-vector-vs-graph">
Understand when to use graph vs vector memory for your use case.
</Card>
</CardGroup>
@@ -0,0 +1,325 @@
---
title: OpenAI Tool Calls with Mem0
description: "Wire Mem0 memories into OpenAI's inbuilt function-calling flow."
---
Integrate Mem0’s memory capabilities with OpenAI’s Inbuilt Tools to create AI agents with persistent memory.
## Getting Started
### Installation
```bash
npm install mem0ai openai zod
```
## Environment Setup
Save your Mem0 and OpenAI API keys in a `.env` file:
```
MEM0_API_KEY=your_mem0_api_key
OPENAI_API_KEY=your_openai_api_key
```
Get your Mem0 API key from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys).
### Configuration
```javascript
const mem0Config = {
apiKey: process.env.MEM0_API_KEY,
user_id: "sample-user",
};
const openAIClient = new OpenAI();
const mem0Client = new MemoryClient(mem0Config);
```
## Adding Memories
Store user preferences, past interactions, or any relevant information:
<CodeGroup>
```javascript JavaScript
async function addUserPreferences() {
const mem0Client = new MemoryClient(mem0Config);
const userPreferences = "I Love BMW, Audi and Porsche. I Hate Mercedes. I love Red cars and Maroon cars. I have a budget of 120K to 150K USD. I like Audi the most.";
await mem0Client.add([{
role: "user",
content: userPreferences,
}], mem0Config);
}
await addUserPreferences();
```
```json Output (Memories)
[
{
"id": "ff9f3367-9e83-415d-b9c5-dc8befd9a4b4",
"data": { "memory": "Loves BMW, Audi, and Porsche" },
"event": "ADD"
},
{
"id": "04172ce6-3d7b-45a3-b4a1-ee9798593cb4",
"data": { "memory": "Hates Mercedes" },
"event": "ADD"
},
{
"id": "db363a5d-d258-4953-9e4c-777c120de34d",
"data": { "memory": "Loves red cars and maroon cars" },
"event": "ADD"
},
{
"id": "5519aaad-a2ac-4c0d-81d7-0d55c6ecdba8",
"data": { "memory": "Has a budget of 120K to 150K USD" },
"event": "ADD"
},
{
"id": "523b7693-7344-4563-922f-5db08edc8634",
"data": { "memory": "Likes Audi the most" },
"event": "ADD"
}
]
```
</CodeGroup>
## Retrieving Memories
Search for relevant memories based on the current user input:
```javascript
const relevantMemories = await mem0Client.search(userInput, mem0Config);
```
## Structured Responses with Zod
Define structured response schemas to get consistent output formats:
```javascript
// Define the schema for a car recommendation
const CarSchema = z.object({
car_name: z.string(),
car_price: z.string(),
car_url: z.string(),
car_image: z.string(),
car_description: z.string(),
});
// Schema for a list of car recommendations
const Cars = z.object({
cars: z.array(CarSchema),
});
// Create a function tool based on the schema
const carRecommendationTool = zodResponsesFunction({
name: "carRecommendations",
parameters: Cars
});
// Use the tool in your OpenAI request
const response = await openAIClient.responses.create({
model: "gpt-4.1-nano-2025-04-14",
tools: [{ type: "web_search_preview" }, carRecommendationTool],
input: `${getMemoryString(relevantMemories)}\n${userInput}`,
});
```
## Using Web Search
Combine memory with web search for up-to-date recommendations:
```javascript
const response = await openAIClient.responses.create({
model: "gpt-4.1-nano-2025-04-14",
tools: [{ type: "web_search_preview" }, carRecommendationTool],
input: `${getMemoryString(relevantMemories)}\n${userInput}`,
});
```
## Examples
## Complete Car Recommendation System
```javascript
import MemoryClient from "mem0ai";
import { OpenAI } from "openai";
import { zodResponsesFunction } from "openai/helpers/zod";
import { z } from "zod";
import dotenv from 'dotenv';
dotenv.config();
const mem0Config = {
apiKey: process.env.MEM0_API_KEY,
user_id: "sample-user",
};
async function run() {
// Responses without memories
console.log("\n\nRESPONSES WITHOUT MEMORIES\n\n");
await main();
// Adding sample memories
await addSampleMemories();
// Responses with memories
console.log("\n\nRESPONSES WITH MEMORIES\n\n");
await main(true);
}
// OpenAI Response Schema
const CarSchema = z.object({
car_name: z.string(),
car_price: z.string(),
car_url: z.string(),
car_image: z.string(),
car_description: z.string(),
});
const Cars = z.object({
cars: z.array(CarSchema),
});
async function main(memory = false) {
const openAIClient = new OpenAI();
const mem0Client = new MemoryClient(mem0Config);
const input = "Suggest me some cars that I can buy today.";
const tool = zodResponsesFunction({ name: "carRecommendations", parameters: Cars });
// Store the user input as a memory
await mem0Client.add([{
role: "user",
content: input,
}], mem0Config);
// Search for relevant memories
let relevantMemories = []
if (memory) {
relevantMemories = await mem0Client.search(input, mem0Config);
}
const response = await openAIClient.responses.create({
model: "gpt-4.1-nano-2025-04-14",
tools: [{ type: "web_search_preview" }, tool],
input: `${getMemoryString(relevantMemories)}\n${input}`,
});
console.log(response.output);
}
async function addSampleMemories() {
const mem0Client = new MemoryClient(mem0Config);
const myInterests = "I Love BMW, Audi and Porsche. I Hate Mercedes. I love Red cars and Maroon cars. I have a budget of 120K to 150K USD. I like Audi the most.";
await mem0Client.add([{
role: "user",
content: myInterests,
}], mem0Config);
}
const getMemoryString = (memories) => {
const MEMORY_STRING_PREFIX = "These are the memories I have stored. Give more weightage to the question by users and try to answer that first. You have to modify your answer based on the memories I have provided. If the memories are irrelevant you can ignore them. Also don't reply to this section of the prompt, or the memories, they are only for your reference. The MEMORIES of the USER are: \n\n";
const memoryString = (memories?.results || memories).map((mem) => `${mem.memory}`).join("\n") ?? "";
return memoryString.length > 0 ? `${MEMORY_STRING_PREFIX}${memoryString}` : "";
};
run().catch(console.error);
```
## Responses
<CodeGroup>
```json Without Memories
{
"cars": [
{
"car_name": "Toyota Camry",
"car_price": "$25,000",
"car_url": "https://www.toyota.com/camry/",
"car_image": "https://link-to-toyota-camry-image.com",
"car_description": "Reliable mid-size sedan with great fuel efficiency."
},
{
"car_name": "Honda Accord",
"car_price": "$26,000",
"car_url": "https://www.honda.com/accord/",
"car_image": "https://link-to-honda-accord-image.com",
"car_description": "Comfortable and spacious with advanced safety features."
},
{
"car_name": "Ford Mustang",
"car_price": "$28,000",
"car_url": "https://www.ford.com/mustang/",
"car_image": "https://link-to-ford-mustang-image.com",
"car_description": "Iconic sports car with powerful engine options."
},
{
"car_name": "Tesla Model 3",
"car_price": "$38,000",
"car_url": "https://www.tesla.com/model3",
"car_image": "https://link-to-tesla-model3-image.com",
"car_description": "Electric vehicle with advanced technology and long range."
},
{
"car_name": "Chevrolet Equinox",
"car_price": "$24,000",
"car_url": "https://www.chevrolet.com/equinox/",
"car_image": "https://link-to-chevron-equinox-image.com",
"car_description": "Compact SUV with a spacious interior and user-friendly technology."
}
]
}
```
```json With Memories
{
"cars": [
{
"car_name": "Audi RS7",
"car_price": "$118,500",
"car_url": "https://www.audiusa.com/us/web/en/models/rs7/2023/overview.html",
"car_image": "https://www.audiusa.com/content/dam/nemo/us/models/rs7/my23/gallery/1920x1080_AOZ_A717_191004.jpg",
"car_description": "The Audi RS7 is a high-performance hatchback with a sleek design, powerful 591-hp twin-turbo V8, and luxurious interior. It's available in various colors including red."
},
{
"car_name": "Porsche Panamera GTS",
"car_price": "$129,300",
"car_url": "https://www.porsche.com/usa/models/panamera/panamera-models/panamera-gts/",
"car_image": "https://files.porsche.com/filestore/image/multimedia/noneporsche-panamera-gts-sample-m02-high/normal/8a6327c3-6c7f-4c6f-a9a8-fb9f58b21795;sP;twebp/porsche-normal.webp",
"car_description": "The Porsche Panamera GTS is a luxury sports sedan with a 473-hp V8 engine, exquisite handling, and available in stunning red. Balances sportiness and comfort."
},
{
"car_name": "BMW M5",
"car_price": "$105,500",
"car_url": "https://www.bmwusa.com/vehicles/m-models/m5/sedan/overview.html",
"car_image": "https://www.bmwusa.com/content/dam/bmwusa/M/m5/2023/bmw-my23-m5-sapphire-black-twilight-purple-exterior-02.jpg",
"car_description": "The BMW M5 is a powerhouse sedan with a 600-hp V8 engine, known for its great handling and luxury. It comes in several distinctive colors including maroon."
}
]
}
```
</CodeGroup>
## Resources
- [Mem0 Documentation](https://docs.mem0.ai)
- [Mem0 Dashboard](https://app.mem0.ai/dashboard)
- [API Reference](https://docs.mem0.ai/api-reference)
- [OpenAI Documentation](https://platform.openai.com/docs)
---
<CardGroup cols={2}>
<Card title="Agents SDK Tool with Mem0" icon="robot" href="/cookbooks/integrations/agents-sdk-tool">
Extend the OpenAI Agents SDK with Mem0 integration capabilities.
</Card>
<Card title="Control Memory Ingestion" icon="filter" href="/cookbooks/essentials/controlling-memory-ingestion">
Fine-tune what memories get stored during tool calls.
</Card>
</CardGroup>
@@ -0,0 +1,206 @@
---
title: Tavily Search with Mem0
description: "Blend Tavily's realtime results with personal context stored in Mem0."
---
<Snippet file="security-compliance.mdx" />
Imagine asking a search assistant for "coffee shops nearby" and instead of generic results, it shows remote-work-friendly cafes with great WiFi in your city because it remembers you mentioned working remotely before. Or when you search for "lunchbox ideas for kids" it knows you have a 7-year-old daughter and recommends peanut-free options that align with her allergy.
That's what we are going to build today, a Personalized Search Assistant powered by Mem0 for memory and [Tavily](https://tavily.com) for real-time search.
## Why Personalized Search
Most assistants treat every query like they've never seen you before. That means repeating yourself about your location, diet, or preferences, and getting results that feel generic.
- With Mem0, your assistant builds a memory of the user's world.
- With Tavily, it fetches fresh and accurate results in real time.
Together, they make every interaction smarter, faster, and more personal.
## Prerequisites
Before you begin, make sure you have:
1. Installed the dependencies:
```bash
pip install langchain mem0ai langchain-tavily langchain-openai
```
2. Set up your API keys in a .env file:
```bash
OPENAI_API_KEY=your-openai-key
TAVILY_API_KEY=your-tavily-key
MEM0_API_KEY=your-mem0-key
```
## Code Walkthrough
Let’s break down the main components.
### 1: Initialize Mem0 with Custom Instructions
We configure Mem0 with custom instructions that guide it to infer user memories tailored specifically for our usecase.
```python
from mem0 import MemoryClient
mem0_client = MemoryClient()
mem0_client.project.update(
custom_instructions='''
INFER THE MEMORIES FROM USER QUERIES EVEN IF IT'S A QUESTION.
We are building personalized search for which we need to understand about user's preferences and life
and extract facts and memories accordingly.
'''
)
```
Now, if a user casually mentions "I need to pick up my daughter" or "What's the weather at Los Angeles", Mem0 remembers they have a daughter or the user is interested in or connected with Los Angeles in terms of location. These details will be referenced for future searches.
### 2. Simulating User History
To test personalization, we preload some sample conversation history for a user:
```python
def setup_user_history(user_id):
conversations = [
[{"role": "user", "content": "What will be the weather today at Los Angeles? I need to pick up my daughter from office."},
{"role": "assistant", "content": "I'll check the weather in LA for you."}],
[{"role": "user", "content": "I'm looking for vegan restaurants in Santa Monica"},
{"role": "assistant", "content": "I'll find great vegan options in Santa Monica."}],
[{"role": "user", "content": "My 7-year-old daughter is allergic to peanuts"},
{"role": "assistant", "content": "I'll remember to check for peanut-free options."}],
[{"role": "user", "content": "I work remotely and need coffee shops with good wifi"},
{"role": "assistant", "content": "I'll find remote-work-friendly coffee shops."}],
[{"role": "user", "content": "We love hiking and outdoor activities on weekends"},
{"role": "assistant", "content": "Great! I'll keep your outdoor activity preferences in mind."}],
]
for conversation in conversations:
mem0_client.add(conversation, user_id=user_id)
```
This gives the agent a baseline understanding of the user’s lifestyle and needs.
### 3. Retrieving User Context from Memory
When a user makes a new search query, we retrieve relevant memories to enhance the search query:
```python
def get_user_context(user_id, query):
# For Platform API, user_id goes in filters
filters = {"user_id": user_id}
user_memories = mem0_client.search(query=query, filters=filters)
if user_memories:
context = "\n".join([f"- {memory['memory']}" for memory in user_memories])
return context
else:
return "No previous user context available."
```
This context is injected into the search agent so results are personalized.
### 4. Creating the Personalized Search Agent
The agent uses Tavily search, but always augments search queries with user context:
```python
def create_personalized_search_agent(user_context):
tavily_search = TavilySearch(
max_results=10,
search_depth="advanced",
include_answer=True,
topic="general"
)
tools = [tavily_search]
prompt = ChatPromptTemplate.from_messages([
("system", f"""You are a personalized search assistant.
USER CONTEXT AND PREFERENCES:
{user_context}
YOUR ROLE:
1. Analyze the user's query and context.
2. Enhance the query with relevant personal memories.
3. Always use tavily_search for results.
4. Explain which memories influenced personalization.
"""),
MessagesPlaceholder(variable_name="messages"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_openai_tools_agent(llm=llm, tools=tools, prompt=prompt)
return AgentExecutor(agent=agent, tools=tools, verbose=True, return_intermediate_steps=True)
```
### 5. Run a Personalized Search
The workflow ties everything together:
```python
def conduct_personalized_search(user_id, query):
user_context = get_user_context(user_id, query)
agent_executor = create_personalized_search_agent(user_context)
response = agent_executor.invoke({"messages": [HumanMessage(content=query)]})
return {"agent_response": response['output']}
```
### 6. Store New Interactions
Every new query/response pair is stored for future personalization:
```python
def store_search_interaction(user_id, original_query, agent_response):
interaction = [
{"role": "user", "content": f"Searched for: {original_query}"},
{"role": "assistant", "content": f"Results based on preferences: {agent_response}"}
]
mem0_client.add(messages=interaction, user_id=user_id)
```
### Full Example Run
```python
if __name__ == "__main__":
user_id = "john"
setup_user_history(user_id)
queries = [
"good coffee shops nearby for working",
"what can I make for my kid in lunch?"
]
for q in queries:
results = conduct_personalized_search(user_id, q)
print(f"\nQuery: {q}")
print(f"Personalized Response: {results['agent_response']}")
```
## How It Works in Practice
Here's how personalization plays out:
- **Context Gathering**: User previously mentioned living in Los Angeles, being vegan, and having a 7-year-old daughter allergic to peanuts.
- **Enhanced Search Query**:
- Query: "good coffee shops nearby for working"
- Enhanced Query: "good coffee shops in Los Angeles with strong WiFi, remote-work-friendly"
- **Personalized Results**: The assistant only returns WiFi-friendly, work-friendly cafes near Los Angeles.
- **Memory Update**: Interaction is saved for better future recommendations.
## Conclusion
With Mem0 and Tavily, you can build a search assistant that doesn't just fetch results but understands the person behind the query.
Whether for shopping, travel, or daily life, this approach turns a generic search into a truly personalized experience.
Full Code: [Personalized Search GitHub](https://github.com/mem0ai/mem0/blob/main/examples/misc/personalized_search.py)
---
<CardGroup cols={2}>
<Card title="Deep Research with Mem0" icon="magnifying-glass" href="/cookbooks/operations/deep-research">
Build comprehensive research agents that remember findings across sessions.
</Card>
<Card title="Tag and Organize Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories">
Categorize search results and user preferences for better personalization.
</Card>
</CardGroup>
@@ -0,0 +1,221 @@
---
title: Content Writing with Mem0
description: "Store voice guidelines once and apply them across every draft."
---
This guide demonstrates how to leverage **Mem0** to streamline content writing by applying your unique writing style and preferences using persistent memory.
## Why Use Mem0?
Integrating Mem0 into your writing workflow helps you:
1. **Store persistent writing preferences** ensuring consistent tone, formatting, and structure.
2. **Automate content refinement** by retrieving preferences when rewriting or reviewing content.
3. **Scale your writing style** so it applies consistently across multiple documents or sessions.
## Setup
```python
import os
from openai import OpenAI
from mem0 import MemoryClient
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
# Set up Mem0 and OpenAI client
client = MemoryClient()
openai = OpenAI()
USER_ID = "content_writer"
RUN_ID = "smart_editing_session"
```
## Storing Your Writing Preferences in Mem0
```python
def store_writing_preferences():
"""Store your writing preferences in Mem0."""
preferences = """My writing preferences:
1. Use headings and sub-headings for structure.
2. Keep paragraphs concise (8–10 sentences max).
3. Incorporate specific numbers and statistics.
4. Provide concrete examples.
5. Use bullet points for clarity.
6. Avoid jargon and buzzwords."""
messages = [
{"role": "user", "content": "Here are my writing style preferences."},
{"role": "assistant", "content": preferences}
]
response = client.add(
messages,
user_id=USER_ID,
run_id=RUN_ID,
metadata={"type": "preferences", "category": "writing_style"}
)
return response
```
## Editing Content Using Stored Preferences
```python
def apply_writing_style(original_content):
"""Use preferences stored in Mem0 to guide content rewriting."""
results = client.search(
query="What are my writing style preferences?",
filters={
"AND": [
{"user_id": USER_ID},
{"run_id": RUN_ID}
]
}
)
if not results:
print("No preferences found.")
return None
preferences = "\n".join(r["memory"] for r in results.get('results', []))
system_prompt = f"""
You are a writing assistant.
Apply the following writing style preferences to improve the user's content:
Preferences:
{preferences}
"""
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"""Original Content:
{original_content}"""}
]
response = openai.chat.completions.create(
model="gpt-4.1-nano-2025-04-14",
messages=messages
)
clean_response = response.choices[0].message.content.strip()
return clean_response
```
## Complete Workflow: Content Editing
```python
def content_writing_workflow(content):
"""Automated workflow for editing a document based on writing preferences."""
# Store writing preferences (if not already stored)
store_writing_preferences() # Ideally done once, or with a conditional check
# Edit the document with Mem0 preferences
edited_content = apply_writing_style(content)
if not edited_content:
return "Failed to edit document."
# Display results
print("\n=== ORIGINAL DOCUMENT ===\n")
print(content)
print("\n=== EDITED DOCUMENT ===\n")
print(edited_content)
return edited_content
```
## Example Usage
```python
# Define your document
original_content = """Project Proposal
The following proposal outlines our strategy for the Q3 marketing campaign.
We believe this approach will significantly increase our market share.
Increase brand awareness
Boost sales by 15%
Expand our social media following
We plan to launch the campaign in July and continue through September.
"""
# Run the workflow
result = content_writing_workflow(original_content)
```
## Expected Output
Your document will be transformed into a structured, well-formatted version based on your preferences.
### Original Document
```
Project Proposal
The following proposal outlines our strategy for the Q3 marketing campaign.
We believe this approach will significantly increase our market share.
Increase brand awareness
Boost sales by 15%
Expand our social media following
We plan to launch the campaign in July and continue through September.
```
### Edited Document
```
# Project Proposal
## Q3 Marketing Campaign Strategy
This proposal outlines our strategy for the Q3 marketing campaign. We aim to significantly increase our market share with this approach.
### Objectives
- **Increase Brand Awareness**: Implement targeted advertising and community engagement to enhance visibility.
- **Boost Sales by 15%**: Increase sales by 15% compared to Q2 figures.
- **Expand Social Media Following**: Grow our social media audience by 20%.
### Timeline
- **Launch Date**: July
- **Duration**: July – September
### Key Actions
- **Targeted Advertising**: Utilize platforms like Google Ads and Facebook to reach specific demographics.
- **Community Engagement**: Host webinars and live Q&A sessions.
- **Content Creation**: Produce engaging videos and infographics.
### Supporting Data
- **Previous Campaign Success**: Our Q2 campaign increased sales by 12%. We will refine similar strategies for Q3.
- **Social Media Growth**: Last year, our Instagram followers grew by 25% during a similar campaign.
### Conclusion
We believe this strategy will effectively increase our market share. To achieve these goals, we need your support and collaboration. Let’s work together to make this campaign a success. Please review the proposal and provide your feedback by the end of the week.
```
Mem0 enables a seamless, intelligent content-writing workflow, perfect for content creators, marketers, and technical writers looking to scale their personal tone and structure across work.
---
<CardGroup cols={2}>
<Card title="Control Memory Ingestion" icon="filter" href="/cookbooks/essentials/controlling-memory-ingestion">
Filter and curate content examples to maintain consistent writing style.
</Card>
<Card title="Email Automation with Mem0" icon="envelope" href="/cookbooks/operations/email-automation">
Automate email drafting with memory-powered context and tone matching.
</Card>
</CardGroup>
@@ -0,0 +1,79 @@
---
title: Deep Research with Mem0
description: "Run multi-session investigations that remember past findings and preferences."
---
Deep Research is an intelligent agent that synthesizes large amounts of online data and completes complex research tasks, customized to your unique preferences and insights. Built on Mem0's technology, it enhances AI-driven online exploration with personalized memories.
You can check out the GitHub repository here: [Personalized Deep Research](https://github.com/mem0ai/personalized-deep-research/tree/mem0)
## Overview
Deep Research leverages Mem0's memory capabilities to:
- Synthesize large amounts of online data
- Complete complex research tasks
- Customize results to your preferences
- Store and utilize personal insights
- Maintain context across research sessions
## Demo
Watch Deep Research in action:
<iframe
width="700"
height="400"
src="https://www.youtube.com/embed/8vQlCtXzF60?si=b8iTOgummAVzR7ia"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
></iframe>
## Features
### 1. Personalized Research
- Analyzes your background and expertise
- Tailors research depth and complexity to your level
- Incorporates your previous research context
### 2. Comprehensive Data Synthesis
- Processes multiple online sources
- Extracts relevant information
- Provides coherent summaries
### 3. Memory Integration
- Stores research findings for future reference
- Maintains context across sessions
- Links related research topics
### 4. Interactive Exploration
- Allows real-time query refinement
- Supports follow-up questions
- Enables deep-diving into specific areas
## Use Cases
- **Academic Research**: Literature reviews, thesis research, paper writing
- **Market Research**: Industry analysis, competitor research, trend identification
- **Technical Research**: Technology evaluation, solution comparison
- **Business Research**: Strategic planning, opportunity analysis
## Try It Out
> To try it yourself, clone the repository and follow the instructions in the README to run it locally or deploy it.
- [Personalized Deep Research GitHub](https://github.com/mem0ai/personalized-deep-research/tree/mem0)
---
<CardGroup cols={2}>
<Card title="Search Memory Operations" icon="magnifying-glass" href="/core-concepts/memory-operations/search">
Master semantic search to retrieve research findings across sessions.
</Card>
<Card title="YouTube Research with Mem0" icon="video" href="/cookbooks/companions/youtube-research">
Build a video research assistant that remembers insights from content.
</Card>
</CardGroup>
@@ -0,0 +1,208 @@
---
title: Email Automation with Mem0
description: "Capture, categorize, and recall inbox threads using persistent memories."
---
This guide demonstrates how to build an intelligent email processing system using Mem0's memory capabilities. You'll learn how to store, categorize, retrieve, and analyze emails to create a smart email management solution.
## Overview
Email overload is a common challenge for many professionals. By leveraging Mem0's memory capabilities, you can build an intelligent system that:
- Stores emails as searchable memories
- Categorizes emails automatically
- Retrieves relevant past conversations
- Prioritizes messages based on importance
- Generates summaries and action items
## Setup
Before you begin, ensure you have the required dependencies installed:
```bash
pip install mem0ai openai
```
## Implementation
### Basic Email Memory System
The following example shows how to create a basic email processing system with Mem0:
```python
import os
from mem0 import MemoryClient
from email.parser import Parser
# Configure API keys
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
# Initialize Mem0 client
client = MemoryClient()
class EmailProcessor:
def __init__(self):
"""Initialize the Email Processor with Mem0 memory client"""
self.client = client
def process_email(self, email_content, user_id):
"""
Process an email and store it in Mem0 memory
Args:
email_content (str): Raw email content
user_id (str): User identifier for memory association
"""
# Parse email
parser = Parser()
email = parser.parsestr(email_content)
# Extract email details
sender = email['from']
recipient = email['to']
subject = email['subject']
date = email['date']
body = self._get_email_body(email)
# Create message object for Mem0
message = {
"role": "user",
"content": f"Email from {sender}: {subject}\n\n{body}"
}
# Create metadata for better retrieval
metadata = {
"email_type": "incoming",
"sender": sender,
"recipient": recipient,
"subject": subject,
"date": date
}
# Store in Mem0 with appropriate categories
response = self.client.add(
messages=[message],
user_id=user_id,
metadata=metadata,
categories=["email", "correspondence"],
)
return response
def _get_email_body(self, email):
"""Extract the body content from an email"""
# Simplified extraction - in real-world, handle multipart emails
if email.is_multipart():
for part in email.walk():
if part.get_content_type() == "text/plain":
return part.get_payload(decode=True).decode()
else:
return email.get_payload(decode=True).decode()
def search_emails(self, query, user_id, sender=None):
"""
Search through stored emails
Args:
query (str): Search query
user_id (str): User identifier
sender (str, optional): Filter by sender email address
"""
# For Platform API, all filters including user_id go in filters object
if not sender:
# Simple filter - just user_id and category
filters = {
"AND": [
{"user_id": user_id},
{"categories": {"contains": "email"}}
]
}
results = self.client.search(query=query, filters=filters)
else:
# Advanced filter - add sender condition
filters = {
"AND": [
{"user_id": user_id},
{"categories": {"contains": "email"}},
{"sender": sender}
]
}
results = self.client.search(query=query, filters=filters)
return results
def get_email_thread(self, subject, user_id):
"""
Retrieve all emails in a thread based on subject
Args:
subject (str): Email subject to match
user_id (str): User identifier
"""
# For Platform API, user_id goes in the filters object
filters = {
"AND": [
{"user_id": user_id},
{"categories": {"contains": "email"}},
{"subject": {"icontains": subject}}
]
}
thread = self.client.get_all(filters=filters)
return thread
# Initialize the processor
processor = EmailProcessor()
# Example raw email
sample_email = """From: alice@example.com
To: bob@example.com
Subject: Meeting Schedule Update
Date: Mon, 15 Jul 2024 14:22:05 -0700
Hi Bob,
I wanted to update you on the schedule for our upcoming project meeting.
We'll be meeting this Thursday at 2pm instead of Friday.
Could you please prepare your section of the presentation?
Thanks,
Alice
"""
# Process and store the email
user_id = "bob@example.com"
processor.process_email(sample_email, user_id)
# Later, search for emails about meetings
meeting_emails = processor.search_emails("meeting schedule", user_id)
print(f"Found {len(meeting_emails['results'])} relevant emails")
```
## Key Features and Benefits
- **Long-term Email Memory**: Store and retrieve email conversations across long periods
- **Semantic Search**: Find relevant emails even if they don't contain exact keywords
- **Intelligent Categorization**: Automatically sort emails into meaningful categories
- **Action Item Extraction**: Identify and track tasks mentioned in emails
- **Priority Management**: Focus on important emails based on AI-determined priority
- **Context Awareness**: Maintain thread context for more relevant interactions
## Conclusion
By combining Mem0's memory capabilities with email processing, you can create intelligent email management systems that help users organize, prioritize, and act on their inbox effectively. The advanced capabilities like automatic categorization, action item extraction, and priority management can significantly reduce the time spent on email management, allowing users to focus on more important tasks.
---
<CardGroup cols={2}>
<Card title="Tag and Organize Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories">
Categorize email threads by sender, topic, and priority for faster retrieval.
</Card>
<Card title="Support Inbox with Mem0" icon="headset" href="/cookbooks/operations/support-inbox">
Build customer support agents that remember context across tickets.
</Card>
</CardGroup>
+123
View File
@@ -0,0 +1,123 @@
---
title: Support Inbox with Mem0
description: "Build a support assistant that keeps past tickets and resolutions at its fingertips."
---
You can create a personalized Customer Support AI Agent using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
## Overview
The Customer Support AI Agent leverages Mem0 to retain information across interactions, enabling a personalized and efficient support experience.
## Setup
Install the necessary packages using pip:
```bash
pip install openai mem0ai
```
## Full Code Example
Below is the simplified code to create and interact with a Customer Support AI Agent using Mem0:
```python
import os
from openai import OpenAI
from mem0 import Memory
# Set the OpenAI API key
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
class CustomerSupportAIAgent:
def __init__(self):
"""
Initialize the CustomerSupportAIAgent with memory configuration and OpenAI client.
"""
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333,
}
},
}
self.memory = Memory.from_config(config)
self.client = OpenAI()
self.app_id = "customer-support"
def handle_query(self, query, user_id=None):
"""
Handle a customer query and store the relevant information in memory.
:param query: The customer query to handle.
:param user_id: Optional user ID to associate with the memory.
"""
# Start a streaming chat completion request to the AI
stream = self.client.chat.completions.create(
model="gpt-4",
stream=True,
messages=[
{"role": "system", "content": "You are a customer support AI agent."},
{"role": "user", "content": query}
]
)
# Store the query in memory
self.memory.add(query, user_id=user_id, metadata={"app_id": self.app_id})
# Print the response from the AI in real-time
for chunk in stream:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="")
def get_memories(self, user_id=None):
"""
Retrieve all memories associated with the given customer ID.
:param user_id: Optional user ID to filter memories.
:return: List of memories.
"""
return self.memory.get_all(user_id=user_id)
# Instantiate the CustomerSupportAIAgent
support_agent = CustomerSupportAIAgent()
# Define a customer ID
customer_id = "jane_doe"
# Handle a customer query
support_agent.handle_query("I need help with my recent order. It hasn't arrived yet.", user_id=customer_id)
```
### Fetching Memories
You can fetch all the memories at any point in time using the following code:
```python
memories = support_agent.get_memories(user_id=customer_id)
for m in memories['results']:
print(m['memory'])
```
### Key Points
- **Initialization**: The CustomerSupportAIAgent class is initialized with the necessary memory configuration and OpenAI client setup.
- **Handling Queries**: The handle_query method sends a query to the AI and stores the relevant information in memory.
- **Retrieving Memories**: The get_memories method fetches all stored memories associated with a customer.
### Conclusion
As the conversation progresses, Mem0's memory automatically updates based on the interactions, providing a continuously improving personalized support experience.
---
<CardGroup cols={2}>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Master the foundational patterns for building memory-powered assistants.
</Card>
<Card title="Email Automation with Mem0" icon="envelope" href="/cookbooks/operations/email-automation">
Extend support capabilities with intelligent email processing and routing.
</Card>
</CardGroup>
@@ -0,0 +1,136 @@
---
title: Team Task Agent with Mem0
description: "Coordinate multi-user projects with shared memories and roles."
---
## Overview
Build a multi-user collaborative chat or task management system with Mem0. Each message is attributed to its author, and all messages are stored in a shared project space. Mem0 makes it easy to track contributions, sort and group messages, and collaborate in real time.
## Setup
Install the required packages:
```bash
pip install openai mem0ai
```
## Full Code Example
```python
from openai import OpenAI
from mem0 import Memory
import os
from datetime import datetime
from collections import defaultdict
# Set your OpenAI API key
os.environ["OPENAI_API_KEY"] = "sk-your-key"
# Shared project context
RUN_ID = "project-demo"
# Initialize Mem0
mem = Memory()
class CollaborativeAgent:
def __init__(self, run_id):
self.run_id = run_id
self.mem = mem
def add_message(self, role, name, content):
msg = {"role": role, "name": name, "content": content}
self.mem.add([msg], run_id=self.run_id, infer=False)
def brainstorm(self, prompt):
# Get recent messages for context
memories = self.mem.search(prompt, run_id=self.run_id, limit=5)["results"]
context = "\n".join(f"- {m['memory']} (by {m.get('actor_id', 'Unknown')})" for m in memories)
client = OpenAI()
messages = [
{"role": "system", "content": "You are a helpful project assistant."},
{"role": "user", "content": f"Prompt: {prompt}\nContext:\n{context}"}
]
reply = client.chat.completions.create(
model="gpt-4.1-nano-2025-04-14",
messages=messages
).choices[0].message.content.strip()
self.add_message("assistant", "assistant", reply)
return reply
def get_all_messages(self):
return self.mem.get_all(run_id=self.run_id)["results"]
def print_sorted_by_time(self):
messages = self.get_all_messages()
messages.sort(key=lambda m: m.get('created_at', ''))
print("\n--- Messages (sorted by time) ---")
for m in messages:
who = m.get("actor_id") or "Unknown"
ts = m.get('created_at', 'Timestamp N/A')
try:
dt = datetime.fromisoformat(ts.replace('Z', '+00:00'))
ts_fmt = dt.strftime('%Y-%m-%d %H:%M:%S')
except Exception:
ts_fmt = ts
print(f"[{ts_fmt}] [{who}] {m['memory']}")
def print_grouped_by_actor(self):
messages = self.get_all_messages()
grouped = defaultdict(list)
for m in messages:
grouped[m.get("actor_id") or "Unknown"].append(m)
print("\n--- Messages (grouped by actor) ---")
for actor, mems in grouped.items():
print(f"\n=== {actor} ===")
for m in mems:
ts = m.get('created_at', 'Timestamp N/A')
try:
dt = datetime.fromisoformat(ts.replace('Z', '+00:00'))
ts_fmt = dt.strftime('%Y-%m-%d %H:%M:%S')
except Exception:
ts_fmt = ts
print(f"[{ts_fmt}] {m['memory']}")
```
## Usage
```python
# Example usage
agent = CollaborativeAgent(RUN_ID)
agent.add_message("user", "alice", "Let's list tasks for the new landing page.")
agent.add_message("user", "bob", "I'll own the hero section copy.")
agent.add_message("user", "carol", "I'll choose product screenshots.")
# Brainstorm with context
print("\nAssistant reply:\n", agent.brainstorm("What are the current open tasks?"))
# Print all messages sorted by time
agent.print_sorted_by_time()
# Print all messages grouped by actor
agent.print_grouped_by_actor()
```
## Key Points
- Each message is attributed to a user or agent (actor)
- All messages are stored in a shared project space (`run_id`)
- You can sort messages by time, group by actor, and format timestamps for clarity
- Mem0 makes it easy to build collaborative, attributed chat/task systems
## Conclusion
Mem0 enables fast, transparent collaboration for teams and agents, with full attribution, flexible memory search, and easy message organization.
---
<CardGroup cols={2}>
<Card title="Build AI with Personality" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Learn how to scope memories across users and agents for team workflows.
</Card>
<Card title="Support Inbox with Mem0" icon="headset" href="/cookbooks/operations/support-inbox">
Apply collaborative memory patterns to customer support scenarios.
</Card>
</CardGroup>
+140
View File
@@ -0,0 +1,140 @@
---
title: Overview
description: How to use mem0 in your existing applications?
---
With Mem0, you can create stateful LLM-based applications such as chatbots, virtual assistants, or AI agents. Mem0 enhances your applications by providing a memory layer that makes responses:
- More personalized
- More reliable
- Cost-effective by reducing the number of LLM interactions
- More engaging
- Enables long-term memory
Here are some examples of how Mem0 can be integrated into various applications:
## Essentials
<CardGroup cols={2}>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Learn the core memory lifecycle before diving into codebases.
</Card>
<Card title="Scope User vs Agent Memories" icon="sparkles" href="/cookbooks/essentials/building-ai-with-personality">
Balance personalization with consistent assistant behavior.
</Card>
<Card title="Control Memory Ingestion" icon="filter" href="/cookbooks/essentials/controlling-memory-ingestion">
Filter speculation, enforce formats, and gate low-confidence data.
</Card>
<Card title="Set Memory Expiration" icon="timer" href="/cookbooks/essentials/memory-expiration-short-and-long-term">
Define short-term versus long-term retention strategies.
</Card>
</CardGroup>
## Companion Playbooks
<CardGroup cols={2}>
<Card title="Quickstart Demo with Mem0" icon="rocket" href="/cookbooks/companions/quickstart-demo">
Spin up the showcase app to see Mem0 memories in action.
</Card>
<Card title="Node.js Companion with Mem0" icon="code" href="/cookbooks/companions/nodejs-companion">
Build a JavaScript coach that remembers user goals.
</Card>
<Card title="AI Tutor with Mem0" icon="graduation-cap" href="/cookbooks/companions/ai-tutor">
Deliver lessons that adapt to student progress and gaps.
</Card>
<Card title="Travel Assistant with Mem0" icon="plane" href="/cookbooks/companions/travel-assistant">
Plan itineraries that remember traveler preferences across trips.
</Card>
<Card title="YouTube Research with Mem0" icon="video" href="/cookbooks/companions/youtube-research">
Layer personalized context over any video in the browser.
</Card>
<Card title="Voice Companion with Mem0 and OpenAI" icon="microphone" href="/cookbooks/companions/voice-companion-openai">
Pair the OpenAI Agents SDK with Mem0 for voice-first experiences.
</Card>
<Card title="Local Companion with Mem0 and Ollama" icon="server" href="/cookbooks/companions/local-companion-ollama">
Run Mem0 end-to-end on your machine with Ollama models.
</Card>
</CardGroup>
## Ops & Automations
<CardGroup cols={2}>
<Card title="Support Inbox with Mem0" icon="headset" href="/cookbooks/operations/support-inbox">
Keep past tickets and resolutions at an agent's fingertips.
</Card>
<Card title="Email Automation with Mem0" icon="envelope" href="/cookbooks/operations/email-automation">
Capture, categorize, and recall inbox threads via memory.
</Card>
<Card title="Content Writing with Mem0" icon="pencil" href="/cookbooks/operations/content-writing">
Store tone and style guidelines once—apply them everywhere.
</Card>
<Card title="Deep Research with Mem0" icon="magnifying-glass" href="/cookbooks/operations/deep-research">
Run multi-session investigations without repeating yourself.
</Card>
<Card title="Team Task Agent with Mem0" icon="users" href="/cookbooks/operations/team-task-agent">
Coordinate projects with shared memories across contributors.
</Card>
</CardGroup>
## Integrations & Platforms
<CardGroup cols={2}>
<Card title="Agents SDK Tool with Mem0" icon="robot" href="/cookbooks/integrations/agents-sdk-tool">
Expose Mem0 memories as callable tools inside agent workflows.
</Card>
<Card title="OpenAI Tool Calls with Mem0" icon="wrench" href="/cookbooks/integrations/openai-tool-calls">
Drop memories into OpenAI's inbuilt function-calling flows.
</Card>
<Card title="Mastra Agent with Mem0" icon="code" href="/cookbooks/integrations/mastra-agent">
Extend Mastra agents with persistent memory state.
</Card>
<Card title="Healthcare Coach with Mem0 and Google ADK" icon="heart-pulse" href="/cookbooks/integrations/healthcare-google-adk">
Remember patient history across ADK sessions.
</Card>
<Card title="AWS Bedrock with Mem0" icon="aws" href="/cookbooks/integrations/aws-bedrock">
Pair Mem0 with Bedrock, OpenSearch, and Neptune Analytics.
</Card>
<Card title="Neptune Analytics with Mem0" icon="database" href="/cookbooks/integrations/neptune-analytics">
Build a hybrid vector + graph memory store on AWS.
</Card>
<Card title="Tavily Search with Mem0" icon="search" href="/cookbooks/integrations/tavily-search">
Blend realtime search with personal context.
</Card>
</CardGroup>
## Frameworks & Multimodal
<CardGroup cols={2}>
<Card title="LlamaIndex ReAct with Mem0" icon="brain" href="/cookbooks/frameworks/llamaindex-react">
Teach a ReAct agent to store and recall context via Mem0.
</Card>
<Card title="LlamaIndex Multi-Agent with Mem0" icon="users" href="/cookbooks/frameworks/llamaindex-multiagent">
Share a persistent memory layer across collaborating agents.
</Card>
<Card title="Multimodal Retrieval with Mem0" icon="image" href="/cookbooks/frameworks/multimodal-retrieval">
Store and recall visual context alongside text conversations.
</Card>
<Card title="Eliza OS Character with Mem0" icon="robot" href="/cookbooks/frameworks/eliza-os-character">
Bring persistent personality to Eliza OS agents.
</Card>
<Card title="Chrome Extension with Mem0" icon="globe" href="/cookbooks/frameworks/chrome-extension">
Add Mem0's universal memory layer to Chrome chat surfaces.
</Card>
</CardGroup>
---
## Contribute a Cookbook
Have a unique Mem0 use case or integration? We'd love to feature your cookbook!
All cookbooks follow a standardized template to ensure consistency and quality. Check out our template to see the structure and best practices.
<CardGroup cols={2}>
<Card title="Cookbook Template" icon="book-open" href="/templates/cookbook_template">
Follow this structure for narrative, end-to-end Mem0 workflows.
</Card>
<Card title="Contribution Guide" icon="github" href="https://github.com/mem0ai/mem0/blob/main/CONTRIBUTING.md">
Learn how to submit your cookbook to the Mem0 repository.
</Card>
</CardGroup>