How do you handle callers who code-switch? Do you lock the language, follow the caller, or ask them?
Our callers mix Hindi and English in the same breath: "haan toh mein bol raha tha, why are you calling me?" We assumed language handling was a detection problem. It turned out to be about six separate problems, and we found them one at a time, in production.
1. Detecting a language switch without flip-flopping
A caller says one English word and the bot jumps languages. We settled on a heuristic switch with guardrails you can configure per agent:
a minimum number of words per turn (default 3)
the same language for consecutive turns (default 2)
a dominant-language threshold (0.6) from a fastText classifier
a reset of the counter on mismatch, so one stray turn doesn't count
"meta" references ignored, for example someone saying "English" while speaking Hindi
2. Callers who just tell you what they want
"Let's speak in English" shouldn't need two confirming turns. We added explicit request detection, in English and Hindi (e.g. "हिंदी में बोलो"). It bypasses the heuristics and switches immediately.
3. The lock that wasn't a lock
Once a caller picks a language, auto-detection shouldn't drag them back. We built a language lock, but in production logs the lock was on and the agent still switched. Turn 6 showed language_locked=True, then Language switch detected: English -> Hindi anyway. Root cause: our LLM node had two independent language-detection paths, and only one checked the lock. The fix was a few lines, but finding it took log archaeology.
4. Lock or no lock is a product decision
Some businesses want a sticky language, and others want the bot to follow the caller turn by turn. So enable_language_lock is now a config flag. When it's on, an explicit request switches and locks, and only another explicit request unlocks. When it's off, the agent follows the caller freely.
5. The agent's own system phrases were speaking the wrong language
This one surprised us. Idle warnings, "are you there?" prompts, tool-filler announcements and end-call lines are spoken straight through TTS without the LLM. We found several ways they came out wrong:
A Hindi-only agent with auto-detect off was speaking English idle warnings in a Hindi voice. Our code treated "no auto-detect" as "no translation needed".
Conditional end-call phrases were never translated into the agent's language, so a Hindi call could end with an English goodbye. The translation function was only producing the English version for matching.
A caller who switched to Hindi mid-call got an English idle warning, because the cached messages were built once at call start for the primary language, and the English fallback looked like a valid hit. Now these messages translate on demand when they're spoken.
6. Testing it
The language-switching logic has 27 unit tests, and every bug above has a regression test.
What we'd tell anyone building this
Treat language as per-turn state with explicit rules, not as a one-time setting.
Anything the agent says outside the LLM (warnings, hangups, announcements) is a second language path you also have to maintain.
Log every switch decision. Our lock bug was only findable because we logged each one.
Make the policy configurable. "Sticky" vs "follow the caller" isn't a technical question.
If you build voice products: how do you handle callers who code-switch? Do you lock the language, follow the caller, or ask them? We'd love to compare notes.


Replies
I'd follow the caller by default and lock only when they explicitly ask. A Hindi sentence with a few English terms shouldn't automatically mean "switch to English."
Curious how you handle the voice itself during a switch. Can the same voice carry across both languages, or does the caller hear a change in accent or tone? Getting the language right but sounding like a different person halfway through would be a strange experience.