<aside> đź’ˇ Note: To toggle Light / Dark mode, press cmd+shift+L

</aside>

Choosing an LLM

Supported LLMs

We support any OpenAI-compatible LLM API, in addition to our hosted instances of GPT-3, GPT-4 and Nous Hermes Mixtral.

To use your own custom LLM API, or to finetune an OpenAI LLM, [contact us](mailto:[email protected]?subject=Use%20Custom%20LLM).

Finetuning LLMs

We offer finetuning custom models for Tier III and Enterprise customers.

Choosing a Voice

We use ElevenLabs as a voice provider. If you are a paid customer, you can [share any ElevenLabs voice](https://help.elevenlabs.io/hc/en-us/articles/18644643807889-How-do-I-share-a-voice-#:~:text=Sharing your voice is quite,toggle for sharing will appear.) with us to import it, including cloned voices.

If you would like to use a cheaper (but lower-quality) voice provider, please [contact us](mailto:[email protected]?subject=Use%20Cheaper%20Voice).

Custom Voices

To import a custom voice, [contact us](mailto:[email protected]?subject=Use%20Custom%20Voice) with the share link to the voice and the Persona name you would like to apply it to.

Prompt: Defining Personality and Behavior

Initial Message

The initial message is the message that the Persona will say upon conversation start.

The {{details.[detailKey]}} wildcard can be used in the initial message.

Rate Limit Message [optional]

The message that your Persona will say when a user hits their message limit (requires tracking user IDs; tracked automatically via phone number if using Twilio).

Saying the rate limit message does not consume messages for your account.

Prompt

A Personas’ behavior is largely defined by its prompt.

If you are unfamiliar with prompting / prompt engineering, it is important to familiarize yourself with the basics and [best practices](https://www.techtarget.com/searchenterpriseai/tip/Prompt-engineering-tips-and-best-practices#:~:text=Include context&text=To make use of this,and detail of the output.). This is an active area of research, so keeping up with the latest developments will help you get the most out of your Persona.

In general, a typical prompting pattern is:

You are [high-level Persona description, e.g. "Tifa, a hardworking, tough bartender with a heart of gold"].

Your job is to [description of job to be done, e.g. "keep the bar in order and take care of your team"].

To do that, you [description of tactics / methods to achieve goals, e.g. "use your fists when necessary"].

[Reiteration of most important details, e.g. "YOU MUST ALWAYS SPEAK IN IAMBIC PENTAMETER"].

Prompt Keywords: PERSONA_VOICE_SCHEMA, DETAILS.*, SCENARIOS_LIST, and CURRENT_DATETIME

There are 4 keywords that you can add to your Prompt to give your Persona additional capabilities using handlebars syntax, like this:

{{actionsSchema}}

The keywords are:

Actions: Making your Persona Do Stuff

In order for your Persona to “do stuff,” your Persona can take Actions via the Actions Schema.

Simply put, actions are structured JSON objects that the Persona can emit during conversation, to be handled by downstream clients — whether our hosted Twilio client or your web application, Unity game, or other client environment.

The Persona Actions Schema combines traditional JSON schema validation with Persona’s proprietary schema definitions.

Every Actions Schema has the following top-level properties:

Key Type Value Description
$schema string “http://json-schema.org/draft-07/schema#” [Does not change] The schema validation version.
type string “object” [Does not change] The type of the schema object.
properties object {**Action Objects}** Where the magic happens. You define the keys in the “properties” sub-object. See below for more information about structuring Actions.

Action Object

Each Action Object must follow the structure:

Key Type Value Description
_description string “When the Persona should hang up the phone.” An English-language description of the Action and the context in which the Action should be taken.
_examples array [Examples] A list of Examples.
_validators [optional] object { Validators } A dictionary of validators to apply to the specified action values.
_action_type [optional] “update_state” “webhook” Either “update_state” or “webhook”
_depends_on [optional] array Array of state value paths. Ensure that the action can only be taken when all of the state values listed are present at the defined paths in the state.
type string “string” “number”
enum [optional]

_validators

You may want to ensure that the output of an action conforms to a particular pattern or schema. In addition to generic JSON schema validation, we offer the following custom validators:

Validator Description
email ensures that an email address is property formatted.
date (MM/dd/yyy) ensures that a date is formatted as (MM/dd/YYYY)
time (hh:mm aa) ensures that a time is formatted as (hh:mm aa)
datetimeiso ensures that a datetime is formatted as a proper Datetime ISO (yyyy-MM-ddTHH:mm)

More validators will become available as requested, so please don’t hesitate to [request a new one](mailto:[email protected]?subject=Add%20Custom%20Validators).

_action_type (“webhook” and “update_state”)

_depends_on

Ensures that the persona can only take the associated action if the listed path(s) exist(s) in the current state.

For example, if you’d like your Persona to only schedule a call once a time has been confirmed, you could make schedule_call depend on confirm_time like this:

"confirm_time": {
            "_action_type": "update_state",
            "_description": "When the user has confirmed the time they'd like to make the appointment.",
            "_examples": [
                {
                    "user says": "<user says what time they are available for a call>",
                    "assistant action includes": {
                        "confirm_time": {
                            "time_confirmed": "true"
                        }
                    }
                }
            ],
            "type": "object",
            "required": [
                "time_confirmed"
            ]
        },
"schedule_call": {
            "_depends_on": [
                "state.time_confirmed"
            ],
						// ...

Putting it altogether: An example

The following example illustrates how to use some of these concepts together to create an appointment-scheduling Persona name Rachel:

{
    "$schema": "<http://json-schema.org/draft-07/schema#>",
    "type": "object",
    "properties": {
        "hang_up_call": {
            "_description": "When Rachel should end the call and hang up the phone.",
            "_examples": [
                {
                    "user says": "Thank you, goodbye",
                    "assistant action includes": {
                        "hang_up_call": "true"
                    }
                }
            ]
        },
				"press_phone_keys": {
				    "_description": "When you should press a key or keys to navigate a phone tree.",
				    "_examples": [
				        {
						         "user says": "Welcome to ACME co. Please press 5 to speak to a representative.",
							       "assistant action includes": {
										    "press_phone_keys": [ 5 ]
							       }
				        }
					  ],
					  "type": "array"
				},
        "save_email_address": {
            "_action_type": "update_state",
            "_description": "When Rachel should commit the user's email address to memory. She should always confirm that she has the correct email address afterwards.",
            "_examples": [
                {
                    "user says": "<provides email address>",
                    "assistant action includes": {
                        "save_email_address": {
                            "email_address": "<email address>"
                        }
                    }
                }
            ],
            "type": "object",
            "required": [
                "email_address"
            ],
            "_validators": {
                "email_address": "email"
            }
        },
        "save_time_for_call": {
            "_action_type": "update_state",
            "_description": "When Rachel should commit the time for the follow-up call to memory. She should always confirm that she has the correct time afterwards.",
            "_examples": [
                {
                    "user says": "<user says what time they are available for a call>",
                    "assistant action includes": {
                        "save_time_for_call": {
                            "followup-datetime": "<datetime iso formatted>"
                        }
                    }
                }
            ],
            "type": "object",
            "required": [
                "followup-datetime"
            ],
            "_validators": {
                "followup-datetime": "datetimeiso"
            }
        },
        "confirm_email_address": {
            "_action_type": "update_state",
            "_depends_on": [
                "state.email_address"
            ],
            "_description": "When Rachel should confirm that she heard the user's email address correctly.",
            "_examples": [
                {
                    "user says": "Yes, that's correct",
                    "assistant action includes": {
                        "confirm_email_address": {
                            "email_address_confirmed": "true"
                        }
                    }
                }
            ],
            "type": "object",
            "required": [
                "email_address_confirmed"
            ]
        },
        "schedule_call_with_brian": {
            "_action_type": "webhook",
            "_depends_on": [
                "state.email_address",
                "state.email_address_confirmed",
                "state.followup-datetime"
            ],
            "_webhook_constants": {
                "url": "<https://hooks.zapier.com/hooks/catch/>[zapier id]/[zapier id]/",
                "method": "POST"
            },
            "_description": "When Rachel should book an appointment. You should convert what the user says into datetime ISO format (yyyy-MM-ddTHH:mm). YOU MUST ALWAYS CONFIRM WHETHER THEY RECEIVED THE CALENDAR INVITATION.",
            "_examples": [
                {
                    "user says": "<provides email address>",
                    "assistant action includes": {
                        "schedule_call_with_brian": {
                            "firstName": "<first name>",
                            "company": "<company name>",
                            "datetime": "<datetime iso formatted>",
                            "email_address": "<email address>"
                        }
                    }
                }
            ],
            "type": "object",
            "required": [
                "firstName",
                "company",
                "datetime",
                "email_address"
            ],
            "_validators": {
                "email_address": "email",
                "datetime": "datetimeiso"
            }
        }
    }
}

Scenarios

Use Scenarios to provide your Persona with specific information in specific conversational contexts.

When you have Scenarios configured, the user’s current statement — along with the Persona’s most recent statement — will be used to retrieve the 5 most relevant Scenarios, which will be injected into the prompt in real-time.

Scenarios are an implementation of RAG (Retrieval-Augmented Generation) that is optimized for ultra-low latency.

NOTE: RAG is a rapidly evolving discipline and our implementation is a first approximation. If you have

different needs than our system currently provides, please email us at [email protected].

Scenario Construction

Scenarios are composed of four sections:

  1. Context [string]: Text that will get injected into the prompt on each conversational turn, prepended with Given the context:
  2. Persona Says [array]: A list of strings that are examples of what the Persona might say to activate the Scenario
  3. User Says [array]: A list of strings that are examples of what a user might say to activate the Scenario
  4. Response Guidelines [string]: Text that will get injected into the prompt, prepended with You should respond by:

Scenarios API Example

To programmatically update scenarios via the API, you can PUT to /api/personas/:id/scenarios with a data structure of the following format:

{
	"scenarios": [
		{
			"context": "If you are discussing prices",
			"personaSays": [
				"Would you like to know about our prices?"
			],
			"userSays": [
				"What are your prices like?"
				"How much does it cost?"
			],
			"responseGuidelines": "Tell the user that our plans start at $99 per month but are negotiable"
		},
		{ ... },
		{ ... }
	]
}

While either the personaSays or userSays array can be empty, both arrays should not be empty.

Deploying your Persona

Personas are deployed via Persona Clients, which handle all incoming and outgoing audio streams, as well as expose helper methods to manage conversation lifecycle and state.

Phone (Twilio)

Our Twilio client is fully-managed, meaning that you only have to point your Twilio phone number to our TwiML webservice and submit a few details via the Persona Playground to have a fully-operational Twilio Phone Persona.

For more details, select Deploy > Phone (Twilio) in the Playground.

Our Twilio client provides some helper Actions to execute Twilio-specific behaviors:

Additionally, for incoming phone calls, the caller’s phone number will automatically be injectable into your prompt as {details.userId}}.

You can also make outgoing calls from your Persona using the API.

Note: Twilio call recording is disabled by default for outgoing phone calls. Please ensure you are complying with all applicable laws and our Terms of Service when making outgoing calls.

Web Browser

Personas can be integrated into most major browsers, including Chrome and Safari using our Javascript SDK.

The Javascript SDK is hosted at https://api.prod.centralus.az.sindarin.tech/PersonaClientPublic?apikey=[client-key].

To include the SDK in your web app, you can do the following:

const publicapikey = "[client-key]"

let personaClient;

const script = document.createElement("script");
script.src = `https://api.prod.centralus.az.sindarin.tech/PersonaClientPublic?apikey=${publicapikey}`;
script.addEventListener("load", async () => {
	personaClient = new window.PersonaClient(publicapikey);
});

document.head.appendChild(script);

The Persona client methods are as follows:

Web Browser Client Methods

Init()

init({
	userId?: string,
	personaName?: string,
	personaId?: string,
	details?: object = {}
}): Promise<void>

Starts a new conversation with the given Persona. You should generate or assign a userId to track individual users.

After initializing a conversation, you can access the conversation ID via personaClient.conversationId.

end()

end(): Promise<void>

Pauses or ends the current conversation.

resume()

resume(conversationId: string): Promise<void>

Resumes a conversation given the conversation ID.

updateState()