Code personnalisé et intégration de back-end
Voici quelques bonnes pratiques pour l'écriture de code personnalisé et l'intégration back-end pour les assistants numériques.
A la fin d'une conversation, vous devez faire quelque chose avec les informations collectées auprès d'un utilisateur. Ce "quelque chose" nécessite généralement l'accès à un service back-end pour l'interrogation de données ou de données persistantes pour lesquelles vous devez créer des composants personnalisés. Une autre utilisation pour les composants personnalisés consiste à intégrer une logique personnalisée qui gère les validations complexes ou d'autres fonctions utilitaires. Oracle Digital Assistant prend en charge deux types de composant personnalisé :
- Composants CCS (Custom Dialog Flow Components)
- Gestionnaires d'événements d'entité (EEH)
Au cours de la phase de planification et de conception de votre assistant numérique, vous devez identifier les ressources back-end dont vous aurez besoin et décider si les API dont vous disposez sont suffisantes ou non.
- Comme les assistants numériques ne sont pas des applications Web, les API existantes peuvent avoir besoin d'être optimisées ou abstraites via une couche d'optimisation pour renvoyer uniquement les données et la quantité de données requises dans une conversation d'assistant numérique.
- Si vous ne disposez pas de services REST pour que la fonctionnalité back-end s'intègre à une conversation d'assistant numérique, vous devez concevoir et déclencher un projet pour les créer.
Lors de l'implémentation de votre intégration de service back-end, vous décidez de déployer des composants personnalisés à distance ou d'utiliser les conteneurs de composants intégrés dans les briques Oracle Digital Assistant.
Comme l'indique la figure ci-dessous, l'intégration back-end est une partie nécessaire de la phase de planification et d'implémentation.
Composants d'un flux de dialogue personnalisé
Avec les composants de flux de dialogue personnalisés, vous pouvez écrire vos propres composants d'interface utilisateur que vous pouvez ajouter à votre flux de dialogue pour exécuter une logique de code personnalisé dans le contexte d'une conversation. Voici quelques exemples d'utilisation de ces composants :
-
Interroger et écrire des services back-end distants via des services REST.
-
Des solutions prêtes à l'emploi qui gèrent toutes les interactions utilisateur pour une tâche spécifique, comme demander un retour utilisateur à la fin d'une conversation, consigner et signaler des erreurs à un administrateur, etc.
-
Prise en charge de la gestion des données dans les tableaux d'objets enregistrés dans une variable de flux de dialogue.
Utiliser des noms corrects pour les composants et les paramètres d'entrée
Il n'existe pas de champ permettant de fournir des descriptions pour les composants personnalisés qui expliquent ce qu'ils font et quelles informations doivent leur être transmises. Ainsi, les meilleurs moyens d'aider les développeurs de briques à utiliser votre composant sont d'utiliser des noms corrects pour le composant et les paramètres d'entrée et de choisir soigneusement les chaînes d'action renvoyées par votre composant.
-
Les composants YAML intégrés utilisent le nom
System.<name>
. Par conséquent, en particulier pour les flux de dialogue basés sur YAML, vous pouvez utiliserCustom.<name>
pour les réviseurs de brique afin de comprendre qu'il s'agit d'un composant personnalisé référencé par le flux de dialogue. Vous pouvez également utiliser un espace de noms pour fournir un contexte. Pour nos exemples de composants personnalisés, nous utilisons souventoracle.sample.<name>
pour indiquer que ces composants ne sont pas destinés à être de qualité de production. -
Les paramètres d'entrée fournissent des données au composant personnalisé à traiter. Souvent, les données transmises à un composant personnalisé ne sont pas la valeur réelle à utiliser, mais plutôt le nom d'une variable qui contient les valeurs de données à traiter ou dans laquelle les données interrogées à partir d'un service distant doivent être écrites. En examinant les composants intégrés, ils utilisent
variable
comme nom de propriété pour contenir le nom de la variable dans laquelle le résultat du composant sera écrit, ou<name>Var
(par exemple,nlpResultVar
) pour indiquer les propriétés qui font référence à un nom de référence de variable. Vous pouvez encore améliorer cela en utilisant les postfixes_in
et_out
pour indiquer si une variable fait référence à une variable qui contient des données ou attend des données du composant. -
Les chaînes d'action sont facultatives et peuvent être utilisées par le développeur de brique pour déterminer l'état de flux de dialogue suivant auquel accéder. L'utilisation de
success
oufailure
comme chaîne d'action ne fournit pas beaucoup de contexte. Nous vous suggérons donc d'utiliser des éléments tels queorderSubmitted
,orderRejected
ouuserUnauthorized
à la place.
Évitez de faire des hypothèses dans votre code
En réalité, souvent, le développeur d'un composant personnalisé est également le développeur de compétences qui l'utilise. Pour cette raison, de nombreux développeurs simplifient leur travail avec des composants personnalisés en faisant des hypothèses sur les variables présentes dans la brique. Ainsi, au lieu de transmettre le nom d'une variable au composant, ils font directement référence au nom dans la logique du composant personnalisé. Nous ne le recommandons pas car de telles hypothèses peuvent facilement rompre un composant personnalisé. Nous vous recommandons de définir un contrat clair et complet entre le composant personnalisé et les compétences qui l'utilisent.
Bibliothèque de réflexion
Une question courante est de savoir combien de composants personnalisés doivent être ajoutés à un package de services de composant personnalisé. En général, il est toujours judicieux de penser aux services de composants personnalisés, et aux composants qu'ils contiennent, en tant que bibliothèques. Ainsi, tous les composants liés à une tâche peuvent être enregistrés dans un seul service de composant personnalisé. Toutefois, les recommandations doivent pouvoir faire face à la réalité. Par conséquent, il est nécessaire de répondre à la question sur la façon de packager des composants personnalisés en fonction de l'utilisation prévue des composants personnalisés.
-
La réutilisation n'est pas une option pour de nombreux développeurs de composants personnalisés. Lorsque des composants personnalisés sont développés et utilisés dans une brique spécifique, il est logique de regrouper tous ces composants dans un déploiement de service de composant personnalisé unique. L'exception concerne les composants qui sont réellement réutilisés dans d'autres briques.
-
Les déploiements de conteneurs de composants intégrés sont limités par le nombre de services de composants personnalisés par instance Oracle Digital Assistant. Par conséquent, vous souhaiterez utiliser un seul service de composant personnalisé par brique ou rechercher un déploiement distant de vos composants personnalisés.
-
Utilisation du déploiement de service de composant personnalisé distant vers Kubernetes dans Oracle Cloud Infrastructure, pour les raisons suivantes :
-
Pour ne pas divulguer les informations confidentielles contenues dans le code de composant personnalisé. Les services de composant personnalisé déployés dans le conteneur imbriqué peuvent être téléchargés par toute personne disposant d'un accès complet à votre instance Oracle Digital Assistant.
-
Pour une meilleure segmentation de votre code. Les composants personnalisés ne doivent contenir que le code nécessaire pour interagir avec le bot et appeler des services REST. Tous les autres codes doivent être stockés dans des fichiers JavaScript externes (si vous utilisez un conteneur imbriqué) ou dans des couches d'intégration (services REST). Les composants personnalisés incluent du code qui effectue les opérations suivantes :
-
paramètres d'entrée de lecture
-
lire/définir des valeurs de variable
-
gérer les messages reçus par un composant
-
afficher l'interface utilisateur du composant personnalisé
-
déterminer le passage à l'état suivant
-
gérer l'état des composants
-
accéder aux services REST
-
-
Pour améliorer les performances. Le conteneur intégré pour le déploiement de composants personnalisés vers les briques utilise les fonctions OCI, qui ont un délai de démarrage à froid. Pour éviter ce retard, ainsi que la limite du nombre de services pouvant être déployés, un déploiement à distance de composants personnalisés vous offre une alternative sans souci.
-
Partager des composants communs. Bien que notre expérience soit que la réutilisation n'est pas très bien classée parmi les développeurs de composants personnalisés, il est logique de créer et de déployer des composants personnalisés couramment utilisés sur un serveur distant. Vous pouvez avoir des composants communs tels que le traitement des erreurs et l'escalade, le traitement des autorisations OAuth2 à 2 branches, etc.
-
Ecriture des messages de journal
Le journaliseur par défaut implémenté pour les composants personnalisés est le journaliseur de la console. Vous accédez à l'enregistreur d'événements via un appel à context.logger()
. Vous pouvez utiliser les fonctions de journalisation des appels disponibles pour l'enregistreur de console, telles que ".info('…')
ou ".warn('…')
".
Remarque : l'utilisation de context.logger()
est particulièrement judicieuse lors du déploiement vers le conteneur imbriqué, car ce dernier sait comment afficher correctement ces journaux. Pour les composants personnalisés que vous déployez en externe, il est préférable d'utiliser une autre bibliothèque de journalisation, telle que log4js.
Gestion de l'état interne de votre composant
Les composants de flux de dialogue personnalisés peuvent avoir une interaction plus longue avec un utilisateur avant que la navigation ne passe à l'état de flux de dialogue suivant. Pour cette interaction, vous devez vous assurer que le composant gère son état interne afin de pouvoir faire la distinction entre un appel initial et les appels suivants. Il existe deux options pour ce faire :
-
Ajoutez un jeton à la charge utile du message de postback. Lorsque le composant personnalisé affiche une interface utilisateur dans laquelle les utilisateurs peuvent appuyer sur un élément d'action, un message de postback est renvoyé au composant personnalisé. Le composant personnalisé doit évaluer les messages de postback qu'il reçoit pour déterminer si ce postback provient de l'interface utilisateur qu'il affiche ou d'un autre composant. Pour cela, il peut vérifier le message de postback pour savoir s'il contient un jeton que le composant personnalisé a ajouté lors de l'affichage de l'élément d'action.
-
Utilisez une variable de flux de dialogue. Si vous devez gérer un état plus complexe entre les appels de composant personnalisé, par exemple pour assurer le suivi des valeurs extraites des messages utilisateur, vous pouvez utiliser une variable de flux de dialogue pour cela. Les composants personnalisés peuvent créer des variables de flux de dialogue lors de l'exécution dans un appel à
context.variable('variable name', value)
. Si aucune variable du nom indiqué n'existe, elle est créée. L'objet "valeur" peut être tout ce dont vous avez besoin pour garder une trace.
Valider les paramètres d'entrée
Les paramètres d'entrée que vous définissez pour un composant personnalisé doivent être validés pour avoir un contenu. Cela est également vrai pour les paramètres que vous définissez comme requis. Les cas suivants doivent être vérifiés :
-
Le paramètre d'entrée a un jeu de valeurs.
-
La valeur ne commence pas par
'$ {'
, car cela indique une expression permettant de lire la valeur du paramètre d'entrée à partir d'une variable ou qu'un objet n'est pas correctement résolu dans le flux de dialogue.
Utiliser la classe MessageFactory pour les messages de composant
Toutes les réponses de bot envoyées à partir d'un composant personnalisé doivent utiliser la classe MessageFactory
. La classe MessageFactory
peut être utilisée pour créer le même type de message utilisateur enrichi que le composant Réponse commune, qui inclut la liste de valeurs, les pièces jointes, les présentations de carte et les messages texte.
En outre, les messages définis avec la classe MessageFactory
sont indépendants des canaux. Cela signifie que vous créez un message de composant unique, qui est ensuite converti par les connecteurs spécifiques au canal dans le format requis par le canal client respectif.
Pour accéder à la classe MessageFactory
à partir d'un composant personnalisé, utilisez la référence suivante :
let MessageFactory = context.MessageFactory();
La classe
MessageFactory
remplace la classe MessageModel
, qui est en phase d'abandon. Les deux classes ont le même usage général, mais MessageFactory
présente les avantages suivants :
- Il prend en charge tous les types et propriétés de message du modèle de message commun (CMM), au lieu d'un sous-ensemble.
- Son implémentation est basée sur une classe, fournissant une méthode get, une méthode set et des méthodes propres pour modifier la définition du message. La finalisation du code est effectuée lors de l'utilisation de Typescript et dans JavaScript lorsque les définitions de type appropriées sont incluses en haut du gestionnaire d'événements ou du composant personnalisé.
- L'implémentation utilise le modèle de générateur, qui vous permet de chaîner un certain nombre de méthodes set ou d'ajouter, ce qui rend le code plus lisible et réduit le nombre de lignes à coder.
Liste de contrôle pour les composants personnalisés
- ☑ Assurez-vous que les services back-end sont optimisés ou abstraits pour être utilisés avec des briques.
- ☑ Les composants personnalisés ne doivent contenir que du code lié aux bots. Tous les autres codes doivent être déplacés vers des classes d'utilitaire ou des bibliothèques, ou déployés en tant que services REST individuels vers un serveur distant ou un service cloud.
- ☑ Créez un contrat clair et complet entre les composants personnalisés et les compétences dans lesquelles ils sont utilisés.
- ☑ Utilisez des composants personnalisés pour les évaluations complexes. Dans ce cas, évitez Apache FreeMarker.
- ☑ Gérer l'état des composants pour les interactions utilisateur multi-demandes.
- ☑ Validez tous les paramètres d'entrée de composant personnalisé.
- ☑ Gérez les erreurs en renvoyant une chaîne d'action pour que le développeur de brique gère les problèmes.
En savoir plus
- Tutoriel : Développement de composants personnalisés pour l'intégration back-end
- Tutoriel : Débogage de composants personnalisés
- Rubrique imbriquée - Limites de conteneur pour les services de composants personnalisés
- Documentation du kit SDK Bots Node : exemple de code MessageFactory pour différentes réponses d'interface utilisateur
Gestionnaires d'événements d'entité
Un gestionnaire d'événements d'entité est un type de composant personnalisé qui vous permet d'appeler le code de composant personnalisé dans le contexte de la résolution des entités de conteneur composite. Les gestionnaires d'événements d'entité sont utilisés dans les conversations basées sur un modèle pour interagir avec les entrées utilisateur et les valider, et pour appeler des services back-end distants pour un accès en lecture et en écriture. Contrairement aux composants de flux de dialogue personnalisés, le risque de réutilisation est minime pour un gestionnaire d'événements, c'est pourquoi l'implémentation par défaut du gestionnaire d'événements d'entité est vers le conteneur de briques intégré.
Ajouter des fonctionnalités manquantes pour résoudre les composants des entités
La plupart des fonctionnalités qui peuvent être définies pour le composant Réponse commune, telles que les boutons globaux d'aide et d'annulation, ne sont pas disponibles pour le composant Résoudre les entités via la configuration.
Toutefois, vous pouvez ajouter des fonctionnalités manquantes à l'aide de gestionnaires d'événements d'entité. Cela vous permet de tirer parti de la simplicité du composant Résoudre les entités dans le flux de dialogue sans sacrifier les fonctionnalités avancées.
Gérer l'état
Les fonctions de gestionnaire d'événements d'entité sont appelées par les composants Résoudre les entités et Réponse commune lors de la résolution d'une entité de conteneur composite. Vous n'avez pas besoin de savoir quel élément de conteneur doit être résolu ensuite, car tout est fait pour vous.
Néanmoins, vous voudrez peut-être enregistrer certaines informations pour une utilisation ultérieure. Deux options s'offrent à vous :
-
Les propriétés de résolution de contexte sont des variables que vous créez sur l'objet de contexte. Les variables et leurs valeurs existent jusqu'à ce que l'entité de conteneur composite soit résolue ou que vous quittiez l'état du flux de dialogue qui résout une entité de conteneur composite. L'avantage de l'utilisation des propriétés de résolution de contexte est qu'il n'y a pas de ménage que vous devez faire.
- Pour écrire, utilisez :
context.setCustomProperty(name, value);
- Pour lire, utilisez :
context.getCustomProperty(name);
- Pour écrire, utilisez :
-
Les variables de flux de dialogue créées lors de l'exécution ou lors de la conception peuvent être utilisées pour stocker les valeurs à conserver au-delà de la résolution de l'entité de conteneur composite. Le contenu stocké dans les variables de flux de dialogue est accessible à partir des états de flux de dialogue (pour les variables définies au moment de la conception uniquement) et à partir d'autres gestionnaires d'événements d'entité.
- Pour écrire, utilisez :
context.variable(name,value);
- Pour lire, utilisez :
context.variable(name);
- Pour écrire, utilisez :
Ecriture des messages de journal
Le journaliseur par défaut implémenté pour les gestionnaires d'événements d'entité est le journaliseur de console.
Vous accédez à l'enregistreur d'événements via un appel à context.logger()
.
Vous pouvez utiliser les fonctions de journalisation des appels disponibles pour le journaliseur de la console, telles que .info('…')
ou .warn('…')
.
Affichage des messages utilisateur
Les messages utilisateur personnalisés sont affichés via la fonction context.addMessage()
. Comme pour les composants de flux de dialogue personnalisés, nous vous recommandons d'utiliser la classe MessageFactory
pour créer des messages indépendants des canaux plutôt que de générer des données traitées propres aux canaux. Les gestionnaires d'événements d'entité prennent également en charge les messages de type liste de valeurs, disposition de carte et pièce jointe.
Liste de contrôle pour les gestionnaires d'événements d'entité
- ☑ Stockez les valeurs temporaires dans le contexte de résolution, sauf si nécessaire dans un état de flux de dialogue ultérieur.
- ☑ Utilisez un seul service de composant personnalisé pour tous les gestionnaires d'événements d'entité utilisés dans une brique.
- ☑ Utilisez la classe
MessageFactory
pour les messages à afficher aux utilisateurs.
En savoir plus
- Vidéo Oracle Digital Assistant Design Camp : Comprendre les gestionnaires d'événements d'entité
-
Tutoriel : Développement du gestionnaire d'événements d'entité dans le navigateur
- Tutoriel : Développement d'un gestionnaire d'événements d'entité dans un IDE externe
- Exemple : Conversations basées sur un modèle utilisant EEH par exemple de note de frais
- Documentation du kit SDK Bots Node : MessageFactory exemple de code pour différentes réponses d'interface utilisateur
- Documentation : Fonctions du gestionnaire d'événements d'entité (exposées sur l'objet de contexte)
Quel composant devez-vous utiliser ?
Les gestionnaires d'événements d'entité sont destinés à être utilisés avec des entités de conteneur composite, tandis que les composants de flux de dialogue personnalisés sont utilisés dans le contexte de conversations passant d'un état à l'autre. Au final, vous utiliserez probablement les deux. Si vous suivez la recommandation d'utiliser des conversations basées sur un modèle, vous aurez plus de chances d'utiliser des gestionnaires d'événements d'entité que des composants de flux de dialogue personnalisés.
D'un point de vue fonctionnel, les composants de flux de dialogue personnalisés (CCS) et les gestionnaires d'événements d'entité (EEH) sont très similaires. Le tableau ci-dessous compare les deux types de composant personnalisé.
Fonctionnalité | CCS | EEH |
---|---|---|
Support du module Node.js / Développement JavaScript | Oui | Oui |
Support TypeScript | Oui | Oui |
Développement sur navigateur | Non | Oui |
Développement dans l'IDE externe | Oui | Oui |
Utiliser dans les flux de dialogue | Oui | Non |
Utiliser dans les entités de conteneur composite | Non | Oui |
Paramètres d'entrée | Oui | Non |
Transition de la navigation programmatique à l'action | Oui | Non |
Appeler des services REST | Oui | Oui |
Lecture/écriture sur les variables de flux de dialogue | Oui | Oui |
Stocker temporairement les valeurs dans le contexte de résolution | Non | Oui |
Utiliser des groupes de ressources/la prise en charge multilingue | Oui | Oui |
Afficher des interfaces utilisateur riches et des invites pour interagir avec les utilisateurs | Oui | Oui |
Prise en charge du déploiement de conteneurs de compétences | Oui | Oui |
Support de déploiement à distance | Oui | Oui |
Prise en charge du débogage local (nécessite NGROK ou d'autres tunnels) | Oui | Oui |
Evénements personnalisés | Non | Oui |
Prise en charge des actions postérieures | Oui | Oui |
Utilisation de groupes de ressources pour CCS et EEH
Les composants de flux de dialogue personnalisés et les gestionnaires d'événements d'entité qui affichent les messages de bot à l'utilisateur doivent afficher les messages dans les langues prises en charge par l'assistant numérique.
Jusqu'à récemment, il n'existait aucun moyen facile d'utiliser des groupes de ressources qui étaient définis dans une brique à partir de composants personnalisés. Mais maintenant, il y a une nouvelle interface de programmation qui vous permet de faire référence aux clés de groupe de ressources dans votre code. Il existe deux restrictions connues que vous devez connaître :
-
L'utilisation de chaînes de groupe de ressources est limitée aux groupes de ressources sans paramètre ou avec des paramètres de position. Les paramètres nommés utilisés avec les groupes de messages ICU ne sont pas encore pris en charge par la nouvelle API.
-
L'API produit une expression qui, lorsqu'elle est renvoyée en tant que réponse de bot, est remplacée par la chaîne de groupe de messages référencée pour la langue détectée.
Pour appeler la nouvelle API, utilisez l'un des appels d'objet de contexte suivants :
let expression = context.translate('resource_bundle_key_name');
let expression = context.translate('resource_bundle_key_name', param1, param2);
L'expression peut être utilisée dans des réponses de texte, en tant que libellés de bouton et sur des cartes à l'aide de la classe MessageFactory
.
-
Exemple de gestionnaire d'événements d'entité :
const messageModel = context.getMessageFactory(); //create a conversation message format text object that references a key name const message = messageModel.createTextMessage(context.translate('resource_bundle_key')); //display the message to the user keeping the turn, which means the composite bag entity //proceeds with the next bag item to resolve context.addMessage(message,true);
-
Exemple de flux de dialogue personnalisé :
const messageModel = context.getMessageFactory(); //create a conversation message format text object that references a key name const message = messageModel.createTextMessage(context.translate('resource_bundle_key')); //display the message to the user keeping the turn, which means the composite bag entity //proceeds with the next bag item to resolve context.reply(message); context.keepTurn(true); context.transition(); done();
Reportez-vous également à l'article TechExchange Utiliser des paramètres d'entrée pour transmettre des chaînes de groupe de ressources traduites à des composants personnalisés.
Utilisation des paramètres nommés
Pour accéder aux paramètres nommés d'un regroupement de ressources, procédez comme suit :
//Entity event handler sample
let expression = "${rb('key_name','param_name1,param_name2',"+value1+","+value2+")}";
let message = messageFactory.createTextMessage(expression);
context.addMessage(message,true);
//Custom dialog flow component sample
let expression = "${rb('key_name','param_name1,param_name2',"+value1+","+value2+")}";
let message = messageFactory.createTextMessage(expression);
context.reply(message);
Notre recommandation concernant les groupes de ressources et les composants personnalisés
L'utilisation de groupes de ressources partout est un thème courant dans ce guide. Cependant, l'utilisation de groupes de ressources stockés dans une brique crée un couplage étroit entre le composant de flux de dialogue personnalisé ou le gestionnaire d'événements et la brique. Si vous êtes d'accord avec cette dépendance et appréciez l'avantage d'avoir des chaînes de ressources gérées en un seul endroit plus que d'éviter le problème de couplage étroit, vous devriez le faire. Pour les gestionnaires d'événements, le risque de réutilisation est minime, c'est pourquoi il ne doit pas y avoir de doute sur l'utilisation de chaînes de groupe de ressources dans les gestionnaires d'événements d'entité.
Pour les composants de flux de dialogue personnalisés réutilisés dans différentes briques, la fonction de traduction fonctionne également si les briques ont les noms de clé de groupe de ressources requis par le composant personnalisé ajouté à leur groupe de ressources.
A l'aide d'une autre solution, vous pouvez éviter de coupler étroitement des composants personnalisés à une brique en transmettant les messages lus à partir d'un groupe de ressources en tant que paramètres d'entrée à un composant de flux de dialogue personnalisé.
Devriez-vous migrer vers les gestionnaires d'événements d'entité ?
Si vous passez de composants de flux de dialogue personnalisés à des gestionnaires d'événements d'entité, ce doit être pour une raison spécifique, et pas seulement parce qu'il s'agit d'une nouvelle technologie. Changer de likes par likes n'améliore pas vos compétences. Si vous n'êtes pas satisfait du flux de conversation en cours et que vous envisagez d'utiliser des entités de conteneur composite pour remplacer des parties de votre conversation de flux de dialogue, c'est une bonne raison de déplacer la logique de code des composants de flux de dialogue personnalisés vers les gestionnaires d'événements d'entité.
Meilleures pratiques lors de la migration vers des gestionnaires d'événements d'entité
Si vous décidez de déplacer des fonctionnalités existantes des composants de flux de dialogue personnalisés vers des gestionnaires d'événements d'entité pour améliorer votre flux de conversation, assurez-vous que vous n'essayez pas seulement d'imiter le comportement que vous avez implémenté avec les composants de flux de dialogue personnalisé et de réponse commune. Au lieu de cela, commencez à utiliser le composant Résoudre les entités et utilisez les fonctions du gestionnaire d'événements d'entité pour implémenter l'ensemble de la validation et de la logique requises pour votre cas d'utilisation conversationnel.