Skip to main content

Customers

A customer is Parlant's special term for anyone who interacts with an agent— whether it's a real person, a bot, or even a human operator.

While agents can operate without knowing who they're talking to ("guest" customers), registering customers lets you personalize interactions based on identity, preferences, and segment.

import parlant.sdk as p

async with p.Server() as server:
customer = await server.create_customer(name="Alice")

Custom IDs

By default, Parlant auto-generates customer IDs. To map directly to your existing user identifiers, pass a custom ID:

customer = await server.create_customer(
id="usr_12345", # Your external system's user ID
name="Alice",
)

This is especially useful when your tools need to look up customer data in external services (CRM, billing, etc.) using the same ID.

Customer Groups

Use tags to segment customers into groups and control group-specific behavior:

vip_tag = await server.create_tag(name="VIP")

customer = await server.create_customer(name="Alice", tags=[vip_tag.id])

Group-Specific Guidelines

To activate guidelines only for customers in a specific group, create an observation with a custom matcher that checks the customer's tags, then make your guidelines depend on it:

# 1. Define a custom code-based matcher that checks for the VIP tag
async def is_vip(
ctx: p.GuidelineMatchingContext,
guideline: p.Guideline
) -> p.GuidelineMatch:
matched = vip_tag.id in p.Customer.current.tags

return p.GuidelineMatch(
id=guideline.id,
matched=matched,
rationale="Customer has VIP tag" if matched else "Customer does not have VIP tag",
)
# 2. Create an observation using that matcher
vip_observation = await agent.create_observation(matcher=is_vip)
# 3. Create guidelines that only activate for VIP customers
vip_guideline = await agent.create_guideline(
condition="The customer asks about pricing",
action="Offer the exclusive VIP discount of 20%",
dependencies=[vip_observation],
)

The matcher letes you bypass the default LLM-based matching with deterministic logic. The dependencies parameter ensures the guideline may only ever activate when the observation also matches, so non-VIP customers will never see VIP-specific behavior.

Learn More

To learn more about personalization possibilities for specific customers and groups, check out the variables section.

Metadata

Attach custom metadata to customers for use in personalization, tool calls, or custom matchers:

customer = await server.create_customer(name="Alice", metadata={
"location": "USA",
"plan": "enterprise",
})

Here's an example of how you'd access that metadata from a tool:

@p.tool
async def get_customer_location(context: p.ToolContext) -> p.ToolResult:
customer = p.Customer.current
return p.ToolResult(customer.metadata.get("location", "Unknown location"))

Updating Customer Data

You can update a customer's name, metadata, and tags at any time:

from parlant.client import ParlantClient

client = ParlantClient("http://localhost:8800")

client.customers.update(
customer_id=CUSTOMER_ID,
name="Alice Smith",
metadata={
"set": {
"location": "Canada",
},
"remove": ["plan"],
},
tags=[NEW_TAG_ID]
)

Authentication and Mid-Session Identity

Parlant is a backend service—authentication and authorization live in your application layer (OAuth, JWT, etc.). Once you've identified a customer, pass their ID when creating a session to enable personalized interactions.

A common pattern is starting a session in guest mode and associating a customer mid-conversation after they authenticate:

from parlant.client import ParlantClient

client = ParlantClient(PARLANT_SERVER_URL)

# User authenticates mid-session
client.sessions.update(
session_id=SESSION_ID,
customer_id="authenticated_user_123"
)
# From now on, the agent can provide a personalized experience

Configuring Customer Storage

In the default configuration, during development, Parlant does not persist customers; they're stored in memory and lost when the server restarts.

You can easily configure persistent storage. For local development, the quickest setup is local file storage. For production, Parlant comes with native MongoDB support for its scalability and performance.

Integrate with Your Existing Database

If you already have customer data in your own database, implement the p.CustomerStore interface to load customers directly from there. In this way, there's no duplication needed with your existing data.

Local Storage

Saves customers under $PARLANT_HOME/customers.json. Zero setup required.

import asyncio
import parlant.sdk as p

async def main():
async with p.Server(customer_store="local") as server:
# ...

asyncio.run(main())

MongoDB

Specify the connection string to your MongoDB instance:

import asyncio
import parlant.sdk as p

async def main():
async with p.Server(customer_store="mongodb://path.to.your.host:27017") as server:
# ...

asyncio.run(main())
Install the MongoDB Extra
pip install "parlant[mongo]"
github Reach out for help