Back to Mem0

Partition Memories by Entity

docs/cookbooks/essentials/entity-partitioning-playbook.mdx

2.0.19.2 KB
Original Source

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 <a href="https://app.mem0.ai/?utm_source=oss&utm_medium=cookbook-entity-partitioning" rel="nofollow">Mem0 dashboard</a> 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

IdentifierWhen to UseExample Values
user_idIndividual preferences that persist across all interactionscam_traveler, sarah_exec, team_alpha
agent_idDifferent AI roles need separate contexttravel_agent, concierge, customer_support
app_idWhite-label deployments or separate productstravel_app_ios, enterprise_portal, partner_integration
run_idTemporary sessions that should be isolatedsupport_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>