Skip to main content
Every memory in MemLayer is scoped to a user_id + agent_id pair. This two-key namespace lets you run multiple specialized agents for the same user without memories from one agent bleeding into another’s recall results — while still giving you the flexibility to share a memory namespace when agents should collaborate.
IDs can be any string up to 255 characters. You don’t register or pre-create them with MemLayer — just use them consistently across store and recall calls and MemLayer handles the rest.

user_id

user_id is the identifier for the end user whose memories are being stored. Use whatever identifier already exists in your system — a database primary key, a UUID, an email address, or an external auth provider’s subject ID. The only requirement is that it’s consistent across sessions so memories accumulate correctly over time.
from memlayer import MemLayerClient

client = MemLayerClient(api_key="YOUR_API_KEY")

# Use your existing user identifier — no registration needed
client.remember(
    "User prefers to be contacted by email, not phone.",
    user_id="usr_7f3a92bc",   # your database user ID
    agent_id="support_bot",
    memory_type="semantic",
)
A single user_id can accumulate memories from many different agents over time. When you query, you always specify which user_id you’re interested in — MemLayer never mixes memories across users.

agent_id

agent_id identifies which agent or bot stored the memory. You define this string yourself — it’s just a label that separates memory namespaces within the same user’s record. Common examples:
  • "support_bot" — customer support agent
  • "sales_agent" — sales or upsell assistant
  • "onboarding_wizard" — first-run experience bot
  • "data_analyst" — internal reporting agent
# Two agents storing memories for the same user — completely isolated
client.remember(
    "User is on the Pro plan and eligible for upgrade.",
    user_id="usr_7f3a92bc",
    agent_id="sales_agent",       # only visible to sales_agent recall
    memory_type="semantic",
)

client.remember(
    "User's last support ticket was about API rate limits.",
    user_id="usr_7f3a92bc",
    agent_id="support_bot",       # only visible to support_bot recall
    memory_type="episodic",
)

Scoping Examples

How you combine user_id and agent_id determines your memory architecture:

Single agent, one user

All memories are stored and recalled with the same pair. Fully isolated — straightforward for single-product apps.
user_id = "usr_7f3a92bc"
agent_id = "my_agent"

Multiple agents, same user

Each agent uses its own agent_id. A sales agent and a support agent serve the same user but never see each other’s memories unless you deliberately share the namespace.
user_id = "usr_7f3a92bc"

# Sales agent stores and recalls from its own namespace
sales_memory = client.recall(query, user_id=user_id, agent_id="sales_agent")

# Support agent stores and recalls from its own namespace
support_memory = client.recall(query, user_id=user_id, agent_id="support_bot")

Shared memory namespace

Multiple agents use the same agent_id to read from a shared pool of memories. Any agent that stores to agent_id="shared" makes that memory visible to all others querying with the same pair.
SHARED_AGENT_ID = "shared_context"

# Both agents write to and read from the same namespace
client.remember("User is on the Enterprise plan.", user_id=user_id, agent_id=SHARED_AGENT_ID)
results = client.recall(query, user_id=user_id, agent_id=SHARED_AGENT_ID)

Architecture Patterns

Assign a dedicated agent_id to each product feature or domain. This is the cleanest separation — each agent’s memory is private to its feature, preventing irrelevant memories from diluting recall quality.
from memlayer import MemLayerClient

client = MemLayerClient(api_key="YOUR_API_KEY")

def support_agent_store(user_id: str, content: str):
    client.remember(
        content,
        user_id=user_id,
        agent_id="support_bot",
        memory_type="episodic",
    )

def sales_agent_recall(user_id: str, query: str):
    return client.recall(
        query=query,
        user_id=user_id,
        agent_id="sales_agent",   # sales sees only its own memories
    )

# Store a support event
support_agent_store("usr_7f3a92bc", "User reported login failures on 2024-11-10.")

# Sales recall is unaffected — different agent_id namespace
leads = sales_agent_recall("usr_7f3a92bc", "Is the user interested in upgrading?")

What Happens if IDs Don’t Match?

If user_id or agent_id doesn’t exactly match the values used when the memory was stored, recall() and list() will return empty results. IDs are case-sensitive"Support_Bot" and "support_bot" are treated as different agents. Always use constants or enums in your code rather than hardcoding ID strings inline.
A common gotcha is inconsistent casing or whitespace introduced when IDs are derived from user input or environment variables. Validate and normalize your IDs at the application boundary before passing them to the MemLayer client.
# Safe pattern: define IDs as module-level constants
USER_ID = user.id                     # pulled from your auth context
AGENT_ID = "support_bot"              # constant — never varies

client.remember("...", user_id=USER_ID, agent_id=AGENT_ID)
results = client.recall("...", user_id=USER_ID, agent_id=AGENT_ID)