What is the best way to create a multilingual chatbot?

Hello everyone,

I am working on a project and I need to build a chatbot that will be used in three different countries, Greece, Italy, Romania. I have seen the N26 video and I have also read some articles like this.

I get these approaches to be different ways (if not please correct me) to develop a multilingual chatbot. But which one is better? What do you suggest? Is there any other tutorial to have a look at?

Thank you in advance.

Hello :slight_smile:

Hope these threads will help:

You can also take a look at my multilingual bot here :slight_smile:


It depends on your use-case:

  • Do you want the bot to
    • understand all languages but reply in one? (easiest)
    • understand all languages but reply in the one specified by the user? (my approach)
    • understand all languages and reply in the detected language of the last message? (hardest)
  • Would the same person usually talk in multiple languages?
    • If yes, you can insert all languages all in the same chatbot/deployment using one of the three options above
      • This saves resources but the chatbot’s files will be bloated due to all the languages and the chatbot may confuse languages
    • If no, consider having three different chatbots/deployments with a language selector on the UI to connect to these different bots
      • This is more expensive in terms of deployment but each chatbot will have a better accuracy and cleaner files
3 Likes

Hey @ChrisRahme, thank you for these threads. I will go through them and come back again.

1 Like

Hey @ChrisRahme , I went through all these. Really helpful. I appreciate your help.

I will follow your approach in this case. I have a question related to this. If users use the agent via an Android app, do you know if it is possible to let’s say the user defines once his preferred language and the app to send this choice to the agent every time the user logs in?

Well, this is something I don’t know for sure but I assume that each user will talk only in one language. Your approach follows the first bullet from the above, correct?

One last question, in your domain file you have implemented some responses to any language and others (like faq) only in one, what is the purpose of this? My understanding is that I have to implement every response to every language I will use.

1 Like

Nice idea :slight_smile:

What you could do is store that preference somewhere on the phone/device and send it via a hidden payload every time the user opens the app.

You surely have a send() function to send you message. At the app startup, you could send something like this:

send('/set_language{"language": "' + saved_language + '"}')

Of course this means you’d need to have an intent set_language with at least two examples with entities, and have the slot autofilled.

This could also double up as a way to let the bot start the conversation, if you do

send('/greet{"language": "' + saved_language + '"}')

with a rule to greet back.


In my country, people usually mix up 3 languages when they talk, even in a same sentence. So my approach was to first ask the user which language they want, then only reply in this language (until user asks to change it again).

But the user will still be able to understand all languages. If you take a look at some of my bot’s NLU data, you can see 5 languages in a same intent, sometimes all mixed up in one example.


Most responses come from the custom actions, which dispatches the message according the language slot (this can now be done without custom actions via conditional response variations).

But, basically, not all responses are implemented because the bot is unfinished :slight_smile: This bot was just a proof-of-concept for a bot that is privatized by a company.

1 Like

Alright, you clarified everything :smiley: Once again, thank you for your help.

1 Like

Glad to be of help :slight_smile:

Hey @ChrisRahme , I am coming back to this because for some reason the tracker seems to have stopped identifying the language entity on the very first user’s message but works fine with the buttons. The thing is that two days ago it worked just fine.

I have followed your chatbot’s implementation.

class ActionUtterGreet(Action):
    def name(self):
        return "action_utter_greet"

    def run(self, dispatcher, tracker, domain):
        announce(self, tracker)
        followup_action = "action_utter_ask_mood"
        text = get_text_from_lang(
            tracker,
            [
                "Hey there! I am your Alameda personal assistant powered by artificial intelligence.",
                "ΓΔÎčÎŹ, Î”ÎŻÎŒÎ±Îč Îż Ï€ÏÎżÏƒÏ‰Ï€ÎčÎșός ÎČÎżÎ·ÎžÏŒÏ‚ Ï„ÎżÏ… Alameda."
            ]
        )

        if tracker.get_slot("language") is None or not tracker.get_slot("language"):
            followup_action = "action_utter_ask_language"

        print("\nBOT:", text)
        dispatcher.utter_message(text=text)
        return [FollowupAction(followup_action)]

It dispatches correctly the text from this function e.g. Hey there! I am your Alameda personal assistant powered by artificial intelligence. but when it comes here

if tracker.get_slot("language") is None or not tracker.get_slot("language"):
            followup_action = "action_utter_ask_language"

seems like the language isn’t being set.

Any ideas?

So it’s probably the case that the language wasn’t even set before (get_text_from_lang() defaults to the first entry in the list if no language was detected).

Anyway, you’re saying the entity is detected when entered via buttons, but not via text?

Exactly.

I agree.

Then it’s just a regular entity recognition problem. Do you have enough examples?

Do you have synonyms (see this and this) set for the languages and/or value annotation like the following?

- intent: set_language
  examples: |
    - change language to [english]{"entity": "language", "value": "English"}
    - plz speak [greek]{"entity": "language", "value": "Greek"}
    - ÎœÏ€ÎżÏÎ”ÎŻÏ‚ Μα ÎŒÎčÎ»ÎŹÏ‚ [ΔλληΜÎčÎșÎŹ]{"entity": "language", "value": "Greek"}
    - change lang to [en]{"entity": "language", "value": "English"}
etc...

I haven’t created them yet.

But, I don’t understand, how does the intent: set_language relates to intent: greet?

set_language is for when the user asks to set the language, which should run action_set_language.

greet will run action_greet, which will greet the user back and then run action_ask_language if the language slot is not already set.

action_ask_language will ask the user to choose a language. Logically, the user will answer with the set_language intent, which should run action_set_language.

Ok, I see. Then I misunderstood the flow :sweat_smile:

I thought that when the user greets in greek the agent is able to understand it and based on that to choose the corresponded answer from the custom action.

But, now I think this is not the case and the language should be set at the very beginning either the user asks for it or in the case of an app somehow the agent get informed to use a specific language, is that correct?

That’s correct :slight_smile:

The bot does not detect the language.

You went with approach #1 from that thread. If you want language detection you should go woth #2 and create a custom pipeline component that detects the language and sets the language slot on each message.

So, the get_text_from_lang() doesn’t make sense to keep it in the case that I don’t detect the language via the pipeline.

get_text_from_lang() is just a function that returns the correct output of the given list according to the language slot :slight_smile:

You can keep it or do a bunch of if language == '...'. But anyway, you don’t need custom actions for that anymore, you can use Conditional Response Variations instead:

responses:
  utter_greet:
    - condition:
        - type: slot
          name: language
          value: greek
      text: "ΓΔÎčÎŹ, Î”ÎŻÎŒÎ±Îč Îż Ï€ÏÎżÏƒÏ‰Ï€ÎčÎșός ÎČÎżÎ·ÎžÏŒÏ‚ Ï„ÎżÏ… Alameda."
    - text: "Hey there! I am your Alameda personal assistant powered by artificial intelligence."

Yes this is true. I started using it. Thank you @ChrisRahme for your time.

2 Likes