Skip to main content

Installation

Environment variables

.env

PersonaConfig

Configure the avatar identity and model:
string
required
Display name for the avatar. Used in logs and debugging.
string
required
UUID of the avatar to use. Get this from the Avatar Gallery or Anam Lab.
string
Avatar model version to use when rendering the avatar. Use cara-4 for new production avatars.

AvatarSession

PersonaConfig
required
Configuration for the avatar’s identity and appearance.
string
required
Your Anam API key.
string
default:"https://api.anam.ai"
Anam API endpoint. Override for staging or self-hosted deployments.

start()

Starts the avatar session and connects it to the LiveKit room.
AgentSession
required
The LiveKit agent session to connect the avatar to.
rtc.Room
required
The LiveKit room instance from the job context.

Director Notes cues

Inline cues let the avatar shift emotion or delivery mid-turn (see Director Notes for the cue list and preset styles). Your LLM writes cues as square-bracketed tags in the spoken text, for example [warm] Hello there. [curious] What brings you here?. Director Notes require a Cara 4 avatar. They work best with a voice that matches the intended performance and a neutral-expression avatar source image; an overly smiley, sad, or angry source image can limit how far cues can move the performance. In a LiveKit agent, Anam reads those cues from the agent’s TTS-aligned transcript, which you publish to the room. Wiring this up takes two things:
  1. use_tts_aligned_transcript=True on the AgentSession, so the agent produces a transcript with per-word timings.
  2. A JSON transcription sink scoped to the agent’s own identity, so that timed transcript (cue tags included) is published to the room on the lk.transcription stream, where the Anam engine reads it to drive per-utterance expression.
This path leaves the [cue] tags in the text sent to your TTS, so it only works with a TTS that does not read square-bracketed cues aloud — for example Cartesia sonic-3.5. Providers that speak the brackets (such as ElevenLabs) are not supported here.
_ParticipantTranscriptionOutput is currently an internal LiveKit Agents API. Set the transcription sink after avatar.start() and before session.start().

Prompt your LLM to emit cues

The transcript sink only forwards cues that are already in the agent’s replies — nothing generates them for you. Your LLM has to write the [cue] tags inline, so add a short instruction to the agent’s system prompt:
See Prompting an LLM to use cues for more detail.

Advanced examples

Gemini with Vision

Use Gemini Live for multimodal conversations with screen share analysis:

Function tools

Extend your agent with custom tools:

Running your agent

Connects to your LiveKit server and automatically joins rooms when participants connect.

Troubleshooting

  • Verify LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET are correct
  • Check that your LiveKit server is accessible
  • Ensure WebSocket connections aren’t blocked by a firewall
  • Test connectivity at meet.livekit.io
  • Verify your ANAM_API_KEY is valid
  • Check that ANAM_AVATAR_ID matches an existing avatar
  • Review agent logs for Anam connection errors
  • Ensure the avatar session starts before the agent session
  • Check your LLM API key is valid (OpenAI, Gemini, etc.)
  • Verify microphone permissions in the browser
  • Look for API errors in the agent logs
  • Confirm the agent is receiving audio tracks
  • Check your network connection stability
  • Consider using LiveKit Cloud for optimized routing
  • Reduce video sampling frequency if CPU-bound
  • Monitor your LLM API response times
Last modified on July 3, 2026