Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa3206cafd | ||
|
|
f98cd925a6 | ||
|
|
86a2b00c65 | ||
|
|
c1ee71ad3f | ||
|
|
a93a7ea6cf | ||
|
|
2dd4e93af4 | ||
|
|
15fe2b978f | ||
|
|
c1b9da45aa | ||
|
|
78ea40c291 | ||
|
|
f0d98ec4cb | ||
|
|
5182c8f311 | ||
|
|
61e8668584 | ||
|
|
a9a1d57dfa | ||
|
|
0cc26fdabf |
@@ -7,8 +7,6 @@ on:
|
||||
- 'mem0/**'
|
||||
- 'tests/**'
|
||||
- 'embedchain/**'
|
||||
- '.github/workflows/**'
|
||||
- 'pyproject.toml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'mem0/**'
|
||||
@@ -30,8 +28,6 @@ jobs:
|
||||
mem0:
|
||||
- 'mem0/**'
|
||||
- 'tests/**'
|
||||
- '.github/workflows/**'
|
||||
- 'pyproject.toml'
|
||||
embedchain:
|
||||
- 'embedchain/**'
|
||||
|
||||
@@ -48,13 +44,6 @@ jobs:
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Clean up disk space
|
||||
run: |
|
||||
df -h
|
||||
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
|
||||
sudo docker image prune --all --force
|
||||
sudo docker builder prune -a
|
||||
df -h
|
||||
- name: Install Hatch
|
||||
run: pip install hatch
|
||||
- name: Load cached venv
|
||||
|
||||
@@ -103,7 +103,7 @@ memory = Memory()
|
||||
# With custom configuration
|
||||
config = MemoryConfig(
|
||||
vector_store={"provider": "qdrant", "config": {"host": "localhost"}},
|
||||
llm={"provider": "openai", "config": {"model": "gpt-4.1-nano-2025-04-14"}},
|
||||
llm={"provider": "openai", "config": {"model": "gpt-4o-mini"}},
|
||||
embedder={"provider": "openai", "config": {"model": "text-embedding-3-small"}}
|
||||
)
|
||||
memory = Memory(config)
|
||||
@@ -339,7 +339,7 @@ config = MemoryConfig(
|
||||
llm={
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4.1-nano-2025-04-14",
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
@@ -527,7 +527,7 @@ const memory = new Memory({
|
||||
},
|
||||
llm: {
|
||||
provider: 'openai',
|
||||
config: { model: 'gpt-4.1-nano' }
|
||||
config: { model: 'gpt-4o-mini' }
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+278
-152
@@ -1,221 +1,347 @@
|
||||
# Migration Guide: Upgrading to mem0 1.0.0
|
||||
# Migration Guide: Upgrading to mem0ai 1.0.0
|
||||
|
||||
## TL;DR
|
||||
This guide will help you migrate from mem0ai 0.x to the new 1.0.0 version.
|
||||
|
||||
**What changed?** We simplified the API by removing confusing version parameters. Now everything returns a consistent format: `{"results": [...]}`.
|
||||
## Breaking Changes
|
||||
|
||||
**What you need to do:**
|
||||
1. Upgrade: `pip install mem0ai==1.0.0`
|
||||
2. Remove `version` and `output_format` parameters from your code
|
||||
3. Update response handling to use `result["results"]` instead of treating responses as lists
|
||||
### 1. API Version Changes
|
||||
|
||||
**Time needed:** ~5-10 minutes for most projects
|
||||
**Before (0.x):**
|
||||
```python
|
||||
# Multiple API versions supported
|
||||
memory = Memory(config=MemoryConfig(version="v1.1"))
|
||||
|
||||
---
|
||||
# Client with output_format parameter
|
||||
client.add(messages, output_format="v1.1")
|
||||
client.search(query, version="v1", output_format="v1.1")
|
||||
client.get_all(version="v1", output_format="v1.1")
|
||||
```
|
||||
|
||||
## Quick Migration Guide
|
||||
**After (1.0.0):**
|
||||
```python
|
||||
# v1.1 format is default (v1.0 is deprecated)
|
||||
memory = Memory() # Defaults to v1.1 format
|
||||
|
||||
### 1. Install the Update
|
||||
# Client API with correct versioning behavior:
|
||||
client.add(messages) # Uses v1 API endpoint, returns v1.1 format
|
||||
client.search(query) # Uses v2 API endpoint, returns v1.1 format
|
||||
client.get_all() # Uses v2 API endpoint, returns v1.1 format
|
||||
```
|
||||
|
||||
### 2. API Versioning Strategy Clarification
|
||||
|
||||
**IMPORTANT: Understanding the New Versioning Strategy**
|
||||
|
||||
The API versioning strategy in mem0ai 1.0.0 has been unified and simplified:
|
||||
|
||||
#### **Endpoint vs Format Distinction**
|
||||
- **API Endpoints** (`/v1/`, `/v2/`): Control which REST API version to use
|
||||
- **Response Formats** (v1.0, v1.1): Control the structure of the returned data
|
||||
|
||||
#### **New Unified Strategy:**
|
||||
- **Add operations**: Always use `/v1/` endpoint with v1.1 response format (no more output_format parameter)
|
||||
- **Search operations**: Always use `/v2/` endpoint with v1.1 response format
|
||||
- **Get_all operations**: Always use `/v2/` endpoint with v1.1 response format
|
||||
- **Response format**: All operations now return v1.1 format (`{"results": [...]}`)
|
||||
|
||||
#### **What Changed:**
|
||||
- ✅ **Consistent response format**: Everything returns v1.1 format
|
||||
- ✅ **Simplified API**: No more `output_format` or `version` parameters to manage
|
||||
- ✅ **Endpoint optimization**: Add uses v1, Search/Get use v2 for best performance
|
||||
- ❌ **Removed v1.0 support**: v1.0 response format is no longer supported
|
||||
|
||||
### 3. Response Format Standardization
|
||||
|
||||
**Before (0.x):**
|
||||
```python
|
||||
# Inconsistent response formats based on api_version
|
||||
result = memory.add(messages)
|
||||
# Could return list or dict depending on version
|
||||
|
||||
memories = memory.get_all()
|
||||
# Could return list or dict depending on version
|
||||
```
|
||||
|
||||
**After (1.0.0):**
|
||||
```python
|
||||
# v1.1 format is now default (consistent dict format)
|
||||
result = memory.add(messages)
|
||||
# Returns: {"results": [...], "relations": [...] (if graph enabled)}
|
||||
|
||||
memories = memory.get_all()
|
||||
# Returns: {"results": [...], "relations": [...] (if graph enabled)}
|
||||
|
||||
# v1.0 format still works but shows deprecation warning
|
||||
memory_v1 = Memory(config=MemoryConfig(version="v1.0"))
|
||||
result = memory_v1.add(messages) # Returns raw list [{...}] (with warning)
|
||||
```
|
||||
|
||||
## Migration Steps
|
||||
|
||||
### Step 1: Update Dependencies
|
||||
|
||||
```bash
|
||||
pip install mem0ai==1.0.0
|
||||
```
|
||||
|
||||
### 2. Update Your Code
|
||||
### Step 2: Update Code
|
||||
|
||||
**If you're using the Memory API:**
|
||||
#### Memory API Changes
|
||||
|
||||
```python
|
||||
# Before
|
||||
from mem0 import Memory
|
||||
|
||||
memory = Memory(config=MemoryConfig(version="v1.1"))
|
||||
result = memory.add("I like pizza")
|
||||
|
||||
# After
|
||||
memory = Memory() # That's it - version is automatic now
|
||||
result = memory.add("I like pizza")
|
||||
# After - no changes needed, v1.1 is automatic
|
||||
from mem0 import Memory
|
||||
|
||||
memory = Memory() # Defaults to v1.1 format
|
||||
```
|
||||
|
||||
**If you're using the Client API:**
|
||||
#### Client API Changes
|
||||
|
||||
```python
|
||||
# Before
|
||||
client.add(messages, output_format="v1.1")
|
||||
client.search(query, version="v2", output_format="v1.1")
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your-key")
|
||||
|
||||
# Remove all version and output_format parameters
|
||||
result = client.add(messages, output_format="v1.1")
|
||||
memories = client.search(query, version="v2", output_format="v1.1")
|
||||
all_memories = client.get_all(version="v2", output_format="v1.1")
|
||||
|
||||
# After
|
||||
client.add(messages) # Just remove those extra parameters
|
||||
client.search(query)
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your-key")
|
||||
|
||||
# Simplified API calls
|
||||
result = client.add(messages)
|
||||
memories = client.search(query)
|
||||
all_memories = client.get_all()
|
||||
```
|
||||
|
||||
### 3. Update How You Handle Responses
|
||||
|
||||
All responses now use the same format: a dictionary with `"results"` key.
|
||||
#### Response Handling
|
||||
|
||||
```python
|
||||
# Before - you might have done this
|
||||
result = memory.add("I like pizza")
|
||||
for item in result: # Treating it as a list
|
||||
# Before - inconsistent response formats
|
||||
result = memory.add(messages)
|
||||
if isinstance(result, list):
|
||||
# Handle v1.0 format
|
||||
for item in result:
|
||||
print(item)
|
||||
else:
|
||||
# Handle v1.1+ format
|
||||
for item in result["results"]:
|
||||
print(item)
|
||||
|
||||
# After - consistent response format
|
||||
result = memory.add(messages)
|
||||
for item in result["results"]:
|
||||
print(item)
|
||||
|
||||
# After - do this instead
|
||||
result = memory.add("I like pizza")
|
||||
for item in result["results"]: # Access the results key
|
||||
print(item)
|
||||
|
||||
# Graph relations (if you use them)
|
||||
# Access graph relations if enabled
|
||||
if "relations" in result:
|
||||
for relation in result["relations"]:
|
||||
print(relation)
|
||||
```
|
||||
|
||||
---
|
||||
### Step 3: Remove Deprecated Code
|
||||
|
||||
## Enhanced Message Handling
|
||||
|
||||
The platform client (MemoryClient) now supports the same flexible message formats as the OSS version:
|
||||
Remove any code that handled multiple API versions:
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
# Remove these patterns
|
||||
if version == "v1.0":
|
||||
# handle old format
|
||||
elif version == "v1.1":
|
||||
# handle new format
|
||||
|
||||
client = MemoryClient(api_key="your-key")
|
||||
|
||||
# All three formats now work:
|
||||
|
||||
# 1. Single string (automatically converted to user message)
|
||||
client.add("I like pizza", user_id="alice")
|
||||
|
||||
# 2. Single message dictionary
|
||||
client.add({"role": "user", "content": "I like pizza"}, user_id="alice")
|
||||
|
||||
# 3. List of messages (conversation)
|
||||
client.add([
|
||||
{"role": "user", "content": "I like pizza"},
|
||||
{"role": "assistant", "content": "I'll remember that!"}
|
||||
], user_id="alice")
|
||||
# Remove version-specific logic
|
||||
def handle_response(response, api_version):
|
||||
if api_version == "v1.0":
|
||||
return response # list format
|
||||
else:
|
||||
return response["results"] # dict format
|
||||
```
|
||||
|
||||
### Async Mode Configuration
|
||||
### Step 4: Update Configuration
|
||||
|
||||
The `async_mode` parameter now defaults to `True` but can be configured:
|
||||
#### Vector Store Configuration
|
||||
|
||||
```python
|
||||
# Default behavior (async_mode=True)
|
||||
client.add(messages, user_id="alice")
|
||||
|
||||
# Explicitly set async mode
|
||||
client.add(messages, user_id="alice", async_mode=True)
|
||||
|
||||
# Disable async mode if needed
|
||||
client.add(messages, user_id="alice", async_mode=False)
|
||||
```
|
||||
|
||||
**Note:** `async_mode=True` provides better performance for most use cases. Only set it to `False` if you have specific synchronous processing requirements.
|
||||
|
||||
---
|
||||
|
||||
## That's It!
|
||||
|
||||
For most users, that's all you need to know. The changes are:
|
||||
- ✅ No more `version` or `output_format` parameters
|
||||
- ✅ Consistent `{"results": [...]}` response format
|
||||
- ✅ Cleaner, simpler API
|
||||
|
||||
---
|
||||
|
||||
## Common Issues
|
||||
|
||||
**Getting `KeyError: 'results'`?**
|
||||
|
||||
Your code is still treating the response as a list. Update it:
|
||||
```python
|
||||
# Change this:
|
||||
for memory in response:
|
||||
|
||||
# To this:
|
||||
for memory in response["results"]:
|
||||
```
|
||||
|
||||
**Getting `TypeError: unexpected keyword argument`?**
|
||||
|
||||
You're still passing old parameters. Remove them:
|
||||
```python
|
||||
# Change this:
|
||||
client.add(messages, output_format="v1.1")
|
||||
|
||||
# To this:
|
||||
client.add(messages)
|
||||
```
|
||||
|
||||
**Seeing deprecation warnings?**
|
||||
|
||||
Remove any explicit `version="v1.0"` from your config:
|
||||
```python
|
||||
# Change this:
|
||||
memory = Memory(config=MemoryConfig(version="v1.0"))
|
||||
|
||||
# To this:
|
||||
memory = Memory()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What's New in 1.0.0
|
||||
|
||||
- **Better vector stores:** Fixed OpenSearch and improved reliability across all stores
|
||||
- **Cleaner API:** One way to do things, no more confusing options
|
||||
- **Enhanced GCP support:** Better Vertex AI configuration options
|
||||
- **Flexible message input:** Platform client now accepts strings, dicts, and lists (aligned with OSS)
|
||||
- **Configurable async_mode:** Now defaults to `True` but users can override if needed
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
- Check [GitHub Issues](https://github.com/mem0ai/mem0/issues)
|
||||
- Read the [documentation](https://docs.mem0.ai/)
|
||||
- Open a new issue if you're stuck
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Configuration Changes
|
||||
|
||||
**If you configured vector stores with version:**
|
||||
|
||||
```python
|
||||
# Before
|
||||
# Before - version in config
|
||||
config = MemoryConfig(
|
||||
version="v1.1",
|
||||
vector_store=VectorStoreConfig(...)
|
||||
)
|
||||
|
||||
# After
|
||||
# After - no version needed
|
||||
config = MemoryConfig(
|
||||
vector_store=VectorStoreConfig(...)
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
#### Enhanced GCP Support
|
||||
|
||||
```python
|
||||
# New: Enhanced Vertex AI configuration options
|
||||
from mem0.configs.vector_stores.vertex_ai_vector_search import GoogleMatchingEngineConfig
|
||||
|
||||
# Option 1: Using credentials file (existing)
|
||||
config = GoogleMatchingEngineConfig(
|
||||
project_id="your-project",
|
||||
credentials_path="/path/to/service-account.json",
|
||||
# ... other params
|
||||
)
|
||||
|
||||
# Option 2: Using credentials dict (new in v1.0.0)
|
||||
service_account_info = {
|
||||
"type": "service_account",
|
||||
"project_id": "your-project",
|
||||
# ... rest of service account JSON
|
||||
}
|
||||
|
||||
config = GoogleMatchingEngineConfig(
|
||||
project_id="your-project",
|
||||
service_account_json=service_account_info,
|
||||
# ... other params
|
||||
)
|
||||
```
|
||||
|
||||
## Testing Your Migration
|
||||
|
||||
Quick sanity check:
|
||||
### 1. Test Basic Functionality
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
# Test memory operations
|
||||
memory = Memory()
|
||||
|
||||
# Add should return a dict with "results"
|
||||
result = memory.add("I like pizza", user_id="test")
|
||||
# Test adding memories
|
||||
result = memory.add("I like pizza")
|
||||
assert "results" in result
|
||||
assert len(result["results"]) > 0
|
||||
|
||||
# Search should return a dict with "results"
|
||||
search = memory.search("food", user_id="test")
|
||||
assert "results" in search
|
||||
# Test searching
|
||||
search_result = memory.search("food preferences", user_id="test_user")
|
||||
assert "results" in search_result
|
||||
|
||||
# Get all should return a dict with "results"
|
||||
all_memories = memory.get_all(user_id="test")
|
||||
# Test listing all
|
||||
all_memories = memory.get_all(user_id="test_user")
|
||||
assert "results" in all_memories
|
||||
|
||||
print("✅ Migration successful!")
|
||||
```
|
||||
|
||||
### 2. Test Client Operations
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your-api-key")
|
||||
|
||||
# Test all client methods work without deprecated parameters
|
||||
messages = [{"role": "user", "content": "I love traveling"}]
|
||||
result = client.add(messages, user_id="test_user")
|
||||
assert "results" in result or isinstance(result, list) # Platform may vary
|
||||
|
||||
memories = client.search("travel", user_id="test_user")
|
||||
all_memories = client.get_all(user_id="test_user")
|
||||
```
|
||||
|
||||
## New Features in v1.0.0
|
||||
|
||||
### 1. Improved Vector Store Support
|
||||
|
||||
- Fixed OpenSearch vector store integration
|
||||
- Enhanced error handling across all vector stores
|
||||
- Better performance and reliability
|
||||
|
||||
### 2. Enhanced GCP Integration
|
||||
|
||||
- Support for service account JSON dict (in addition to file path)
|
||||
- Improved Vertex AI Vector Search configuration
|
||||
|
||||
### 3. Simplified API
|
||||
|
||||
- Default API version is now v1.1 (v1.0 deprecated)
|
||||
- Removed deprecated parameters
|
||||
- Standardized response formats
|
||||
|
||||
## Deprecation Warning for v1.0 Users
|
||||
|
||||
If you're currently using `version="v1.0"`, you'll see a deprecation warning:
|
||||
|
||||
```
|
||||
DeprecationWarning: The v1.0 API format is deprecated and will be removed in mem0ai 2.0.0.
|
||||
Please upgrade to v1.1 format which returns a dict with 'results' key.
|
||||
Set version='v1.1' in your MemoryConfig.
|
||||
```
|
||||
|
||||
**To resolve this:**
|
||||
```python
|
||||
# Before (shows warning)
|
||||
memory = Memory(config=MemoryConfig(version="v1.0"))
|
||||
|
||||
# After (no warning)
|
||||
memory = Memory() # Uses v1.1 by default
|
||||
# OR explicitly set v1.1
|
||||
memory = Memory(config=MemoryConfig(version="v1.1"))
|
||||
```
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### Issue 1: "KeyError: 'results'"
|
||||
|
||||
**Problem:** Your code expects the old list format response.
|
||||
|
||||
**Solution:** Update response handling:
|
||||
```python
|
||||
# Before
|
||||
for memory in response: # Assuming response is a list
|
||||
print(memory)
|
||||
|
||||
# After
|
||||
for memory in response["results"]:
|
||||
print(memory)
|
||||
```
|
||||
|
||||
### Issue 2: "TypeError: unexpected keyword argument 'output_format'"
|
||||
|
||||
**Problem:** Code still passing deprecated parameters.
|
||||
|
||||
**Solution:** Remove all deprecated parameters:
|
||||
```python
|
||||
# Before
|
||||
client.add(messages, output_format="v1.1", async_mode=True)
|
||||
|
||||
# After
|
||||
client.add(messages)
|
||||
```
|
||||
|
||||
### Issue 3: Vector Store Connection Issues
|
||||
|
||||
**Problem:** Vector store tests failing after upgrade.
|
||||
|
||||
**Solution:** The OpenSearch integration has been fixed. Update your test configurations and retry.
|
||||
|
||||
## Support
|
||||
|
||||
If you encounter issues during migration:
|
||||
|
||||
1. Check the [GitHub Issues](https://github.com/mem0ai/mem0/issues) for similar problems
|
||||
2. Review the updated [API documentation](https://docs.mem0.ai/)
|
||||
3. Create a new issue with your specific migration problem
|
||||
|
||||
## Summary
|
||||
|
||||
mem0ai 1.0.0 provides a cleaner, more consistent API while removing deprecated features. The migration primarily involves:
|
||||
|
||||
1. Removing deprecated parameters (`output_format`, `version`, `async_mode`)
|
||||
2. Updating response handling to expect consistent `{"results": [...]}` format
|
||||
3. Updating dependencies to v1.0.0
|
||||
|
||||
Most applications will require minimal changes, mainly removing deprecated parameters and updating response parsing logic.
|
||||
@@ -97,7 +97,7 @@ npm install mem0ai
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Mem0 requires an LLM to function, with `gpt-4.1-nano-2025-04-14 from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/components/llms/overview).
|
||||
Mem0 requires an LLM to function, with `gpt-4o-mini` from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/components/llms/overview).
|
||||
|
||||
First step is to instantiate the memory:
|
||||
|
||||
@@ -116,7 +116,7 @@ def chat_with_memories(message: str, user_id: str = "default_user") -> str:
|
||||
# Generate Assistant response
|
||||
system_prompt = f"You are a helpful AI. Answer the question based on query and memories.\nUser Memories:\n{memories_str}"
|
||||
messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": message}]
|
||||
response = openai_client.chat.completions.create(model="gpt-4.1-nano-2025-04-14", messages=messages)
|
||||
response = openai_client.chat.completions.create(model="gpt-4o-mini", messages=messages)
|
||||
assistant_response = response.choices[0].message.content
|
||||
|
||||
# Create new memories from the conversation
|
||||
@@ -168,4 +168,4 @@ We now have a paper you can cite:
|
||||
|
||||
## ⚖️ License
|
||||
|
||||
Apache 2.0 — see the [LICENSE](https://github.com/mem0ai/mem0/blob/main/LICENSE) file for details.
|
||||
Apache 2.0 — see the [LICENSE](LICENSE) file for details.
|
||||
@@ -1,3 +1,3 @@
|
||||
<Note type="info">
|
||||
<strong>🎉 Mem0 1.0.0 is here!</strong> Enhanced filtering, reranking, and smarter memory management.
|
||||
📢 Announcing our research paper: Mem0 achieves <strong>26%</strong> higher accuracy than OpenAI Memory, <strong>91%</strong> lower latency, and <strong>90%</strong> token savings! [Read the paper](https://mem0.ai/research) to learn how we're revolutionizing AI agent memory.
|
||||
</Note>
|
||||
+171
-88
@@ -1,108 +1,191 @@
|
||||
---
|
||||
title: "Overview"
|
||||
icon: "terminal"
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
description: "REST APIs for memory management, search, and entity operations"
|
||||
---
|
||||
|
||||
## Mem0 REST API
|
||||
Mem0 provides a powerful set of APIs that allow you to integrate advanced memory management capabilities into your applications. Our APIs are designed to be intuitive, efficient, and scalable, enabling you to create, retrieve, update, and delete memories across various entities such as users, agents, apps, and runs.
|
||||
|
||||
Mem0 provides a comprehensive REST API for integrating advanced memory capabilities into your applications. Create, search, update, and manage memories across users, agents, and custom entities with simple HTTP requests.
|
||||
## Key Features
|
||||
|
||||
<Info>
|
||||
**Quick start:** Get your API key from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys) and make your first memory operation in minutes.
|
||||
</Info>
|
||||
- **Memory Management**: Add, retrieve, update, and delete memories with ease.
|
||||
- **Entity-based Operations**: Perform operations on memories associated with specific users, agents, apps, or runs.
|
||||
- **Advanced Search**: Utilize our search API to find relevant memories based on various criteria.
|
||||
- **History Tracking**: Access the history of memory interactions for comprehensive analysis.
|
||||
- **User Management**: Manage user entities and their associated memories.
|
||||
|
||||
---
|
||||
## API Structure
|
||||
|
||||
## Quick Start Guide
|
||||
Our API is organized into several main categories:
|
||||
|
||||
Get started with Mem0 API in three simple steps:
|
||||
|
||||
1. **[Add Memories](/api-reference/memory/add-memories)** - Store information and context from user conversations
|
||||
2. **[Search Memories](/api-reference/memory/v2-search-memories)** - Retrieve relevant memories using semantic search
|
||||
3. **[Get Memories](/api-reference/memory/v2-get-memories)** - Fetch all memories for a specific entity
|
||||
|
||||
---
|
||||
|
||||
## Core Operations
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Add Memories" icon="plus" href="/api-reference/memory/add-memories">
|
||||
Store new memories from conversations and interactions
|
||||
</Card>
|
||||
|
||||
<Card title="Search Memories" icon="magnifying-glass" href="/api-reference/memory/v2-search-memories">
|
||||
Find relevant memories using semantic search with filters
|
||||
</Card>
|
||||
|
||||
<Card title="Update Memory" icon="pen" href="/api-reference/memory/update-memory">
|
||||
Modify existing memory content and metadata
|
||||
</Card>
|
||||
|
||||
<Card title="Delete Memory" icon="trash" href="/api-reference/memory/delete-memory">
|
||||
Remove specific memories or batch delete operations
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
---
|
||||
|
||||
## API Categories
|
||||
|
||||
Explore the full API organized by functionality:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Memory APIs" icon="microchip" href="/api-reference/memory/add-memories">
|
||||
Core and advanced operations: CRUD, search, batch updates, history, and exports
|
||||
</Card>
|
||||
|
||||
<Card title="Events APIs" icon="clock" href="/api-reference/events/get-events">
|
||||
Track and monitor the status of asynchronous memory operations
|
||||
</Card>
|
||||
|
||||
<Card title="Entities APIs" icon="users" href="/api-reference/entities/get-users">
|
||||
Manage users, agents, and their associated memory data
|
||||
</Card>
|
||||
|
||||
<Card title="Organizations & Projects" icon="building" href="/api-reference/organizations-projects">
|
||||
Multi-tenant support, access control, and team collaboration
|
||||
</Card>
|
||||
|
||||
<Card title="Webhooks" icon="webhook" href="/api-reference/webhook/create-webhook">
|
||||
Real-time notifications for memory events and updates
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Note>
|
||||
**Building multi-tenant apps?** Learn about [Organizations & Projects](/api-reference/organizations-projects) for team isolation and access control.
|
||||
</Note>
|
||||
|
||||
---
|
||||
1. **Memory APIs**: Core operations for managing individual memories and collections.
|
||||
2. **Entities APIs**: Manage different entity types (users, agents, etc.) and their associated memories.
|
||||
3. **Search API**: Advanced search functionality to retrieve relevant memories.
|
||||
4. **History API**: Track and retrieve the history of memory interactions.
|
||||
|
||||
## Authentication
|
||||
|
||||
All API requests require authentication using Token-based authentication. Include your API key in the Authorization header:
|
||||
All API requests require authentication using HTTP Basic Auth. Ensure you include your API key in the Authorization header of each request.
|
||||
|
||||
```bash
|
||||
Authorization: Token <your-api-key>
|
||||
## Organizations and projects (optional)
|
||||
|
||||
Organizations and projects provide the following capabilities:
|
||||
|
||||
- **Multi-org/project Support**: Specify organization and project when initializing the Mem0 client to attribute API usage appropriately
|
||||
- **Member Management**: Control access to data through organization and project membership
|
||||
- **Access Control**: Only members can access memories and data within their organization/project scope
|
||||
- **Team Isolation**: Maintain data separation between different teams and projects for secure collaboration
|
||||
|
||||
Example with the mem0 Python package:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
client = MemoryClient(org_id='YOUR_ORG_ID', project_id='YOUR_PROJECT_ID')
|
||||
```
|
||||
|
||||
Get your API key from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys).
|
||||
</Tab>
|
||||
|
||||
<Warning>
|
||||
**Keep your API key secure.** Never expose it in client-side code or public repositories. Use environment variables and server-side requests only.
|
||||
</Warning>
|
||||
<Tab title="Node.js">
|
||||
|
||||
---
|
||||
```javascript
|
||||
import { MemoryClient } from "mem0ai";
|
||||
const client = new MemoryClient({organizationId: "YOUR_ORG_ID", projectId: "YOUR_PROJECT_ID"});
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Add Your First Memory" icon="rocket" href="/api-reference/memory/add-memories">
|
||||
Start storing memories via the REST API
|
||||
</Card>
|
||||
### Project Management Methods
|
||||
|
||||
<Card title="Search with Filters" icon="filter" href="/api-reference/memory/v2-search-memories">
|
||||
Learn advanced search and filtering techniques
|
||||
</Card>
|
||||
</CardGroup>
|
||||
The Mem0 client provides comprehensive project management capabilities through the `client.project` interface:
|
||||
|
||||
#### Get Project Details
|
||||
|
||||
Retrieve information about the current project:
|
||||
|
||||
```python
|
||||
# Get all project details
|
||||
project_info = client.project.get()
|
||||
|
||||
# Get specific fields only
|
||||
project_info = client.project.get(fields=["name", "description", "custom_categories"])
|
||||
```
|
||||
|
||||
#### Create a New Project
|
||||
|
||||
Create a new project within your organization:
|
||||
|
||||
```python
|
||||
# Create a project with name and description
|
||||
new_project = client.project.create(
|
||||
name="My New Project",
|
||||
description="A project for managing customer support memories"
|
||||
)
|
||||
```
|
||||
|
||||
#### Update Project Settings
|
||||
|
||||
Modify project configuration including custom instructions, categories, and graph settings:
|
||||
|
||||
```python
|
||||
# Update project with custom categories
|
||||
client.project.update(
|
||||
custom_categories=[
|
||||
{"customer_preferences": "Customer likes, dislikes, and preferences"},
|
||||
{"support_history": "Previous support interactions and resolutions"}
|
||||
]
|
||||
)
|
||||
|
||||
# Update project with custom instructions
|
||||
client.project.update(
|
||||
custom_instructions="..."
|
||||
)
|
||||
|
||||
# Enable graph memory for the project
|
||||
client.project.update(enable_graph=True)
|
||||
|
||||
# Update multiple settings at once
|
||||
client.project.update(
|
||||
custom_instructions="...",
|
||||
custom_categories=[
|
||||
{"personal_info": "User personal information and preferences"},
|
||||
{"work_context": "Professional context and work-related information"}
|
||||
],
|
||||
enable_graph=True
|
||||
)
|
||||
```
|
||||
|
||||
#### Delete Project
|
||||
|
||||
<Note>
|
||||
This action will remove all memories, messages, and other related data in the project. This operation is irreversible.
|
||||
</Note>
|
||||
|
||||
Remove a project and all its associated data:
|
||||
|
||||
```python
|
||||
# Delete the current project (irreversible)
|
||||
result = client.project.delete()
|
||||
```
|
||||
|
||||
#### Member Management
|
||||
|
||||
Manage project members and their access levels:
|
||||
|
||||
```python
|
||||
# Get all project members
|
||||
members = client.project.get_members()
|
||||
|
||||
# Add a new member as a reader
|
||||
client.project.add_member(
|
||||
email="colleague@company.com",
|
||||
role="READER" # or "OWNER"
|
||||
)
|
||||
|
||||
# Update a member's role
|
||||
client.project.update_member(
|
||||
email="colleague@company.com",
|
||||
role="OWNER"
|
||||
)
|
||||
|
||||
# Remove a member from the project
|
||||
client.project.remove_member(email="colleague@company.com")
|
||||
```
|
||||
|
||||
#### Member Roles
|
||||
|
||||
- **READER**: Can view and search memories, but cannot modify project settings or manage members
|
||||
- **OWNER**: Full access including project modification, member management, and all reader permissions
|
||||
|
||||
#### Async Support
|
||||
|
||||
All project methods are also available in async mode:
|
||||
|
||||
```python
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
async def manage_project():
|
||||
client = AsyncMemoryClient(org_id='YOUR_ORG_ID', project_id='YOUR_PROJECT_ID')
|
||||
|
||||
# All methods support async/await
|
||||
project_info = await client.project.get()
|
||||
await client.project.update(enable_graph=True)
|
||||
members = await client.project.get_members()
|
||||
|
||||
# To call the async function properly
|
||||
import asyncio
|
||||
asyncio.run(manage_project())
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
To begin using the Mem0 API, you'll need to:
|
||||
|
||||
1. Sign up for a [Mem0 account](https://app.mem0.ai) and obtain your API key.
|
||||
2. Familiarize yourself with the API endpoints and their functionalities.
|
||||
3. Make your first API call to add or retrieve a memory.
|
||||
|
||||
Explore the detailed documentation for each API endpoint to learn more about request/response formats, parameters, and example usage.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
title: 'Delete User'
|
||||
openapi: delete /v2/entities/{entity_type}/{entity_id}/
|
||||
openapi: delete /v1/entities/{entity_type}/{entity_id}/
|
||||
---
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
title: 'Get Event'
|
||||
openapi: get /v1/event/{event_id}/
|
||||
---
|
||||
|
||||
Retrieve details about a specific event by passing its `event_id`. This endpoint is particularly helpful for tracking the status, payload, and completion details of asynchronous memory operations.
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
title: 'Get Events'
|
||||
openapi: get /v1/events/
|
||||
---
|
||||
|
||||
List recent events for your organization and project.
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **Dashboards**: Summarize adds/searches over time by paging through events.
|
||||
- **Alerting**: Poll for `FAILED` events and trigger follow-up workflows.
|
||||
- **Audit**: Store the returned payload/metadata for compliance logs.
|
||||
|
||||
@@ -1,97 +1,4 @@
|
||||
---
|
||||
title: 'Add Memories'
|
||||
openapi: post /v1/memories/
|
||||
---
|
||||
|
||||
Add new facts, messages, or metadata to a user’s memory store. The Add Memories endpoint accepts either raw text or conversational turns and commits them asynchronously so the memory is ready for later search, retrieval, and graph queries.
|
||||
|
||||
## Endpoint
|
||||
|
||||
- **Method**: `POST`
|
||||
- **URL**: `/v1/memories/`
|
||||
- **Content-Type**: `application/json`
|
||||
|
||||
Memories are processed asynchronously by default. The response contains queued events you can track while the platform finalizes enrichment.
|
||||
|
||||
## Required headers
|
||||
|
||||
| Header | Required | Description |
|
||||
| --- | --- | --- |
|
||||
| `Authorization: Token <MEM0_API_KEY>` | Yes | API key scoped to your workspace. |
|
||||
| `Accept: application/json` | Yes | Ensures a JSON response. |
|
||||
|
||||
## Request body
|
||||
|
||||
Provide at least one message or direct memory string. Most callers supply `messages` so Mem0 can infer structured memories as part of ingestion.
|
||||
|
||||
<CodeGroup>
|
||||
```json Basic request
|
||||
{
|
||||
"user_id": "alice",
|
||||
"messages": [
|
||||
{ "role": "user", "content": "I moved to Austin last month." }
|
||||
],
|
||||
"metadata": {
|
||||
"source": "onboarding_form"
|
||||
}
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Common fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `user_id` | string | No* | Associates the memory with a user. Provide when you want the memory scoped to a specific identity. |
|
||||
| `messages` | array | No* | Conversation turns for Mem0 to infer memories from. Each object should include `role` and `content`. |
|
||||
| `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). |
|
||||
| `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. |
|
||||
| `async_mode` | boolean (default `true`) | Optional | Controls asynchronous processing. Most clients leave this enabled. |
|
||||
| `output_format` | string (default `v1.1`) | Optional | Response format. `v1.1` wraps results in a `results` array. |
|
||||
|
||||
> \* Provide at least one `messages` entry to describe what you are storing. For scoped memories, include `user_id`. You can also attach `agent_id`, `app_id`, `run_id`, `project_id`, or `org_id` to refine ownership.
|
||||
|
||||
## Response
|
||||
|
||||
Successful requests return an array of events queued for processing. Each event includes the generated memory text and an identifier you can persist for auditing.
|
||||
|
||||
<CodeGroup>
|
||||
```json 200 response
|
||||
[
|
||||
{
|
||||
"id": "mem_01JF8ZS4Y0R0SPM13R5R6H32CJ",
|
||||
"event": "ADD",
|
||||
"data": {
|
||||
"memory": "The user moved to Austin in 2025."
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
```json 400 response
|
||||
{
|
||||
"error": "400 Bad Request",
|
||||
"details": {
|
||||
"message": "Invalid input data. Please refer to the memory creation documentation at https://docs.mem0.ai/platform/quickstart#4-1-create-memories for correct formatting and required fields."
|
||||
}
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Graph relationships
|
||||
|
||||
Add Memories can enrich the knowledge graph on write. Set `enable_graph: true` to create entity nodes and relationships for the stored memory. Use this when you want downstream `get_all` or search calls to traverse connected entities.
|
||||
|
||||
<CodeGroup>
|
||||
```json Graph-aware request
|
||||
{
|
||||
"user_id": "alice",
|
||||
"messages": [
|
||||
{ "role": "user", "content": "I met with Dr. Lee at General Hospital." }
|
||||
],
|
||||
"enable_graph": true
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The response follows the same format, and related entities become available in [Graph Memory](/platform/features/graph-memory) queries.
|
||||
---
|
||||
@@ -3,4 +3,4 @@ title: 'Create Memory Export'
|
||||
openapi: post /v1/exports/
|
||||
---
|
||||
|
||||
Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you're exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `run_id`, or `session_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs.
|
||||
Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you’re exporting a large number of memories. You can tailor the export by applying various filters (e.g., user_id, agent_id, run_id, or session_id) and by modifying the Pydantic schema to ensure the final data matches your exact needs.
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
---
|
||||
title: "Get Memories"
|
||||
openapi: post /v2/memories/
|
||||
---
|
||||
|
||||
The v2 get memories API is powerful and flexible, allowing for more precise memory listing without the need for a search query. It supports complex logical operations (AND, OR, NOT) and comparison operators for advanced filtering capabilities. The comparison operators include:
|
||||
|
||||
- `in`: Matches any of the values specified
|
||||
- `gte`: Greater than or equal to
|
||||
- `lte`: Less than or equal to
|
||||
- `gt`: Greater than
|
||||
- `lt`: Less than
|
||||
- `ne`: Not equal to
|
||||
- `icontains`: Case-insensitive containment check
|
||||
- `*`: Wildcard character that matches everything
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
memories = client.get_all(
|
||||
filters={
|
||||
"AND": [
|
||||
{
|
||||
"user_id": "alex"
|
||||
},
|
||||
{
|
||||
"created_at": {"gte": "2024-07-01", "lte": "2024-07-31"}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```python Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "f4cbdb08-7062-4f3e-8eb2-9f5c80dfe64c",
|
||||
"memory": "Alex is planning a trip to San Francisco from July 1st to July 10th",
|
||||
"created_at": "2024-07-01T12:00:00Z",
|
||||
"updated_at": "2024-07-01T12:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "a2b8c3d4-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
|
||||
"memory": "Alex prefers vegetarian restaurants",
|
||||
"created_at": "2024-07-05T15:30:00Z",
|
||||
"updated_at": "2024-07-05T15:30:00Z"
|
||||
}
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Graph Memory
|
||||
|
||||
To retrieve graph memory relationships between entities, pass `output_format="v1.1"` in your request. This will return memories with entity and relationship information from the knowledge graph.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
memories = client.get_all(
|
||||
filters={
|
||||
"user_id": "alex"
|
||||
},
|
||||
output_format="v1.1"
|
||||
)
|
||||
```
|
||||
|
||||
```python Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "f4cbdb08-7062-4f3e-8eb2-9f5c80dfe64c",
|
||||
"memory": "Alex is planning a trip to San Francisco",
|
||||
"entities": [
|
||||
{
|
||||
"id": "entity-1",
|
||||
"name": "Alex",
|
||||
"type": "person"
|
||||
},
|
||||
{
|
||||
"id": "entity-2",
|
||||
"name": "San Francisco",
|
||||
"type": "location"
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{
|
||||
"source": "entity-1",
|
||||
"target": "entity-2",
|
||||
"relationship": "traveling_to"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
@@ -1,104 +0,0 @@
|
||||
---
|
||||
title: 'Search Memories'
|
||||
openapi: post /v2/memories/search/
|
||||
---
|
||||
|
||||
The v2 search API is powerful and flexible, allowing for more precise memory retrieval. It supports complex logical operations (AND, OR, NOT) and comparison operators for advanced filtering capabilities. The comparison operators include:
|
||||
- `in`: Matches any of the values specified
|
||||
- `gte`: Greater than or equal to
|
||||
- `lte`: Less than or equal to
|
||||
- `gt`: Greater than
|
||||
- `lt`: Less than
|
||||
- `ne`: Not equal to
|
||||
- `icontains`: Case-insensitive containment check
|
||||
- `*`: Wildcard character that matches everything
|
||||
|
||||
<CodeGroup>
|
||||
```python Platform API Example
|
||||
related_memories = client.search(
|
||||
query="What are Alice's hobbies?",
|
||||
filters={
|
||||
"OR": [
|
||||
{
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"agent_id": {"in": ["travel-agent", "sports-agent"]}
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"memories": [
|
||||
{
|
||||
"id": "ea925981-272f-40dd-b576-be64e4871429",
|
||||
"memory": "Likes to play cricket and plays cricket on weekends.",
|
||||
"metadata": {
|
||||
"category": "hobbies"
|
||||
},
|
||||
"score": 0.32116443111457704,
|
||||
"created_at": "2024-07-26T10:29:36.630547-07:00",
|
||||
"updated_at": null,
|
||||
"user_id": "alice",
|
||||
"agent_id": "sports-agent"
|
||||
}
|
||||
],
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<CodeGroup>
|
||||
```python Wildcard Example
|
||||
# Using wildcard to match all run_ids for a specific user
|
||||
all_memories = client.search(
|
||||
query="What are Alice's hobbies?",
|
||||
filters={
|
||||
"AND": [
|
||||
{
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"run_id": "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<CodeGroup>
|
||||
```python Categories Filter Examples
|
||||
# Example 1: Using 'contains' for partial matching
|
||||
finance_memories = client.search(
|
||||
query="What are my financial goals?",
|
||||
filters={
|
||||
"AND": [
|
||||
{ "user_id": "alice" },
|
||||
{
|
||||
"categories": {
|
||||
"contains": "finance"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Example 2: Using 'in' for exact matching
|
||||
personal_memories = client.search(
|
||||
query="What personal information do you have?",
|
||||
filters={
|
||||
"AND": [
|
||||
{ "user_id": "alice" },
|
||||
{
|
||||
"categories": {
|
||||
"in": ["personal_information"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Memories (v1 - Deprecated)'
|
||||
openapi: get /v1/memories/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Search Memories (v1 - Deprecated)'
|
||||
openapi: post /v1/memories/search/
|
||||
---
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
title: 'Get Memories (v2)'
|
||||
openapi: post /v2/memories/
|
||||
---
|
||||
|
||||
The v2 get memories API is powerful and flexible, allowing for more precise memory listing without the need for a search query. It supports complex logical operations (AND, OR, NOT) and comparison operators for advanced filtering capabilities. The comparison operators include:
|
||||
- `in`: Matches any of the values specified
|
||||
- `gte`: Greater than or equal to
|
||||
- `lte`: Less than or equal to
|
||||
- `gt`: Greater than
|
||||
- `lt`: Less than
|
||||
- `ne`: Not equal to
|
||||
- `icontains`: Case-insensitive containment check
|
||||
- `*`: Wildcard character that matches everything
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
memories = m.get_all(
|
||||
filters={
|
||||
"AND": [
|
||||
{
|
||||
"user_id": "alex"
|
||||
},
|
||||
{
|
||||
"created_at": {"gte": "2024-07-01", "lte": "2024-07-31"}
|
||||
}
|
||||
]
|
||||
},
|
||||
version="v2"
|
||||
)
|
||||
```
|
||||
|
||||
```json Output
|
||||
[
|
||||
{
|
||||
"id":"f38b689d-6b24-45b7-bced-17fbb4d8bac7",
|
||||
"memory":"Name: Alex. Vegetarian. Allergic to nuts.",
|
||||
"user_id":"alex",
|
||||
"hash":"62bc074f56d1f909f1b4c2b639f56f6a",
|
||||
"metadata":null,
|
||||
"created_at":"2024-07-25T23:57:00.108347-07:00",
|
||||
"updated_at":"2024-07-25T23:57:00.108367-07:00"
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<CodeGroup>
|
||||
```python Wildcard Example
|
||||
# Using wildcard to get all memories for a specific user across all run_ids
|
||||
memories = m.get_all(
|
||||
filters={
|
||||
"AND": [
|
||||
{
|
||||
"user_id": "alex"
|
||||
},
|
||||
{
|
||||
"run_id": "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
version="v2"
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: 'Search Memories (v2)'
|
||||
openapi: post /v2/memories/search/
|
||||
---
|
||||
|
||||
The v2 search API is powerful and flexible, allowing for more precise memory retrieval. It supports complex logical operations (AND, OR, NOT) and comparison operators for advanced filtering capabilities. The comparison operators include:
|
||||
- `in`: Matches any of the values specified
|
||||
- `gte`: Greater than or equal to
|
||||
- `lte`: Less than or equal to
|
||||
- `gt`: Greater than
|
||||
- `lt`: Less than
|
||||
- `ne`: Not equal to
|
||||
- `icontains`: Case-insensitive containment check
|
||||
- `*`: Wildcard character that matches everything
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
related_memories = m.search(
|
||||
query="What are Alice's hobbies?",
|
||||
version="v2",
|
||||
filters={
|
||||
"OR": [
|
||||
{
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"agent_id": {"in": ["travel-agent", "sports-agent"]}
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"memories": [
|
||||
{
|
||||
"id": "ea925981-272f-40dd-b576-be64e4871429",
|
||||
"memory": "Likes to play cricket and plays cricket on weekends.",
|
||||
"metadata": {
|
||||
"category": "hobbies"
|
||||
},
|
||||
"score": 0.32116443111457704,
|
||||
"created_at": "2024-07-26T10:29:36.630547-07:00",
|
||||
"updated_at": null,
|
||||
"user_id": "alice",
|
||||
"agent_id": "sports-agent"
|
||||
}
|
||||
],
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<CodeGroup>
|
||||
```python Wildcard Example
|
||||
# Using wildcard to match all run_ids for a specific user
|
||||
all_memories = m.search(
|
||||
query="What are Alice's hobbies?",
|
||||
version="v2",
|
||||
filters={
|
||||
"AND": [
|
||||
{
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"run_id": "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<CodeGroup>
|
||||
```python Categories Filter Examples
|
||||
# Example 1: Using 'contains' for partial matching
|
||||
finance_memories = m.search(
|
||||
query="What are my financial goals?",
|
||||
version="v2",
|
||||
filters={
|
||||
"AND": [
|
||||
{ "user_id": "alice" },
|
||||
{
|
||||
"categories": {
|
||||
"contains": "finance"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Example 2: Using 'in' for exact matching
|
||||
personal_memories = m.search(
|
||||
query="What personal information do you have?",
|
||||
version="v2",
|
||||
filters={
|
||||
"AND": [
|
||||
{ "user_id": "alice" },
|
||||
{
|
||||
"categories": {
|
||||
"in": ["personal_information"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -1,197 +0,0 @@
|
||||
---
|
||||
title: Organizations & Projects
|
||||
icon: "building"
|
||||
description: "Manage multi-tenant applications with organization and project APIs"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Organizations and projects provide multi-tenant support, access control, and team collaboration capabilities for Mem0 Platform. Use these APIs to build applications that support multiple teams, customers, or isolated environments.
|
||||
|
||||
<Info>
|
||||
Organizations and projects are **optional** features. You can use Mem0 without them for single-user or simple multi-user applications.
|
||||
</Info>
|
||||
|
||||
## Key Capabilities
|
||||
|
||||
- **Multi-org/project Support**: Specify organization and project when initializing the Mem0 client to attribute API usage appropriately
|
||||
- **Member Management**: Control access to data through organization and project membership
|
||||
- **Access Control**: Only members can access memories and data within their organization/project scope
|
||||
- **Team Isolation**: Maintain data separation between different teams and projects for secure collaboration
|
||||
|
||||
---
|
||||
|
||||
## Using Organizations & Projects
|
||||
|
||||
### Initialize with Org/Project Context
|
||||
|
||||
Example with the mem0 Python package:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
client = MemoryClient(org_id='YOUR_ORG_ID', project_id='YOUR_PROJECT_ID')
|
||||
```
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Node.js">
|
||||
|
||||
```javascript
|
||||
import { MemoryClient } from "mem0ai";
|
||||
const client = new MemoryClient({
|
||||
organizationId: "YOUR_ORG_ID",
|
||||
projectId: "YOUR_PROJECT_ID"
|
||||
});
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
## Project Management
|
||||
|
||||
The Mem0 client provides comprehensive project management through the `client.project` interface:
|
||||
|
||||
### Get Project Details
|
||||
|
||||
Retrieve information about the current project:
|
||||
|
||||
```python
|
||||
# Get all project details
|
||||
project_info = client.project.get()
|
||||
|
||||
# Get specific fields only
|
||||
project_info = client.project.get(fields=["name", "description", "custom_categories"])
|
||||
```
|
||||
|
||||
### Create a New Project
|
||||
|
||||
Create a new project within your organization:
|
||||
|
||||
```python
|
||||
# Create a project with name and description
|
||||
new_project = client.project.create(
|
||||
name="My New Project",
|
||||
description="A project for managing customer support memories"
|
||||
)
|
||||
```
|
||||
|
||||
### Update Project Settings
|
||||
|
||||
Modify project configuration including custom instructions, categories, and graph settings:
|
||||
|
||||
```python
|
||||
# Update project with custom categories
|
||||
client.project.update(
|
||||
custom_categories=[
|
||||
{"customer_preferences": "Customer likes, dislikes, and preferences"},
|
||||
{"support_history": "Previous support interactions and resolutions"}
|
||||
]
|
||||
)
|
||||
|
||||
# Update project with custom instructions
|
||||
client.project.update(
|
||||
custom_instructions="..."
|
||||
)
|
||||
|
||||
# Enable graph memory for the project
|
||||
client.project.update(enable_graph=True)
|
||||
|
||||
# Update multiple settings at once
|
||||
client.project.update(
|
||||
custom_instructions="...",
|
||||
custom_categories=[
|
||||
{"personal_info": "User personal information and preferences"},
|
||||
{"work_context": "Professional context and work-related information"}
|
||||
],
|
||||
enable_graph=True
|
||||
)
|
||||
```
|
||||
|
||||
### Delete Project
|
||||
|
||||
<Warning>
|
||||
This action will remove all memories, messages, and other related data in the project. **This operation is irreversible.**
|
||||
</Warning>
|
||||
|
||||
Remove a project and all its associated data:
|
||||
|
||||
```python
|
||||
# Delete the current project (irreversible)
|
||||
result = client.project.delete()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Member Management
|
||||
|
||||
Manage project members and their access levels:
|
||||
|
||||
```python
|
||||
# Get all project members
|
||||
members = client.project.get_members()
|
||||
|
||||
# Add a new member as a reader
|
||||
client.project.add_member(
|
||||
email="colleague@company.com",
|
||||
role="READER" # or "OWNER"
|
||||
)
|
||||
|
||||
# Update a member's role
|
||||
client.project.update_member(
|
||||
email="colleague@company.com",
|
||||
role="OWNER"
|
||||
)
|
||||
|
||||
# Remove a member from the project
|
||||
client.project.remove_member(email="colleague@company.com")
|
||||
```
|
||||
|
||||
### Member Roles
|
||||
|
||||
| Role | Permissions |
|
||||
|------|-------------|
|
||||
| **READER** | Can view and search memories, but cannot modify project settings or manage members |
|
||||
| **OWNER** | Full access including project modification, member management, and all reader permissions |
|
||||
|
||||
---
|
||||
|
||||
## Async Support
|
||||
|
||||
All project methods are available in async mode:
|
||||
|
||||
```python
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
async def manage_project():
|
||||
client = AsyncMemoryClient(org_id='YOUR_ORG_ID', project_id='YOUR_PROJECT_ID')
|
||||
|
||||
# All methods support async/await
|
||||
project_info = await client.project.get()
|
||||
await client.project.update(enable_graph=True)
|
||||
members = await client.project.get_members()
|
||||
|
||||
# To call the async function properly
|
||||
import asyncio
|
||||
asyncio.run(manage_project())
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Reference
|
||||
|
||||
For complete API specifications and additional endpoints, see:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Organizations APIs" icon="building" href="/api-reference/organization/create-org">
|
||||
Create, get, and manage organizations
|
||||
</Card>
|
||||
|
||||
<Card title="Project APIs" icon="folder" href="/api-reference/project/create-project">
|
||||
Full project CRUD and member management endpoints
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -3,3 +3,7 @@ title: 'Create Webhook'
|
||||
openapi: post /api/v1/webhooks/projects/{project_id}/
|
||||
---
|
||||
|
||||
## Create Webhook
|
||||
|
||||
Create a webhook by providing the project ID and the webhook details.
|
||||
|
||||
|
||||
@@ -2,3 +2,7 @@
|
||||
title: 'Delete Webhook'
|
||||
openapi: delete /api/v1/webhooks/{webhook_id}/
|
||||
---
|
||||
|
||||
## Delete Webhook
|
||||
|
||||
Delete a webhook by providing the webhook ID.
|
||||
|
||||
@@ -3,3 +3,7 @@ title: 'Get Webhook'
|
||||
openapi: get /api/v1/webhooks/projects/{project_id}/
|
||||
---
|
||||
|
||||
## Get Webhook
|
||||
|
||||
Get a webhook by providing the project ID.
|
||||
|
||||
|
||||
@@ -3,3 +3,7 @@ title: 'Update Webhook'
|
||||
openapi: put /api/v1/webhooks/{webhook_id}/
|
||||
---
|
||||
|
||||
## Update Webhook
|
||||
|
||||
Update a webhook by providing the webhook ID and the fields to update.
|
||||
|
||||
|
||||
+3
-204
@@ -7,124 +7,6 @@ mode: "wide"
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
|
||||
<Update label="2026-03-03" description="v1.0.5">
|
||||
- **Telemetry Fix**
|
||||
- Fixed an issue where the PostHog client was initialized even after telemetry was disabled. Although events were not captured, the client was unnecessarily initialized.
|
||||
</Update>
|
||||
|
||||
<Update label="2026-02-17" description="v1.0.4">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Memory Update:**
|
||||
- Added `timestamp` parameter to `update()` — accepts Unix epoch (int/float) or ISO 8601 string
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-01-29" description="v1.0.3">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Project Settings:**
|
||||
- Added inclusion prompt, exclusion prompt, memory depth, and usecase setting
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-01-13" description="v1.0.2">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Vector Stores:**
|
||||
- Added DriverInfo metadata to MongoDB vector store
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-11-14" description="v1.0.1">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Vector Stores:**
|
||||
- Added Apache Cassandra vector store support
|
||||
- **Embeddings:**
|
||||
- Added FastEmbed embedding support for local embeddings
|
||||
- **Graph Store:**
|
||||
- Added configurable embedding similarity threshold for graph store node matching
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Core:**
|
||||
- Fixed condition check for memories_result type in Memory class
|
||||
- Fixed list_memories endpoint Pydantic validation error
|
||||
- Fixed memory deletion not removing from vector store
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-10-16" description="v1.0.0">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Vector Stores:**
|
||||
- Added Azure MySQL support
|
||||
- Added Azure AI Search Vector Store support
|
||||
- **LLMs:**
|
||||
- Added Tool Call support for LangchainLLM
|
||||
- Enabled custom model and parameters for Hugging Face with huggingface_base_url
|
||||
- Updated default LLM configuration
|
||||
- **Rerankers:**
|
||||
- Added reranker support: Cohere, ZeroEntropy, Hugging Face, Sentence Transformers, and LLMs
|
||||
- **Core:**
|
||||
- Added metadata filtering for OSS
|
||||
- Added Assistant memory retrieval
|
||||
- Enabled async mode as default
|
||||
|
||||
**Improvements:**
|
||||
- **Prompts:**
|
||||
- Improved prompt for better memory retrieval
|
||||
- **Dependencies:**
|
||||
- Updated dependency compatibility with OpenAI 2.x
|
||||
- **Validation:**
|
||||
- Validated embedding_dims for Kuzu integration
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Vector Stores:**
|
||||
- Fixed Databricks Vector Store integration
|
||||
- Fixed Milvus DB bug and added test coverage
|
||||
- Fixed Weaviate search method
|
||||
- **LLMs:**
|
||||
- Fixed bug with thinking LLM in vLLM
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-09-25" description="v0.1.118">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Vector Stores:**
|
||||
- Added Valkey vector store support
|
||||
- Added support for ChromaDB Cloud
|
||||
- Added Mem0 vector store backend integration for Neptune Analytics
|
||||
- **Graph Store:**
|
||||
- Added Neptune-DB graph store with vector store
|
||||
- **Core:**
|
||||
- Implemented structured exception classes with error codes and suggested actions
|
||||
|
||||
**Improvements:**
|
||||
- **Dependencies:**
|
||||
- Updated OpenAI dependency and improved Ollama compatibility
|
||||
- **Testing:**
|
||||
- Added Weaviate DB test
|
||||
- Added comprehensive test suite for SQLiteManager
|
||||
- **Documentation:**
|
||||
- Updated category docs
|
||||
- Updated Search V2 / Get All V2 filters documentation
|
||||
- Refactored AWS example title
|
||||
- Fixed Quickstart cURL example
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Vector Stores:**
|
||||
- Databricks bug fixes
|
||||
- Fixed S3 Vectors memory initialization issue from configuration
|
||||
- **Core:**
|
||||
- Fixed JSON parsing with new memories
|
||||
- Replaced hardcoded LLM provider with provider from configuration
|
||||
- **LLMs:**
|
||||
- Fixed Bedrock Anthropic models to use system field
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-09-03" description="v0.1.117">
|
||||
|
||||
**New Features & Updates:**
|
||||
@@ -729,74 +611,6 @@ mode: "wide"
|
||||
|
||||
<Tab title="TypeScript">
|
||||
|
||||
<Update label="2026-03-14" description="v2.4.0">
|
||||
|
||||
**Bug Fixes:**
|
||||
- **OSS Storage:** Fixed `SQLITE_CANTOPEN` errors when running as a LaunchAgent, systemd service, or in containers where `process.cwd()` is read-only (e.g. `/`). Default `vector_store.db` location changed from `process.cwd()/vector_store.db` to `~/.mem0/vector_store.db`.
|
||||
- **OSS Storage:** Fixed `historyDbPath` config being silently ignored — config merging always overwrote it with defaults. Top-level `historyDbPath` is now correctly propagated into `historyStore.config` with proper precedence.
|
||||
- **OSS Storage:** Added `ensureSQLiteDirectory()` — parent directories for SQLite database files are now auto-created before opening, preventing `SQLITE_CANTOPEN` when using nested paths.
|
||||
|
||||
**Improvements:**
|
||||
- **Migration:** Added deprecation warning when an existing `vector_store.db` is found at the old `process.cwd()` location, guiding users to move it or set `vectorStore.config.dbPath` explicitly.
|
||||
- **Config:** Limited default SQLite config spreading to only SQLite history providers, preventing config leaking into Supabase or other providers.
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-03-09" description="v2.3.0">
|
||||
|
||||
**Breaking Changes:**
|
||||
- **Dependencies:** Minimum Node.js version for OSS sqlite features is now Node 20+ (due to `better-sqlite3` v12)
|
||||
|
||||
**Bug Fixes:**
|
||||
- **OSS Storage:** Replaced `sqlite3` with `better-sqlite3` to fix native binding resolution failures under jiti-based loaders (e.g. OpenClaw plugin system). Fixes issues where the `bindings` module walked V8 stack frames with synthetic filenames, failing to locate the native `.node` addon.
|
||||
- **OSS Storage:** Fixed async init race condition in `SQLiteManager` — `init()` is now synchronous
|
||||
- **OSS Vector Store:** Migrated `MemoryVectorStore` from `sqlite3` to `better-sqlite3` with transactional batch inserts
|
||||
|
||||
**Improvements:**
|
||||
- **Performance:** Cached prepared statements in `SQLiteManager` for faster history operations
|
||||
- **Performance:** Batch `insert()` in `MemoryVectorStore` wrapped in a transaction for atomicity
|
||||
- **Build:** Updated `tsup.config.ts` externals from `sqlite3` to `better-sqlite3`
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-02-17" description="v2.2.3">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Memory Update:**
|
||||
- Added `timestamp` parameter to `update()` — accepts Unix epoch or ISO 8601 string
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-01-29" description="v2.2.2">
|
||||
|
||||
**New Features & Updates:**
|
||||
- **Project Settings:**
|
||||
- Added inclusion prompt, exclusion prompt, memory depth, and usecase setting
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-12-30" description="v2.2.1">
|
||||
|
||||
**Improvements:**
|
||||
- **Client:** Added support for keyword arguments in `add` and `search` methods, allowing additional properties beyond defined options for experimental features
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-12-29" description="v2.2.0">
|
||||
|
||||
**New Features:**
|
||||
- **Vector Stores:** Added Azure AI Search vector store support
|
||||
|
||||
**Improvements:**
|
||||
- **Config:** Fixed embedder config schema to support `embeddingDims` and `url` parameters
|
||||
- **Graph Memory:** Replaced hardcoded LLM provider with provider from configuration
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Embedders:** Fixed hardcoded `embeddingDims` values in embedders (OpenAI, Ollama, Google, Azure)
|
||||
- **Build:** Fixed TypeScript build errors
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-09-04" description="v2.1.38">
|
||||
**New Features:**
|
||||
- **Client:** Added `metadata` param to `update` method.
|
||||
@@ -823,17 +637,17 @@ mode: "wide"
|
||||
</Update>
|
||||
|
||||
<Update label="2025-06-24" description="v2.1.33">
|
||||
**Improvement:**
|
||||
**Improvement :**
|
||||
- **Client:** Added `immutable` param to `add` method.
|
||||
</Update>
|
||||
|
||||
<Update label="2025-06-20" description="v2.1.32">
|
||||
**Improvement:**
|
||||
**Improvement :**
|
||||
- **Client:** Made `api_version` V2 as default.
|
||||
</Update>
|
||||
|
||||
<Update label="2025-06-17" description="v2.1.31">
|
||||
**Improvement:**
|
||||
**Improvement :**
|
||||
- **Client:** Added param `filter_memories`.
|
||||
</Update>
|
||||
|
||||
@@ -1273,21 +1087,6 @@ mode: "wide"
|
||||
|
||||
<Tab title="Vercel AI SDK">
|
||||
|
||||
<Update label="2025-12-26" description="v2.0.5">
|
||||
**Bug Fix:**
|
||||
- **Vercel AI SDK:** Removed unnecessary dependencies to make the package lighter.
|
||||
</Update>
|
||||
|
||||
<Update label="2025-09-25" description="v2.0.4">
|
||||
**Bug Fix:**
|
||||
- **Vercel AI SDK:** Fixed version parameter in the AI SDK to use V2 for addition.
|
||||
</Update>
|
||||
|
||||
<Update label="2025-09-25" description="v2.0.3">
|
||||
**New Features:**
|
||||
- **Vercel AI SDK:** Added file support for multimodal capabilities with memory context
|
||||
</Update>
|
||||
|
||||
<Update label="2025-09-03" description="v2.0.2">
|
||||
**Bug Fix:**
|
||||
- **Vercel AI SDK:** Fixed streaming response in the AI SDK.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -23,7 +23,7 @@ config = {
|
||||
"embedder": {
|
||||
"provider": "azure_openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-large",
|
||||
"model": "text-embedding-3-large"
|
||||
"azure_kwargs": {
|
||||
"api_version": "",
|
||||
"azure_deployment": "",
|
||||
@@ -40,7 +40,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -68,7 +68,7 @@ const memory = new Memory(config);
|
||||
|
||||
const 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": "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."}
|
||||
]
|
||||
@@ -117,20 +117,9 @@ Refer to [Azure Identity troubleshooting tips](https://github.com/Azure/azure-sd
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Azure OpenAI embedder:
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `text-embedding-3-small` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `azure_kwargs` | The Azure OpenAI configs | `config_keys` |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Default Value |
|
||||
| ----------------- | --------------------------------------------- | -------------------------- |
|
||||
| `model` | The name of the embedding model to use | `text-embedding-3-small` |
|
||||
| `embeddingDims` | Dimensions of the embedding model | `1536` |
|
||||
| `apiKey` | Azure OpenAI API key | `None` |
|
||||
| `modelProperties` | Object containing endpoint and other settings | `{ endpoint: "",...rest }`|
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -26,7 +26,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -38,19 +38,19 @@ import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
embedder: {
|
||||
provider: "google",
|
||||
config: {
|
||||
apiKey: process.env["GOOGLE_API_KEY"],
|
||||
model: "gemini-embedding-001",
|
||||
embeddingDims: 1536,
|
||||
},
|
||||
provider: 'google',
|
||||
config: {
|
||||
apiKey: process.env.GOOGLE_API_KEY || '',
|
||||
model: 'text-embedding-004',
|
||||
// The output dimensionality is fixed at 768 for Google AI embeddings
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
@@ -61,19 +61,9 @@ await memory.add(messages, { userId: "john" });
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Gemini embedder:
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description | Default Value |
|
||||
| ---------------- | ------------------------------------ | ----------------------- |
|
||||
| `model` | The name of the embedding model to use| `models/text-embedding-004` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `api_key` | The Google API key | `None` |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Default Value |
|
||||
| ----------------- | --------------------------------------------- | -------------------------- |
|
||||
| `model` | The name of the embedding model to use | `gemini-embedding-001` |
|
||||
| `embeddingDims` | Dimensions of the embedding model | `1536` |
|
||||
| `apiKey` | Google API key | `None` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `models/text-embedding-004` |
|
||||
| `embedding_dims` | Dimensions of the embedding model (output_dimensionality will be considered as embedding_dims, so please set embedding_dims accordingly) | `768` |
|
||||
| `api_key` | The Google API key | `None` |
|
||||
|
||||
@@ -24,7 +24,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -36,7 +36,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -66,7 +66,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -20,7 +20,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -29,10 +29,10 @@ m.add(messages, user_id="john")
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring LM Studio embedder:
|
||||
Here are the parameters available for configuring Ollama embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the LM Studio model to use | `nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.f16.gguf` |
|
||||
| `model` | The name of the OpenAI model to use | `nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.f16.gguf` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `lmstudio_base_url` | Base URL for LM Studio connection | `http://localhost:1234/v1` |
|
||||
@@ -21,7 +21,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -44,7 +44,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
@@ -69,6 +69,5 @@ Here are the parameters available for configuring Ollama embedder:
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the Ollama model to use | `nomic-embed-text:latest` |
|
||||
| `url` | Base URL for Ollama server | `http://localhost:11434` |
|
||||
| `embeddingDims` | Dimensions of the embedding model | 768
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -25,7 +25,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -27,7 +27,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -27,7 +27,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 offers support for various embedding models, allowing users to choose the one that best suits their needs.
|
||||
@@ -27,6 +29,6 @@ See the list of supported embedders below.
|
||||
|
||||
## Usage
|
||||
|
||||
To utilize an embedding model, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `OpenAI` will be used as the embedding model.
|
||||
To utilize a embedder, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `OpenAI` will be used as the embedder.
|
||||
|
||||
For a comprehensive list of available parameters for embedding model configuration, please refer to [Config](./config).
|
||||
For a comprehensive list of available parameters for embedder configuration, please refer to [Config](./config).
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## How to define configurations?
|
||||
|
||||
@@ -29,7 +29,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -54,7 +54,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -31,7 +31,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -48,7 +48,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -77,7 +77,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -28,7 +28,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -30,7 +30,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -55,7 +55,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -20,7 +20,7 @@ os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
# Initialize a LangChain model directly
|
||||
openai_model = ChatOpenAI(
|
||||
model="gpt-4.1-nano-2025-04-14",
|
||||
model="gpt-4o",
|
||||
temperature=0.2,
|
||||
max_tokens=2000
|
||||
)
|
||||
@@ -38,7 +38,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -69,7 +69,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -12,7 +12,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "litellm",
|
||||
"config": {
|
||||
"model": "gpt-4.1-nano-2025-04-14",
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
@@ -22,7 +22,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -29,7 +29,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -57,7 +57,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -28,7 +28,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -53,7 +53,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
---
|
||||
title: Ollama
|
||||
---
|
||||
|
||||
You can use LLMs from Ollama to run Mem0 locally. These [models](https://ollama.com/search?c=tools) support tool calling.
|
||||
You can use LLMs from Ollama to run Mem0 locally. These [models](https://ollama.com/search?c=tools) support tool support.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -27,7 +23,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -51,7 +47,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -19,7 +19,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4.1-nano-2025-04-14",
|
||||
"model": "gpt-4o",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
@@ -40,7 +40,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -65,7 +65,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
@@ -85,7 +85,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "openai_structured",
|
||||
"config": {
|
||||
"model": "gpt-4.1-nano-2025-04-14",
|
||||
"model": "gpt-4o-2024-08-06",
|
||||
"temperature": 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
---
|
||||
title: Together
|
||||
---
|
||||
|
||||
To use Together LLM models, you have to set the `TOGETHER_API_KEY` environment variable. You can obtain the Together API key from their [Account settings page](https://api.together.xyz/settings/api-keys).
|
||||
To use TogetherAI LLM models, you have to set the `TOGETHER_API_KEY` environment variable. You can obtain the TogetherAI API key from their [Account settings page](https://api.together.xyz/settings/api-keys).
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -27,7 +23,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -36,4 +32,4 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `together` config are present in [Master List of All Params in Config](../config).
|
||||
All available parameters for the `togetherai` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -29,7 +29,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 includes built-in support for various popular large language models. Memory can utilize the LLM provided by the user, ensuring efficient use for specific needs.
|
||||
@@ -26,8 +28,8 @@ See the list of supported LLMs below.
|
||||
<Card title="Together" href="/components/llms/models/together" />
|
||||
<Card title="Groq" href="/components/llms/models/groq" />
|
||||
<Card title="Litellm" href="/components/llms/models/litellm" />
|
||||
<Card title="Mistral AI" href="/components/llms/models/mistral_AI" />
|
||||
<Card title="Google AI" href="/components/llms/models/google_AI" />
|
||||
<Card title="Mistral AI" href="/components/llms/models/mistral_ai" />
|
||||
<Card title="Google AI" href="/components/llms/models/google_ai" />
|
||||
<Card title="AWS bedrock" href="/components/llms/models/aws_bedrock" />
|
||||
<Card title="DeepSeek" href="/components/llms/models/deepseek" />
|
||||
<Card title="xAI" href="/components/llms/models/xAI" />
|
||||
|
||||
@@ -1,71 +1,57 @@
|
||||
---
|
||||
title: Config
|
||||
description: "Configuration options for rerankers in Mem0"
|
||||
description: 'Configuration options for rerankers in Mem0'
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Common Configuration Parameters
|
||||
|
||||
All rerankers share these common configuration parameters:
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| ---------- | --------------------------------------------------- | ----- | -------- |
|
||||
| `provider` | Reranker provider name | `str` | Required |
|
||||
| `top_k` | Maximum number of results to return after reranking | `int` | `None` |
|
||||
| `api_key` | API key for the reranker service | `str` | `None` |
|
||||
| Parameter | Description | Type | Default |
|
||||
|-----------|-------------|------|---------|
|
||||
| `provider` | Reranker provider name | `str` | Required |
|
||||
| `top_k` | Maximum number of results to return after reranking | `int` | `None` |
|
||||
| `api_key` | API key for the reranker service | `str` | `None` |
|
||||
|
||||
## Provider-Specific Configuration
|
||||
|
||||
### Zero Entropy
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| --------- | -------------------------------------------- | ----- | ------------ |
|
||||
| `model` | Model to use: `zerank-1` or `zerank-1-small` | `str` | `"zerank-1"` |
|
||||
| `api_key` | Zero Entropy API key | `str` | `None` |
|
||||
| Parameter | Description | Type | Default |
|
||||
|-----------|-------------|------|---------|
|
||||
| `model` | Model to use: `zerank-1` or `zerank-1-small` | `str` | `"zerank-1"` |
|
||||
| `api_key` | Zero Entropy API key | `str` | `None` |
|
||||
|
||||
### Cohere
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| -------------------- | -------------------------------------------- | ------ | ----------------------- |
|
||||
| `model` | Cohere rerank model | `str` | `"rerank-english-v3.0"` |
|
||||
| `api_key` | Cohere API key | `str` | `None` |
|
||||
| `return_documents` | Whether to return document texts in response | `bool` | `False` |
|
||||
| `max_chunks_per_doc` | Maximum chunks per document | `int` | `None` |
|
||||
| Parameter | Description | Type | Default |
|
||||
|-----------|-------------|------|---------|
|
||||
| `model` | Cohere rerank model | `str` | `"rerank-english-v3.0"` |
|
||||
| `api_key` | Cohere API key | `str` | `None` |
|
||||
| `return_documents` | Whether to return document texts in response | `bool` | `False` |
|
||||
| `max_chunks_per_doc` | Maximum chunks per document | `int` | `None` |
|
||||
|
||||
### Sentence Transformer
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| ------------------- | -------------------------------------------- | ------ | ---------------------------------------- |
|
||||
| `model` | HuggingFace cross-encoder model name | `str` | `"cross-encoder/ms-marco-MiniLM-L-6-v2"` |
|
||||
| `device` | Device to run model on (`cpu`, `cuda`, etc.) | `str` | `None` |
|
||||
| `batch_size` | Batch size for processing | `int` | `32` |
|
||||
| `show_progress_bar` | Show progress during processing | `bool` | `False` |
|
||||
|
||||
### Hugging Face
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| --------- | -------------------------------------------- | ----- | --------------------------- |
|
||||
| `model` | HuggingFace reranker model name | `str` | `"BAAI/bge-reranker-large"` |
|
||||
| `api_key` | HuggingFace API token | `str` | `None` |
|
||||
| `device` | Device to run model on (`cpu`, `cuda`, etc.) | `str` | `None` |
|
||||
| Parameter | Description | Type | Default |
|
||||
|-----------|-------------|------|---------|
|
||||
| `model` | HuggingFace cross-encoder model name | `str` | `"cross-encoder/ms-marco-MiniLM-L-6-v2"` |
|
||||
| `device` | Device to run model on (`cpu`, `cuda`, etc.) | `str` | `None` |
|
||||
| `batch_size` | Batch size for processing | `int` | `32` |
|
||||
| `show_progress_bar` | Show progress during processing | `bool` | `False` |
|
||||
|
||||
### LLM-based
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| ---------------- | ------------------------------------------ | ------- | ---------------------- |
|
||||
| `model` | LLM model to use for scoring | `str` | `"gpt-4o-mini"` |
|
||||
| `provider` | LLM provider (`openai`, `anthropic`, etc.) | `str` | `"openai"` |
|
||||
| `api_key` | API key for LLM provider | `str` | `None` |
|
||||
| `temperature` | Temperature for LLM generation | `float` | `0.0` |
|
||||
| `max_tokens` | Maximum tokens for LLM response | `int` | `100` |
|
||||
| `scoring_prompt` | Custom prompt template for scoring | `str` | Default scoring prompt |
|
||||
|
||||
### LLM Reranker
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| -------------- | --------------------------- | ------ | -------- |
|
||||
| `llm.provider` | LLM provider for reranking | `str` | Required |
|
||||
| `llm.config` | LLM configuration object | `dict` | Required |
|
||||
| `top_n` | Number of results to return | `int` | `None` |
|
||||
| Parameter | Description | Type | Default |
|
||||
|-----------|-------------|------|---------|
|
||||
| `model` | LLM model to use for scoring | `str` | `"gpt-4o-mini"` |
|
||||
| `provider` | LLM provider (`openai`, `anthropic`, etc.) | `str` | `"openai"` |
|
||||
| `api_key` | API key for LLM provider | `str` | `None` |
|
||||
| `temperature` | Temperature for LLM generation | `float` | `0.0` |
|
||||
| `max_tokens` | Maximum tokens for LLM response | `int` | `100` |
|
||||
| `scoring_prompt` | Custom prompt template for scoring | `str` | Default scoring prompt |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -73,7 +59,6 @@ You can set API keys using environment variables:
|
||||
|
||||
- `ZERO_ENTROPY_API_KEY` - Zero Entropy API key
|
||||
- `COHERE_API_KEY` - Cohere API key
|
||||
- `HUGGINGFACE_API_KEY` - HuggingFace API token
|
||||
- `OPENAI_API_KEY` - OpenAI API key (for LLM-based reranker)
|
||||
- `ANTHROPIC_API_KEY` - Anthropic API key (for LLM-based reranker)
|
||||
|
||||
@@ -91,10 +76,10 @@ config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4.1-nano-2025-04-14"
|
||||
"model": "gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
"reranker": {
|
||||
"rerank": {
|
||||
"provider": "zero_entropy",
|
||||
"config": {
|
||||
"model": "zerank-1",
|
||||
@@ -102,4 +87,4 @@ config = {
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
@@ -1,220 +0,0 @@
|
||||
---
|
||||
title: Custom Prompts
|
||||
---
|
||||
|
||||
When using LLM rerankers, you can customize the prompts used for ranking to better suit your specific use case and domain.
|
||||
|
||||
## Default Prompt
|
||||
|
||||
The default LLM reranker prompt is designed to be general-purpose:
|
||||
|
||||
```
|
||||
Given a query and a list of memory entries, rank the memory entries based on their relevance to the query.
|
||||
Rate each memory on a scale of 1-10 where 10 is most relevant.
|
||||
|
||||
Query: {query}
|
||||
|
||||
Memory entries:
|
||||
{memories}
|
||||
|
||||
Provide your ranking as a JSON array with scores for each memory.
|
||||
```
|
||||
|
||||
## Custom Prompt Configuration
|
||||
|
||||
You can provide a custom prompt template when configuring the LLM reranker:
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
custom_prompt = """
|
||||
You are an expert at ranking memories for a personal AI assistant.
|
||||
Given a user query and a list of memory entries, rank each memory based on:
|
||||
1. Direct relevance to the query
|
||||
2. Temporal relevance (recent memories may be more important)
|
||||
3. Emotional significance
|
||||
4. Actionability
|
||||
|
||||
Query: {query}
|
||||
User Context: {user_context}
|
||||
|
||||
Memory entries:
|
||||
{memories}
|
||||
|
||||
Rate each memory from 1-10 and provide reasoning.
|
||||
Return as JSON: {{"rankings": [{{"index": 0, "score": 8, "reason": "..."}}]}}
|
||||
"""
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4.1-nano-2025-04-14",
|
||||
"api_key": "your-openai-key"
|
||||
}
|
||||
},
|
||||
"custom_prompt": custom_prompt,
|
||||
"top_n": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memory = Memory.from_config(config)
|
||||
```
|
||||
|
||||
## Prompt Variables
|
||||
|
||||
Your custom prompt can use the following variables:
|
||||
|
||||
| Variable | Description |
|
||||
| ---------------- | ------------------------------------- |
|
||||
| `{query}` | The search query |
|
||||
| `{memories}` | The list of memory entries to rank |
|
||||
| `{user_id}` | The user ID (if available) |
|
||||
| `{user_context}` | Additional user context (if provided) |
|
||||
|
||||
## Domain-Specific Examples
|
||||
|
||||
### Customer Support
|
||||
|
||||
```python
|
||||
customer_support_prompt = """
|
||||
You are ranking customer support conversation memories.
|
||||
Prioritize memories that:
|
||||
- Relate to the current customer issue
|
||||
- Show previous resolution patterns
|
||||
- Indicate customer preferences or constraints
|
||||
|
||||
Query: {query}
|
||||
Customer Context: Previous interactions with this customer
|
||||
|
||||
Memories:
|
||||
{memories}
|
||||
|
||||
Rank each memory 1-10 based on support relevance.
|
||||
"""
|
||||
```
|
||||
|
||||
### Educational Content
|
||||
|
||||
```python
|
||||
educational_prompt = """
|
||||
Rank these learning memories for a student query.
|
||||
Consider:
|
||||
- Prerequisite knowledge requirements
|
||||
- Learning progression and difficulty
|
||||
- Relevance to current learning objectives
|
||||
|
||||
Student Query: {query}
|
||||
Learning Context: {user_context}
|
||||
|
||||
Available memories:
|
||||
{memories}
|
||||
|
||||
Score each memory for educational value (1-10).
|
||||
"""
|
||||
```
|
||||
|
||||
### Personal Assistant
|
||||
|
||||
```python
|
||||
personal_assistant_prompt = """
|
||||
Rank personal memories for relevance to the user's query.
|
||||
Consider:
|
||||
- Recent vs. historical importance
|
||||
- Personal preferences and habits
|
||||
- Contextual relationships between memories
|
||||
|
||||
Query: {query}
|
||||
Personal context: {user_context}
|
||||
|
||||
Memories to rank:
|
||||
{memories}
|
||||
|
||||
Provide relevance scores (1-10) with brief explanations.
|
||||
"""
|
||||
```
|
||||
|
||||
## Advanced Prompt Techniques
|
||||
|
||||
### Multi-Criteria Ranking
|
||||
|
||||
```python
|
||||
multi_criteria_prompt = """
|
||||
Evaluate memories using multiple criteria:
|
||||
|
||||
1. RELEVANCE (40%): How directly related to the query
|
||||
2. RECENCY (20%): How recent the memory is
|
||||
3. IMPORTANCE (25%): Personal or business significance
|
||||
4. ACTIONABILITY (15%): How useful for next steps
|
||||
|
||||
Query: {query}
|
||||
Context: {user_context}
|
||||
|
||||
Memories:
|
||||
{memories}
|
||||
|
||||
For each memory, provide:
|
||||
- Overall score (1-10)
|
||||
- Breakdown by criteria
|
||||
- Final ranking recommendation
|
||||
|
||||
Format: JSON with detailed scoring
|
||||
"""
|
||||
```
|
||||
|
||||
### Contextual Ranking
|
||||
|
||||
```python
|
||||
contextual_prompt = """
|
||||
Consider the following context when ranking memories:
|
||||
- Current user situation: {user_context}
|
||||
- Time of day: {current_time}
|
||||
- Recent activities: {recent_activities}
|
||||
|
||||
Query: {query}
|
||||
|
||||
Rank these memories considering both direct relevance and contextual appropriateness:
|
||||
{memories}
|
||||
|
||||
Provide contextually-aware relevance scores (1-10).
|
||||
"""
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Be Specific**: Clearly define what makes a memory relevant for your use case
|
||||
2. **Use Examples**: Include examples in your prompt for better model understanding
|
||||
3. **Structure Output**: Specify the exact JSON format you want returned
|
||||
4. **Test Iteratively**: Refine your prompt based on actual ranking performance
|
||||
5. **Consider Token Limits**: Keep prompts concise while being comprehensive
|
||||
|
||||
## Prompt Testing
|
||||
|
||||
You can test different prompts by comparing ranking results:
|
||||
|
||||
```python
|
||||
# Test multiple prompt variations
|
||||
prompts = [
|
||||
default_prompt,
|
||||
custom_prompt_v1,
|
||||
custom_prompt_v2
|
||||
]
|
||||
|
||||
for i, prompt in enumerate(prompts):
|
||||
config["reranker"]["config"]["custom_prompt"] = prompt
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
results = memory.search("test query", user_id="test_user")
|
||||
print(f"Prompt {i+1} results: {results}")
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
- **Too Long**: Keep prompts under token limits for your chosen LLM
|
||||
- **Too Vague**: Be specific about ranking criteria
|
||||
- **Inconsistent Format**: Ensure JSON output format is clearly specified
|
||||
- **Missing Context**: Include relevant variables for your use case
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Cohere
|
||||
description: "Reranking with Cohere"
|
||||
description: 'Enterprise-grade reranking with Cohere'
|
||||
icon: "building"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Cohere provides enterprise-grade reranking models with excellent multilingual support and production-ready performance.
|
||||
@@ -35,10 +37,10 @@ config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4.1-nano-2025-04-14"
|
||||
"model": "gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
"reranker": {
|
||||
"rerank": {
|
||||
"provider": "cohere",
|
||||
"config": {
|
||||
"model": "rerank-english-v3.0",
|
||||
@@ -122,13 +124,13 @@ config = {
|
||||
|
||||
## Configuration Parameters
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| -------------------- | -------------------------------- | ------ | ----------------------- |
|
||||
| `model` | Cohere rerank model to use | `str` | `"rerank-english-v3.0"` |
|
||||
| `api_key` | Cohere API key | `str` | `None` |
|
||||
| `top_k` | Maximum documents to return | `int` | `None` |
|
||||
| `return_documents` | Whether to return document texts | `bool` | `False` |
|
||||
| `max_chunks_per_doc` | Maximum chunks per document | `int` | `None` |
|
||||
| Parameter | Description | Type | Default |
|
||||
|-----------|-------------|------|---------|
|
||||
| `model` | Cohere rerank model to use | `str` | `"rerank-english-v3.0"` |
|
||||
| `api_key` | Cohere API key | `str` | `None` |
|
||||
| `top_k` | Maximum documents to return | `int` | `None` |
|
||||
| `return_documents` | Whether to return document texts | `bool` | `False` |
|
||||
| `max_chunks_per_doc` | Maximum chunks per document | `int` | `None` |
|
||||
|
||||
## Features
|
||||
|
||||
@@ -142,4 +144,4 @@ config = {
|
||||
1. **Model Selection**: Use `rerank-english-v3.0` for English, `rerank-multilingual-v3.0` for other languages
|
||||
2. **Batch Processing**: Process multiple queries efficiently
|
||||
3. **Error Handling**: Implement retry logic for production systems
|
||||
4. **Monitoring**: Track reranking performance and costs
|
||||
4. **Monitoring**: Track reranking performance and costs
|
||||
@@ -1,350 +0,0 @@
|
||||
---
|
||||
title: Hugging Face Reranker
|
||||
description: 'Access thousands of reranking models from Hugging Face Hub'
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The Hugging Face reranker provider gives you access to thousands of reranking models available on the Hugging Face Hub. This includes popular models like BAAI's BGE rerankers and other state-of-the-art cross-encoder models.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"device": "cpu"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `model` | str | Required | Hugging Face model identifier |
|
||||
| `device` | str | "cpu" | Device to run model on ("cpu", "cuda", "mps") |
|
||||
| `batch_size` | int | 32 | Batch size for processing |
|
||||
| `max_length` | int | 512 | Maximum input sequence length |
|
||||
| `trust_remote_code` | bool | False | Allow remote code execution |
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
```python
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-large",
|
||||
"device": "cuda",
|
||||
"batch_size": 16,
|
||||
"max_length": 512,
|
||||
"trust_remote_code": False,
|
||||
"model_kwargs": {
|
||||
"torch_dtype": "float16"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Popular Models
|
||||
|
||||
### BGE Rerankers (Recommended)
|
||||
|
||||
```python
|
||||
# Base model - good balance of speed and quality
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Large model - better quality, slower
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-large",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# v2 models - latest improvements
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-v2-m3",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Multilingual Models
|
||||
|
||||
```python
|
||||
# Multilingual BGE reranker
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-v2-multilingual",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Domain-Specific Models
|
||||
|
||||
```python
|
||||
# For code search
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "microsoft/codebert-base",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# For biomedical content
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "dmis-lab/biobert-base-cased-v1.1",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
m = Memory.from_config(config)
|
||||
|
||||
# Add some memories
|
||||
m.add("I love hiking in the mountains", user_id="alice")
|
||||
m.add("Pizza is my favorite food", user_id="alice")
|
||||
m.add("I enjoy reading science fiction books", user_id="alice")
|
||||
|
||||
# Search with reranking
|
||||
results = m.search(
|
||||
"What outdoor activities do I enjoy?",
|
||||
user_id="alice",
|
||||
rerank=True
|
||||
)
|
||||
|
||||
for result in results["results"]:
|
||||
print(f"Memory: {result['memory']}")
|
||||
print(f"Score: {result['score']:.3f}")
|
||||
```
|
||||
|
||||
### Batch Processing
|
||||
|
||||
```python
|
||||
# Process multiple queries efficiently
|
||||
queries = [
|
||||
"What are my hobbies?",
|
||||
"What food do I like?",
|
||||
"What books interest me?"
|
||||
]
|
||||
|
||||
results = []
|
||||
for query in queries:
|
||||
result = m.search(query, user_id="alice", rerank=True)
|
||||
results.append(result)
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### GPU Acceleration
|
||||
|
||||
```python
|
||||
# Use GPU for better performance
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"device": "cuda",
|
||||
"batch_size": 64, # Increase batch size for GPU
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Memory Optimization
|
||||
|
||||
```python
|
||||
# For limited memory environments
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"device": "cpu",
|
||||
"batch_size": 8, # Smaller batch size
|
||||
"max_length": 256, # Shorter sequences
|
||||
"model_kwargs": {
|
||||
"torch_dtype": "float16" # Half precision
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Model Comparison
|
||||
|
||||
| Model | Size | Quality | Speed | Memory | Best For |
|
||||
|-------|------|---------|-------|---------|----------|
|
||||
| bge-reranker-base | 278M | Good | Fast | Low | General use |
|
||||
| bge-reranker-large | 560M | Better | Medium | Medium | High quality needs |
|
||||
| bge-reranker-v2-m3 | 568M | Best | Medium | Medium | Latest improvements |
|
||||
| bge-reranker-v2-multilingual | 568M | Good | Medium | Medium | Multiple languages |
|
||||
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
try:
|
||||
results = m.search(
|
||||
"test query",
|
||||
user_id="alice",
|
||||
rerank=True
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Reranking failed: {e}")
|
||||
# Fall back to vector search only
|
||||
results = m.search(
|
||||
"test query",
|
||||
user_id="alice",
|
||||
rerank=False
|
||||
)
|
||||
```
|
||||
|
||||
## Custom Models
|
||||
|
||||
### Using Private Models
|
||||
|
||||
```python
|
||||
# Use a private model from Hugging Face
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "your-org/custom-reranker",
|
||||
"device": "cuda",
|
||||
"use_auth_token": "your-hf-token"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Local Model Path
|
||||
|
||||
```python
|
||||
# Use a locally downloaded model
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "/path/to/local/model",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Choose the Right Model**: Balance quality vs speed based on your needs
|
||||
2. **Use GPU**: Significantly faster than CPU for larger models
|
||||
3. **Optimize Batch Size**: Tune based on your hardware capabilities
|
||||
4. **Monitor Memory**: Watch GPU/CPU memory usage with large models
|
||||
5. **Cache Models**: Download once and reuse to avoid repeated downloads
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Out of Memory Error**
|
||||
```python
|
||||
# Reduce batch size and sequence length
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"batch_size": 4,
|
||||
"max_length": 256
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Model Download Issues**
|
||||
```python
|
||||
# Set cache directory
|
||||
import os
|
||||
os.environ["TRANSFORMERS_CACHE"] = "/path/to/cache"
|
||||
|
||||
# Or use offline mode
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"local_files_only": True
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**CUDA Not Available**
|
||||
```python
|
||||
import torch
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"device": "cuda" if torch.cuda.is_available() else "cpu"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Reranker Overview" icon="sort" href="/components/rerankers/overview">
|
||||
Learn about reranking concepts
|
||||
</Card>
|
||||
<Card title="Configuration Guide" icon="gear" href="/components/rerankers/config">
|
||||
Detailed configuration options
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -1,12 +1,10 @@
|
||||
---
|
||||
title: LLM as Reranker
|
||||
description: 'Flexible reranking using LLMs'
|
||||
title: LLM-based
|
||||
description: 'Flexible reranking using any Large Language Model'
|
||||
icon: "robot"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
**This page has been superseded.** Please see [LLM Reranker](/components/rerankers/models/llm_reranker) for the complete and up-to-date documentation on using LLMs for reranking.
|
||||
</Warning>
|
||||
|
||||
LLM-based reranker provides maximum flexibility by using any Large Language Model to score document relevance. This approach allows for custom prompts and domain-specific scoring logic.
|
||||
|
||||
## Supported LLM Providers
|
||||
@@ -39,7 +37,7 @@ config = {
|
||||
"model": "gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
"reranker": {
|
||||
"rerank": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
@@ -73,7 +71,7 @@ Score from 0.0 to 1.0 where:
|
||||
|
||||
Provide only a single numerical score between 0.0 and 1.0."""
|
||||
|
||||
config["reranker"]["config"]["scoring_prompt"] = custom_prompt
|
||||
config["rerank"]["config"]["scoring_prompt"] = custom_prompt
|
||||
```
|
||||
|
||||
## Usage Example
|
||||
@@ -89,7 +87,7 @@ os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
config = {
|
||||
"vector_store": {"provider": "chroma"},
|
||||
"llm": {"provider": "openai", "config": {"model": "gpt-4o-mini"}},
|
||||
"reranker": {
|
||||
"rerank": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
@@ -120,16 +118,6 @@ for result in results['results']:
|
||||
print()
|
||||
```
|
||||
|
||||
```text Output
|
||||
Memory: I'm learning Python programming
|
||||
Vector Score: 0.856
|
||||
Rerank Score: 0.920
|
||||
|
||||
Memory: I find object-oriented programming challenging
|
||||
Vector Score: 0.782
|
||||
Rerank Score: 0.850
|
||||
```
|
||||
|
||||
## Domain-Specific Scoring
|
||||
|
||||
Create specialized scoring for your domain:
|
||||
@@ -149,7 +137,7 @@ Consider:
|
||||
Score from 0.0 to 1.0. Provide only the numerical score."""
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"rerank": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
@@ -168,7 +156,7 @@ Use different LLM providers for reranking:
|
||||
```python Python
|
||||
# Using Anthropic Claude
|
||||
anthropic_config = {
|
||||
"reranker": {
|
||||
"rerank": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "claude-3-haiku-20240307",
|
||||
@@ -180,8 +168,8 @@ anthropic_config = {
|
||||
|
||||
# Using local Ollama model
|
||||
ollama_config = {
|
||||
"reranker": {
|
||||
"provider": "llm",
|
||||
"rerank": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "llama2:7b",
|
||||
"provider": "ollama",
|
||||
|
||||
@@ -1,489 +0,0 @@
|
||||
---
|
||||
title: LLM Reranker
|
||||
description: 'Use any language model as a reranker with custom prompts'
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The LLM reranker allows you to use any supported language model as a reranker. This approach uses prompts to instruct the LLM to score and rank memories based on their relevance to the query. While slower than specialized rerankers, it offers maximum flexibility and can be fine-tuned with custom prompts.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4",
|
||||
"api_key": "your-openai-api-key"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `llm` | dict | Required | LLM configuration object |
|
||||
| `top_k` | int | 10 | Number of results to rerank |
|
||||
| `temperature` | float | 0.0 | LLM temperature for consistency |
|
||||
| `custom_prompt` | str | None | Custom reranking prompt |
|
||||
| `score_range` | tuple | (0, 10) | Score range for relevance |
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
```python
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "anthropic",
|
||||
"config": {
|
||||
"model": "claude-3-sonnet-20240229",
|
||||
"api_key": "your-anthropic-api-key"
|
||||
}
|
||||
},
|
||||
"top_k": 15,
|
||||
"temperature": 0.0,
|
||||
"score_range": (1, 5),
|
||||
"custom_prompt": """
|
||||
Rate the relevance of each memory to the query on a scale of 1-5.
|
||||
Consider semantic similarity, context, and practical utility.
|
||||
Only provide the numeric score.
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Supported LLM Providers
|
||||
|
||||
### OpenAI
|
||||
|
||||
```python
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4",
|
||||
"api_key": "your-openai-api-key",
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Anthropic
|
||||
|
||||
```python
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "anthropic",
|
||||
"config": {
|
||||
"model": "claude-3-sonnet-20240229",
|
||||
"api_key": "your-anthropic-api-key"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Ollama (Local)
|
||||
|
||||
```python
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "ollama",
|
||||
"config": {
|
||||
"model": "llama2",
|
||||
"ollama_base_url": "http://localhost:11434"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Azure OpenAI
|
||||
|
||||
```python
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "azure_openai",
|
||||
"config": {
|
||||
"model": "gpt-4",
|
||||
"api_key": "your-azure-api-key",
|
||||
"azure_endpoint": "https://your-resource.openai.azure.com/",
|
||||
"azure_deployment": "gpt-4-deployment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Prompts
|
||||
|
||||
### Default Prompt Behavior
|
||||
|
||||
The default prompt asks the LLM to score relevance on a 0-10 scale:
|
||||
|
||||
```
|
||||
Given a query and a memory, rate how relevant the memory is to answering the query.
|
||||
Score from 0 (completely irrelevant) to 10 (perfectly relevant).
|
||||
Only provide the numeric score.
|
||||
|
||||
Query: {query}
|
||||
Memory: {memory}
|
||||
Score:
|
||||
```
|
||||
|
||||
### Custom Prompt Examples
|
||||
|
||||
#### Domain-Specific Scoring
|
||||
|
||||
```python
|
||||
custom_prompt = """
|
||||
You are a medical information specialist. Rate how relevant each memory is for answering the medical query.
|
||||
Consider clinical accuracy, specificity, and practical applicability.
|
||||
Rate from 1-10 where:
|
||||
- 1-3: Irrelevant or potentially harmful
|
||||
- 4-6: Somewhat relevant but incomplete
|
||||
- 7-8: Relevant and helpful
|
||||
- 9-10: Highly relevant and clinically useful
|
||||
|
||||
Query: {query}
|
||||
Memory: {memory}
|
||||
Score:
|
||||
"""
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4",
|
||||
"api_key": "your-api-key"
|
||||
}
|
||||
},
|
||||
"custom_prompt": custom_prompt
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Contextual Relevance
|
||||
|
||||
```python
|
||||
contextual_prompt = """
|
||||
Rate how well this memory answers the specific question asked.
|
||||
Consider:
|
||||
- Direct relevance to the question
|
||||
- Completeness of information
|
||||
- Recency and accuracy
|
||||
- Practical usefulness
|
||||
|
||||
Rate 1-5:
|
||||
1 = Not relevant
|
||||
2 = Slightly relevant
|
||||
3 = Moderately relevant
|
||||
4 = Very relevant
|
||||
5 = Perfectly answers the question
|
||||
|
||||
Query: {query}
|
||||
Memory: {memory}
|
||||
Score:
|
||||
"""
|
||||
```
|
||||
|
||||
#### Conversational Context
|
||||
|
||||
```python
|
||||
conversation_prompt = """
|
||||
You are helping evaluate which memories are most useful for a conversational AI assistant.
|
||||
Rate how helpful this memory would be for generating a relevant response.
|
||||
|
||||
Consider:
|
||||
- Direct relevance to user's intent
|
||||
- Emotional appropriateness
|
||||
- Factual accuracy
|
||||
- Conversation flow
|
||||
|
||||
Rate 0-10:
|
||||
Query: {query}
|
||||
Memory: {memory}
|
||||
Score:
|
||||
"""
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
m = Memory.from_config(config)
|
||||
|
||||
# Add memories
|
||||
m.add("I'm allergic to peanuts", user_id="alice")
|
||||
m.add("I love Italian food", user_id="alice")
|
||||
m.add("I'm vegetarian", user_id="alice")
|
||||
|
||||
# Search with LLM reranking
|
||||
results = m.search(
|
||||
"What foods should I avoid?",
|
||||
user_id="alice",
|
||||
rerank=True
|
||||
)
|
||||
|
||||
for result in results["results"]:
|
||||
print(f"Memory: {result['memory']}")
|
||||
print(f"LLM Score: {result['score']:.2f}")
|
||||
```
|
||||
|
||||
### Batch Processing with Error Handling
|
||||
|
||||
```python
|
||||
def safe_llm_rerank_search(query, user_id, max_retries=3):
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
return m.search(query, user_id=user_id, rerank=True)
|
||||
except Exception as e:
|
||||
print(f"Attempt {attempt + 1} failed: {e}")
|
||||
if attempt == max_retries - 1:
|
||||
# Fall back to vector search
|
||||
return m.search(query, user_id=user_id, rerank=False)
|
||||
|
||||
# Use the safe function
|
||||
results = safe_llm_rerank_search("What are my preferences?", "alice")
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Speed vs Quality Trade-offs
|
||||
|
||||
| Model Type | Speed | Quality | Cost | Best For |
|
||||
|------------|-------|---------|------|----------|
|
||||
| GPT-3.5 Turbo | Fast | Good | Low | High-volume applications |
|
||||
| GPT-4 | Medium | Excellent | Medium | Quality-critical applications |
|
||||
| Claude 3 Sonnet | Medium | Excellent | Medium | Balanced performance |
|
||||
| Ollama Local | Variable | Good | Free | Privacy-sensitive applications |
|
||||
|
||||
### Optimization Strategies
|
||||
|
||||
```python
|
||||
# Fast configuration for high-volume use
|
||||
fast_config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-3.5-turbo",
|
||||
"api_key": "your-api-key"
|
||||
}
|
||||
},
|
||||
"top_k": 5, # Limit candidates
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# High-quality configuration
|
||||
quality_config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4",
|
||||
"api_key": "your-api-key"
|
||||
}
|
||||
},
|
||||
"top_k": 15,
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Use Cases
|
||||
|
||||
### Multi-Step Reasoning
|
||||
|
||||
```python
|
||||
reasoning_prompt = """
|
||||
Evaluate this memory's relevance using multi-step reasoning:
|
||||
|
||||
1. What is the main intent of the query?
|
||||
2. What key information does the memory contain?
|
||||
3. How directly does the memory address the query?
|
||||
4. What additional context might be needed?
|
||||
|
||||
Based on this analysis, rate relevance 1-10:
|
||||
|
||||
Query: {query}
|
||||
Memory: {memory}
|
||||
|
||||
Analysis:
|
||||
Step 1 (Intent):
|
||||
Step 2 (Information):
|
||||
Step 3 (Directness):
|
||||
Step 4 (Context):
|
||||
Final Score:
|
||||
"""
|
||||
```
|
||||
|
||||
### Comparative Ranking
|
||||
|
||||
```python
|
||||
comparative_prompt = """
|
||||
You will see a query and multiple memories. Rank them in order of relevance.
|
||||
Consider which memories best answer the question and would be most helpful.
|
||||
|
||||
Query: {query}
|
||||
|
||||
Memories to rank:
|
||||
{memories}
|
||||
|
||||
Provide scores 1-10 for each memory, considering their relative usefulness.
|
||||
"""
|
||||
```
|
||||
|
||||
### Emotional Intelligence
|
||||
|
||||
```python
|
||||
emotional_prompt = """
|
||||
Consider both factual relevance and emotional appropriateness.
|
||||
Rate how suitable this memory is for responding to the user's query.
|
||||
|
||||
Factors to consider:
|
||||
- Factual accuracy and relevance
|
||||
- Emotional tone and sensitivity
|
||||
- User's likely emotional state
|
||||
- Appropriateness of response
|
||||
|
||||
Query: {query}
|
||||
Memory: {memory}
|
||||
Emotional Context: {context}
|
||||
Score (1-10):
|
||||
"""
|
||||
```
|
||||
|
||||
## Error Handling and Fallbacks
|
||||
|
||||
```python
|
||||
class RobustLLMReranker:
|
||||
def __init__(self, primary_config, fallback_config=None):
|
||||
self.primary = Memory.from_config(primary_config)
|
||||
self.fallback = Memory.from_config(fallback_config) if fallback_config else None
|
||||
|
||||
def search(self, query, user_id, max_retries=2):
|
||||
# Try primary LLM reranker
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
return self.primary.search(query, user_id=user_id, rerank=True)
|
||||
except Exception as e:
|
||||
print(f"Primary reranker attempt {attempt + 1} failed: {e}")
|
||||
|
||||
# Try fallback reranker
|
||||
if self.fallback:
|
||||
try:
|
||||
return self.fallback.search(query, user_id=user_id, rerank=True)
|
||||
except Exception as e:
|
||||
print(f"Fallback reranker failed: {e}")
|
||||
|
||||
# Final fallback: vector search only
|
||||
return self.primary.search(query, user_id=user_id, rerank=False)
|
||||
|
||||
# Usage
|
||||
primary_config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {"llm": {"provider": "openai", "config": {"model": "gpt-4"}}}
|
||||
}
|
||||
}
|
||||
|
||||
fallback_config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {"llm": {"provider": "openai", "config": {"model": "gpt-3.5-turbo"}}}
|
||||
}
|
||||
}
|
||||
|
||||
reranker = RobustLLMReranker(primary_config, fallback_config)
|
||||
results = reranker.search("What are my preferences?", "alice")
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use Specific Prompts**: Tailor prompts to your domain and use case
|
||||
2. **Set Temperature to 0**: Ensure consistent scoring across runs
|
||||
3. **Limit Top-K**: Don't rerank too many candidates to control costs
|
||||
4. **Implement Fallbacks**: Always have a backup plan for API failures
|
||||
5. **Monitor Costs**: Track API usage, especially with expensive models
|
||||
6. **Cache Results**: Consider caching reranking results for repeated queries
|
||||
7. **Test Prompts**: Experiment with different prompts to find what works best
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Inconsistent Scores**
|
||||
- Set temperature to 0.0
|
||||
- Use more specific prompts
|
||||
- Consider using multiple calls and averaging
|
||||
|
||||
**API Rate Limits**
|
||||
- Implement exponential backoff
|
||||
- Use cheaper models for high-volume scenarios
|
||||
- Add retry logic with delays
|
||||
|
||||
**Poor Ranking Quality**
|
||||
- Refine your custom prompt
|
||||
- Try different LLM models
|
||||
- Add examples to your prompt
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Custom Prompts Guide" icon="pencil" href="/components/rerankers/custom-prompts">
|
||||
Learn to craft effective reranking prompts
|
||||
</Card>
|
||||
<Card title="Performance Optimization" icon="bolt" href="/components/rerankers/optimization">
|
||||
Optimize LLM reranker performance
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Sentence Transformer
|
||||
description: 'Local reranking with HuggingFace cross-encoder models'
|
||||
icon: "server"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Sentence Transformer reranker provides local reranking using HuggingFace cross-encoder models, perfect for privacy-focused deployments where you want to keep data on-premises.
|
||||
@@ -65,7 +67,7 @@ config = {
|
||||
"config": {
|
||||
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
|
||||
"device": "cuda", # Use GPU
|
||||
"batch_size": 64 # high batch size for high memory GPUs
|
||||
"batch_size": 64 # Larger batch size for GPU
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
---
|
||||
title: Zero Entropy
|
||||
description: 'Neural reranking with Zero Entropy'
|
||||
description: 'State-of-the-art neural reranking with Zero Entropy'
|
||||
icon: "sparkles"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
[Zero Entropy](https://www.zeroentropy.dev) provides neural reranking models that significantly improve search relevance with fast performance.
|
||||
[Zero Entropy](https://www.zeroentropy.dev) provides state-of-the-art neural reranking models that significantly improve search relevance with fast performance.
|
||||
|
||||
## Models
|
||||
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
---
|
||||
title: Performance Optimization
|
||||
---
|
||||
|
||||
Optimizing reranker performance is crucial for maintaining fast search response times while improving result quality. This guide covers best practices for different reranker types.
|
||||
|
||||
## General Optimization Principles
|
||||
|
||||
### Candidate Set Size
|
||||
The number of candidates sent to the reranker significantly impacts performance:
|
||||
|
||||
```python
|
||||
# Optimal candidate sizes for different rerankers
|
||||
config_map = {
|
||||
"cohere": {"initial_candidates": 100, "top_n": 10},
|
||||
"sentence_transformer": {"initial_candidates": 50, "top_n": 10},
|
||||
"huggingface": {"initial_candidates": 30, "top_n": 5},
|
||||
"llm_reranker": {"initial_candidates": 20, "top_n": 5}
|
||||
}
|
||||
```
|
||||
|
||||
### Batching Strategy
|
||||
Process multiple queries efficiently:
|
||||
|
||||
```python
|
||||
# Configure for batch processing
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "sentence_transformer",
|
||||
"config": {
|
||||
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
|
||||
"batch_size": 16, # Process multiple candidates at once
|
||||
"top_n": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Provider-Specific Optimizations
|
||||
|
||||
### Cohere Optimization
|
||||
|
||||
```python
|
||||
# Optimized Cohere configuration
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "cohere",
|
||||
"config": {
|
||||
"model": "rerank-english-v3.0",
|
||||
"top_n": 10,
|
||||
"max_chunks_per_doc": 10, # Limit chunk processing
|
||||
"return_documents": False # Reduce response size
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Best Practices:**
|
||||
- Use v3.0 models for better speed/accuracy balance
|
||||
- Limit candidates to 100 or fewer
|
||||
- Cache API responses when possible
|
||||
- Monitor API rate limits
|
||||
|
||||
### Sentence Transformer Optimization
|
||||
|
||||
```python
|
||||
# Performance-optimized configuration
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "sentence_transformer",
|
||||
"config": {
|
||||
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
|
||||
"device": "cuda", # Use GPU when available
|
||||
"batch_size": 32,
|
||||
"top_n": 10,
|
||||
"max_length": 512 # Limit input length
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Device Optimization:**
|
||||
```python
|
||||
import torch
|
||||
|
||||
# Auto-detect best device
|
||||
device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu"
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "sentence_transformer",
|
||||
"config": {
|
||||
"device": device,
|
||||
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Hugging Face Optimization
|
||||
|
||||
```python
|
||||
# Optimized for Hugging Face models
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"use_fp16": True, # Half precision for speed
|
||||
"max_length": 512,
|
||||
"batch_size": 8,
|
||||
"top_n": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### LLM Reranker Optimization
|
||||
|
||||
```python
|
||||
# Optimized LLM reranker configuration
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-3.5-turbo", # Faster than gpt-4
|
||||
"temperature": 0, # Deterministic results
|
||||
"max_tokens": 500 # Limit response length
|
||||
}
|
||||
},
|
||||
"batch_ranking": True, # Rank multiple at once
|
||||
"top_n": 5, # Fewer results for faster processing
|
||||
"timeout": 10 # Request timeout
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Monitoring
|
||||
|
||||
### Latency Tracking
|
||||
```python
|
||||
import time
|
||||
from mem0 import Memory
|
||||
|
||||
def measure_reranker_performance(config, queries, user_id):
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
latencies = []
|
||||
for query in queries:
|
||||
start_time = time.time()
|
||||
results = memory.search(query, user_id=user_id)
|
||||
latency = time.time() - start_time
|
||||
latencies.append(latency)
|
||||
|
||||
return {
|
||||
"avg_latency": sum(latencies) / len(latencies),
|
||||
"max_latency": max(latencies),
|
||||
"min_latency": min(latencies)
|
||||
}
|
||||
```
|
||||
|
||||
### Memory Usage Monitoring
|
||||
```python
|
||||
import psutil
|
||||
import os
|
||||
|
||||
def monitor_memory_usage():
|
||||
process = psutil.Process(os.getpid())
|
||||
return {
|
||||
"memory_mb": process.memory_info().rss / 1024 / 1024,
|
||||
"memory_percent": process.memory_percent()
|
||||
}
|
||||
```
|
||||
|
||||
## Caching Strategies
|
||||
|
||||
### Result Caching
|
||||
```python
|
||||
from functools import lru_cache
|
||||
import hashlib
|
||||
|
||||
class CachedReranker:
|
||||
def __init__(self, config):
|
||||
self.memory = Memory.from_config(config)
|
||||
self.cache_size = 1000
|
||||
|
||||
@lru_cache(maxsize=1000)
|
||||
def search_cached(self, query_hash, user_id):
|
||||
return self.memory.search(query, user_id=user_id)
|
||||
|
||||
def search(self, query, user_id):
|
||||
query_hash = hashlib.md5(f"{query}_{user_id}".encode()).hexdigest()
|
||||
return self.search_cached(query_hash, user_id)
|
||||
```
|
||||
|
||||
### Model Caching
|
||||
```python
|
||||
# Pre-load models to avoid initialization overhead
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "sentence_transformer",
|
||||
"config": {
|
||||
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
|
||||
"cache_folder": "/path/to/model/cache",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Parallel Processing
|
||||
|
||||
### Async Configuration
|
||||
```python
|
||||
import asyncio
|
||||
from mem0 import Memory
|
||||
|
||||
async def parallel_search(config, queries, user_id):
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
# Process multiple queries concurrently
|
||||
tasks = [
|
||||
memory.search_async(query, user_id=user_id)
|
||||
for query in queries
|
||||
]
|
||||
|
||||
results = await asyncio.gather(*tasks)
|
||||
return results
|
||||
```
|
||||
|
||||
## Hardware Optimization
|
||||
|
||||
### GPU Configuration
|
||||
```python
|
||||
# Optimize for GPU usage
|
||||
import torch
|
||||
|
||||
if torch.cuda.is_available():
|
||||
torch.cuda.set_per_process_memory_fraction(0.8) # Reserve GPU memory
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "sentence_transformer",
|
||||
"config": {
|
||||
"device": "cuda",
|
||||
"model": "cross-encoder/ms-marco-electra-base",
|
||||
"batch_size": 64, # Larger batch for GPU
|
||||
"fp16": True # Half precision
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CPU Optimization
|
||||
```python
|
||||
import torch
|
||||
|
||||
# Optimize CPU threading
|
||||
torch.set_num_threads(4) # Adjust based on your CPU
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "sentence_transformer",
|
||||
"config": {
|
||||
"device": "cpu",
|
||||
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
|
||||
"num_workers": 4 # Parallel processing
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Benchmarking Different Configurations
|
||||
|
||||
```python
|
||||
def benchmark_rerankers():
|
||||
configs = [
|
||||
{"provider": "cohere", "model": "rerank-english-v3.0"},
|
||||
{"provider": "sentence_transformer", "model": "cross-encoder/ms-marco-MiniLM-L-6-v2"},
|
||||
{"provider": "huggingface", "model": "BAAI/bge-reranker-base"}
|
||||
]
|
||||
|
||||
test_queries = ["sample query 1", "sample query 2", "sample query 3"]
|
||||
|
||||
results = {}
|
||||
for config in configs:
|
||||
provider = config["provider"]
|
||||
performance = measure_reranker_performance(
|
||||
{"reranker": {"provider": provider, "config": config}},
|
||||
test_queries,
|
||||
"test_user"
|
||||
)
|
||||
results[provider] = performance
|
||||
|
||||
return results
|
||||
```
|
||||
|
||||
## Production Best Practices
|
||||
|
||||
1. **Model Selection**: Choose the right balance of speed vs. accuracy
|
||||
2. **Resource Allocation**: Monitor CPU/GPU usage and memory consumption
|
||||
3. **Error Handling**: Implement fallbacks for reranker failures
|
||||
4. **Load Balancing**: Distribute reranking load across multiple instances
|
||||
5. **Monitoring**: Track latency, throughput, and error rates
|
||||
6. **Caching**: Cache frequent queries and model predictions
|
||||
7. **Batch Processing**: Group similar queries for efficient processing
|
||||
@@ -1,78 +1,47 @@
|
||||
---
|
||||
title: Overview
|
||||
description: 'Pick the right reranker path to boost Mem0 search relevance.'
|
||||
icon: "arrow-up-arrow-down"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 rerankers rescore vector search hits so your agents surface the most relevant memories. Use this hub to decide when reranking helps, configure a provider, and fine-tune performance.
|
||||
Mem0 includes built-in support for various reranking providers to improve the relevance of memory search results. Rerankers post-process initial vector search results by re-scoring and re-ordering them using more sophisticated relevance models.
|
||||
|
||||
<Info>
|
||||
Reranking trades extra latency for better precision. Start once you have baseline search working and measure before/after relevance.
|
||||
</Info>
|
||||
## Usage
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card
|
||||
title="Understand Reranking"
|
||||
description="See how reranker-enhanced search changes your retrieval flow."
|
||||
icon="search"
|
||||
href="/open-source/features/reranker-search"
|
||||
/>
|
||||
<Card
|
||||
title="Configure Providers"
|
||||
description="Add reranker blocks to your memory configuration."
|
||||
icon="settings"
|
||||
href="/components/rerankers/config"
|
||||
/>
|
||||
<Card
|
||||
title="Optimize Performance"
|
||||
description="Balance relevance, latency, and cost with tuning tactics."
|
||||
icon="speedometer"
|
||||
href="/components/rerankers/optimization"
|
||||
/>
|
||||
<Card
|
||||
title="Custom Prompts"
|
||||
description="Shape LLM-based reranking with tailored instructions."
|
||||
icon="code"
|
||||
href="/components/rerankers/custom-prompts"
|
||||
/>
|
||||
<Card
|
||||
title="Zero Entropy Guide"
|
||||
description="Adopt the managed neural reranker for production workloads."
|
||||
icon="sparkles"
|
||||
href="/components/rerankers/models/zero_entropy"
|
||||
/>
|
||||
<Card
|
||||
title="Sentence Transformers"
|
||||
description="Keep reranking on-device with cross-encoder models."
|
||||
icon="cpu"
|
||||
href="/components/rerankers/models/sentence_transformer"
|
||||
/>
|
||||
</CardGroup>
|
||||
To use a reranker, you must provide a `rerank` configuration section in your memory config. If no reranker is configured, search results will rely on vector similarity scoring alone.
|
||||
|
||||
## Picking the Right Reranker
|
||||
For comprehensive configuration parameters for each reranker, please refer to [Config](./config).
|
||||
|
||||
- **API-first** when you need top quality and can absorb request costs (Cohere, Zero Entropy).
|
||||
- **Self-hosted** for privacy-sensitive deployments that must stay on your hardware (Sentence Transformer, Hugging Face).
|
||||
- **LLM-driven** when you need bespoke scoring logic or complex prompts.
|
||||
- **Hybrid** by enabling reranking only on premium journeys to control spend.
|
||||
## How Reranking Works
|
||||
|
||||
## Implementation Checklist
|
||||
1. **Initial Search**: Vector similarity search retrieves candidate memories
|
||||
2. **Reranking**: Selected reranker re-scores candidates using advanced models
|
||||
3. **Final Results**: Re-ordered results with both vector and rerank scores
|
||||
|
||||
1. Confirm baseline search KPIs so you can measure uplift.
|
||||
2. Select a provider and add the `reranker` block to your config.
|
||||
3. Test latency impact with production-like query batches.
|
||||
4. Decide whether to enable reranking globally or per-search via the `rerank` flag.
|
||||
<Note>
|
||||
Reranking operates as a post-processing step and can significantly improve search relevance at the cost of additional latency and API calls.
|
||||
</Note>
|
||||
|
||||
## Supported Rerankers
|
||||
|
||||
See the list of supported rerankers below.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Set Up Reranking"
|
||||
description="Walk through the configuration fields and defaults."
|
||||
icon="settings"
|
||||
href="/components/rerankers/config"
|
||||
/>
|
||||
<Card
|
||||
title="Example: Reranker Search"
|
||||
description="Follow the feature guide to see reranking in action."
|
||||
icon="rocket"
|
||||
href="/open-source/features/reranker-search"
|
||||
/>
|
||||
<Card title="Zero Entropy" href="/components/rerankers/models/zero_entropy" />
|
||||
<Card title="Cohere" href="/components/rerankers/models/cohere" />
|
||||
<Card title="Sentence Transformer" href="/components/rerankers/models/sentence_transformer" />
|
||||
<Card title="LLM-based" href="/components/rerankers/models/llm" />
|
||||
</CardGroup>
|
||||
|
||||
## When to Use Reranking
|
||||
|
||||
- **Improved Relevance**: When vector search alone doesn't provide sufficiently relevant results
|
||||
- **Domain-Specific Queries**: For specialized terminology or context that benefits from advanced models
|
||||
- **Quality vs Speed Trade-off**: When you can accept higher latency for better search quality
|
||||
- **Production Systems**: Where search quality directly impacts user experience
|
||||
|
||||
Choose the reranker that best fits your use case:
|
||||
- **Zero Entropy**: Best balance of speed and quality for general use
|
||||
- **Cohere**: Enterprise-grade with excellent multilingual support
|
||||
- **Sentence Transformer**: Local deployment for privacy-sensitive applications
|
||||
- **LLM-based**: Maximum customization with custom prompts and logic
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## How to define configurations?
|
||||
|
||||
@@ -27,7 +27,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -107,13 +107,13 @@ To enable Role-Based Access Control (RBAC) for Azure AI Search, follow these ste
|
||||
- Click **Add** > **Add role assignment**.
|
||||
6. **Choose Role:**
|
||||
- Mem0 requires the **Search Index Data Contributor** and **Search Service Contributor** role.
|
||||
7. **Choose Member**
|
||||
- To assign to a User, Group, Service Principal or Managed Identity:
|
||||
7. **Choose Member**
|
||||
- To assign to a User, Group, Service Principle or Managed Identity:
|
||||
- For production it is recommended to use a service principal or managed identity.
|
||||
- For a service principal: select **User, group, or service principal** and search for the service principal.
|
||||
- For a managed identity: select **Managed identity** and choose the managed identity.
|
||||
- For development, you can assign the role to a user account.
|
||||
- For development: select **User, group, or service principal** and pick an Azure Entra ID account (the same used with `az login`).
|
||||
- For development: select ***User, group, or service principal** and pick a Azure Entra ID account (the same used with `az login`).
|
||||
8. **Complete the Assignment:**
|
||||
- Click **Review + Assign**.
|
||||
|
||||
@@ -133,7 +133,7 @@ config = {
|
||||
}
|
||||
```
|
||||
|
||||
### Environment Variables to Use Azure Identity Credential
|
||||
### Environment Variables to set to use Azure Identity Credential:
|
||||
* For an Environment Credential, you will need to setup a Service Principal and set the following environment variables:
|
||||
- `AZURE_TENANT_ID`: Your Azure Active Directory tenant ID.
|
||||
- `AZURE_CLIENT_ID`: The client ID of your service principal or managed identity.
|
||||
@@ -142,7 +142,7 @@ config = {
|
||||
- `AZURE_CLIENT_ID`: The client ID of the user-assigned managed identity.
|
||||
* For a System-Assigned Managed Identity, no additional environment variables are needed.
|
||||
|
||||
### Developer Logins for Azure Identity Credential
|
||||
### Developer logins to use for a Azure Identity Credential:
|
||||
* For an Azure CLI Credential, you need to have the Azure CLI installed and logged in with `az login`.
|
||||
* For an Azure PowerShell Credential, you need to have the Azure PowerShell module installed and logged in with `Connect-AzAccount`.
|
||||
* For an Azure Developer CLI Credential, you need to have the Azure Developer CLI installed and logged in with `azd auth login`.
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
---
|
||||
title: Azure MySQL
|
||||
---
|
||||
|
||||
[Azure Database for MySQL](https://azure.microsoft.com/products/mysql) is a fully managed relational database service that provides enterprise-grade reliability and security. It supports JSON-based vector storage for semantic search capabilities in AI applications.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "azure_mysql",
|
||||
"config": {
|
||||
"host": "your-server.mysql.database.azure.com",
|
||||
"port": 3306,
|
||||
"user": "your_username",
|
||||
"password": "your_password",
|
||||
"database": "mem0_db",
|
||||
"collection_name": "memories",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
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."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
#### Using Azure Managed Identity
|
||||
|
||||
For production deployments, use Azure Managed Identity instead of passwords:
|
||||
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "azure_mysql",
|
||||
"config": {
|
||||
"host": "your-server.mysql.database.azure.com",
|
||||
"user": "your_username",
|
||||
"database": "mem0_db",
|
||||
"collection_name": "memories",
|
||||
"use_azure_credential": True, # Uses DefaultAzureCredential
|
||||
"ssl_disabled": False
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
When `use_azure_credential` is enabled, the password is obtained via Azure DefaultAzureCredential (supports Managed Identity, Azure CLI, etc.)
|
||||
</Note>
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Azure MySQL:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `host` | MySQL server hostname | Required |
|
||||
| `port` | MySQL server port | `3306` |
|
||||
| `user` | Database user | Required |
|
||||
| `password` | Database password (optional with Azure credential) | `None` |
|
||||
| `database` | Database name | Required |
|
||||
| `collection_name` | Table name for storing vectors | `"mem0"` |
|
||||
| `embedding_model_dims` | Dimensions of embedding vectors | `1536` |
|
||||
| `use_azure_credential` | Use Azure DefaultAzureCredential | `False` |
|
||||
| `ssl_ca` | Path to SSL CA certificate | `None` |
|
||||
| `ssl_disabled` | Disable SSL (not recommended) | `False` |
|
||||
| `minconn` | Minimum connections in pool | `1` |
|
||||
| `maxconn` | Maximum connections in pool | `5` |
|
||||
|
||||
### Setup
|
||||
|
||||
#### Create MySQL Flexible Server using Azure CLI:
|
||||
|
||||
```bash
|
||||
# Create resource group
|
||||
az group create --name mem0-rg --location eastus
|
||||
|
||||
# Create MySQL Flexible Server
|
||||
az mysql flexible-server create \
|
||||
--resource-group mem0-rg \
|
||||
--name mem0-mysql-server \
|
||||
--location eastus \
|
||||
--admin-user myadmin \
|
||||
--admin-password <YourPassword> \
|
||||
--version 8.0.21
|
||||
|
||||
# Create database
|
||||
az mysql flexible-server db create \
|
||||
--resource-group mem0-rg \
|
||||
--server-name mem0-mysql-server \
|
||||
--database-name mem0_db
|
||||
|
||||
# Configure firewall
|
||||
az mysql flexible-server firewall-rule create \
|
||||
--resource-group mem0-rg \
|
||||
--name mem0-mysql-server \
|
||||
--rule-name AllowMyIP \
|
||||
--start-ip-address <YourIP> \
|
||||
--end-ip-address <YourIP>
|
||||
```
|
||||
|
||||
#### Enable Azure AD Authentication:
|
||||
|
||||
1. In Azure Portal, navigate to your MySQL Flexible Server
|
||||
2. Go to **Security** > **Authentication** and enable Azure AD
|
||||
3. Add your application's managed identity as a MySQL user:
|
||||
|
||||
```sql
|
||||
CREATE AADUSER 'your-app-identity' IDENTIFIED BY 'your-client-id';
|
||||
GRANT ALL PRIVILEGES ON mem0_db.* TO 'your-app-identity'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
<Tip>
|
||||
For production, use [Managed Identity](https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/) to eliminate password management.
|
||||
</Tip>
|
||||
@@ -37,7 +37,7 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Baidu VectorDB:
|
||||
Here are the available parameters for the `mochow` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
---
|
||||
title: Apache Cassandra
|
||||
---
|
||||
|
||||
[Apache Cassandra](https://cassandra.apache.org/) is a highly scalable, distributed NoSQL database designed for handling large amounts of data across many commodity servers with no single point of failure. It supports vector storage for semantic search capabilities in AI applications and can scale to massive datasets with linear performance improvements.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "cassandra",
|
||||
"config": {
|
||||
"contact_points": ["127.0.0.1"],
|
||||
"port": 9042,
|
||||
"username": "cassandra",
|
||||
"password": "cassandra",
|
||||
"keyspace": "mem0",
|
||||
"collection_name": "memories",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
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."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
#### Using DataStax Astra DB
|
||||
|
||||
For managed Cassandra with DataStax Astra DB:
|
||||
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "cassandra",
|
||||
"config": {
|
||||
"contact_points": ["dummy"], # Not used with secure connect bundle
|
||||
"username": "token",
|
||||
"password": "AstraCS:...", # Your Astra DB application token
|
||||
"keyspace": "mem0",
|
||||
"collection_name": "memories",
|
||||
"secure_connect_bundle": "/path/to/secure-connect-bundle.zip"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
When using DataStax Astra DB, provide the secure connect bundle path. The contact_points parameter is ignored when a secure connect bundle is provided.
|
||||
</Note>
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Apache Cassandra:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `contact_points` | List of contact point IP addresses | Required |
|
||||
| `port` | Cassandra port | `9042` |
|
||||
| `username` | Database username | `None` |
|
||||
| `password` | Database password | `None` |
|
||||
| `keyspace` | Keyspace name | `"mem0"` |
|
||||
| `collection_name` | Table name for storing vectors | `"memories"` |
|
||||
| `embedding_model_dims` | Dimensions of embedding vectors | `1536` |
|
||||
| `secure_connect_bundle` | Path to Astra DB secure connect bundle | `None` |
|
||||
| `protocol_version` | CQL protocol version | `4` |
|
||||
| `load_balancing_policy` | Custom load balancing policy | `None` |
|
||||
|
||||
### Setup
|
||||
|
||||
#### Option 1: Local Cassandra Setup using Docker:
|
||||
|
||||
```bash
|
||||
# Pull and run Cassandra container
|
||||
docker run --name mem0-cassandra \
|
||||
-p 9042:9042 \
|
||||
-e CASSANDRA_CLUSTER_NAME="Mem0Cluster" \
|
||||
-d cassandra:latest
|
||||
|
||||
# Wait for Cassandra to start (may take 1-2 minutes)
|
||||
docker exec -it mem0-cassandra cqlsh
|
||||
|
||||
# Create keyspace
|
||||
CREATE KEYSPACE IF NOT EXISTS mem0
|
||||
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
|
||||
```
|
||||
|
||||
#### Option 2: DataStax Astra DB (Managed Cloud):
|
||||
|
||||
1. Sign up at [DataStax Astra](https://astra.datastax.com/)
|
||||
2. Create a new database
|
||||
3. Download the secure connect bundle
|
||||
4. Generate an application token
|
||||
|
||||
<Tip>
|
||||
For production deployments, use DataStax Astra DB for fully managed Cassandra with automatic scaling, backups, and security.
|
||||
</Tip>
|
||||
|
||||
#### Option 3: Install Cassandra Locally:
|
||||
|
||||
**Ubuntu/Debian:**
|
||||
```bash
|
||||
# Add Apache Cassandra repository
|
||||
echo "deb https://downloads.apache.org/cassandra/debian 40x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list
|
||||
curl https://downloads.apache.org/cassandra/KEYS | sudo apt-key add -
|
||||
|
||||
# Install Cassandra
|
||||
sudo apt-get update
|
||||
sudo apt-get install cassandra
|
||||
|
||||
# Start Cassandra
|
||||
sudo systemctl start cassandra
|
||||
|
||||
# Verify installation
|
||||
nodetool status
|
||||
```
|
||||
|
||||
**macOS:**
|
||||
```bash
|
||||
# Using Homebrew
|
||||
brew install cassandra
|
||||
|
||||
# Start Cassandra
|
||||
brew services start cassandra
|
||||
|
||||
# Connect to CQL shell
|
||||
cqlsh
|
||||
```
|
||||
|
||||
### Python Client Installation
|
||||
|
||||
Install the required Python package:
|
||||
|
||||
```bash
|
||||
pip install cassandra-driver
|
||||
```
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
- **Replication Factor**: For production, use replication factor of at least 3
|
||||
- **Consistency Level**: Balance between consistency and performance (QUORUM recommended)
|
||||
- **Partitioning**: Cassandra automatically distributes data across nodes
|
||||
- **Scaling**: Add nodes to linearly increase capacity and performance
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
```python
|
||||
from cassandra.policies import DCAwareRoundRobinPolicy
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "cassandra",
|
||||
"config": {
|
||||
"contact_points": ["node1.example.com", "node2.example.com", "node3.example.com"],
|
||||
"port": 9042,
|
||||
"username": "mem0_user",
|
||||
"password": "secure_password",
|
||||
"keyspace": "mem0_prod",
|
||||
"collection_name": "memories",
|
||||
"protocol_version": 4,
|
||||
"load_balancing_policy": DCAwareRoundRobinPolicy(local_dc='DC1')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
For production use, configure appropriate replication strategies and consistency levels based on your availability and consistency requirements.
|
||||
</Warning>
|
||||
|
||||
@@ -26,7 +26,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -31,7 +31,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -40,7 +40,7 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Elasticsearch:
|
||||
Let's see the available parameters for the `elasticsearch` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| ---------------------- | -------------------------------------------------- | ------------- |
|
||||
|
||||
@@ -22,7 +22,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -38,7 +38,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -64,12 +64,12 @@ const memory = new Memory(config);
|
||||
|
||||
const 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: "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." }
|
||||
]
|
||||
|
||||
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
|
||||
memory.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[Milvus](https://milvus.io/) is an open-source vector database that suits AI applications of every size, from running a demo chatbot in a Jupyter notebook to building web-scale search that serves billions of users.
|
||||
[Milvus](https://milvus.io/) Milvus is an open-source vector database that suits AI applications of every size from running a demo chatbot in Jupyter notebook to building web-scale search that serves billions of users.
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -11,7 +11,7 @@ config = {
|
||||
"provider": "milvus",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"embedding_model_dims": 1536,
|
||||
"embedding_model_dims": "123",
|
||||
"url": "127.0.0.1",
|
||||
"token": "8e4b8ca8cf2c67",
|
||||
"db_name": "my_database",
|
||||
@@ -22,7 +22,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -31,7 +31,7 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Milvus:
|
||||
Here's the parameters available for configuring Milvus Database:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
|
||||
@@ -24,7 +24,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -40,6 +40,6 @@ Here are the parameters available for configuring MongoDB:
|
||||
| db_name | Name of the MongoDB database | `"mem0_db"` |
|
||||
| collection_name | Name of the MongoDB collection | `"mem0_collection"` |
|
||||
| embedding_model_dims | Dimensions of the embedding vectors | `1536` |
|
||||
| mongo_uri | The MongoDB URI connection string | `mongodb://username:password@localhost:27017` |
|
||||
| mongo_uri | The mongo URI connection string | mongodb://username:password@localhost:27017 |
|
||||
|
||||
> **Note**: If `mongo_uri` is not provided, it will default to `mongodb://username:password@localhost:27017`.
|
||||
> **Note**: If Mongo_uri is not provided it will default to mongodb://username:password@localhost:27017.
|
||||
|
||||
@@ -58,7 +58,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -74,8 +74,8 @@ results = m.search("What kind of movies does Alice like?", user_id="alice")
|
||||
### Features
|
||||
|
||||
- Fast and Efficient Vector Search
|
||||
- Can be deployed on-premises, in containers, or on cloud platforms like AWS OpenSearch Service
|
||||
- Multiple authentication and security methods (Basic Authentication, API Keys, LDAP, SAML, and OpenID Connect)
|
||||
- Can be deployed on-premises, in containers, or on cloud platforms like AWS OpenSearch Service.
|
||||
- Multiple Authentication and Security Methods (Basic Authentication, API Keys, LDAP, SAML, and OpenID Connect)
|
||||
- Automatic index creation with optimized mappings for vector search
|
||||
- Memory optimization through disk-based vector search and quantization
|
||||
- Real-time analytics and observability
|
||||
- Memory Optimization through Disk-Based Vector Search and Quantization
|
||||
- Real-Time Analytics and Observability
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[pgvector](https://github.com/pgvector/pgvector) is an open-source vector similarity search extension for Postgres. After connecting to Postgres, run `CREATE EXTENSION IF NOT EXISTS vector;` to create the vector extension.
|
||||
[pgvector](https://github.com/pgvector/pgvector) is open-source vector similarity search for Postgres. After connecting with postgres run `CREATE EXTENSION IF NOT EXISTS vector;` to create the vector extension.
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -24,7 +24,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -54,7 +54,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
@@ -64,7 +64,7 @@ await memory.add(messages, { userId: "alice", metadata: { category: "movies" } }
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring pgvector:
|
||||
Here's the parameters available for configuring pgvector:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
|
||||
@@ -33,7 +33,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
|
||||
@@ -23,7 +23,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -48,7 +48,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -34,7 +34,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -60,7 +60,7 @@ const config = {
|
||||
const memory = new Memory(config);
|
||||
const 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": "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."}
|
||||
]
|
||||
|
||||
@@ -28,7 +28,7 @@ config = {
|
||||
"provider": "s3_vectors",
|
||||
"config": {
|
||||
"vector_bucket_name": "my-mem0-vector-bucket",
|
||||
"collection_name": "my-memories-index",
|
||||
"index_name": "my-memories-index",
|
||||
"embedding_model_dims": 1536,
|
||||
"distance_metric": "cosine",
|
||||
"region_name": "us-east-1"
|
||||
@@ -48,15 +48,15 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Amazon S3 Vectors:
|
||||
Here are the available parameters for the `s3_vectors` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| ---------------------- | -------------------------------------------------------------------------------- | ------------------------------------- |
|
||||
| `vector_bucket_name` | The name of the S3 Vector bucket to use. It will be created if it doesn't exist. | Required |
|
||||
| `collection_name` | The name of the vector index within the bucket. | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model. Must match your embedder. | `1536` |
|
||||
| `distance_metric` | Distance metric for similarity search. Options: `cosine`, `euclidean`. | `cosine` |
|
||||
| `region_name` | The AWS region where the bucket and index reside. | `None` (uses default from AWS config) |
|
||||
| Parameter | Description | Default Value |
|
||||
| ---------------------- | -------------------------------------------------------------------- | ------------- |
|
||||
| `vector_bucket_name` | The name of the S3 Vector bucket to use. It will be created if it doesn't exist. | Required |
|
||||
| `index_name` | The name of the vector index within the bucket. | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model. Must match your embedder. | `1536` |
|
||||
| `distance_metric` | Distance metric for similarity search. Options: `cosine`, `euclidean`. | `cosine` |
|
||||
| `region_name` | The AWS region where the bucket and index reside. | `None` (uses default from AWS config) |
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
@@ -64,15 +64,15 @@ Your AWS identity (user or role) needs permissions to perform actions on S3 Vect
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3vectors:*",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3vectors:*",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
For production, it is recommended to scope down the resource ARN to your specific buckets and indexes.
|
||||
For production, it is recommended to scope down the resource ARN to your specific buckets and indexes.
|
||||
@@ -26,7 +26,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -53,7 +53,7 @@ const memory = new Memory(config);
|
||||
|
||||
const 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": "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."}
|
||||
]
|
||||
@@ -109,7 +109,7 @@ end;
|
||||
$$;
|
||||
```
|
||||
|
||||
Go to [Supabase](https://supabase.com/dashboard/projects) and run the above SQL migrations in the SQL Editor.
|
||||
Goto [Supabase](https://supabase.com/dashboard/projects) and run the above SQL migrations inside the SQL Editor.
|
||||
|
||||
### Config
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
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": "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."}
|
||||
]
|
||||
@@ -35,7 +35,7 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
## Parameters
|
||||
|
||||
Here are the parameters available for configuring Valkey:
|
||||
Let's see the available parameters for the `valkey` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
|
||||
@@ -31,7 +31,7 @@ await memory.add(messages, { userId: "bob", metadata: { interest: "books" } });
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Vectorize:
|
||||
Let's see the available parameters for the `vectorize` config:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
|
||||
@@ -37,7 +37,7 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Weaviate:
|
||||
Let's see the available parameters for the `weaviate` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 includes built-in support for various popular databases. Memory can utilize the database provided by the user, ensuring efficient use for specific needs.
|
||||
@@ -15,7 +17,7 @@ See the list of supported vector databases below.
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Qdrant" href="/components/vectordbs/dbs/qdrant"></Card>
|
||||
<Card title="Chroma" href="/components/vectordbs/dbs/chroma"></Card>
|
||||
<Card title="PGVector" href="/components/vectordbs/dbs/pgvector"></Card>
|
||||
<Card title="Pgvector" href="/components/vectordbs/dbs/pgvector"></Card>
|
||||
<Card title="Upstash Vector" href="/components/vectordbs/dbs/upstash-vector"></Card>
|
||||
<Card title="Milvus" href="/components/vectordbs/dbs/milvus"></Card>
|
||||
<Card title="Pinecone" href="/components/vectordbs/dbs/pinecone"></Card>
|
||||
@@ -42,10 +44,12 @@ For a comprehensive list of available parameters for vector database configurati
|
||||
|
||||
## Common issues
|
||||
|
||||
### Using Model with Different Dimensions
|
||||
### Using model with different dimensions
|
||||
|
||||
If you are using a customized model with different dimensions other than 1536 (for example, 768), you may encounter the following error:
|
||||
If you are using customized model, which is having different dimensions other than 1536
|
||||
for example 768, you may encounter below error:
|
||||
|
||||
`ValueError: shapes (0,1536) and (768,) not aligned: 1536 (dim 1) != 768 (dim 0)`
|
||||
|
||||
You can add `"embedding_model_dims": 768,` to the config of the vector_store to resolve this issue.
|
||||
you could add `"embedding_model_dims": 768,` to the config of the vector_store to overcome this issue.
|
||||
|
||||
|
||||
@@ -19,25 +19,25 @@ To contribute, follow these steps:
|
||||
4. **Code Quality Checks**:
|
||||
- Run **linting** to catch style issues
|
||||
- Ensure **all tests pass**
|
||||
5. **Submit a Pull Request**
|
||||
5. **Submit a Pull Request** 🚀
|
||||
|
||||
For detailed guidance on pull requests, refer to [GitHub's documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
|
||||
|
||||
---
|
||||
|
||||
## Dependency Management
|
||||
## 📦 Dependency Management
|
||||
|
||||
We use `hatch` as our package manager. Install it by following the [official instructions](https://hatch.pypa.io/latest/install/).
|
||||
|
||||
**Do NOT use `pip` or `conda` for dependency management.** Instead, follow these steps in order:
|
||||
⚠️ **Do NOT use `pip` or `conda` for dependency management.** Instead, follow these steps in order:
|
||||
|
||||
```bash
|
||||
# 1. Install base dependencies
|
||||
make install
|
||||
|
||||
# 2. Activate virtual environment (this will install dependencies)
|
||||
hatch shell # For default environment
|
||||
hatch -e dev_py_3_11 shell # For dev_py_3_11 (differences are mentioned in pyproject.toml)
|
||||
# 2. Activate virtual environment (this will install deps.)
|
||||
hatch shell (for default env)
|
||||
hatch -e dev_py_3_11 shell (for dev_py_3_11) (differences are mentioned in pyproject.toml)
|
||||
|
||||
# 3. Install all optional dependencies
|
||||
make install_all
|
||||
@@ -45,9 +45,9 @@ make install_all
|
||||
|
||||
---
|
||||
|
||||
## Development Standards
|
||||
## 🛠️ Development Standards
|
||||
|
||||
### Pre-commit Hooks
|
||||
### ✅ Pre-commit Hooks
|
||||
|
||||
Ensure `pre-commit` is installed before contributing:
|
||||
|
||||
@@ -55,7 +55,7 @@ Ensure `pre-commit` is installed before contributing:
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
### Linting with `ruff`
|
||||
### 🔍 Linting with `ruff`
|
||||
|
||||
Run the linter and fix any reported issues before submitting your PR:
|
||||
|
||||
@@ -63,7 +63,7 @@ Run the linter and fix any reported issues before submitting your PR:
|
||||
make lint
|
||||
```
|
||||
|
||||
### Code Formatting
|
||||
### 🎨 Code Formatting
|
||||
|
||||
To maintain a consistent code style, format your code:
|
||||
|
||||
@@ -71,7 +71,7 @@ To maintain a consistent code style, format your code:
|
||||
make format
|
||||
```
|
||||
|
||||
### Testing with `pytest`
|
||||
### 🧪 Testing with `pytest`
|
||||
|
||||
Run tests to verify functionality before submitting your PR:
|
||||
|
||||
@@ -79,14 +79,14 @@ Run tests to verify functionality before submitting your PR:
|
||||
make test
|
||||
```
|
||||
|
||||
**Note:** Some dependencies have been removed from the main dependencies to reduce package size. Run `make install_all` to install necessary dependencies before running tests.
|
||||
💡 **Note:** Some dependencies have been removed from the main dependencies to reduce package size. Run `make install_all` to install necessary dependencies before running tests.
|
||||
|
||||
---
|
||||
|
||||
## Release Process
|
||||
## 🚀 Release Process
|
||||
|
||||
Currently, releases are handled manually. We aim for frequent releases, typically when new features or bug fixes are introduced.
|
||||
|
||||
---
|
||||
|
||||
Thank you for contributing to Mem0!
|
||||
Thank you for contributing to Mem0! 🎉
|
||||
@@ -5,13 +5,13 @@ icon: "book"
|
||||
|
||||
# Documentation Contributions
|
||||
|
||||
## Prerequisites
|
||||
## 📌 Prerequisites
|
||||
|
||||
Before getting started, ensure you have **Node.js (version 23.6.0 or higher)** installed on your system.
|
||||
|
||||
---
|
||||
|
||||
## Setting Up Mintlify
|
||||
## 🚀 Setting Up Mintlify
|
||||
|
||||
### Step 1: Install Mintlify
|
||||
|
||||
@@ -41,7 +41,7 @@ The documentation website will be available at: [http://localhost:3000](http://l
|
||||
|
||||
---
|
||||
|
||||
## Custom Ports
|
||||
## 🔧 Custom Ports
|
||||
|
||||
By default, Mintlify runs on **port 3000**. To use a different port, add the `--port` flag:
|
||||
|
||||
@@ -51,5 +51,5 @@ mintlify dev --port 3333
|
||||
|
||||
---
|
||||
|
||||
By following these steps, you can efficiently contribute to Mem0's documentation.
|
||||
By following these steps, you can efficiently contribute to **Mem0's documentation**. Happy documenting! ✍️
|
||||
|
||||
|
||||
@@ -1,530 +0,0 @@
|
||||
---
|
||||
title: Build a Companion with Mem0
|
||||
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(
|
||||
query="injury concerns",
|
||||
filters={
|
||||
"AND": [
|
||||
{"user_id": "max"},
|
||||
{"categories": {"in": ["constraints"]}}
|
||||
]
|
||||
},
|
||||
threshold=0.0 # optional: widen recall for short phrases
|
||||
)
|
||||
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(filters={"AND": [{"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(filters={"AND": [{"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(filters={"AND": [{"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="Partition Memories by Entity" icon="layers" href="/cookbooks/essentials/entity-partitioning-playbook">
|
||||
Keep companions from leaking context by combining user, agent, and session scopes.
|
||||
</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>
|
||||
@@ -1,361 +0,0 @@
|
||||
---
|
||||
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="Partition Memories by Entity" icon="layers" href="/cookbooks/essentials/entity-partitioning-playbook">
|
||||
Scope memories across users, agents, apps, and sessions 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>
|
||||
@@ -1,523 +0,0 @@
|
||||
---
|
||||
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
|
||||
|
||||
<Warning>
|
||||
That “no duplicates” promise comes from the inference pipeline. Keep `infer=True` when you rely on automatic updates. Raw imports (`infer=False`) skip conflict checks, so mixing the two modes for the same fact will create duplicates.
|
||||
</Warning>
|
||||
|
||||
**Maintains relationships:**
|
||||
|
||||
- If using graph memory, connections to other entities persist
|
||||
|
||||
### Pick the right inference mode
|
||||
|
||||
| Mode | What it does | Best for | Watch out for |
|
||||
| --- | --- | --- | --- |
|
||||
| `infer=True` *(default)* | Runs the LLM pipeline so Mem0 extracts structured facts and resolves conflicts automatically. | Daily conversations, preference tracking, anything you want deduped. | Slightly slower because inference runs on every write. |
|
||||
| `infer=False` | Stores your payload exactly as-is—no inference, no dedupe. | Bulk imports, compliance snapshots, curated facts you already trust. | Later `infer=True` calls for the same fact will create duplicates you must clean manually. |
|
||||
|
||||
<Tip>
|
||||
Stay consistent per data source. If you need both behaviors, keep them in separate scopes (e.g., different `app_id` or `run_id`) so you always know which memories are inferred vs direct imports.
|
||||
</Tip>
|
||||
|
||||
---
|
||||
|
||||
## 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>
|
||||
@@ -1,336 +0,0 @@
|
||||
---
|
||||
title: Partition Memories by Entity
|
||||
description: Keep memories separate by tagging each write and query with user, agent, app, and session identifiers.
|
||||
---
|
||||
|
||||
Nora runs a travel service. When she stored all memories in one bucket, a recruiter's nut allergy accidentally appeared in a traveler's dinner reservation. Let's fix this by properly separating memories for different users, agents, and applications.
|
||||
|
||||
<Info icon="clock">
|
||||
**Time to complete:** ~15 minutes · **Languages:** Python
|
||||
</Info>
|
||||
|
||||
## Setup
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="m0-...")
|
||||
```
|
||||
|
||||
Grab an API key from the <Link href="https://app.mem0.ai/">Mem0 dashboard</Link> to get started.
|
||||
|
||||
## Store and Retrieve Scoped Memories
|
||||
|
||||
Let's start by storing Cam's travel preferences and retrieving them:
|
||||
|
||||
```python
|
||||
cam_messages = [
|
||||
{"role": "user", "content": "I'm Cam. Keep in mind I avoid shellfish and prefer boutique hotels."},
|
||||
{"role": "assistant", "content": "Noted! I'll use those preferences in future itineraries."}
|
||||
]
|
||||
|
||||
result = client.add(
|
||||
cam_messages,
|
||||
user_id="traveler_cam",
|
||||
agent_id="travel_planner",
|
||||
run_id="tokyo-2025-weekend",
|
||||
app_id="concierge_app"
|
||||
)
|
||||
```
|
||||
|
||||
The memory is now stored. Let's retrieve those memories with the same identifiers:
|
||||
|
||||
```python
|
||||
user_scope = {
|
||||
"AND": [
|
||||
{"user_id": "traveler_cam"},
|
||||
{"app_id": "concierge_app"},
|
||||
{"run_id": "tokyo-2025-weekend"}
|
||||
]
|
||||
}
|
||||
user_memories = client.search("Any dietary restrictions?", filters=user_scope)
|
||||
print(user_memories)
|
||||
|
||||
agent_scope = {
|
||||
"AND": [
|
||||
{"agent_id": "travel_planner"},
|
||||
{"app_id": "concierge_app"}
|
||||
]
|
||||
}
|
||||
agent_memories = client.search("Any dietary restrictions?", filters=agent_scope)
|
||||
print(agent_memories)
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
# User scope returns user's memory
|
||||
{'results': [{'memory': 'avoids shellfish and prefers boutique hotels', ...}]}
|
||||
# Agent scope returns agent's own memory
|
||||
{'results': [{'memory': 'Cam prefers boutique hotels and avoids shellfish', ...}]}
|
||||
```
|
||||
|
||||
<Tip icon="compass">
|
||||
Memories can be written with several identifiers, but each search resolves one entity boundary at a time. Run separate queries for user and agent scopes—just like above—rather than combining both in a single filter.
|
||||
</Tip>
|
||||
|
||||
## When Memories Leak
|
||||
|
||||
When Nora adds a chef agent, Cam's travel preferences leak into food recommendations:
|
||||
|
||||
```python
|
||||
chef_filters = {"AND": [{"user_id": "traveler_cam"}]}
|
||||
|
||||
collision = client.search("What should I cook?", filters=chef_filters)
|
||||
print(collision)
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
['avoids shellfish and prefers boutique hotels', 'prefers Kyoto kaiseki dining experiences']
|
||||
```
|
||||
|
||||
The travel preferences appear because we only filtered by `user_id`. The chef agent shouldn't see hotel preferences.
|
||||
|
||||
## Fix the Leak with Proper Filters
|
||||
|
||||
First, let's add a memory specifically for the chef agent:
|
||||
|
||||
```python
|
||||
chef_memory = [
|
||||
{"role": "user", "content": "I'd like to try some authentic Kyoto cuisine."},
|
||||
{"role": "assistant", "content": "I'll remember that you prefer Kyoto kaiseki dining experiences."}
|
||||
]
|
||||
|
||||
client.add(
|
||||
chef_memory,
|
||||
user_id="traveler_cam",
|
||||
agent_id="chef_recommender",
|
||||
run_id="menu-planning-2025-04",
|
||||
app_id="concierge_app"
|
||||
)
|
||||
```
|
||||
|
||||
Now search within the chef's scope:
|
||||
|
||||
```python
|
||||
safe_filters = {
|
||||
"AND": [
|
||||
{"agent_id": "chef_recommender"},
|
||||
{"app_id": "concierge_app"},
|
||||
{"run_id": "menu-planning-2025-04"}
|
||||
]
|
||||
}
|
||||
|
||||
chef_memories = client.search("Any food alerts?", filters=safe_filters)
|
||||
print(chef_memories)
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
{'results': [{'memory': 'prefers Kyoto kaiseki dining experiences', ...}]}
|
||||
```
|
||||
|
||||
Now the chef agent only sees its own food preferences. The hotel preferences stay with the travel agent.
|
||||
|
||||
## Separate Apps with app_id
|
||||
|
||||
Nora white-labels her travel service for a sports brand. Use `app_id` to keep enterprise data separate:
|
||||
|
||||
```python
|
||||
enterprise_filters = {
|
||||
"AND": [
|
||||
{"app_id": "sports_brand_portal"}
|
||||
],
|
||||
"OR": [
|
||||
{"user_id": "*"},
|
||||
{"agent_id": "*"}
|
||||
]
|
||||
}
|
||||
|
||||
page = client.get_all(filters=enterprise_filters, page=1, page_size=10)
|
||||
print([row["user_id"] for row in page["results"]])
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
['athlete_jane', 'coach_mike', 'team_admin']
|
||||
```
|
||||
|
||||
<Info>
|
||||
Wildcards (`"*"` ) only match non-null values. Make sure you write memories with explicit `app_id` values.
|
||||
</Info>
|
||||
|
||||
<Tip icon="sparkles">
|
||||
Need a deeper tour of AND vs OR, nested filters, or wildcard tricks? Check the <Link href="/platform/features/v2-memory-filters">Memory Filters v2 guide</Link> for full examples you can copy into this flow.
|
||||
</Tip>
|
||||
|
||||
When the sports brand offboards, delete all their data:
|
||||
|
||||
```python
|
||||
client.delete_all(app_id="sports_brand_portal")
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
{'message': 'Memories deleted successfully!'}
|
||||
```
|
||||
|
||||
## Production Patterns
|
||||
|
||||
```python
|
||||
# Nightly audits - check all data for an app
|
||||
def audit_app(app_id: str):
|
||||
filters = {
|
||||
"AND": [{"app_id": app_id}],
|
||||
"OR": [{"user_id": "*"}, {"agent_id": "*"}]
|
||||
}
|
||||
return client.get_all(filters=filters, page=1, page_size=50)
|
||||
|
||||
# Session cleanup - delete temporary conversations
|
||||
def close_ticket(ticket_id: str, user_id: str):
|
||||
client.delete_all(user_id=user_id, run_id=ticket_id)
|
||||
|
||||
# Compliance exports - get all data for one tenant
|
||||
export = client.get_memory_export(filters={"AND": [{"app_id": "sports_brand_portal"}]})
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
Putting it all together - here's how to properly scope memories:
|
||||
|
||||
```python
|
||||
# Store memories with all identifiers
|
||||
client.add(
|
||||
[{"role": "user", "content": "I need a hotel near the conference center."}],
|
||||
user_id="exec_123",
|
||||
agent_id="booking_assistant",
|
||||
app_id="enterprise_portal",
|
||||
run_id="trip-2025-03"
|
||||
)
|
||||
|
||||
# Retrieve with the same scope
|
||||
filters = {
|
||||
"AND": [
|
||||
{"user_id": "exec_123"},
|
||||
{"app_id": "enterprise_portal"},
|
||||
{"run_id": "trip-2025-03"}
|
||||
]
|
||||
}
|
||||
|
||||
# Alternative: Use wildcards if you're not sure about some fields
|
||||
# filters = {
|
||||
# "AND": [
|
||||
# {"user_id": "exec_123"},
|
||||
# {"agent_id": "*"}, # Match any agent
|
||||
# {"app_id": "enterprise_portal"},
|
||||
# {"run_id": "*"} # Match any run
|
||||
# ]
|
||||
# }
|
||||
|
||||
results = client.search("Hotels near conference", filters=filters)
|
||||
|
||||
# Debug: Print the filter you're using
|
||||
print(f"Searching with filters: {filters}")
|
||||
|
||||
# If no results, try a broader search to see what's stored
|
||||
if not results["results"]:
|
||||
print("No results found! Trying broader search...")
|
||||
broader = client.get_all(filters={"user_id": "exec_123"})
|
||||
print(broader)
|
||||
|
||||
print(results["results"][0]["memory"])
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
I need a hotel near the conference center.
|
||||
```
|
||||
|
||||
## When to Use Each Identifier
|
||||
|
||||
| Identifier | When to Use | Example Values |
|
||||
|------------|-------------|----------------|
|
||||
| `user_id` | Individual preferences that persist across all interactions | `cam_traveler`, `sarah_exec`, `team_alpha` |
|
||||
| `agent_id` | Different AI roles need separate context | `travel_agent`, `concierge`, `customer_support` |
|
||||
| `app_id` | White-label deployments or separate products | `travel_app_ios`, `enterprise_portal`, `partner_integration` |
|
||||
| `run_id` | Temporary sessions that should be isolated | `support_ticket_9234`, `chat_session_456`, `booking_flow_789` |
|
||||
|
||||
## Troubleshooting Common Issues
|
||||
|
||||
### My search returns empty results!
|
||||
|
||||
**Problem**: Using `AND` with exact matches but some fields might be `null`.
|
||||
|
||||
**Solution**:
|
||||
```python
|
||||
# If this returns nothing:
|
||||
filters = {"AND": [{"user_id": "u1"}, {"agent_id": "a1"}]}
|
||||
|
||||
# Try using wildcards:
|
||||
filters = {"AND": [{"user_id": "u1"}, {"agent_id": "*"}]}
|
||||
|
||||
# Or don't include fields you don't need:
|
||||
filters = {"AND": [{"user_id": "u1"}]}
|
||||
```
|
||||
|
||||
### OR gives results but AND doesn't
|
||||
|
||||
This confirms you have a **field mismatch**. The memory exists but some identifier values don't match exactly.
|
||||
|
||||
**Always check what's actually stored:**
|
||||
```python
|
||||
# Get all memories for the user to see the actual field values
|
||||
all_mems = client.get_all(filters={"user_id": "your_user_id"})
|
||||
print(json.dumps(all_mems, indent=2))
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use consistent identifier formats**
|
||||
```python
|
||||
# Good: consistent patterns
|
||||
user_id = "cam_traveler"
|
||||
agent_id = "travel_agent_v1"
|
||||
app_id = "nora_concierge_app"
|
||||
run_id = "tokyo_trip_2025_03"
|
||||
|
||||
# Avoid: mixed patterns
|
||||
# user_id = "123", agent_id = "agent2", app_id = "app"
|
||||
```
|
||||
|
||||
2. **Print filters when debugging**
|
||||
```python
|
||||
filters = {"AND": [{"user_id": "cam", "agent_id": "chef"}]}
|
||||
print(f"Searching with filters: {filters}") # Helps catch typos
|
||||
```
|
||||
|
||||
3. **Clean up temporary sessions**
|
||||
```python
|
||||
# After a support ticket closes
|
||||
client.delete_all(user_id="customer_123", run_id="ticket_456")
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
You learned how to:
|
||||
- Store memories with proper entity scoping using `user_id`, `agent_id`, `app_id`, and `run_id`
|
||||
- Prevent memory leaks between different agents and applications
|
||||
- Clean up data for specific tenants or sessions
|
||||
- Use wildcards to query across scoped memories
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Deep Dive: Memory Filters v2"
|
||||
description="Layer entity filters with JSON logic to answer complex queries."
|
||||
icon="sliders"
|
||||
href="/platform/features/v2-memory-filters"
|
||||
/>
|
||||
<Card
|
||||
title="Control Memory Ingestion"
|
||||
description="Pair scoped storage with rules that block low-quality facts."
|
||||
icon="shield-check"
|
||||
href="/cookbooks/essentials/controlling-memory-ingestion"
|
||||
/>
|
||||
</CardGroup>
|
||||
@@ -1,289 +0,0 @@
|
||||
---
|
||||
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>
|
||||
@@ -1,277 +0,0 @@
|
||||
---
|
||||
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>
|
||||
@@ -1,251 +0,0 @@
|
||||
---
|
||||
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>
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
title: Persistent Eliza Characters
|
||||
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="Partition Memories by Entity" icon="layers" href="/cookbooks/essentials/entity-partitioning-playbook">
|
||||
Keep character personas isolated by tagging user, agent, and session identifiers.
|
||||
</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>
|
||||
@@ -1,246 +0,0 @@
|
||||
---
|
||||
title: "Gemini 3 with Mem0 MCP"
|
||||
description: "Create snappy, smart, memory-aware agents by pairing Gemini 3 with Mem0 MCP server."
|
||||
---
|
||||
|
||||
Gemini 3, when paired with mem0-mcp-server, works in synergy to create snappy, smart, memory-aware agents.
|
||||
|
||||
<Callout type="info" icon="sparkles" color="#8B5CF6">
|
||||
This is the primary example of MCP integration - the same patterns work with Claude Desktop, Cursor, or any MCP-compatible client.
|
||||
</Callout>
|
||||
|
||||
## MCP Server Tools
|
||||
|
||||
The Mem0 MCP server provides these tools to Gemini:
|
||||
|
||||
| Tool | Description |
|
||||
| --------------------- | ---------------------------------------- |
|
||||
| `add_memory` | Store new information in memory |
|
||||
| `search_memories` | Find relevant memories |
|
||||
| `get_memories` | Retrieve specific memories by ID |
|
||||
| `get_memory` | Retrieve one memory by its `memory_id` |
|
||||
| `update_memory` | Modify existing memory content |
|
||||
| `delete_memory` | Remove specific memories |
|
||||
| `delete_all_memories` | Clear all memories for a user |
|
||||
| `delete_entities` | Delete all memories related to an entity |
|
||||
| `list_entities` | Enumerate users/agents/apps/runs stored |
|
||||
|
||||
## Setup
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
pip install pydantic-ai nest-asyncio python-dotenv uv google-genai
|
||||
```
|
||||
|
||||
### Environment Setup
|
||||
|
||||
Create a file named `.env`:
|
||||
|
||||
```bash
|
||||
MEM0_API_KEY=m0-xxxxxxxxxxxxxxxxx
|
||||
GEMINI_API_KEY=your-gemini-api-key-here
|
||||
MEM0_DEFAULT_USER_ID=demo-user
|
||||
```
|
||||
|
||||
<Note>
|
||||
Ensure you have your Mem0 API key from the [Mem0 Dashboard](https://app.mem0.ai) and your Gemini API key from the [Google AI Studio](https://ai.studio/app/api-keys).
|
||||
</Note>
|
||||
|
||||
## Gemini Memory Agent
|
||||
|
||||
This example shows how to create a memory-augmented agent using Gemini 3 through an agent loop.
|
||||
|
||||
<Info icon="document">
|
||||
Save this as <strong>gemini_agent.py</strong>:
|
||||
</Info>
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
from pydantic_ai import Agent
|
||||
from pydantic_ai.mcp import MCPServerStdio
|
||||
|
||||
# Load environment variables
|
||||
load_dotenv()
|
||||
|
||||
|
||||
class MemoryAgent:
|
||||
def __init__(self, model="gemini-3-pro-preview"):
|
||||
self.agent = None
|
||||
self.server = None
|
||||
self.model = model
|
||||
self._setup()
|
||||
|
||||
def _setup(self):
|
||||
"""Initialize the agent with MCP tools"""
|
||||
# Create MCP server directly
|
||||
self.server = MCPServerStdio(
|
||||
command="uvx",
|
||||
args=["mem0-mcp-server"],
|
||||
env=os.environ
|
||||
)
|
||||
|
||||
# Create agent with Gemini and memory tools
|
||||
self.agent = Agent(
|
||||
f"google-gla:{self.model}",
|
||||
toolsets=[self.server],
|
||||
system_prompt=(
|
||||
"You are an assistant with memory capabilities. "
|
||||
"Automatically remember important details about users, "
|
||||
"preferences, and facts. Search memories before answering "
|
||||
"questions about past information."
|
||||
),
|
||||
)
|
||||
print(f"Agent initialized with {self.model}")
|
||||
|
||||
async def chat(self, message):
|
||||
"""Send message and get response"""
|
||||
async with self.server:
|
||||
result = await self.agent.run(message)
|
||||
return result.output
|
||||
|
||||
async def interactive_chat(self):
|
||||
"""Run interactive chat session"""
|
||||
print("\nMemory Agent Ready! (Type 'quit' to exit)")
|
||||
|
||||
while True:
|
||||
try:
|
||||
user_input = input("\nYou: ").strip()
|
||||
if user_input.lower() in ["quit", "exit"]:
|
||||
print("Goodbye!")
|
||||
break
|
||||
|
||||
if not user_input:
|
||||
continue
|
||||
|
||||
response = await self.chat(user_input)
|
||||
print(f"\nAgent: {response}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nGoodbye!")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"\nError: {e}")
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main entry point"""
|
||||
agent = MemoryAgent()
|
||||
await agent.interactive_chat()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## Running the Agent
|
||||
|
||||
To run the interactive agent:
|
||||
|
||||
```bash
|
||||
python gemini_agent.py
|
||||
```
|
||||
|
||||
## Example Interactions
|
||||
|
||||
### Multi-Tool Capabilities
|
||||
*Shows Gemini generating synthetic data while simultaneously storing and searching in one request*
|
||||
|
||||
**Prompt:**
|
||||
```
|
||||
I need player statistics for a basketball team dashboard demo. Generate 5 synthetic player profiles with different positions, ages, and performance metrics, then store all of them. Also check if we have any existing player data in memory.
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```
|
||||
I've created and stored 5 synthetic player profiles for your basketball team dashboard demo:
|
||||
- Marcus Chen (32, Point Guard) - 12.5 PPG, 8.2 APG, 45% FG, 3 seasons with team
|
||||
- Jamal Williams (28, Center) - 18.7 PPG, 10.5 RPG, 2.3 BPG, rookie season
|
||||
- Carlos Rodriguez (35, Small Forward) - 15.3 PPG, 6.8 RPG, 38% 3PT, team captain
|
||||
- Tito Kawaguchi (24, Shooting Guard) - 22.1 PPG, 4.1 APG, 42% 3PT, 6th man of the year candidate
|
||||
- Viktor Petrov (30, Power Forward) - 14.8 PPG, 9.2 RPG, 52% FG, defensive specialist
|
||||
|
||||
I searched for existing player data in your memory but found none. All synthetic player profiles have been stored with appropriate basketball statistics for demo purposes.
|
||||
```
|
||||
|
||||
### Smart Query Generation
|
||||
*Demonstrates how Gemini transforms vague human input into optimal search queries*
|
||||
|
||||
**Prompt:**
|
||||
```
|
||||
Anything about my health I should know about?
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```
|
||||
Based on your memory history, I searched for health-related information using these queries: "medical", "allergies", "dietary restrictions", "exercise", "wellness", "doctor visits", "health conditions".
|
||||
|
||||
**Health Information Found:**
|
||||
- Allergies: Shellfish allergy
|
||||
- Dietary preferences: Weekday vegetarian, flexible weekends, dislikes kiwi
|
||||
- Exercise routine: 5km runs on weekday mornings
|
||||
- Diet: Oat milk cappuccino with one sugar (monitoring sugar intake recommended)
|
||||
|
||||
I don't see any medical conditions or recent doctor visits in your stored information.
|
||||
```
|
||||
|
||||
### Memory Attribution
|
||||
*Shows how Gemini distinguishes between stored memories and general knowledge*
|
||||
|
||||
**Prompt:**
|
||||
```
|
||||
What's my coffee order again?
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```
|
||||
Based on your stored memories, your coffee order is an oat milk cappuccino with one sugar.
|
||||
|
||||
This information was retrieved from your memory history where you previously mentioned this preference. I don't have any information about whether you've changed this preference recently.
|
||||
```
|
||||
|
||||
## Why Use Gemini with Mem0 MCP?
|
||||
|
||||
### How Mem0 Enhances Your Application
|
||||
|
||||
- **Smart Memory Management** - Organizes memories into searchable information *without setting up vector databases*
|
||||
- **Fast Retrieval** - Instant lookups with *sub-millisecond ping*, handles large datasets
|
||||
- **Graph Capabilities** - Builds knowledge *automatically* as you push information
|
||||
- **Simple Integration** - Uses Mem0 API in the backend, works with *any MCP client* with just a few lines of code
|
||||
|
||||
### Gemini 3 + Mem0 Benefits
|
||||
|
||||
- **Native function calling**: Built-in support for Mem0's memory tools
|
||||
- **Large context window**: Supports up to 1M tokens for extensive memory context
|
||||
- **Parallel execution**: Can call multiple memory tools simultaneously
|
||||
- **Cost-effective**: Competitive pricing for memory-intensive applications
|
||||
|
||||
## What You Built
|
||||
|
||||
- **Memory-augmented AI agent** - Gemini with persistent memory across sessions
|
||||
- **Automatic context management** - Agent automatically stores and retrieves relevant information
|
||||
- **Multi-tool parallel execution** - Simultaneous memory operations for efficiency
|
||||
- **Natural memory interface** - Users interact normally while agent manages memory behind the scenes
|
||||
|
||||
## Conclusion
|
||||
|
||||
You've successfully built a Gemini 3 agent with persistent memory using Mem0's MCP server. The agent can now remember user preferences, maintain context across sessions, and provide more personalized interactions.
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="MCP Integration Feature"
|
||||
description="Learn about MCP configuration options and deployment methods"
|
||||
icon="plug"
|
||||
href="/platform/features/mcp-integration"
|
||||
/>
|
||||
<Card
|
||||
title="MCP Quickstart"
|
||||
description="Get started with MCP for any AI client in minutes"
|
||||
icon="rocket"
|
||||
href="/platform/mem0-mcp"
|
||||
/>
|
||||
</CardGroup>
|
||||
@@ -1,228 +0,0 @@
|
||||
---
|
||||
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 Companion with Mem0"
|
||||
icon="users"
|
||||
href="/cookbooks/essentials/building-ai-companion"
|
||||
>
|
||||
Learn core memory lifecycle patterns.
|
||||
</Card>
|
||||
<Card
|
||||
title="Partition Memories by Entity"
|
||||
icon="server"
|
||||
href="/cookbooks/essentials/entity-partitioning-playbook"
|
||||
>
|
||||
Balance personalization with consistent behavior across users, agents, and apps.
|
||||
</Card>
|
||||
<Card
|
||||
title="Control Memory Ingestion"
|
||||
icon="filter"
|
||||
href="/cookbooks/essentials/controlling-memory-ingestion"
|
||||
>
|
||||
Filter speculation and low-confidence data.
|
||||
</Card>
|
||||
<Card
|
||||
title="Set Memory Expiration"
|
||||
icon="timer"
|
||||
href="/cookbooks/essentials/memory-expiration-short-and-long-term"
|
||||
>
|
||||
Short-term vs long-term retention strategies.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Companion Playbooks
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Interactive Memory Demo" icon="rocket" href="/cookbooks/companions/quickstart-demo">
|
||||
See Mem0 memories in action.
|
||||
</Card>
|
||||
<Card
|
||||
title="Research Assistant for YouTube"
|
||||
icon="video"
|
||||
href="/cookbooks/companions/youtube-research"
|
||||
>
|
||||
Personalized context for video browsing.
|
||||
</Card>
|
||||
<Card
|
||||
title="Voice-First AI Companion"
|
||||
icon="microphone"
|
||||
href="/cookbooks/companions/voice-companion-openai"
|
||||
>
|
||||
Voice-first experiences with Agents SDK.
|
||||
</Card>
|
||||
<Card title="Personalized AI Tutor" icon="graduation-cap" href="/cookbooks/companions/ai-tutor">
|
||||
Student progress persistent across sessions.
|
||||
</Card>
|
||||
<Card title="Smart Travel Assistant" icon="plane" href="/cookbooks/companions/travel-assistant">
|
||||
Itineraries that remember traveler preferences.
|
||||
</Card>
|
||||
<Card title="Build a Node.js Companion" icon="js" href="/cookbooks/companions/nodejs-companion">
|
||||
JavaScript fitness coach remembering goals.
|
||||
</Card>
|
||||
<Card
|
||||
title="Self-Hosted AI Companion"
|
||||
icon="server"
|
||||
href="/cookbooks/companions/local-companion-ollama"
|
||||
>
|
||||
Run Mem0 end-to-end with Ollama.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Ops & Automations
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Automated Email Intelligence"
|
||||
icon="envelope"
|
||||
href="/cookbooks/operations/email-automation"
|
||||
>
|
||||
Capture and recall inbox threads.
|
||||
</Card>
|
||||
<Card
|
||||
title="Content Creation Workflow"
|
||||
icon="pencil"
|
||||
href="/cookbooks/operations/content-writing"
|
||||
>
|
||||
Store tone and style guidelines.
|
||||
</Card>
|
||||
<Card
|
||||
title="Multi-Session Research Agent"
|
||||
icon="magnifying-glass"
|
||||
href="/cookbooks/operations/deep-research"
|
||||
>
|
||||
Multi-session investigations without repeating.
|
||||
</Card>
|
||||
<Card
|
||||
title="Memory-Powered Support Agent"
|
||||
icon="headset"
|
||||
href="/cookbooks/operations/support-inbox"
|
||||
>
|
||||
Past tickets at support fingertips.
|
||||
</Card>
|
||||
<Card
|
||||
title="Collaborative Task Assistant"
|
||||
icon="users"
|
||||
href="/cookbooks/operations/team-task-agent"
|
||||
>
|
||||
Coordinate multi-user projects with roles.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Integrations & Platforms
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Memory-Powered Agent SDK"
|
||||
icon="robot"
|
||||
href="/cookbooks/integrations/agents-sdk-tool"
|
||||
>
|
||||
Callable tools inside agent workflows.
|
||||
</Card>
|
||||
<Card
|
||||
title="Memory as OpenAI Tool"
|
||||
icon="wrench"
|
||||
href="/cookbooks/integrations/openai-tool-calls"
|
||||
>
|
||||
Memories in function-calling flows.
|
||||
</Card>
|
||||
<Card title="Persistent Mastra Agents" icon="code" href="/cookbooks/integrations/mastra-agent">
|
||||
Persistent memory for Mastra agents.
|
||||
</Card>
|
||||
<Card
|
||||
title="Healthcare Coach with ADK"
|
||||
icon="heart-pulse"
|
||||
href="/cookbooks/integrations/healthcare-google-adk"
|
||||
>
|
||||
Patient history across ADK sessions.
|
||||
</Card>
|
||||
<Card
|
||||
title="Search with Personal Context"
|
||||
icon="search"
|
||||
href="/cookbooks/integrations/tavily-search"
|
||||
>
|
||||
Realtime search with personal context.
|
||||
</Card>
|
||||
<Card
|
||||
title="Bedrock with Persistent Memory"
|
||||
icon="aws"
|
||||
href="/cookbooks/integrations/aws-bedrock"
|
||||
>
|
||||
Mem0 with AWS Bedrock and Neptune.
|
||||
</Card>
|
||||
<Card
|
||||
title="Graph Memory on Neptune"
|
||||
icon="network-wired"
|
||||
href="/cookbooks/integrations/neptune-analytics"
|
||||
>
|
||||
Graph memory with Neptune Analytics.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Frameworks & Multimodal
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="ReAct Agents with Memory" icon="brain" href="/cookbooks/frameworks/llamaindex-react">
|
||||
ReAct agents with memory storage.
|
||||
</Card>
|
||||
<Card
|
||||
title="Multi-Agent Collaboration"
|
||||
icon="users"
|
||||
href="/cookbooks/frameworks/llamaindex-multiagent"
|
||||
>
|
||||
Shared memory across collaborating agents.
|
||||
</Card>
|
||||
<Card
|
||||
title="Visual Memory Retrieval"
|
||||
icon="image"
|
||||
href="/cookbooks/frameworks/multimodal-retrieval"
|
||||
>
|
||||
Visual context alongside text conversations.
|
||||
</Card>
|
||||
<Card
|
||||
title="Persistent Eliza Characters"
|
||||
icon="robot"
|
||||
href="/cookbooks/frameworks/eliza-os-character"
|
||||
>
|
||||
Persistent personality for Eliza agents.
|
||||
</Card>
|
||||
<Card title="Browser Extension Memory" icon="globe" href="/cookbooks/frameworks/chrome-extension">
|
||||
Universal memory layer for Chrome.
|
||||
</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>
|
||||
@@ -5,56 +5,43 @@ icon: "plus"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
# How Mem0 Adds Memory
|
||||
|
||||
Adding memory is how Mem0 captures useful details from a conversation so your agents can reuse them later. Think of it as saving the important sentences from a chat transcript into a structured notebook your agent can search.
|
||||
## Overview
|
||||
|
||||
<Info>
|
||||
**Why it matters**
|
||||
- Preserves user preferences, goals, and feedback across sessions.
|
||||
- Powers personalization and decision-making in downstream conversations.
|
||||
- Keeps context consistent between managed Platform and OSS deployments.
|
||||
</Info>
|
||||
The `add` operation is how you store memory into Mem0. Whether you're working with a chatbot, a voice assistant, or a multi-agent system, this is the entry point to create long-term memory.
|
||||
|
||||
## Key terms
|
||||
Memories typically come from a **user-assistant interaction** and Mem0 handles the extraction, transformation, and storage for you.
|
||||
|
||||
- **Messages** – The ordered list of user/assistant turns you send to `add`.
|
||||
- **Infer** – Controls whether Mem0 extracts structured memories (`infer=True`, default) or stores raw messages.
|
||||
- **Metadata** – Optional filters (e.g., `{"category": "movie_recommendations"}`) that improve retrieval later.
|
||||
- **User / Session identifiers** – `user_id`, `session_id`, or `run_id` that scope the memory for future searches.
|
||||
Mem0 offers two implementation flows:
|
||||
|
||||
## How does it work?
|
||||
- **Mem0 Platform** (Managed, scalable, with dashboard + API)
|
||||
- **Mem0 Open Source** (Lightweight, fully local, flexible SDKs)
|
||||
|
||||
Mem0 offers two flows:
|
||||
Each supports the same core memory operations, but with slightly different setup. Below, we walk through examples for both.
|
||||
|
||||
- **Mem0 Platform** – Fully managed API with dashboard, scaling, and graph features.
|
||||
- **Mem0 Open Source** – Local SDK that you run in your own environment.
|
||||
|
||||
Both flows take the same payload and pass it through the same pipeline.
|
||||
## Architecture
|
||||
|
||||
<Frame caption="Architecture diagram illustrating the process of adding memories.">
|
||||
<img src="../../images/add_architecture.png" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="Information extraction">
|
||||
Mem0 sends the messages through an LLM that pulls out key facts, decisions, or preferences to remember.
|
||||
</Step>
|
||||
<Step title="Conflict resolution">
|
||||
Existing memories are checked for duplicates or contradictions so the latest truth wins.
|
||||
</Step>
|
||||
<Step title="Storage">
|
||||
The resulting memories land in managed vector storage (and optional graph storage) so future searches return them quickly.
|
||||
</Step>
|
||||
</Steps>
|
||||
When you call `add`, Mem0 performs the following steps under the hood:
|
||||
|
||||
<Warning>
|
||||
Duplicate protection only runs during that conflict-resolution step when you let Mem0 infer memories (`infer=True`, the default). If you switch to `infer=False`, Mem0 stores your payload exactly as provided, so duplicates will land. Mixing both modes for the same fact will save it twice.
|
||||
</Warning>
|
||||
1. **Information Extraction**
|
||||
The input messages are passed through an LLM that extracts key facts, decisions, preferences, or events worth remembering.
|
||||
|
||||
You trigger this pipeline with a single `add` call—no manual orchestration needed.
|
||||
2. **Conflict Resolution**
|
||||
Mem0 compares the new memory against existing ones to detect duplication or contradiction and handles updates accordingly.
|
||||
|
||||
## Add with Mem0 Platform
|
||||
3. **Memory Storage**
|
||||
The result is stored in a vector database (for semantic search) and optionally in a graph structure (for relationship mapping).
|
||||
|
||||
You don’t need to handle any of this manually, Mem0 takes care of it with a single API call or SDK method.
|
||||
|
||||
---
|
||||
|
||||
## Example: Mem0 Platform
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -70,6 +57,7 @@ messages = [
|
||||
client.add(
|
||||
messages=messages,
|
||||
user_id="alice",
|
||||
version="v2"
|
||||
)
|
||||
```
|
||||
|
||||
@@ -83,18 +71,17 @@ const messages = [
|
||||
{ role: "assistant", content: "Great! I’ll remember that for future suggestions." }
|
||||
];
|
||||
|
||||
await client.add(messages, {
|
||||
await client.add({
|
||||
messages,
|
||||
user_id: "alice",
|
||||
version: "v2",
|
||||
version: "v2"
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Info icon="check">
|
||||
Expect a `memory_id` (or list of IDs) in the response. Check the Mem0 dashboard to confirm the new entry under the correct user.
|
||||
</Info>
|
||||
---
|
||||
|
||||
## Add with Mem0 Open Source
|
||||
## Example: Mem0 Open Source
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -107,7 +94,7 @@ m = Memory()
|
||||
|
||||
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": "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."}
|
||||
]
|
||||
@@ -138,13 +125,7 @@ const result = memory.add(messages, {
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Tip>
|
||||
Use `infer=False` only when you need to store raw transcripts. Most workflows benefit from Mem0 extracting structured memories automatically.
|
||||
</Tip>
|
||||
|
||||
<Warning>
|
||||
If you do choose `infer=False`, keep it consistent. Raw inserts skip conflict resolution, so a later `infer=True` call with the same content will create a second memory instead of updating the first.
|
||||
</Warning>
|
||||
---
|
||||
|
||||
## When Should You Add Memory?
|
||||
|
||||
@@ -156,10 +137,6 @@ Add memory whenever your agent learns something useful:
|
||||
- A new entity is introduced
|
||||
- A user gives feedback or clarification
|
||||
|
||||
<Callout type="tip" icon="plug">
|
||||
**MCP Alternative**: With <Link href="/platform/mem0-mcp">Mem0 MCP</Link>, AI agents can add memories automatically based on context.
|
||||
</Callout>
|
||||
|
||||
Storing this context allows the agent to reason better in future interactions.
|
||||
|
||||
|
||||
@@ -168,38 +145,9 @@ Storing this context allows the agent to reason better in future interactions.
|
||||
For full list of supported fields, required formats, and advanced options, see the
|
||||
[Add Memory API Reference](/api-reference/memory/add-memories).
|
||||
|
||||
## Managed vs OSS differences
|
||||
---
|
||||
|
||||
| Capability | Mem0 Platform | Mem0 OSS |
|
||||
| --- | --- | --- |
|
||||
| Conflict resolution | Automatic with dashboard visibility | SDK handles merges locally; you control storage |
|
||||
| Graph writes | Toggle per request (`enable_graph=True`) | Requires configuring a graph provider |
|
||||
| Rate limits | Managed quotas per workspace | Limited by your hardware and provider APIs |
|
||||
| Dashboard visibility | Yes — inspect memories visually | Inspect via CLI, logs, or custom UI |
|
||||
## Need help?
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
## Put it into practice
|
||||
|
||||
- Review the <Link href="/platform/advanced-memory-operations">Advanced Memory Operations</Link> guide to layer metadata, rerankers, and graph toggles.
|
||||
- Explore the <Link href="/api-reference/memory/add-memories">Add Memories API reference</Link> for every request/response field.
|
||||
|
||||
## See it live
|
||||
|
||||
- <Link href="/cookbooks/operations/support-inbox">Support Inbox with Mem0</Link> shows add + search powering a support flow.
|
||||
- <Link href="/cookbooks/companions/ai-tutor">AI Tutor with Mem0</Link> uses add to personalize lesson plans.
|
||||
|
||||
{/* DEBUG: verify CTA targets */}
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Explore Search Concepts"
|
||||
description="See how stored memories feed retrieval in the Search guide."
|
||||
icon="search"
|
||||
href="/core-concepts/memory-operations/search"
|
||||
/>
|
||||
<Card
|
||||
title="Build a Support Agent"
|
||||
description="Follow the cookbook to apply add/search/update in production."
|
||||
icon="rocket"
|
||||
href="/cookbooks/operations/support-inbox"
|
||||
/>
|
||||
</CardGroup>
|
||||
<Snippet file="get-help.mdx"/>
|
||||
@@ -5,39 +5,27 @@ icon: "trash"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
# Remove Memories Safely
|
||||
## Overview
|
||||
|
||||
Deleting memories is how you honor compliance requests, undo bad data, or clean up expired sessions. Mem0 lets you delete a specific memory, a list of IDs, or everything that matches a filter.
|
||||
Memories can become outdated, irrelevant, or need to be removed for privacy or compliance reasons. Mem0 offers flexible ways to delete memory:
|
||||
|
||||
<Info>
|
||||
**Why it matters**
|
||||
- Satisfies user erasure (GDPR/CCPA) without touching the rest of your data.
|
||||
- Keeps knowledge bases accurate by removing stale or incorrect facts.
|
||||
- Works for both the managed Platform API and the OSS SDK.
|
||||
</Info>
|
||||
1. **Delete a Single Memory**: Using a specific memory ID
|
||||
2. **Batch Delete**: Delete multiple known memory IDs (up to 1000)
|
||||
3. **Filtered Delete**: Delete memories matching a filter (e.g., `user_id`, `metadata`, `run_id`)
|
||||
|
||||
## Key terms
|
||||
This page walks through code example for each method.
|
||||
|
||||
- **memory_id** – Unique ID returned by `add`/`search` identifying the record to delete.
|
||||
- **batch_delete** – API call that removes up to 1000 memories in one request.
|
||||
- **delete_all** – Filter-based deletion by user, agent, run, or metadata.
|
||||
- **immutable** – Flagged memories that cannot be updated; delete + re-add instead.
|
||||
|
||||
## How the delete flow works
|
||||
## Use Cases
|
||||
|
||||
<Steps>
|
||||
<Step title="Choose the scope">
|
||||
Decide whether you’re removing a single memory, a list, or everything that matches a filter.
|
||||
</Step>
|
||||
<Step title="Submit the delete call">
|
||||
Call `delete`, `batch_delete`, or `delete_all` with the required IDs or filters.
|
||||
</Step>
|
||||
<Step title="Verify">
|
||||
Confirm the response message, then re-run `search` or check the dashboard/logs to ensure the memory is gone.
|
||||
</Step>
|
||||
</Steps>
|
||||
- Forget a user’s past preferences by request
|
||||
- Remove outdated or incorrect memory entries
|
||||
- Clean up memory after session expiration
|
||||
- Comply with data deletion requests (e.g., GDPR)
|
||||
|
||||
## Delete a single memory (Platform)
|
||||
---
|
||||
|
||||
## 1. Delete a Single Memory by ID
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -60,11 +48,9 @@ client.delete("your_memory_id")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Info icon="check">
|
||||
You’ll receive a confirmation payload. The dashboard reflects the removal within seconds.
|
||||
</Info>
|
||||
---
|
||||
|
||||
## Batch delete multiple memories (Platform)
|
||||
## 2. Batch Delete Multiple Memories
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -97,7 +83,9 @@ client.batchDelete(deleteMemories)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Delete memories by filter (Platform)
|
||||
---
|
||||
|
||||
## 3. Delete Memories by Filter (e.g., user_id)
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -107,12 +95,6 @@ client = MemoryClient(api_key="your-api-key")
|
||||
|
||||
# Delete all memories for a specific user
|
||||
client.delete_all(user_id="alice")
|
||||
|
||||
# Delete all memories for a specific agent
|
||||
client.delete_all(agent_id="support-bot")
|
||||
|
||||
# Delete all memories for a specific run
|
||||
client.delete_all(run_id="session-xyz")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
@@ -127,115 +109,33 @@ client.deleteAll({ user_id: "alice" })
|
||||
</CodeGroup>
|
||||
|
||||
You can also filter by other parameters such as:
|
||||
|
||||
- `agent_id`
|
||||
- `run_id`
|
||||
- `metadata` (as JSON string)
|
||||
|
||||
<Warning>
|
||||
**Breaking change:** `delete_all` previously wiped all project memories when called with no filters. It now **raises an error** if no filters are provided. Use `"*"` wildcards for intentional bulk deletion (see below).
|
||||
</Warning>
|
||||
---
|
||||
|
||||
### Wildcard deletes
|
||||
## Key Differences
|
||||
|
||||
Setting a filter to `"*"` deletes **all memories** for that entity type across the entire project. This is an intentionally explicit opt-in to bulk deletion.
|
||||
| Method | Use When | IDs Needed | Filters |
|
||||
|----------------------|-------------------------------------------|------------|----------|
|
||||
| `delete(memory_id)` | You know exactly which memory to remove | ✔ | ✘ |
|
||||
| `batch_delete([...])`| You have a known list of memory IDs | ✔ | ✘ |
|
||||
| `delete_all(...)` | You want to delete by user/agent/run/etc | ✘ | ✔ |
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your-api-key")
|
||||
### More Details
|
||||
|
||||
# Delete all memories across every user in the project
|
||||
client.delete_all(user_id="*")
|
||||
For request/response schema and additional filtering options, see:
|
||||
- [Delete Memory API Reference](/api-reference/memory/delete-memory)
|
||||
- [Batch Delete API Reference](/api-reference/memory/batch-delete)
|
||||
- [Delete Memories by Filter Reference](/api-reference/memory/delete-memories)
|
||||
|
||||
# Delete all memories across every agent in the project
|
||||
client.delete_all(agent_id="*")
|
||||
You’ve now seen how to add, search, update, and delete memories in Mem0.
|
||||
|
||||
# Full project wipe — all four filters must be explicitly set to "*"
|
||||
client.delete_all(user_id="*", agent_id="*", app_id="*", run_id="*")
|
||||
```
|
||||
---
|
||||
|
||||
```javascript JavaScript
|
||||
import MemoryClient from 'mem0ai';
|
||||
## Need help?
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
const client = new MemoryClient({ apiKey: "your-api-key" });
|
||||
|
||||
// Delete all memories across every user in the project
|
||||
client.deleteAll({ user_id: "*" })
|
||||
.then(result => console.log(result))
|
||||
.catch(error => console.error(error));
|
||||
|
||||
// Full project wipe — all four filters must be explicitly set to "*"
|
||||
client.deleteAll({ user_id: "*", agent_id: "*", app_id: "*", run_id: "*" })
|
||||
.then(result => console.log(result))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Warning>
|
||||
A full project wipe requires **all four** filters set to `"*"`. Setting only some to `"*"` deletes memories only for those entity types, not the entire project.
|
||||
</Warning>
|
||||
|
||||
## Delete with Mem0 OSS
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
|
||||
memory = Memory()
|
||||
|
||||
memory.delete(memory_id="mem_123")
|
||||
memory.delete_all(user_id="alice")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
The OSS JavaScript SDK does not yet expose deletion helpers—use the REST API or Python SDK when self-hosting.
|
||||
</Note>
|
||||
|
||||
## Use cases recap
|
||||
|
||||
- Forget a user’s preferences at their request.
|
||||
- Remove outdated or incorrect facts before they spread.
|
||||
- Clean up memories after session expiration or retention deadlines.
|
||||
- Comply with privacy legislation (GDPR, CCPA) and internal policies.
|
||||
|
||||
<Callout type="tip" icon="plug">
|
||||
**MCP Alternative**: With <Link href="/platform/mem0-mcp">Mem0 MCP</Link>, AI agents can delete their own memories when data becomes irrelevant or at user request.
|
||||
</Callout>
|
||||
|
||||
## Method comparison
|
||||
|
||||
| Method | Use when | IDs required | Filters |
|
||||
| --- | --- | --- | --- |
|
||||
| `delete(memory_id)` | You know the exact record | ✔️ | ✖️ |
|
||||
| `batch_delete([...])` | You have a list of IDs to purge | ✔️ | ✖️ |
|
||||
| `delete_all(...)` | You need to forget a user/agent/run | ✖️ | ✔️ |
|
||||
|
||||
## Put it into practice
|
||||
|
||||
- Review the <Link href="/api-reference/memory/delete-memory">Delete Memory API reference</Link>, plus <Link href="/api-reference/memory/batch-delete">Batch Delete</Link> and <Link href="/api-reference/memory/delete-memories">Filtered Delete</Link>.
|
||||
- Pair deletes with <Link href="/platform/features/expiration-date">Expiration Policies</Link> to automate retention.
|
||||
|
||||
## See it live
|
||||
|
||||
- <Link href="/cookbooks/operations/support-inbox">Support Inbox with Mem0</Link> demonstrates compliance-driven deletes.
|
||||
- <Link href="/platform/features/direct-import">Data Management tooling</Link> shows how deletes fit into broader lifecycle flows.
|
||||
|
||||
{/* DEBUG: verify CTA targets */}
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Review Add Concepts"
|
||||
description="Ensure the memories you keep are structured from the start."
|
||||
icon="circle-check"
|
||||
href="/core-concepts/memory-operations/add"
|
||||
/>
|
||||
<Card
|
||||
title="Enable Expiration Policies"
|
||||
description="Automate retention with the platform’s expiration feature."
|
||||
icon="clock"
|
||||
href="/platform/features/expiration-date"
|
||||
/>
|
||||
</CardGroup>
|
||||
<Snippet file="get-help.mdx"/>
|
||||
|
||||
@@ -5,23 +5,20 @@ icon: "magnifying-glass"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
# How Mem0 Searches Memory
|
||||
## Overview
|
||||
|
||||
Mem0's search operation lets agents ask natural-language questions and get back the memories that matter most. Like a smart librarian, it finds exactly what you need from everything you've stored.
|
||||
The `search` operation allows you to retrieve relevant memories based on a natural language query and optional filters like user ID, agent ID, categories, and more. This is the foundation of giving your agents memory-aware behavior.
|
||||
|
||||
<Info>
|
||||
**Why it matters**
|
||||
- Retrieves the right facts without rebuilding prompts from scratch.
|
||||
- Supports both managed Platform and OSS so you can test locally and deploy at scale.
|
||||
- Keeps results relevant with filters, rerankers, and thresholds.
|
||||
</Info>
|
||||
Mem0 supports:
|
||||
- Semantic similarity search
|
||||
- Metadata filtering (with advanced logic)
|
||||
- Reranking and thresholds
|
||||
- Cross-agent, multi-session context resolution
|
||||
|
||||
## Key terms
|
||||
This applies to both:
|
||||
- **Mem0 Platform** (hosted API with full-scale features)
|
||||
- **Mem0 Open Source** (local-first with LLM inference and local vector DB)
|
||||
|
||||
- **Query** – Natural-language question or statement you pass to `search`.
|
||||
- **Filters** – JSON logic (AND/OR, comparison operators) that narrows results by user, categories, dates, etc.
|
||||
- **top_k / threshold** – Controls how many memories return and the minimum similarity score.
|
||||
- **Rerank** – Optional second pass that boosts precision when a reranker is configured.
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -29,58 +26,23 @@ Mem0's search operation lets agents ask natural-language questions and get back
|
||||
<img src="../../images/search_architecture.png" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="Query processing">
|
||||
Mem0 cleans and enriches your natural-language query so the downstream embedding search is accurate.
|
||||
</Step>
|
||||
<Step title="Vector search">
|
||||
Embeddings locate the closest memories using cosine similarity across your scoped dataset.
|
||||
</Step>
|
||||
<Step title="Filtering & reranking">
|
||||
Logical filters narrow candidates; rerankers or thresholds fine-tune ordering.
|
||||
</Step>
|
||||
<Step title="Results delivery">
|
||||
Formatted memories (with metadata and timestamps) return to your agent or calling service.
|
||||
</Step>
|
||||
</Steps>
|
||||
The search flow follows these steps:
|
||||
|
||||
This pipeline runs the same way for the hosted Platform API and the OSS SDK.
|
||||
1. **Query Processing**
|
||||
An LLM refines and optimizes your natural language query.
|
||||
|
||||
## How does it work?
|
||||
2. **Vector Search**
|
||||
Semantic embeddings are used to find the most relevant memories using cosine similarity.
|
||||
|
||||
Search converts your natural language question into a vector embedding, then finds memories with similar embeddings in your database. The results are ranked by similarity score and can be further refined with filters or reranking.
|
||||
3. **Filtering & Ranking**
|
||||
Logical and comparison-based filters are applied. Memories are scored, filtered, and optionally reranked.
|
||||
|
||||
```python
|
||||
# Minimal example that shows the concept in action
|
||||
# Platform API
|
||||
client.search("What are Alice's hobbies?", filters={"user_id": "alice"})
|
||||
4. **Results Delivery**
|
||||
Relevant memories are returned with associated metadata and timestamps.
|
||||
|
||||
# OSS
|
||||
m.search("What are Alice's hobbies?", user_id="alice")
|
||||
```
|
||||
---
|
||||
|
||||
<Tip>
|
||||
Always provide at least a `user_id` filter to scope searches to the right user's memories. This prevents cross-contamination between users.
|
||||
</Tip>
|
||||
|
||||
## When should you use it?
|
||||
|
||||
- **Context retrieval** - When your agent needs past context to generate better responses
|
||||
- **Personalization** - To recall user preferences, history, or past interactions
|
||||
- **Fact checking** - To verify information against stored memories before responding
|
||||
- **Decision support** - When agents need relevant background information to make decisions
|
||||
|
||||
## Platform vs OSS usage
|
||||
|
||||
| Capability | Mem0 Platform | Mem0 OSS |
|
||||
| --- | --- | --- |
|
||||
| **user_id usage** | In `filters={"user_id": "alice"}` for search/get_all | As parameter `user_id="alice"` for all operations |
|
||||
| **Filter syntax** | Logical operators (`AND`, `OR`, comparisons) with field-level access | Basic field filters, extend via Python hooks |
|
||||
| **Reranking** | Toggle `rerank=True` with managed reranker catalog | Requires configuring local or third-party rerankers |
|
||||
| **Thresholds** | Request-level configuration (`threshold`, `top_k`) | Controlled via SDK parameters |
|
||||
| **Response metadata** | Includes confidence scores, timestamps, dashboard visibility | Determined by your storage backend |
|
||||
|
||||
## Search with Mem0 Platform
|
||||
## Example: Mem0 Platform
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -96,7 +58,7 @@ filters = {
|
||||
]
|
||||
}
|
||||
|
||||
results = client.search(query, filters=filters)
|
||||
results = client.search(query, version="v2", filters=filters)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
@@ -112,139 +74,51 @@ const filters = {
|
||||
};
|
||||
|
||||
const results = await client.search(query, {
|
||||
version: "v2",
|
||||
filters
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Search with Mem0 Open Source
|
||||
---
|
||||
|
||||
## Example: Mem0 Open Source
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
|
||||
m = Memory()
|
||||
|
||||
# Simple search
|
||||
related_memories = m.search("Should I drink coffee or tea?", user_id="alice")
|
||||
|
||||
# Search with filters
|
||||
memories = m.search(
|
||||
"food preferences",
|
||||
user_id="alice",
|
||||
filters={"categories": {"contains": "diet"}}
|
||||
)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const memory = new Memory();
|
||||
|
||||
// Simple search
|
||||
const relatedMemories = memory.search("Should I drink coffee or tea?", { userId: "alice" });
|
||||
|
||||
// Search with filters (if supported)
|
||||
const memories = memory.search("food preferences", {
|
||||
userId: "alice",
|
||||
filters: { categories: { contains: "diet" } }
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Info icon="check">
|
||||
Expect an array of memory documents. Platform responses include vectors, metadata, and timestamps; OSS returns your stored schema.
|
||||
</Info>
|
||||
---
|
||||
|
||||
## Filter patterns
|
||||
## Tips for Better Search
|
||||
|
||||
Filters help narrow down search results. Common use cases:
|
||||
- Use descriptive natural queries (Mem0 can interpret intent)
|
||||
- Apply filters for scoped, faster lookup
|
||||
- Use `version: "v2"` for enhanced results
|
||||
- Consider wildcard filters (e.g., `run_id: "*"`) for broader matches
|
||||
- Tune with `top_k`, `threshold`, or `rerank` if needed
|
||||
|
||||
**Filter by Session Context:**
|
||||
|
||||
*Platform API:*
|
||||
```python
|
||||
# Get memories from a specific agent session
|
||||
client.search("query", filters={
|
||||
"AND": [
|
||||
{"user_id": "alice"},
|
||||
{"agent_id": "chatbot"},
|
||||
{"run_id": "session-123"}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
*OSS:*
|
||||
```python
|
||||
# Get memories from a specific agent session
|
||||
m.search("query", user_id="alice", agent_id="chatbot", run_id="session-123")
|
||||
```
|
||||
|
||||
**Filter by Date Range:**
|
||||
```python
|
||||
# Platform only - date filtering
|
||||
client.search("recent memories", filters={
|
||||
"AND": [
|
||||
{"user_id": "alice"},
|
||||
{"created_at": {"gte": "2024-07-01"}}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
**Filter by Categories:**
|
||||
```python
|
||||
# Platform only - category filtering
|
||||
client.search("preferences", filters={
|
||||
"AND": [
|
||||
{"user_id": "alice"},
|
||||
{"categories": {"contains": "food"}}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
## Tips for better search
|
||||
|
||||
- **Use natural language**: Mem0 understands intent, so describe what you're looking for naturally
|
||||
- **Scope with user ID**: Always provide `user_id` to scope search to relevant memories
|
||||
- **Platform API**: Use `filters={"user_id": "alice"}`
|
||||
- **OSS**: Use `user_id="alice"` as parameter
|
||||
- **Combine filters**: Use AND/OR logic to create precise queries (Platform)
|
||||
- **Consider wildcard filters**: Use wildcard filters (e.g., `run_id: "*"`) for broader matches
|
||||
- **Tune parameters**: Adjust `top_k` for result count, `threshold` for relevance cutoff
|
||||
- **Enable reranking**: Use `rerank=True` (default) when you have a reranker configured
|
||||
|
||||
<Callout type="tip" icon="plug">
|
||||
**MCP Alternative**: With <Link href="/platform/mem0-mcp">Mem0 MCP</Link>, AI agents can search their own memories proactively when needed.
|
||||
</Callout>
|
||||
|
||||
### More Details
|
||||
|
||||
For the full list of filter logic, comparison operators, and optional search parameters, see the
|
||||
[Search Memory API Reference](/api-reference/memory/search-memories).
|
||||
[Search Memory API Reference](/api-reference/memory/v2-search-memories).
|
||||
|
||||
## Put it into practice
|
||||
---
|
||||
|
||||
- Revisit the <Link href="/core-concepts/memory-operations/add">Add Memory</Link> guide to ensure you capture the context you expect to retrieve.
|
||||
- Configure rerankers and filters in <Link href="/platform/features/advanced-retrieval">Advanced Retrieval</Link> for higher precision.
|
||||
## Need help?
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
## See it live
|
||||
|
||||
- <Link href="/cookbooks/operations/support-inbox">Support Inbox with Mem0</Link> demonstrates scoped search with rerankers.
|
||||
- <Link href="/cookbooks/integrations/tavily-search">Tavily Search with Mem0</Link> shows hybrid search in action.
|
||||
|
||||
{/* DEBUG: verify CTA targets */}
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Search Memory API"
|
||||
description="Complete API reference with all filter operators and parameters."
|
||||
icon="book"
|
||||
href="/api-reference/memory/search-memories"
|
||||
/>
|
||||
<Card
|
||||
title="Support Inbox Cookbook"
|
||||
description="Build a complete support system with scoped search and reranking."
|
||||
icon="rocket"
|
||||
href="/cookbooks/operations/support-inbox"
|
||||
/>
|
||||
</CardGroup>
|
||||
<Snippet file="get-help.mdx"/>
|
||||
|
||||
@@ -1,45 +1,33 @@
|
||||
---
|
||||
title: Update Memory
|
||||
description: Modify an existing memory by updating its content or metadata.
|
||||
icon: "pen-to-square"
|
||||
icon: "pencil"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
# Keep Memories Accurate with Update
|
||||
## Overview
|
||||
|
||||
Mem0’s update operation lets you fix or enrich an existing memory without deleting it. When a user changes their preference or clarifies a fact, use update to keep the knowledge base fresh.
|
||||
User preferences, interests, and behaviors often evolve over time. The `update` operation lets you revise a stored memory, whether it's updating facts and memories, rephrasing a message, or enriching metadata.
|
||||
|
||||
<Info>
|
||||
**Why it matters**
|
||||
- Corrects outdated or incorrect memories immediately.
|
||||
- Adds new metadata so filters and rerankers stay sharp.
|
||||
- Works for both one-off edits and large batches (up to 1000 memories).
|
||||
</Info>
|
||||
Mem0 supports both:
|
||||
- **Single Memory Update** for one specific memory using its ID
|
||||
- **Batch Update** for updating many memories at once (up to 1000)
|
||||
|
||||
## Key terms
|
||||
This guide includes usage for both single update and batch update of memories through **Mem0 Platform**
|
||||
|
||||
- **memory_id** – Unique identifier returned by `add` or `search` results.
|
||||
- **text** / **data** – New content that replaces the stored memory value.
|
||||
- **metadata** – Optional key-value pairs you update alongside the text.
|
||||
- **timestamp** – Unix epoch (int/float) or ISO 8601 string to override the memory's timestamp.
|
||||
- **batch_update** – Platform API that edits multiple memories in a single request.
|
||||
- **immutable** – Flagged memories that must be deleted and re-added instead of updated.
|
||||
|
||||
## How the update flow works
|
||||
## Use Cases
|
||||
|
||||
<Steps>
|
||||
<Step title="Locate the memory">
|
||||
Use `search` or dashboard inspection to capture the `memory_id` you want to change.
|
||||
</Step>
|
||||
<Step title="Submit the update">
|
||||
Call `update` (or `batch_update`) with new text and optional metadata. Mem0 overwrites the stored value and adjusts indexes.
|
||||
</Step>
|
||||
<Step title="Verify">
|
||||
Check the response or re-run `search` to ensure the revised memory appears with the new content.
|
||||
</Step>
|
||||
</Steps>
|
||||
- Refine a vague or incorrect memory after a correction
|
||||
- Add or edit memory with new metadata (e.g., categories, tags)
|
||||
- Evolve factual knowledge as the user’s profile changes
|
||||
- A user profile evolves: “I love spicy food” → later says “Actually, I can’t handle spicy food.”
|
||||
|
||||
## Single memory update (Platform)
|
||||
Updating memory ensures your agents remain accurate, adaptive, and personalized.
|
||||
|
||||
---
|
||||
|
||||
## Update Memory
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -51,8 +39,7 @@ memory_id = "your_memory_id"
|
||||
client.update(
|
||||
memory_id=memory_id,
|
||||
text="Updated memory content about the user",
|
||||
metadata={"category": "profile-update"},
|
||||
timestamp="2025-01-15T12:00:00Z"
|
||||
metadata={"category": "profile-update"}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -62,19 +49,18 @@ import MemoryClient from 'mem0ai';
|
||||
const client = new MemoryClient({ apiKey: "your-api-key" });
|
||||
const memory_id = "your_memory_id";
|
||||
|
||||
await client.update(memory_id, {
|
||||
client.update(memory_id, {
|
||||
text: "Updated memory content about the user",
|
||||
metadata: { category: "profile-update" },
|
||||
timestamp: "2025-01-15T12:00:00Z"
|
||||
});
|
||||
metadata: { category: "profile-update" }
|
||||
})
|
||||
.then(result => console.log(result))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Info icon="check">
|
||||
Expect a confirmation message and the updated memory to appear in the dashboard almost instantly.
|
||||
</Info>
|
||||
---
|
||||
|
||||
## Batch update (Platform)
|
||||
## Batch Update
|
||||
|
||||
Update up to 1000 memories in one call.
|
||||
|
||||
@@ -109,70 +95,23 @@ client.batchUpdate(updateMemories)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Update with Mem0 OSS
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
|
||||
memory = Memory()
|
||||
|
||||
memory.update(
|
||||
memory_id="mem_123",
|
||||
data="Alex now prefers decaf coffee",
|
||||
)
|
||||
```
|
||||
```
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
OSS JavaScript SDK does not expose `update` yet—use the REST API or Python SDK when self-hosting.
|
||||
</Note>
|
||||
---
|
||||
|
||||
## Tips
|
||||
|
||||
- Update both `text` **and** `metadata` together to keep filters accurate.
|
||||
- Batch updates are ideal after large imports or when syncing CRM corrections.
|
||||
- Immutable memories must be deleted and re-added instead of updated.
|
||||
- Pair updates with feedback signals (thumbs up/down) to self-heal memories automatically.
|
||||
- You can update both `text` and `metadata` in the same call.
|
||||
- Use `batchUpdate` when you're applying similar corrections at scale.
|
||||
- If memory is marked `immutable`, it must first be deleted and re-added.
|
||||
- Combine this with feedback mechanisms (e.g., user thumbs-up/down) to self-improve memory.
|
||||
|
||||
<Callout type="tip" icon="plug">
|
||||
**MCP Alternative**: With <Link href="/platform/mem0-mcp">Mem0 MCP</Link>, AI agents can update their own memories when users correct information.
|
||||
</Callout>
|
||||
|
||||
## Managed vs OSS differences
|
||||
### More Details
|
||||
|
||||
| Capability | Mem0 Platform | Mem0 OSS |
|
||||
| --- | --- | --- |
|
||||
| Update call | `client.update(memory_id, {...})` | `memory.update(memory_id, data=...)` |
|
||||
| Batch updates | `client.batch_update` (up to 1000 memories) | Script your own loop or bulk job |
|
||||
| Dashboard visibility | Inspect updates in the UI | Inspect via logs or custom tooling |
|
||||
| Immutable handling | Returns descriptive error | Raises exception—delete and re-add |
|
||||
Refer to the full [Update Memory API Reference](/api-reference/memory/update-memory) and [Batch Update Reference](/api-reference/memory/batch-update) for schema and advanced fields.
|
||||
|
||||
## Put it into practice
|
||||
---
|
||||
|
||||
- Review the <Link href="/api-reference/memory/update-memory">Update Memory API reference</Link> for request/response details.
|
||||
- Combine updates with <Link href="/platform/features/feedback-mechanism">Feedback Mechanism</Link> to automate corrections.
|
||||
## Need help?
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
## See it live
|
||||
|
||||
- <Link href="/cookbooks/operations/support-inbox">Support Inbox with Mem0</Link> uses updates to refine customer profiles.
|
||||
- <Link href="/cookbooks/companions/ai-tutor">AI Tutor with Mem0</Link> demonstrates user preference corrections mid-course.
|
||||
|
||||
{/* DEBUG: verify CTA targets */}
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Learn Delete Concepts"
|
||||
description="Understand when to remove memories instead of editing them."
|
||||
icon="trash"
|
||||
href="/core-concepts/memory-operations/delete"
|
||||
/>
|
||||
<Card
|
||||
title="Automate Corrections"
|
||||
description="See how feedback loops trigger updates in production."
|
||||
icon="rocket"
|
||||
href="/platform/features/feedback-mechanism"
|
||||
/>
|
||||
</CardGroup>
|
||||
<Snippet file="get-help.mdx"/>
|
||||
|
||||
@@ -1,129 +1,49 @@
|
||||
---
|
||||
title: Memory Types
|
||||
description: "See how Mem0 layers conversation, session, and user memories to keep agents contextual."
|
||||
icon: "tag"
|
||||
description: Understanding different types of memory in AI Applications
|
||||
icon: "memory"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
# How Mem0 Organizes Memory
|
||||
To build useful AI applications, we need to understand how different memory systems work together. This guide explores the fundamental types of memory in AI systems and shows how Mem0 implements these concepts.
|
||||
|
||||
Mem0 separates memory into layers so agents remember the right detail at the right time. Think of it like a notebook: a sticky note for the current task, a daily journal for the session, and an archive for everything a user has shared.
|
||||
## Why Memory Matters
|
||||
|
||||
<Info>
|
||||
**Why it matters**
|
||||
- Keeps conversations coherent without repeating instructions.
|
||||
- Lets agents personalize responses based on long-term preferences.
|
||||
- Avoids over-fetching data by scoping memory to the correct layer.
|
||||
</Info>
|
||||
AI systems need memory for three key purposes:
|
||||
1. Maintaining context during conversations
|
||||
2. Learning from past interactions
|
||||
3. Building personalized experiences over time
|
||||
|
||||
## Key terms
|
||||
Without proper memory systems, AI applications would treat each interaction as completely new, losing valuable context and personalization opportunities.
|
||||
|
||||
- **Conversation memory** – In-flight messages inside a single turn (what was just said).
|
||||
- **Session memory** – Short-lived facts that apply for the current task or channel.
|
||||
- **User memory** – Long-lived knowledge tied to a person, account, or workspace.
|
||||
- **Organizational memory** – Shared context available to multiple agents or teams.
|
||||
## Short-Term Memory
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Conversation turn] --> B[Session memory]
|
||||
B --> C[User memory]
|
||||
C --> D[Org memory]
|
||||
C --> E[Mem0 retrieval layer]
|
||||
```
|
||||
The most basic form of memory in AI systems holds immediate context - like a person remembering what was just said in a conversation. This includes:
|
||||
|
||||
## Short-term vs long-term memory
|
||||
- **Conversation History**: Recent messages and their order
|
||||
- **Working Memory**: Temporary variables and state
|
||||
- **Attention Context**: Current focus of the conversation
|
||||
|
||||
Short-term memory keeps the current conversation coherent. It includes:
|
||||
## Long-Term Memory
|
||||
|
||||
- **Conversation history** – recent turns in order so the agent remembers what was just said.
|
||||
- **Working memory** – temporary state such as tool outputs or intermediate calculations.
|
||||
- **Attention context** – the immediate focus of the assistant, similar to what a person holds in mind mid-sentence.
|
||||
More sophisticated AI applications implement long-term memory to retain information across conversations. This includes:
|
||||
|
||||
Long-term memory preserves knowledge across sessions. It captures:
|
||||
- **Factual Memory**: Stored knowledge about users, preferences, and domain-specific information
|
||||
- **Episodic Memory**: Past interactions and experiences
|
||||
- **Semantic Memory**: Understanding of concepts and their relationships
|
||||
|
||||
- **Factual memory** – user preferences, account details, and domain facts.
|
||||
- **Episodic memory** – summaries of past interactions or completed tasks.
|
||||
- **Semantic memory** – relationships between concepts so agents can reason about them later.
|
||||
## Memory Characteristics
|
||||
|
||||
Mem0 maps these classic categories onto its layered storage so you can decide what should fade quickly versus what should last for months.
|
||||
Each memory type has distinct characteristics:
|
||||
|
||||
## How does it work?
|
||||
| Type | Persistence | Access Speed | Use Case |
|
||||
|------|-------------|--------------|-----------|
|
||||
| Short-Term | Temporary | Instant | Active conversations |
|
||||
| Long-Term | Persistent | Fast | User preferences and history |
|
||||
|
||||
Mem0 stores each layer separately and merges them when you query:
|
||||
## How Mem0 Implements Long-Term Memory
|
||||
Mem0's long-term memory system builds on these foundations by:
|
||||
|
||||
1. **Capture** – Messages enter the conversation layer while the turn is active.
|
||||
2. **Promote** – Relevant details persist to session or user memory based on your `user_id`, `session_id`, and metadata.
|
||||
3. **Retrieve** – The search pipeline pulls from all layers, ranking user memories first, then session notes, then raw history.
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
from mem0 import Memory
|
||||
|
||||
memory = Memory(api_key=os.environ["MEM0_API_KEY"])
|
||||
|
||||
# Sticky note: conversation memory
|
||||
memory.add(
|
||||
["I'm Alex and I prefer boutique hotels."],
|
||||
user_id="alex",
|
||||
session_id="trip-planning-2025",
|
||||
)
|
||||
|
||||
# Later in the session, pull long-term + session context
|
||||
results = memory.search(
|
||||
"Any hotel preferences?",
|
||||
user_id="alex",
|
||||
session_id="trip-planning-2025",
|
||||
)
|
||||
```
|
||||
|
||||
<Tip>
|
||||
Use `session_id` when you want short-term context to expire automatically; rely on `user_id` for lasting personalization.
|
||||
</Tip>
|
||||
|
||||
## When should you use each layer?
|
||||
|
||||
- **Conversation memory** – Tool calls or chain-of-thought that only matter within the current turn.
|
||||
- **Session memory** – Multi-step tasks (onboarding flows, debugging sessions) that should reset once complete.
|
||||
- **User memory** – Personal preferences, account state, or compliance details that must persist across interactions.
|
||||
- **Organizational memory** – Shared FAQs, product catalogs, or policies that every agent should recall.
|
||||
|
||||
## How it compares
|
||||
|
||||
| Layer | Lifetime | Short or long term | Best for | Trade-offs |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Conversation | Single response | Short-term | Tool execution detail | Lost after the turn finishes |
|
||||
| Session | Minutes to hours | Short-term | Multi-step flows | Clear it manually when done |
|
||||
| User | Weeks to forever | Long-term | Personalization | Requires consent/governance |
|
||||
| Org | Configured globally | Long-term | Shared knowledge | Needs owner to keep current |
|
||||
|
||||
<Warning>
|
||||
Avoid storing secrets or unredacted PII in user or org memories—Mem0 is retrievable by design. Encrypt or hash sensitive values first.
|
||||
</Warning>
|
||||
|
||||
## Put it into practice
|
||||
|
||||
- Use the <Link href="/core-concepts/memory-operations/add">Add Memory</Link> guide to persist user preferences.
|
||||
- Follow <Link href="/platform/advanced-memory-operations">Advanced Memory Operations</Link> to tune metadata and graph writes.
|
||||
|
||||
## See it live
|
||||
|
||||
- <Link href="/cookbooks/companions/ai-tutor">AI Tutor with Mem0</Link> shows session vs user memories in action.
|
||||
- <Link href="/cookbooks/operations/support-inbox">Support Inbox with Mem0</Link> demonstrates shared org memory.
|
||||
|
||||
{/* DEBUG: verify CTA targets */}
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Explore Memory Operations"
|
||||
description="Dive into the add/search/update/delete concepts next."
|
||||
icon="circle-check"
|
||||
href="/core-concepts/memory-operations/add"
|
||||
/>
|
||||
<Card
|
||||
title="See a Cookbook"
|
||||
description="Apply layered memories inside a customer support agent."
|
||||
icon="rocket"
|
||||
href="/cookbooks/operations/support-inbox"
|
||||
/>
|
||||
</CardGroup>
|
||||
1. Using vector embeddings to store and retrieve semantic information
|
||||
2. Maintaining user-specific context across sessions
|
||||
3. Implementing efficient retrieval mechanisms for relevant past interactions
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user