Speaking Bots

Personas

Reusable characters with their own prompt, knowledge, voice and avatar

A persona is a folder of Markdown under config/personas/. The hosted API ships about seventy of them — baas_onboarder, interviewer, pair_programmer, level10_meeting_facilitator, debate_champion, a stoic_philosopher, a pirate_queen and so on — and a self-hosted server can add its own. Ask for one by its folder name:

{ "meeting_url": "...", "personas": ["interviewer"] }

personas is a list: the first one that exists is used. If personas is empty and bot_name matches a folder name, that persona is used. With neither, and no prompt, one is picked at random.

A prompt in the request replaces the persona entirely — see Sending a bot for the precedence.

Anatomy of a persona

config/personas/baas_onboarder/
├── README.md          # the persona: prompt, characteristics, voice, metadata
├── Content.md         # extra knowledge, appended to the prompt
├── Rules.md           # more of the same
└── pricing.md         # any .md file in the folder is loaded

README.md is the only required file. Its structure is parsed:

# BaaS onboarder

You are here to present the Meeting Baas API. ... (the first paragraph is the prompt)

## Characteristics
- Gen-Z speech patterns
- Tech-savvy and modern

## Voice
BaaS onboarder speaks with:
- modern internet slang

## Metadata
- image: https://utfs.io/f/....png
- entry_message: Hey, I'm here to help you onboard yourself on the BaaS API.
- cartesia_voice_id: 156fb8d2-335b-4950-9cb3-a2d33befec77
- gender: FEMALE
- relevant_links:
PartUsed for
Title (# ...)Display name, and the default bot_name
First paragraphThe system prompt
Other sectionsAppended to the prompt, except Characteristics, Voice and Metadata, which are parsed
imageDefault avatar (bot_image in the request overrides it)
entry_messageSpoken when admitted, unless the request sets its own
cartesia_voice_idThe bot's voice; omit it for the server default
language_codeThe language the bot listens for (Deepgram speech-to-text); default en-US
Every other *.md in the folderLoaded as additional context, each under a "Content from <file>" heading

There is no retrieval step: every file goes into the prompt on every turn, so keep the knowledge curated and split by topic rather than dumping a manual in.

Write for speech: short sentences, no markdown or code in the prompt, and tell the persona to be concise — everything the model produces is spoken aloud.

Creating a persona

On a self-hosted server, add a folder with a README.md in that shape and restart; it is available by folder name immediately. There is also an interactive CLI that writes the folder for you, matches a Cartesia voice to the description with OpenAI, and generates an avatar with Replicate:

poetry run python config/create_persona.py tech_expert \
  --name "Tech Expert" \
  --prompt "You are a patient senior engineer who explains systems clearly." \
  --entry-message "Hi, Tech Expert here. What are we looking at?"

Add --blank for a minimal folder without image generation, or --non-interactive to skip the prompts. Image generation needs REPLICATE_KEY, UTFS_KEY and APP_ID (environment variables); the same generator is exposed on the API as POST /personas/generate-image.

The persona library is part of the open-source repository; a pull request is the way to get a new one onto the hosted API.

On this page