- Different data only (e.g. user name, profile, session goal) → Approach A: Reuse personas and pass per-conversation data via
conversational_contextand related options. - Different behavior (e.g. different voice, objectives, guardrails, or tools per session) → Approach B: Create a persona per conversation — define the persona config in your code, create it via the API at session start, then delete it when the session ends.
Approach A: Reuse Personas + conversational_context
How it works
You keep persistent personas in Tavus — whether one or many — and reuse them. For each new conversation you call POST /v2/conversations and pass per-user or per-session data via request body fields. The persona itself is unchanged; only the conversation-level context changes.What you can customize per conversation
- Any text/data in the LLM context — e.g. user name, profile, history, prior session summary — via
conversational_contextwhen creating the conversation. - Custom greeting — via
custom_greetingso each participant gets a personalized opening.
Mid-session context — You can inject or replace context during a call via WebSocket events: append_llm_context to add context without replacing what’s there, or overwrite_llm_context to replace the current
conversational_context. Useful for injecting tool results or refreshed instructions without ending the call.What you cannot customize per conversation
Everything that lives on the persona is shared by all conversations using that persona:- Objectives, guardrails, TTS voice, LLM model, tools — all are persona-level. A PATCH to the persona affects every current and future conversation that uses it.
Advantages
- Low API overhead — one call to create a conversation (
POST /v2/conversations) withpersona_idand optionalconversational_context,custom_greeting, etc. - Centralized updates — change the persona once (e.g. system prompt, guardrails, voice) and all new conversations immediately use the new config.
- Simple at scale — fewer personas to manage; no create/delete lifecycle per session.
Disadvantages
- No per-session behavioral isolation — a mistaken or premature PATCH to the persona affects every conversation using it.
- No per-session variation of voice, objectives, guardrails, or tools — those stay fixed at the persona level.
Example use cases
- Single shared persona, rich context per call — A team uses one persona and builds a detailed
conversational_contextserver-side before each call (e.g. user lifecycle stage, profile, engagement history, prior session summary). During the call they can use append_llm_context (and optionally respond events) to inject tool outputs or updated guidance without interrupting the avatar. - Centralized prompt, per-user personalization — One persona holds the core system prompt and behavior. Each conversation gets a different
conversational_context(e.g. participant name, background, preferences). A single update to the persona rolls out to all users at once while still allowing personalized greetings and questions per session. - Static knowledge, dynamic audience — A single persona is configured with fixed reference content (e.g. product FAQs, academic programs). Institution or user context is passed in via
conversational_contextper conversation. - Storyteller — A persona has a static
system_promptand base context; each conversation passes in the participant’s name, age, and genre preferences viaconversational_contextand optionally acustom_greeting.
Approach B: New Persona Per Conversation (Create & Delete)
How it works
You define the persona config in your own code (or in a config file, database, etc. — however you want to store it). That “template” is not stored in Tavus. At session start you:- POST /v2/personas — create a new persona with the config from your code, including any session-specific overrides (e.g. voice, objectives, guardrails, system prompt).
- POST /v2/conversations — create the conversation using the new persona’s ID.
- When the session ends — DELETE /v2/personas/ to remove the ephemeral persona.
What you can customize per conversation
Everything that lives on a persona can differ per session:- Objectives, guardrails, TTS voice, LLM model, tools, system_prompt, and any other persona-level fields.
conversational_context and custom_greeting on the conversation for additional per-session data.
Advantages
- Full isolation — no cross-session contamination. A change or mistake in one session’s persona does not affect others.
- Maximum flexibility — every persona-level setting can vary per session (e.g. different voice per conversation, different objectives per role or demo).
- Safe for multi-tenant or demo flows — each tenant or demo can have its own persona instance with custom guardrails, objectives, and context.
- No risk of a PATCH affecting live sessions — you only patch or delete the ephemeral persona for that session.
Disadvantages
- Three API calls per session — create persona → create conversation → delete persona (after session end). You need reliable cleanup logic (e.g. on session-end webhook or timeout) so ephemeral personas don’t accumulate.
- Template updates don’t affect in-flight sessions — only new sessions pick up changes when you deploy updated code; existing conversations keep the config they were created with.
Example use cases
- Different TTS voice per conversation — Because voice is configured at the persona level and can’t be overridden at conversation creation, one practical approach is to create a new persona per session (from your code template) with the desired voice. This pattern is often adopted as the standard production approach when voice-per-session is a requirement.
- Demos with custom guardrails and objectives — Demos need custom guardrails, objectives, and persona context per demo — all persona-level. Define your base config in code and create a new persona per demo with demo-specific overrides. That way you avoid maintaining a large library of static personas in Tavus or running batch update jobs when behavior changes; the template in your code is the single source of truth.
- Structured flows where persona-level changes broke global state — Teams running structured conversations (e.g. role-specific recruiting or role-play) found that changing a shared persona’s voice or objectives affected all active conversations. Creating a persona per session from their code template gave per-conversation isolation and avoided those side effects.
- Event- or deployment-specific config — For kiosks or event-specific advisors, the persona config can vary per event or deployment (system prompt, LLM backend, TTS provider). Store the config in your code or deployment pipeline and create a fresh persona per context when the session starts.
Choosing an approach
| If you need… | Prefer |
|---|---|
| Different data per conversation (user name, profile, history, session goal) | Approach A — reuse personas and use conversational_context, custom_greeting, and (optionally) mid-session context events. |
| Different behavior per conversation (voice, objectives, guardrails, tools, or system prompt) | Approach B — define the persona config in your code and create a new persona per session via the API, then delete it when the session ends. |
conversational_context and custom_greeting when creating the conversation for extra per-session data.
