Partition Memories by Entity - Mem0
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
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.
Time to complete: ~15 minutes · Languages: Python
Setup
from mem0 import MemoryClient
client = MemoryClient(api_key="m0-...")
Grab an API key from the Mem0 dashboard to get started.
Store and Retrieve Scoped Memories
Let’s start by storing Cam’s travel preferences and retrieving them:
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:
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', ...}]}
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, as shown above, rather than combining both in a single filter.
When Memories Leak
When Nora adds a chef agent, Cam’s travel preferences leak into food recommendations:
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:
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:
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:
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']
Wildcards ("*") only match non-null values. Make sure you write memories with explicit app_id values.
When the sports brand offboards, delete all their data:
client.delete_all(app_id="sports_brand_portal")
Output:
{'message': 'Memories deleted successfully!'}
Production Patterns
# 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:
# 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:
# 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:
# 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
- Use consistent identifier formats
# 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"
- Print filters when debugging
filters = {"AND": [{"user_id": "cam", "agent_id": "chef"}]}
print(f"Searching with filters: {filters}") # Helps catch typos
- Clean up temporary sessions
# 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, andrun_id - Prevent memory leaks between different agents and applications
- Clean up data for specific tenants or sessions
- Use wildcards to query across scoped memories