21 Languages and Skills
You can design both single-language and multi-language skills. For understanding user input, you can either use Oracle Digital Assistant's native support for various languages or a translation service. For output, you typically define the strings for each target language in resource bundles.
Language Use Cases for Skills
The approach you take to handling your language requirements for skills depends on a number of factors. Here are some typical use cases and ways you can approach them.
You Want the Skill to Work Equally Well in Multiple Languages
For skills that you target to the languages that Oracle Digital Assistant supports natively, you can add training data for all of the target languages. This includes example utterances for intents and custom entity values.
Prerequisites:
- The languages you are targeting all are on the list of Natively-Supported Languages.
- The Platform Version of the skill is 20.12 or higher.
General steps:
- When creating the version (or clone) of the skill, designate one of the natively-supported languages as the primary language. This language will serve as the default language in the skill. Once you have set it, you can not change it.
- On the skill's Settings, Intents, or Entities page, add any additional natively-supported languages that you want to target.
- Build the training corpus in the primary language.
- For each additional language, augment the training corpus as necessary.
- For any value list entities that you create in the primary language, add values in the additional language that correspond to each of the values in the primary language.
- Create resource bundles for each of the skill's output strings, provide entries for each language, and reference the resource bundle keys from the appropriate places in the dialog flow and the skill's settings.
Other notes and considerations:
- In terms of user experience, this approach gives you the best opportunity to satisfy user expectations in multiple languages.
- To realize the potential of this approach, be sure to allocate adequate resources for multi-language intent training and formulating effective output messages in all of the target languages.
You Want to Avoid Using a 3rd-Party Translation Service
If you want to create a skill with one or more non-English languages but don't want to use a 3rd-party translation service, you can use Digital Assistant's native language support. See the above section on optimizing skills for multiple languages.
You Want to Create a Single-Language Skill in a Language Not Supported Natively
Prerequisite:
- You have configured a translation service (either Microsoft Translator or the Google Translation API).
General steps:
- Create intent utterances and entity values in the language that you are supporting.
- Add code to the dialog flow to detect the language of the user input and to translate it behind the scenes. (For non-English skills that rely on a translation service, the underlying training model of the skill is in English.)
- Create resource bundles for the skill responses.
Other notes and considerations:
- If the target language of your skill is among the natively-supported languages, consider using the native language approach. Then, if you later need to add other languages that are natively supported, you will be able to optimize intent resolution for each language (in addition to having more control over the output messages).
- If you later want to add other languages to the skill and one or more of the desired languages isn't supported natively, you would need to create a new skill from scratch and set English as the primary language in the new skill.
- Entity values for built-in entity types (such as NUMBER, EMAIL, and DATE) are extracted after the user input has been translated to English behind the scenes.
You Want to Create a Multi-Language Skill that Contains One or More Languages That Are Not Supported Natively
Prerequisites:
- You have configured a translation service (either Microsoft Translator or the Google Translation API).
- The primary language of the skill is English.
- All languages that you add are handled through the translation service.
General steps:
- When creating the skill, designate English as the primary language (and in translation mode).
- Create intent utterances and entity values in English.
- Add code to the dialog flow to detect the language of the user input and to translate it behind the scenes.
- To handle skill responses, either:
- Set up the dialog flow to translate skill responses from English to the user's language.
- Create resource bundles with entries for each target language and configure the skill to use them in its responses.
Other notes and considerations:
- Entity values for built-in entity types (such as NUMBER, EMAIL, and DATE) are extracted after the user input has been translated to English behind the scenes.
You Want a Multi-Language Skill Without Needing to Create Resource Bundles for Each Language
If you'd like to create a multi-language skill but do not want to create resource bundle entries for the various languages, you can use the translation service to handle the skill's responses. (This approach does not work with Digital Assistant's native language support.)
Prerequisites:
- You have configured a translation service (either Microsoft Translator or the Google Translation API).
- The primary language of the skill is English.
- All languages that you add are handled through the translation service.
General steps:
- When creating the skill, designate English as the primary language (and in translation mode).
- Add code to the dialog flow to detect the language of the user input and to translate it behind the scenes.
- Set up the dialog flow to translate skill responses to the user's language.
Other notes and considerations:
- If the target languages of your skill are all among the natively-supported languages, consider using the native language approach, since this will enable you to optimize intent resolution for each language (in addition to having more control over the output messages).
- Even if you need to target languages that are not natively supported, you may find that the benefits of having greater control of the output messages justify the costs.
Language Mode
When you create a new skill (or version or clone of a skill), you use the Primary Language field in the Create dialog to determine both:
- A primary language.
- A language mode (either Natively Supported or Translation Service).
The language mode determines:
- How the user language is detected and processed.
- Which languages you can add to your skill.
- If your skill uses the Natively Supported language mode, you can use any of the languages that are supported natively in Oracle Digital Assistant.
- If it uses the Translation Service mode, you can use any of the languages supported by the translation service.
Caution:
Once you have clicked Create in the wizard, the language mode is permanently set for that version of the skill. You can't mix and match language mode in skills or digital assistants.Native Language Support for Skills
Starting with Platform Version 20.12, there is native support in Oracle Digital Assistant for multiple languages. When you develop a skill with this native language support, you don't need to use a 3rd-party translation service to handle user input and skill responses in those languages.
If you are developing such skills for inclusion in a digital assistant, that digital assistant must also use the native language support. See Native Language Support in Digital Assistants.
How Native Language Support Works
-
Training data can be supplied in each of the (natively-supported) languages that you are designing the skill for.
When you use native language support, the skill is trained according to a unified model that incorporates all of the natively-supported languages. You can provide training utterances in one or more of your skill's target languages.The training utterances that you provide in one language help build the model for all of the natively-supported languages that you are using in your skill. For skills that you target to multiple languges, typically you will start by building your training corpus in the skill's primary language. Then you can (and should) add training utterances in the other languages, though you probably won't need nearly as many in those other languages.
This differs from skills that use a translation service. In those skills, the underlying training model is always in English, even if the training corpus is provided in another language.
- Entity values for built-in entity types (such as NUMBER, EMAIL, and DATE) are extracted in the language of the conversation. (This differs from the case with skills in translation service mode, where the values are extracted after the input has been translated by the translation service.
- Entity values for custom entities are matched to the values provided for the language of the current conversation.
Natively-Supported Languages
Here are the languages (and the corresponding languages codes) that are currently supported natively in Oracle Digital Assistant.
- Arabic (ar)
- Dutch (nl)
- English (en)
- French (fr)
- German (de)
- Italian (it)
- Portuguese (pt)
- Spanish (es)
This means that you can create skills and digital assistants for these languages without using a translation service, such as Google Translate.
Here's an overview of the level of support for each language.
Language | Language Understanding | Voice | Insights | Data Manufacturing | Conversation Designer |
---|---|---|---|---|---|
Arabic (ar) | Yes | No | Yes | Yes | No |
Dutch (nl) | Yes | No | Yes | Yes | No |
English (en) | Yes | Yes | Yes | Yes | Yes |
French (fr) | Yes | Yes | Yes | Yes | No |
German (de) | Yes | No | Yes | Yes | No |
Italian (it) | Yes | No | Yes | Yes | No |
Portuguese (pt) | Yes | Yes | Yes | Yes | No |
Spanish (es) | Yes | Yes | Yes | Yes | No |
For a more detailed comparison of the support for each language, see Feature Support by Language.
Create a Skill with Natively-Supported Languages
Here are the general steps for creating a skill that uses Oracle Digital Assistant's native support for multiple languages.
- When creating the skill, select Platform Version 20.12 or higher and select the primary language that you want to support from the Primary Language dropdown.
The language you select must be within the Natively-Supported section of the dropdown.
- For each intent that you create, add utterances for your skill in the primary language:
- Click
to open the side menu, select Development > Skills, and open your skill.
- In the left navigation for the skill, click
- Select an intent.
- In the Examples text field, type the utterance and press Enter.
- Repeat the previous two sub-steps for each intent.
- Click
-
For any custom entities in your skill, make sure the values are in the skill's primary language.
You can add and edit custom entities by clicking
in the left navigation of the skill.
- For any components in your dialog flow that have properties that display prompts or labels, make sure that you explicitly define those properties. If you don't define these properties, customers may encounter default text from those properties, which are in English.
- In the skill's settings, update all of the configuration messages and prompts to use the primary language:
To access these messages and prompts:
- In the left navigation for the skill, click
.
The messages and prompts are located on the Configuration and Digital Assistant tabs.
Note:
If you're planning to support multiple languages in the skill, you will need to define resource bundle keys for these values and then refer to those keys in the fields for these properties. And, even if you don't plan to support multiple languages, you may want to do this anyway, since the resource bundle provides a single place where you can edit the values of all of your strings. See Resource Bundles for Skills. - In the left navigation for the skill, click
Add Natively-Supported Languages to a Skill
For skills (or versions of skills) where you have chosen a natively-supported primary language, you can add additional natively-supported languages.
- Make sure your skill is running on Platform Version 20.12 or higher.
If it isn't, you need to create a clone or a new version of the skill and set it to use Platform Version 20.12 or higher.
- In the skill's left navbar, click the Settings(
) icon and select the General tab.
- Scroll down to the languages section, click Add Language and select the language from the dropdown.
- For each of the intents in the skill, add a conversation name and additional utterances in the added language:
- Click Intents (
) in the left navbar.
- Select the intent to edit.
- Select the tab for the language that you just added.
- Click
to enter a descriptive name or phrase for the intent in the Conversation Name field.
- Click Intents (
- For any entities that are based on key-value pairs (value list entities and dynamic entities), enter values for that language.
- Enable the skill to display entity values in the language of the conversation:
- In components that you use to resolve entities (
System.ResolveEntities
andSystem.CommonResponse
), add theuseFullEntityMatches
property and set it totrue
.By making this change, custom entity values are stored as JSON objects instead of as simple strings.
- In all of your FreeMarker expressions that reference custom entity values (whether in the dialog flow or in various skill properties), insert the attribute corresponding to the value you want to read. You can use any of the following attributes:
value
- returns the value of the entity in the conversation of the language.primaryLanguageValue
- returns the value of the entity in the primary language of the skill. You would use this option for expressions that are used for business logic (e.g. to determine whether or not to display a prompt, based on the entity value).originalString
- returns the value that the user entered to match the entity. This value could be a synonym of the entity value.
For example, if you have the expression
${PizzaSize}
for referencing the value of the PizzaSize entity, you would change it to${PizzaSize.value}
to display the value in the language of the conversation.
- In components that you use to resolve entities (
- If you haven't already done so, create resource bundle keys for all of the output that users will see, enter values for the primary language, and insert references to those keys in the appropriate places. This includes:
- Output text in the dialog flow.
- Prompts for entities that are included in the entity definition.
- Messages and prompts defined in the skill's settings. To access them:
- In the left navigation for the skill, click
.
The messages and prompts are located on the Configuration and Digital Assistant tabs.
- In the left navigation for the skill, click
- For any components in your dialog flow that have properties that display prompts or labels, make sure that you explicitly define those properties (so that they don't default to English values) and create resource bundle entries for them.
- Add values in the additional language for all of the resource bundle keys.
- Augment the training corpus as necessary in the additional language.
Since skills with natively-supported languages are based on a unified training model in which all of the training helps with intent resolution in all of the skill's target languages, the training model should already work for your additional language, even without adding utterances in that language. But its accuracy will be probably be lower than it is for the primary language. To improve the accuracy, do the following:
- Build batch tests in the additional language and run them to determine how well the model performs without any utterances in the additional language. See Batch Test Intents.
- Iteratively add training utterances in that language and test until you get a satisfactory level of intent resolution.
- Click Intents (
) in the left navbar.
- Select the intent to edit.
- Select the tab for the language that you just added.
- In the Examples section, enter example utterances in the additional language.
You probably won't need to add as many utterances in those additional target languages as you did in the primary language.
- Click Intents (
Switch from a Translation Service to Native Language Support
If you want to take advantage of Oracle Digital Assistant native language support in a skill that has been configured to use a translation service, you can create a new version or clone of that skill and enable that support.
To convert a skill to use native language support, all of the following conditions need to be met:
- The version of the skill that you are converting must only use languages that are supported natively in the version of the platform that you are converting to. For that list, see Natively-Supported Languages.
- Upon creation of the skill (or new version or clone), specifying the Platform Version as 20.12 (or later).
If all of those conditions aren't met, you'll need to continue using a translation service for all of the non-English languages in the skill.
To convert a skill to use Digital Assistant's native language support:
- Create the new version or clone, and specify the primary language for the skill.
-
Click
to open the side menu and select Development > Skills.
-
In the tile for the skill that you want to version or clone, click
and select Version or Clone.
- In the Platform Version field, select version 20.12 or later.
If it wasn't present before, a Primary Language field will appear.
- In the Primary Language dropdown, select the language from the Natively Supported section of the dropdown that best corresponds to the predominant language of the previous version of the skill.
Note:
The platform version and primary language can't be changed after you click Create. - Click Create.
-
- Add any additional languages that you want to support.
- In your dialog flow, remove any translation components (
System.DetectLanguage
,System.TranslateInput
, andSystem.TranslateOutput
), theautotranslate
context variable, and the component-leveltranslate
property.
Training Corpus for an Additional Language
When you add a language, here's how the various parts of the skill are handled:
-
Intents—The intent names, whatever their language, remain the same for each language. For each intent, you can add example utterances in each language. Since the model for natively-supported skills is unified, any utterances that you add for a given language can also help the model for other languages. Nevertheless, you can strengthen your model by adding utterances for each language.
In particular, you should concentrate on adding phrases that express an intent in a languages that are not direct translations of the phrase in the primary language.
-
Entities—For entities that are based on key-value pairs (value list entities and dynamic entities), you define the values in the primary language and then, for each additional language, add values that correspond to the primary language's values.
For prompts and messages that are defined in the entities (including prompts that are defined in composite bag entities), you reference resource bundle keys, where you provide the appropriate text in each target language.
For other properties, such as Enumeration Range Size, the values apply for all languages.
Note:
The Fuzzy Match property is disabled for skills where it is not supported for all of the languages.
Language Detection in Skills with Natively-Supported Languages
In skills that use multiple natively-supported languages, the digital assistant (or standalone skill) can automatically detect the user's language at the beginning of the session. Here's how it works:
- The language is automatically detected for digital assistants and skills that are configured with multiple natively-supported languages.
- If there is only one (natively-supported) language in the skill or digital assistant, language detection is turned off.
- If the digital assistant or skill uses a translation service, the translation service handles the language detection, not the skill or digital assistant.
- The language is not automatically detected if the skill or digital assistant is accessed through a channel where the profile.languageTag or profile.locale variable has been set.
- The language is detected in the first utterance of the conversation and not updated in the session, even if the user switches languages.
- By default, the channel session last 7 days before it expires.
Translation Services in Skills
For skills that target languages other than English and which don't use Digital Assistant's native language support, you need to configure a translation service. You can use either Microsoft Translator or the Google Translation API.
For such skills, when a user enters a non-English request or response, the skill uses the translation service to convert this input to English. Once it’s translated, the Natural Language Processing (NLP) engine can resolve it to an intent and match the entities. The skill can then respond to the user by using the translation service to translate the labels and prompts or by referencing language-specific strings in resource bundles.
For skills that have a training corpus in a non-English language, the translation service is also used at design time. When you train such a non-English skill, it creates English versions of the example utterances and custom entity values to be used in the training model (though these translations are not shown in the skill designer).
Note:
If you intend to add a skill that is based on a translation service to a digital assistant, that digital assistant must also use a translation service.Change in Translation Service Skills Starting with Platform Version 20.12
Starting with Platform Version 20.12 of Oracle Digital Assistant, support for working with translation services has changed:
- When you create a new skill, skill version, clone, or skill extension using platform version 20.12 or later, you need to designate a primary language. (On platform versions 20.09 and prior, the predominate language is detected, based on your training data for the skill.)
- The
autotranslate
context variable and thetranslate
property now can be given different values for input and output. See autotranslate context variable and translate property.
Note:
If you are working with a version of a skill that is based on Platform Version 20.09 or earlier, the automatically-detected predominant language is still used.Translation Services Supported
Google Translation API
To use the Google Translation API, you need to generate the API Key. You create this key from the GCP Console (APIs & services > Credentials). To find out more, see the Google Cloud Platform Documentation.
Microsoft Translator
If you want to use Microsoft Translator as your translation service in Oracle Digital Assistant, you need to subscribe to Translator or the Cognitive Services multi-service and get a secret key. See https://docs.microsoft.com/en-gb/azure/cognitive-services/translator/reference/v3-0-reference.
These are the main things you need to know:
- You need to use the Global region and its corresponding URL (
https://api.cognitive.microsofttranslator.com/
). - You need to obtain a secret key for authentication. You can get it from the Keys and Endpoints section of the Azure Portal.
Register a Translation Service in Oracle Digital Assistant
-
Click
to open the side menu and select Settings > Translation Service.
-
Click + Service.
-
In the Translation Services dialog, enter the URL and authorization key (for the Microsoft Translator service) or authorization token (for the Google Translation API) .
- URL
- Authorization key (for the Microsoft Translator service) or authorization token (for the Google Translation API) .
Add a Translation Service to Your Skill
- If you haven't done so already, register a translation service in Oracle Digital Assistant.
- Click
to open the side menu, select Development > Skills, and select your skill.
- In the skill's left navbar, click the Settings(
) icon and select the General tab.
- Navigate to the Translation Service dropdown and select your translation service.
Predominant Language
For skills that you set up to use Platform Version 20.09 or earlier and which have been configured with a translation service, Oracle Digital Assistant automatically assigns a predominant language for that skill, based on the language of the skill's example utterances.
You can find what predominant language has been assigned for a skill by clicking the Settings() icon in the skill's left navbar, selecting the General tab, and checking the value of the Predominant Language property.
For such skills, make sure that all of your intent example utterances, entities, and dialog response text are in the predominant language.
If you are designing the skill to support multiple languages, the predominant language must be English.
For digital assistants that are based on Platform Version 20.09 or earlier, the predominant language is determined by the predominant language of the first skill that you add to the digital assistant. Any other skills that you add to the digital assistant must have the same predominant language.
If the first skill that you add has no predominant language (because no translation service has been specified in the skill), the digital assistant's predominant language is set to English. In this case, you can either add skills that have English as the predominant language (or which have no predominant language set).
Note:
For skills and digital assistants that are based on Platform Version 20.12 or higher, a predominant language is not set. Instead, you specify the primary language when you create the skill or digital assistant.Approaches Based on Translation Services
When you use a translation service to support skills that converse in non-English languages, you can use one of these development approaches:
-
Create non-English single-language skills where you:
- Prepare the training corpus in the target language of the skill.
When you develop non-English single-language digital assistants, you populate them with such single-language skills (where all of the skills in a given digital assistant have the same predominant language).
-
Create multi-language skills where you:
- Prepare the training corpus in English.
- Enhance the skill's dialog flow to manage the translation of the user input and the skill's responses.
- Optionally (but preferably), create resource bundles for one or more languages for the skill's labels, prompts, and messages. This is desirable because it allows you to control the wording of the skill's responses.
In both cases, Digital Assistant uses the translation service to translate user input to the base language. For responses, it uses resource bundles (if provided in the skill) or the translation service to translate the skill's response back to the user's language.
Non-English Single-Language Skill Using a Translation Service
To develop a skill for a single non-English language that relies on a translation service, you:
-
If you haven't already done so, add a translation service to your skill.
- Create the utterances for your skill in the target language of the skill (instead of in English):
- Click
to open the side menu, select Development > Skills, and open your skill.
- In the left navigation for the skill, click
- Select an intent.
- In the Examples text field, type the utterance and press Enter.
- Repeat the previous two sub-steps for each intent.
- Click
-
For any custom entities in your skill, make sure the values are in the skill's predominant language.
You can add and edit custom entities by clicking
in the left navigation of the skill.
If you don't provide custom entity values in the predominant language, the skill won't be able to properly process user input that contains any values that need to be matched by a custom entity.
- In the skill, update all of the configuration messages and prompts to use the predominant language:
To access these messages and prompts:
- In the left navigation for the skill, click
.
The messages and prompts are located on the Configuration and Digital Assistant tabs.
- In the left navigation for the skill, click
-
You can’t translate the names of the built-in entities.
-
When you set up your skill this way, the language processing framework detects non-English input and then translates it into English (the language of the training model) behind the scenes. After evaluating the input, it determines the appropriate response and translates it back to the target language.
This can impact translation costs because it requires more calls to the translation service than a skill where the training corpus is already in the English.
Multi-Language Skills with Auto-Translation
For skills that use a translation service, you can enable a to automatically detect the user’s language and communicate in that language.
To set this up, you need to update the dialog flow to:
- Detect the user's language.
- Translate the user input so that it can be resolved by the
System.Intent
component.
You can handle translation of user input using either of the following strategies:
- Opt-in: You individually set the
translate
property totrue
for each component that you want to have translated. - Opt-out: You set the
autoTranslate
context variable totrue
so that input for each component is translated by default. If there is a component for which you don't want translation, you set itstranslate
property tofalse
.
Note:
For both thetranslate
property and the autoTranslate
context variable, you can also distinguish between input and output. For example, you may wish to have the input translated by the translation service but leave the output untranslated by the translation service (so that you can provide the translations yourself through resource bundles).
autotranslate
context variable and translate
property
You can use either or both the autotranslate
context variable and the component-level translate
property to determine what gets translated by the translation service.
- The
autotranslate
context variable applies globally to the whole skill. If you don't specifyautotranslate
, it's value isfalse
. - The
translate
property can be set individually for each component. When thetranslate
property is set for a component, it overrides theautotranslate
value for that component.
For both autotranslate
and translate
, you can set the value as a single Boolean or you can specify separate Boolean values for input and output.
autotranslate
Context Variable
Here's an example of using autotranslate
, to turn on automatic translation for both input and output:
setAutoTranslate:
component: "System.SetVariable"
properties:
variable: "autoTranslate"
value: true
And here's how you could use autotranslate
to translate input by default, but not output:
setAutoTranslate:
component: "System.SetVariable"
properties:
variable: "autoTranslate"
value:
input: true
output: false
Note:
You don't have to specifyautotranslation
values that are false. For example, in the previous snippet, you don't need to include the line:
output: false
translate
Property
Here's an example of setting the translate
property to send both the component's input and output to the translation service that has been specified for the skill:
askName:
component: "System.Text"
properties:
prompt: "${rb.askNamePrompt}"
variable: "name"
translate: true
And here's an example of sending on the component's input to the translation service:
askName:
component: "System.Text"
properties:
prompt: "${rb.askNamePrompt}"
variable: "name"
translate:
input: true
output: false
Opt-In Translation
Here are the steps if you want to individually specify which components to translate :
- If you haven't already done so, add a translation service to your skill.
- Make sure that the
autoTranslate
context variable is not set (or set tofalse
). - Above the state for the
System.Intent
component, add the System.DetectLanguage component:detect: component: "System.DetectLanguage" properties: useExistingProfileLanguageTag: true transitions: {}
Note:
TheuseExistingProfileLanguageTag
property is used when a skill is part of a digital assistant that has a translation service. This enables the skill to use the language that is detected by the digital assistant immediately. Otherwise, the skill might provide a message or prompt in English before the language is (re-)detected. If the skill is not in a translation-enabled digital assistant, the property is ignored. - In the System.Intent component, set the translate property to
true
.intent: component: "System.Intent" properties: variable: "iResult" translate: true
- For other input components, also set the translate property property to
true
, or set theinput
attribute of thetranslate
property totrue
, e.g.:askName: component: "System.Text" properties: prompt: "${rb.askNamePrompt}" variable: "name" translate: input: true output: false
Example: Multi-Language Skill with Auto-Translation (Opt-In)
metadata:
platformVersion: "1.0"
main: true
name: "AutoTranslatePizzaJoe"
parameters:
age: 18
context:
variables:
size: "PizzaSize"
type: "PizzaType"
crust: "PizzaCrust"
iResult: "nlpresult"
states:
detect:
component: "System.DetectLanguage"
properties:
useExistingProfileLanguageTag: true
transitions: {}
intent:
component: "System.Intent"
properties:
variable: "iResult"
translate: true
ShowMenu:
component: "System.CommonResponse"
properties:
processUserMessage: true
translate:
input: true
output: false
metadata:
responseItems:
- type: "text"
text: "Hello ${profile.firstName}, this is our menu today:"
...
...
Opt-Out Translation
Here are the steps if you want to use auto-translation by default (and individually specify components to not translate) :
- If you haven't already done so, add a translation service to your skill.
- Add
autoTranslate: "map"
as a variable to thecontext
node.context: variables: ... autoTranslate: "map"
- Within the
states
node, above yourSystem.Intent
component, add aSystem.SetVariable
component. Then set thevariable
property to use theautoTranslate
context variable and set theinput
(and, optionally,output
) attribute of thevalue
property totrue
.setAutoTranslate: component: "System.SetVariable" properties: variable: "autoTranslate" value: input: true output: true transitions: ...
Note:
If you are using resource bundles, you'd set theoutput
value tofalse
. - For the next state, add the System.DetectLanguage component:
detect: component: "System.DetectLanguage" properties: useExistingProfileLanguageTag: true transitions: {}
Note:
TheuseExistingProfileLanguageTag
property is used when a skill is part of a digital assistant that has a translation service. This enables the skill to use the language that is detected by the digital assistant immediately. Otherwise, the skill might provide a message or prompt in English before the language is (re-)detected. If the skill is not in a translation-enabled digital assistant, the property is ignored. - For any components that you don't want auto-translated, see the translate property to
false
, e.g.:done: component: "System.Output" properties: text: "${rb('OnTheWay','${size.value}','${type.value}')}" translate: input: true output: false transitions: return: "done"
Example: Multi-Language Skill with Auto-Translation for Input (Opt-Out)
In this example, auto-translation is set up for input, but it is off for output (so that output text can be specified in resource bundles).
metadata:
platformVersion: "1.0"
main: true
name: "AutoTranslatePizzaJoe"
parameters:
age: 18
context:
variables:
size: "PizzaSize"
type: "PizzaType"
crust: "PizzaCrust"
iResult: "nlpresult"
autoTranslate: "map"
states:
setAutoTranslate:
component: "System.SetVariable"
properties:
variable: "autoTranslate"
value:
input: true
output: false
transitions: {}
detect:
component: "System.DetectLanguage"
properties:
useExistingProfileLanguageTag: true
transitions:
...
Manipulate Input Before Translation
If you want to be able to manipulate input text before sending it to the translation service, you can use the System.TranslateInput component. For example, you might want to process user input to remove some personal data before sending it to the translation service.
sourceString
variable holds the text to be translated. (This input, for example, may have been gathered by a System.Text
component and processed by another component.) After the System.TranslateInput
completes its processing, the English translation is stored in the translatedString
variable.context:
variables:
autoTranslate: "boolean"
translatedString: "string"
sourceString: "string"
...
states:
...
translateInputString:
component: "System.TranslateInput"
properties:
source: "sourceString"
variable: "translatedString"
transitions: {}
Resource Bundles for Skills
If your skill is designed to handle multiple languages and you want to control the wording for your skill’s responses, use resource bundles. You can provide resources bundles for as many languages and dialects as you need.
Even if your skill is targeted toward only one language, using resource bundles has benefits, such as enabling you to put all of your use-facing text in one place.
There are number of options for parameterizing resource bundle entries, which enables you to embed variables in the strings. In addition, you can use ICU formatting for bundle entries to help construct the wording of a response depending on how its parameters are resolved. This enables you to do things like adjust wording according to whether something is singular or plural.
Create a Resource Bundle Key
For each skill, you can define resource bundle keys that identify the output text that needs to be translated and then provide values for those keys in one or more languages. Keys are automatically defined for the conversation name of any intents you have created as well as for the answers for any answer intents. However, you need to create keys yourself for other output text that you want to translate, such as text from your dialog flow.
-
In the skill's left navbar, click
.
- Click the User-Defined tab.
-
Click Add Bundle.
The Create Entry dialog appears, which enables you to create your first entry in the skill's primary language.
-
Enter the a key (which you use to reference the bundle entry) and its corresponding text. For example, for the user prompt How old are you?, you might enter HowOld in the Key field and then How old are you? in the Text field.
- For Annotation, enter any information that will be useful for those that may need to reference the entry later, such as translators.
-
Click Create Entry.
Note:
Resource bundles are not the mechanism for translating value list entities. Instead, you provide the translation within the custom entity definition. For skills using natively-supported languages, you provide values for that native language. For skills based on a translation service, you provide the translated values as synonyms for the values in the default language.Add a Language to a Resource Bundle Key
When you create a bundle key, its initial Text value is for the skill's default (i.e. primary or predominant language).
To add text for a bundle key in another language:
-
Select the key and then click Add Language.
-
Complete the Create Entry dialog:
-
Language—Add an IETF BCP 47 language tag like
fr
for French orde
for German. -
Text—The output string. For example, for a French translation (
fr
) of the HowOld key, you’d add a string like quel âge avez-vous ?Note:
You can also use more specific locales (such asen-US
), but they are not useful in most cases. For example, if you are using a translation service (via theSystem.DetectLanguage
component) to detect the language, only a two-letter code will be returned.If the skill can’t match the input language with a language tag defined in the bundle, it defaults to a less-specific tag (if one is available). If none of the entries match the browser’s language, the skill uses the default entry, English. See Resource Bundle Entry Resolution for details.
-
Translate Conversation Name
At some points within a conversation, such as when the skill is trying to determine what flow the user wants to follow, the skill may present a dialog that refers to one more intents. In these cases, the skill refers to the intents by their conversation names, for which keys and default entries are generated in the resource bundle.
To provide a translation for a conversation name:
-
Click Resource Bundle in the left navbar (
).
-
Click the Intents tab on the Resource Bundles page.
-
Select the intent
-
Click Add Language.
-
Complete the Create Entry dialog:
-
Language—Add an IETF BCP 47 language tag like
fr
for French,de
for German, oren-US
for U.S. English. -
Text—The output string. For example, for a French translation (
fr
) of the HowOld key, you’d add a string like quel âge avez-vous ?
-
Note:
If the intent for which you want to change the conversation name doesn't appear in the list, click
Translate Answers for Answer Intents
When you create an answer intent, a resource bundle key is automatically created for the answer.
To provide a translation for an answer in an answer intent:
-
Click Resource Bundle in the left navbar (
).
-
Click the Q&A tab on the Resource Bundles page.
-
Select the key for the answer that you want to translate.
-
Click Add Language.
-
Complete the Create Entry dialog:
-
Language—Add an IETF BCP 47 language tag like
fr
for French,de
for German, oren-US
for U.S. English. -
Text—The output string.
-
Reference Resource Bundles in the Dialog Flow
To set the output for a built-in component, you reference the resource bundle context variable and message key.
rb
, in the context section. Further down, value expressions define the text property for the System.Output
components reference the rb
variable and the keys, WhatType
and OnTheWay
. The first outputs a simple string and the other uses dynamic values. context:
variables:
rb: "resourcebundle"
...
pizzaType:
component: "System.Output"
properties:
text: "${rb('WhatType')}" # rb refers to the variable, WhatType is the key to the message in the resource bundle.
transitions: {}
...
done:
component: "System.Output"
properties:
text: "${rb('OnTheWay','${size.value}','${type.value}')}" # size.value and type.value are the arguments for the 'OnTheWay' message key.
transitions:
return: "done"
You can also create bundle entries with more complex message formats to handle plurals and other cases. See the following topics to learn about the range of message formats and how to reference them in your dialog flow.
Tip:
To test your resource bundles using the tester, set your browser to another language.Message Formats
There are several formats that you can use for your resource bundle messages to handle everything from returning static messages to assembling messages depending on multiple variables.
Simple Messages
For simple static messages:
- As the value for the bundle key, provide plain text. For example:
This is the value of my bundle key
- From the dialog flow or the configuration property, reference the bundle key in the form:
{rb.bundleKey}
or{rb('bundleKey')}
Messages with Parameters
For messages with variables:
- As the value for the bundle key, provide text and include parameters in one of the following formats:
- Named parameters in the form
{parameterName}
- Sequentially-numbered parameters starting with
{0}
- Named parameters in the form
- From the dialog flow or the configuration property, reference the bundle key in the form:
{rb('bundleKey','variable1','variable2',...)}
Example: Message with Named Parameters
Here's an example with two named parameters:
- Resource Bundle Key:
pizzaOnTheWayWithNamedParams
- Resource Bundle Message (in English):
(whereYour {pizzaSizeParam} {pizzaTypeParam} pizza is on the way.
{pizzaSizeParam}
and{pizzaTypeParam}
are parameters for values to be resolved and inserted during the conversation) - Expression for Referencing Resource Bundle Key:
(where${rb('pizzaOnTheWayWithNamedParams','pizzaSizeParam,pizzaTypeParam',pizzaSize.value, pizzaType.value)}
pizzaSize
andpizzaType
are variables defined in the dialog flow)
Example: Message with Numbered Parameters
Here's an example using numbered parameters:
- Resource Bundle Key:
pizzaOnTheWayWithNumberedParams
- Resource Bundle Message:
(whereYour {0} {1} pizza is on the way.
{0}
and{1}
are parameters for values to be resolved and inserted during the conversation) - Expression for Referencing the Resource Bundle Key:
(where${rb('pizzaOnTheWayWithNumberedParams','pizzaSize.value', 'pizzaType.value')}
pizzaSize
andpizzaType
are variables defined in the dialog flow)
Complex Messages
You can also create complex messages, where the value of one or more variables may affect the surrounding output text. For example, if the response includes a variable for the number of pizzas ordered, you can use a complex message to determine whether to use the singular ("pizza") or plural ("pizzas").
Tip:
When you compose complex bundle entries, you can use this tester to make sure that the entries resolve as you intend:https://format-message.github.io/icu-message-format-for-translators/editor.html.Messages that Handle Both Singular and Plural
For messages that include a variable that expresses a quantity of something, you may need to vary the wording of the assembled message depending on how the variable resolves. And for some languages, you may need to account for more than a simple singular/plural distinction. To handle messages with variables for quantity, you can use a plural
argument in the key's value to specify the different ways the message may need to be constructed.
In a plural argument, part of the message is determined by a numeric value along with grammar rules for the specified language. You define the message text for different cases, depending on how the plural argument resolves. There are several predefined cases, such as one
, two
, few
, many
, and other
. You can also specify a case for a specific number by pre-pending =
to that number (e.g., =3
). Not all of the predefined cases are relevant for every language. For example, for English you might just use =0
, =1
, and other
.
You must always include a case and a message for other
. To include the resolved number in the message text for a case, use #
to output the number.
When you use plural arguments, the format typically looks something like this:
{plural_arg_name, plural,
=0 {Text used when the plural argument resolves to 0}
=1 {Text used when the plural argument resolves to 1}
other {Text used when the plural argument resolves to a value that doesn't match the other cases (in this case 0 or 1)}
}
In the above example 0
, 1
, and other
are the possible quantities. More details on how plural argument types work can be found in the Unicode Locale Data Markup specification.
For details on the plural support for various languages, see the unicode.org plural language rules.
Other Complex Messages
If the content of the message needs to based on other conditions, you can use a select
argument with keywords that you define to assemble the message.
{select_arg_name, select,
keyword1 {Text used when the select argument resolves to keyword1}
keyword2 {Text used when the select argument resolves to keyword2}
other {Text used when the plural argument resolves to a value that doesn't match the other keywords}
}
You can also nest plural and select arguments:
{select_arg_name, select,
keyword1 {
{plural_arg_name, plural,
=0{Text used when the select argument resolves to keyword1 and the plural argument resolves to 0.}
=1 {Text used when the select argument resolves to keyword1 and the plural argument resolves to 1}
other {Text used when the select argument resolves to keyword1 and the plural argument resolves to a value that doesn't match the other cases (in this case 0 or 1)}}}
keyword2 {
{plural_arg_name, plural,
=0 {Text used when the select argument resolves to keyword2 and the plural argument resolves to 0.}
=1 {Text used when the select argument resolves to keyword2 and the plural argument resolves to 1}
other {Text used when the select argument resolves to keyword2 and the plural argument resolves to a value that doesn't match the other cases (in this case 0 or 1)}}}
other {
{plural_arg_name, plural,
=0 {Text used when the select argument resolves to other and the plural argument resolves to 0.}
=1 {Text used when the select argument resolves to other and the plural argument resolves to 1}
other {Text used when the select argument resolves to other and the plural argument resolves to a value that doesn't match the other cases (in this case 0 or 1)}}}
}
Note:
For the keyword names, you should only use ASCII alphabet characters (A-Z,a-z).You can find more details on complex messages in the ICU User Guide.
Referencing Complex Messages
You can reference complex messages in one of the following two ways:
- Using a map variable where values for each of the parameters are assembled:
${rb('bundleKey', formatMap.value)}
- Including a list argument with the parameter names followed by arguments for each value:
${rb('bundleKey', 'param1, param2, param3', paramValue1, paramValue2, paramValue3)}
Note:
Where the parameter values are strings, they should be enclosed in single quotes ('
).
For further details, see the Complex Argument Types topic in the ICU documentation.
Maps for Complex Resource Bundle Values
If you decide to use map variable to assemble the parameters for a complex messages, here's what you do:
- Declare a map context variable.
context: variables: formatMap: "map"
- Use a
System.SetVariable
component to populate the value of the map from other variables.populateMap: component: "System.SetVariable" properties: variable: "formatMap" value: pizzaSize: "${pizzaSize.value}" pizzaType: "${pizzaType.value}" count: "${pizzaNum.value}"
- In the expression where you reference the bundle key, include the map as an argument. For example:
plural: component: "System.Output" properties: # use map variable to resolve text: "${rb('pizzaOnTheWaySingularOrPlural', formatMap.value)}"
Example: Message that Handles Both Singular and Plural Variants
Here's an example of a resource bundle entry for a message that could have either singular or plural content:
- Resource Bundle Key:
pizzaOnTheWaySingularOrPlural
- Resource Bundle Message (in English):
{count, plural, =0 {No pizzas will be delivered.} =1 {Your {pizzaSizeParam} {pizzaTypeParam} pizza is on the way.} other {# pizzas are on the way.} }
- Expression for Reference to Resource Bundle Key:
As you can see, the expression contains two arguments:${rb('pizzaOnTheWaySingularOrPlural','count, pizzaSizeParam, pizzaTypeParam', 'pizzaNum.value, pizzaSize.value, pizzaType.value')}
- A list of parameter names (
count, pizzaSizeParam, pizzaTypeParam
) - A list of values for those parameters (
pizzaNum.value, pizzaSize.value, pizzaType.value
)
- A list of parameter names (
Example: Message with Nested Parameters
{ gender, select,
female
{{count, plural,
=0 {She has not ordered anything.}
=1 {She has ordered only one.}
other {She has ordered #.}}}
male
{{count, plural,
=0 {He has not ordered anything.}
=1 {He has ordered only one.}
other {He has ordered #.}}}
other
{{count, plural,
=0 {They have not ordered anything.}
=1 {They have ordered only one.}
other {They have ordered #.}}}}
- She has not ordered anything.
- She has ordered only one.
- She has ordered 2.
- He has not ordered anything.
- He has ordered only one.
- He has ordered 2.
- They have not ordered anything.
- They have ordered only one.
- They have ordered 2.
Note:
2
is given in the above example as the number resolved by the count
argument, but it could be any number other than 0 or 1.
Resource Bundles and Auto-Translation of Skills
Here are the general steps for setting up a skill to use a translation service only for user input while using resource bundles for the skill's responses:
- If you haven't already done so, add a translation service to your skill.
- Use the
System.DetectLanguage
component to determine the language of the user's input. - Apply resource bundles to handle the skill's responses to the user.
- For any components that reference resource bundles, make sure that the output is not translated automatically. You can handle this globally in the skill by setting the
autoTranslate
context variable to translate input and not translate output. For example:setAutoTranslate: component: "System.SetVariable" properties: variable: "autoTranslate" value: input: true output: false
Note:
You can also handle this at the component level by using each component'stranslate
property and not setting theautoTranslate
variable. For example, to set up automatic translation for aSystem.Text
component's input and disable automatic translation for its output, you might do something like this:askName: component: "System.Text" properties: prompt: "${rb.askNamePrompt}" variable: "name" translate: input: true output: false
If your skill uses resource bundles for some components but relies on auto-translation for other components, you can:
- Set the
autoTranslate
context variable totrue
. - Like in the above code sample, set the
translate:input
property tofalse
for each component that uses a resource bundle.
Conditional Auto-Translation
If you have defined resource bundles for some languages but also want to be able to provide responses for languages for which you don't have resource bundle entries, you can use FreeMarker expressions to determine how autotranslate
and translate
resolve. For example, if only English and Dutch resource bundles are defined, you could conditionally enable output translation for the other languages like this:
detectLanguage:
component: "System.DetectLanguage"
properties: {}
setAutoTranslate:
component: "System.SetVariable"
properties:
variable: "autoTranslate"
value:
input: true
output: "${profile.languageTag!='en'&& profile.languageTag!='nl'}"
Resource Bundle Entry Resolution
The resource bundle that gets applied depends on the value stored for the two location-specific user context variables, profile.languageTag
and profile.locale
. If both variables are set, profile.languageTag
takes precedence.
profile.languageTag
is set to the language of the user's input by the System.DetectLanguage
component, if you have that component in your dialog flow. The value of profile.languageTag
takes the form of a two-character language code (e.g. en
for English).
profile.locale
is set by the messenging client. The value of profile.locale
can take the form of language-country-variant (e.g. en-AU-sydney
), language-country (e.g. en-AU
), or language (e.g. en
).
When resolving which language to use, Oracle Digital Assistant first searches for an exact match. If it doesn't find one, it incrementally broadens its search until it succeeds. If it still can't find a match, it returns the default language, which is English (en
).
${profile.locale}
is en-AU-sydney
(and profile.languageTag
isn't set), Oracle Digital Assistant does the following to find the best language match:
-
Searches the bundle by the language-country-variant criteria (
en-AU-sydney
). -
If it can’t find that, it searches the bundle by language and country (
en-AU
). -
Failing that, it broadens its search for language (
en
).
Export and Import Resource Bundles
You can export and import resource bundles in the form of a CSV file, which enables you to work with the bundles offline.
The CSV file needs to have the following columns:
languageTag
key
message
annotation
To export a CSV file with the existing resource bundle:
-
On the Resource Bundle page for your skill or digital assistant, click
to export a CSV file with the existing resource bundle.
Even if you haven't yet added any keys to the resource bundle, a file with the required format of the CSV will be exported.
To import a resource bundle file:
- On the Resource Bundle page for your skill or digital assistant, click
.
How Do I Translate Custom Component Responses?
- Store a data object sent from a custom component in a context variable. You can then reference this variable in the built-in user interface components like
System.Output
,System.Text
, orSystem.CommonResponse
. - Save string messages in a context variable, and then pass the name of the context variable as an input parameter to system components like
System.Output
,System.List
,System.CommonResponse
, orSystem.TranslateOutput
. - Translate the custom component output in the component itself and then directly write the response to the messenger client (thus avoiding the system components altogether).
Option 1: Storing Data in a Context Variable
-
Save the data in a context variable in your dialog flow.
To write data from a data object to a context variable, add the following code to your custom component:
For this particular line of code to work, you need to add a corresponding context variable to your dialog flow definition namedconversation.variable('dialogVar', dataObject); conversation.transition(); done();
dialogVar
that’s astring
type :dialogVar: "string"
Tip:
As a best practice, pass the name of the context variable that the custom component should write to as a input parameter to the custom component. This way, you ensure that the context parameter really exists when accessing it. -
Include the
translate: true
property in an output component definition, or use theSystem.TranslateOutput
component to translate it to the user’s language.The system components can’t translate a data object as a whole, so if you need to translate data objects stored in a context variable, then you need to reference the context variable along with the name of the data object attribute that’s displayed to user and gets translated by an output component. In the following example, the context variable isdialogVar
. The data object that’s passed from the custom component to this context variable is{product: "an apple", type: "fruit", origin: "Spain" }
. To display and translate this object, you’d reference it aSystem.Output
component and enable its translation:
If a translation service is enabled for the skill, then this message gets translated to the user’s language. The custom component also passes the translated content of the data object.printProduct: component: "System.Output" properties: text: "The product in your cart is a ${dialogVar.value.type}. It is ${dialogVar.value.product} from ${dialogVar.value.origin}" translate: true
Option 2: Saving Messages in a Context Variable
In this approach, you can pass the name of the context variable that holds the component response as an input parameter to the custom component. This ensures that custom components are not dependent on a specific OBotML implementation code and remain reusable.
initializeReceipt
state and passes the name of the context variable
(receipt
) that holds the component response and purchaseId
as input
parameters.initializeReceipt:
component: "sample.receipt.dataresponse"
properties:
dataVariable: "receipt"
purchaseid: "${purchaseId.value}
printReceipt:
component: "System.Output"
properties:
text:"${receipt.value}"
translate: true
...
The
custom code for accessing these input parameters is as
follows:...
invoke: (conversation, done) => {
var responseVariable = conversation.properties().dataVariable;
var purchaseId = conversation.properties().purchaseId;
...
var message = queryRemoteServiceForReceipt(purchaseId);
...
conversation.variable(responseVariable, message);
conversation.transition();
done();
}
System.TranslateOutput
component or set the translate
property on an output component like System.CommonResponse
or
System.Output
, as shown in the printReceipt
state:If a
custom component returns a message that’s not in English and therefore requires processing by
the Natural Language Processing (NLP) engine, then you’d position the
System.TranslateInput
component before the System.Intent
in the dialog flow. This allows the System.Intent
component to process the
English version of the
message.translateMessage:
component: "System.TranslateInput"
properties:
source: "variable_populated_by_custom_component"
variable: "translationStringVar"
getIntent:
component: "System.Intent"
properties:
variable: "iResult"
sourceVariable: "translationStringVar"
...
Option 3: Sending Responses Directly to the User
conversation.reply
helper method.
Note:
Responses that are directly sent to a user can’t be translated by a translation service. In this case, you'd need to code the translations into the custom component- Let the component’s output be translated by the translation service (which can be enabled by setting the skill's
autotranslate
context variable totrue
or by defining thetranslate
property on the component and setting it totrue
). Use this approach when the message does not originate from the custom component, but is queried from a remote backend. - Use message bundles to provide translated responses for the languages you that want the skill to support. Message bundles can use placeholders in the translated strings in which the custom component inserts the data value at runtime. Message bundles in custom components are a viable option if the custom component queries data from a remote service.
To detect the preferred language in the custom component, you can either pass the locale as an input parameter to the component or access the
profile.locale
andprofile.languageTag
variables as shown in the following example://detect user locale. If not set, define a default var locale = conversation.variable('profile.locale')? conversation.variable('profile.locale') : 'en'; //when profile languageTag is set, use it. If not, use profile.locale var languageTag = conversation.variable('profile.langageTag')? conversation.variable('profile.langageTag') : locale;