Header Logo

How to Support English, Spanish, and French Voices in a Pipecat-Based AI Avatar

How to Support English, Spanish, and French Voices in a Pipecat-Based AI Avatar

Pipecat multilingual avatar guide: manage ASR, LLM, TTS, and lip sync for English, Spanish, and French in realtime.

Introduction


Supporting English, Spanish, and French in a realtime avatar is not just a translation problem. It is a streaming systems problem: your ASR, LLM, TTS, and avatar renderer all need to agree on language, pacing, and turn boundaries often enough that the face still feels “live.” If you get this wrong, the result is usually one of three failures: the model answers in the wrong language, the voice sounds translated but unnatural, or the lip sync drifts because the speech stream and video stream were not aligned well enough.


By the end of this post, you should be able to design a multilingual avatar pipeline that detects or selects language per turn, routes text and speech correctly for English, Spanish, and French, and avoids the common latency and UX traps that show up in realtime voice agents.


What actually changes when you add multilingual support


For a voice avatar, “supporting a language” means more than swapping TTS voices. Each language affects four layers:


  • Input: speech recognition needs the correct language model, or at least robust language detection.

  • Reasoning: the LLM prompt and system behavior need to preserve language choice across turns.

  • Output: TTS must speak in the target language with the right phonemes, prosody, and punctuation handling.

  • Rendering: the avatar video must stay synchronized with the generated audio, even when phoneme timing varies by language.


The hard part is that these are coupled in realtime. For example, Spanish often expands character count relative to English, which can increase TTS latency and alter the cadence of the response. French has its own punctuation and liaison behavior that can make bad prompts or poorly chosen voices sound especially robotic. So the implementation needs to be explicit about language state, not just “let the model figure it out.”


Choose a language strategy up front


There are two practical ways to support English, Spanish, and French:


  1. Per-session language selection. The user chooses a language at session start, and the entire conversation stays in that language unless you intentionally switch.

  2. Per-turn language detection. The system detects the incoming language on each user utterance and responds in the same language.


Per-session selection is simpler and usually the right default for customer support or guided flows. It gives you stable voice selection, predictable prompts, and fewer edge cases. Per-turn detection is useful when the user may code-switch or start in one language and continue in another, but it requires stricter state handling so the agent does not bounce between languages mid-conversation.


A useful middle ground is: detect language on the first few user turns, then lock the session to the dominant language unless the user explicitly switches. That avoids accidental flips caused by a single foreign phrase or a borrowed proper noun.


Keep language state explicit in the agent


Whatever stack you use, treat language as a first-class piece of session state. Your agent should know:


  • the active language code, such as en, es, or fr

  • the corresponding TTS voice

  • the prompt variant or system instructions for that language

  • whether language switching is allowed mid-session


That state should drive every downstream component. If the user is speaking Spanish, do not rely on the model to infer that it should also answer in Spanish. Pass the language explicitly into the prompt and into the TTS layer. In practice, this is the difference between “works in demos” and “is debuggable in production.”


# Pseudocode: keep language in session state and reuse it everywhere
# Pseudocode: keep language in session state and reuse it everywhere
# Pseudocode: keep language in session state and reuse it everywhere


For prompt design, keep the instruction short and unambiguous. The model should not translate user input unless asked; it should respond naturally in the active language. If you need bilingual behavior, tell the model how to handle code-switching, names, or quoted content. Otherwise, you will get unwanted translation of product names, addresses, and technical terms.


TTS and lip sync: why language choice affects the avatar


Realtime avatars are usually driven by audio timing rather than text timing. The renderer needs a stream of audio chunks with consistent latency so it can keep mouth movement aligned. Once you change languages, the timing characteristics of the generated speech change too:


  • Spanish tends to be syllable-forward and can sound rushed if the voice settings are too aggressive.

  • French often benefits from slightly more measured pacing to preserve intelligibility.

  • English voices can tolerate more aggressive compression, but over-compression makes lip motion look clipped.


That means your TTS configuration should be language-specific, not just voice-specific. Even if the underlying provider exposes a single “speed” or “stability” control, test each language separately. The same numeric setting can feel natural in English and awkward in French.


Also watch punctuation. Most TTS systems use punctuation as a timing signal. If the LLM outputs inconsistent punctuation across languages, the speech rhythm will wobble. Good multilingual prompts should explicitly ask for normal punctuation and discourage overly long sentences unless the use case wants them.


# Example: a simple language-to-voice mapping for TTS selection
# Example: a simple language-to-voice mapping for TTS selection
# Example: a simple language-to-voice mapping for TTS selection


In production, measure end-to-end turn latency per language. If French responses consistently take longer to start speaking, users will perceive that as lower intelligence even if the text quality is good. For avatar systems, perceived responsiveness matters as much as correctness.


Practical agent behavior for multilingual conversations


There are a few rules that make multilingual avatars behave well:


  1. Answer in the user’s language unless a business rule says otherwise.

  2. Do not translate identifiers. Preserve names, emails, URLs, SKU codes, and commands.

  3. Switch languages only on explicit user intent or strong confidence.

  4. Keep short acknowledgments in-language. Even “okay” versus “d’accord” matters for consistency.

  5. Reset voice and prompt state when the language changes. Do not keep using the English voice for French text.


If you are building a support agent, the cleanest implementation is usually to route the conversation through one of three language profiles. Each profile defines the prompt, TTS voice, and any style constraints. That keeps behavior predictable and makes QA easier: you can test each profile independently, then test cross-language switching as a separate concern.


How this fits into a Pipecat-based avatar stack


If you are using Pipecat, the cleanest place to express this logic is in the agent pipeline, before text is sent to TTS and before the avatar renderer consumes the resulting audio. The Pipecat Protoface integration and the plugin repo are the right references if you want a concrete avatar service wired into a live voice pipeline.


The implementation pattern is straightforward: detect or select language early, attach it to the conversation state, and use that state to choose prompts and voices. The avatar service itself should stay dumb about language. It just needs synchronized audio/video; your agent decides which language to speak.


That separation matters because it makes the avatar layer reusable. The same avatar can speak English, Spanish, or French without special-casing the renderer. Only the agent-side language policy changes.


# Illustrative Pipecat-style pseudocode
# Illustrative Pipecat-style pseudocode
# Illustrative Pipecat-style pseudocode


One subtle but important trade-off: if your ASR is already language-specific, you may not need separate language detection at all. In that case, let the ASR output drive the language state. If ASR is multilingual and the language is ambiguous, add a lightweight detection step before the LLM. Either way, avoid having both the ASR and LLM independently decide language. That usually creates conflicting signals.


Testing and operational gotchas


Multilingual avatar systems tend to fail in predictable ways, so test for them directly:


  • Language drift: the model starts in English and answers the last clause in Spanish because the prompt was too loose.

  • Voice mismatch: the language changes but the TTS voice does not.

  • Latency spikes: one language has a slower TTS path or longer LLM outputs.

  • Transcript mismatch: ASR transcription is correct, but punctuation and casing degrade the downstream TTS rhythm.

  • Switching errors: the user asks, “Can we continue in French?” and the session state does not update cleanly.


Build a small test matrix with representative phrases in each language, including names, numbers, dates, and short interruptions. Measure: time to first audio, total turn duration, and whether the spoken answer matches the requested language. For avatar quality, subjective listening tests still matter, but these metrics will catch most regressions before they ship.


Finally, be careful with fallback behavior. If your English voice is high quality and your French voice is weaker, do not silently route French users to English. That kind of degradation may look operationally safe, but it produces a broken experience. It is better to fail clearly, or to degrade text-only, than to speak the wrong language with the wrong avatar cadence.


One concrete way to wire this up with Protoface


For teams already using a LiveKit voice agent, the most direct path is to drop the avatar into the agent with the Protoface LiveKit integration. The plugin is published on PyPI as pipecat-protoface, and the examples in the plugin repository are the quickest way to see how the avatar attaches to the live audio stream.


pip install pipecat-protoface
pip install pipecat-protoface
pip install pipecat-protoface


From there, your language logic stays in the agent layer. The avatar integration receives the synthesized audio and renders the face synchronously. If you need to manage avatars or sessions outside the agent process, the REST API and Python SDK are there for that control plane work; the exact request shapes are documented in the docs.


curl -X POST https://api.protoface.com/sessions \
curl -X POST https://api.protoface.com/sessions \
curl -X POST https://api.protoface.com/sessions \


Conclusion


To support English, Spanish, and French well in a realtime avatar, treat language as explicit session state, not an incidental output of the model. Select or detect the language early, use language-specific prompts and TTS voices, and keep the avatar layer focused on synchronized audio/video rather than language policy. Most of the work is in avoiding ambiguity and keeping latency stable per language.


If you are building on Pipecat, start by wiring language choice into the agent pipeline and validating the full turn loop in each language. Then use the avatar integration to keep lip sync aligned with the audio stream. For implementation details and current API shapes, check docs.protoface.com and the linked quickstarts in the GitHub repo.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.