Fermer

octobre 9, 2018

Construire des robots Lex plus intelligents avec l'intégration Lambda


Dans un précédent article de blog nous expliquions comment Amazon Connect peut utiliser les robots Lex pour collecter des informations sur l'appelant et effectuer une tâche simple, telle que l'envoi d'un courrier électronique ou d'un message texte. En utilisant une fonction Lambda dans le crochet de code d'exécution d'un robot, nous pouvons déclencher à peu près n'importe quelle tâche automatisée que Lambda peut gérer. Une fois que cette tâche est terminée et que Lex reçoit la réponse appropriée, il retourne au flux de contacts et l'appelant peut être acheminé vers une file d'attente ou un autre flux.

C'est incroyablement puissant si nous voulons que notre bot exécute une tâche après son identification. l'intention de l'appelant et collecte tous les créneaux requis. Cependant, il peut arriver que, selon la valeur collectée, nous ayons besoin de collecter plus de détails ou, après vérification de la base de données, de vouloir remplacer un emplacement collecté précédemment. Dans cet article, nous verrons comment construire ces types d'interactions intelligentes en utilisant des réponses Lambda plus complexes.

Commençons par examiner les principes de base de l'interaction des deux services AWS.

Lors de l'appel de Lambda, Lex envoie un fichier JSON. charge utile qui contiendra l'intention actuelle, des détails sur les emplacements ainsi que des informations sur le bot et sur certaines variables système (y compris l'emplacement dans lequel le bot Lex a été appelé). Pour une description complète de l'ensemble des entrées, veuillez consulter la documentation officielle d'AWS, mais pour les besoins de notre propos, la partie la plus pertinente se trouve dans la section relative à l'intention actuelle, illustrée ci-dessous:

 "currentIntent": {

"name": "BookHotel",

"slots": {

"ville": null,

"chambre": null

}

En référençant cette section de l'entrée, Lambda peut accéder à l'intention et aux emplacements collectés par Lex et effectuer les opérations nécessaires, puis renvoyer une réponse appropriée. Cette réponse sera différente selon l'action que vous souhaitez que Lex fasse ensuite. Il existe actuellement 5 actions ou instructions que Lambda peut renvoyer à Lex.

“dialogAction”: {“type”: “ElicitIntent, ElicitSlot, ConfirmIntent, Delegate ou Close”}

Le corps de chaque action sera considéré comme un Un peu différent. Voici, par exemple, à quoi ressemblera une réponse «proche»:

 const response = {
  "dialogAction":
            {"type": "Fermer",
            "omplementState ":" rempli ",
            "message": {
                "contentType": "PlainText",
                "contenu": "Votre hôtel a été réservé."
            }
        }
};

Ceci est un exemple de la réponse typique qu'une fonction Lambda d'accomplissement renverrait à Lex après avoir terminé l'action nécessaire. Cela permettra au bot de savoir que tout s'est bien passé, il peut maintenant lire le contenu du message à l'appelant et revenir au flux de contacts.

Cependant, si quelque chose ne va pas, il faut que le bot Lex soit installé. collecter des détails supplémentaires, nous pouvons utiliser la réponse de fente d'élicit. Comme son nom l'indique, cette action de dialogue indiquera au bot qu'il doit revenir en arrière et collecter une nouvelle valeur de slot. Pour l’exemple ci-dessous, supposons que notre code Lambda a vérifié une base de données et découvert que les chambres king ne sont pas disponibles à Chicago. Notre fonction peut renvoyer la réponse suivante qui informera l'appelant dont il a besoin pour choisir une chambre queen ou une chambre simple.

 const response = {
 "dialogAction":
            {"type": "ElicitSlot",
                "message": {
                    "contentType": "PlainText",
                    "content": `Nous sommes désolés, mais King n'est pas pris en charge pour $ {event.currentIntent.slots.city}. S'il vous plaît choisir Queen ou Single`
                    },
            "intentName": "BookHotel",
            "slots": event.currentIntent.slots,
            "slotToElicit": "salle"
            }
}

Il convient de garder à l'esprit que si vous créez ce type de réponse, vous devez vous assurer que, dans votre fonction Lambda d'accomplissement, vous avez un chemin «proche» qui remplit réellement l'intention de l'appelant si toutes les valeurs sont valides. Les boucles potentiellement infinies qui continuent à demander les mêmes créneaux risquent très fort de générer une erreur du type: "Réponse Lambda non valide: deuxième exécution de lambda accomplie atteinte sur le même énoncé".

Un autre élément à prendre en compte est qu'il est également possible d'utiliser Lex. simplement pour collecter des données et tout valider dans Amazon Connect. Cela pourrait ressembler à la capture d'écran ci-dessous. Nous utilisons Lex pour collecter la ville et la pièce et transmettons les deux paramètres à une fonction Lambda qui vérifie une base de données et nous permet de savoir si les entrées sont invalides. Dans cet exemple, nous demandons à l'appelant de saisir à nouveau leurs détails, mais nous pourrions également définir une intention distincte (ou un bot distinct) pour la collecte de la ville ou de la pièce et acheminer l'appelant vers ce nouveau noeud d'entrée get.

Cette approche peut avoir beaucoup de sens si nous collectons seulement une ou deux entrées de l’appelant et si la fonction Lambda n’a rien à faire, sauf à les valider. Il pourrait également être plus facile de gérer les superviseurs de centre d'appels, car ils peuvent examiner la logique dans les flux de contacts au lieu de devoir lire le code dans AWS Lambda. Enfin, cette approche vous permet également de personnaliser plus facilement le comportement si l'une des entrées n'est pas valide. En gérant la validation dans Connect, nous pouvons créer un menu plus détaillé pour gérer les exceptions au lieu de s’en remettre au texte de l’invite issu d’une réponse à un intervalle. Cela dit, si vous devez procéder à une validation plus complexe des entrées, le hook de code de dialogue est probablement la meilleure option.

Jusqu'à présent, nous n'avions couvert que l'invocation de Lambda comme dernière étape du bot Lex, à l'intérieur du hook de code de réalisation, nous pouvons également appeler des fonctions dans la zone de raccordement du code de validation ou de dialogue. La principale différence est que, pour la validation, Amazon Lex appelle la fonction Lambda spécifiée sur chaque entrée d'utilisateur (énoncé), tandis que la fonction Lambda d'accomplissement ne sera invoquée qu'une fois tous les emplacements remplis.

Dans la mesure où le hook de code de la boîte de dialogue sera invoqué après chaque Avant même que toutes les machines à sous aient des entrées de client, nous aurons besoin d’un type de réponse différent. Si la valeur de l’emplacement de la salle est nulle, car nous n’avons pas encore demandé à l’appelant de sélectionner une salle, nous ne souhaitons pas utiliser de réponse à un intervalle induit et ignorer le mécanisme de collecte des emplacements habituel. Au lieu de cela, nous pouvons utiliser l'action de dialogue de délégué. Délégué renvoie essentiellement tous les détails à Lex et lui permet de décider quelle est la prochaine action appropriée, qui peut consister à collecter le prochain emplacement requis ou à respecter l'intention.

Une réponse d'action de dialogue de délégué pourrait ressembler à ceci:

[[19659005] const réponse = {
 "dialogAction":
                    {
                     "type": "délégué",
                     "slots":
                        {
                         "ville": "Seattle",
                         "chambre": null
                        }
                    }
}

Cette réponse indiquera à Lex que l'entrée de la ville de Seattle est une entrée valide et que la salle est actuellement vide, elle devrait donc être collectée ensuite. Notez que vous devez faire attention à ne pas coder en dur null comme une option qui pourrait être répétée car Lex essaiera de collecter cet emplacement uniquement pour le faire écraser de nouveau et encore par la réponse Lambda nulle. Pour une explication pas à pas du fonctionnement du délégué avec Lex, veuillez consulter cet exemple dans .

Notez que, si vous utilisez délégué, vous pouvez également écraser la saisie du client. Au lieu de Seattle, votre système doit peut-être utiliser la zone métropolitaine «Seattle-Tacoma-Bellevue». Une fois la validation effectuée, la réponse du délégué peut simplement renvoyer la nouvelle entrée à Lex et le bot la transmettra à Amazon Connect une fois la collecte des données terminée.

Nous avons maintenant présenté les différentes options permettant d'invoquer Lambda et les différentes réponses. Lex peut recevoir, examinons un pseudo-code pour une fonction capable de gérer à la fois la validation et l'exécution d'une licence d'hôtel Lex Bot.

 // --------------- Des assistants pour construire des réponses qui correspondent à la structure des actions de dialogue nécessaires ----------------- ------
fonction elicitSlot (sessionAttributes, intentName, slots, slotToElicit, message) {
     revenir {
        sessionAttributes,
        dialogAction: {
            type: 'ElicitSlot',
            intentName,
            créneaux horaires,
            slotToElicit,
            message,
         
        },
    };
}

fonction close (sessionAttributes, applymentState, message) {
    revenir {
        sessionAttributes,
        dialogAction: {
            type: 'Fermer',
            l'état de réalisation,
            message,
        },
    };
}
 
délégué de fonction (sessionAttributes, slots) {
    revenir {
        sessionAttributes,
        dialogAction: {
            type: 'délégué',
            créneaux horaires,
        },
    };
}
  

// --------------- Gestionnaire principal -----------------------

exports.handler = (événement, contexte, rappel) => {
    console.log ("détails de l'événement entrant:" + JSON.stringify (event));
    essayer {
        console.log (`event.bot.name = $ {event.bot.name}`);
        console.log ("détails de l'événement entrant:" + JSON.stringify (event));
 
        // Sauvegarder les détails de l'entrée Lex
        const city = event.currentIntent.slots.city;
        const room = event.currentIntent.slots.room;
        const source = event.invocationSource;
        
        
        // Vérifie si Lambda est appelé pour valider ou répondre à la demande
        if (source === "DialogCodeHook") {
            const outputSessionAttributes = event.sessionAttributes || {};
            laissez slots = intentRequest.currentIntent.slots;
        
            // Vérifiez si des emplacements ont déjà été collectés et validez ceux qui ont été collectés.
            if (ville === null && room === null) {
                
                // rien n'a encore été collecté pour que nous puissions simplement renvoyer les valeurs nulles à Lex pour la collecte standard
                
                callback (délégué (outputSessionAttributes, slots));
            }
            else if (ville === null && room! == null) {
                // C'est ici que vous pouvez valider le type de chambre
                
                if (entrée valide)
                    // Le choix de la pièce est une entrée valide, nous pouvons donc simplement renvoyer les slots nuls à Lex pour la collecte.
                    slots = {
                        "ville": null,
                        "chambre": chambre
                    };
                callback (délégué (outputSessionAttributes, slots));
                }
                
                else if (entrée non valide) {
                    // Le choix de la pièce n'est pas une entrée valide, nous allons donc obtenir à nouveau la place.
                    callback (elicitSlot (outputSessionAttributes, intentRequest.currentIntent.name, intentRequest.currentIntent.slots, "salle",
            {contentType: 'PlainText', content: 'Nous nous en excusons, mais ce n'est pas une entrée valide pour le type de chambre. Veuillez faire une nouvelle sélection. ' }))
                }
                        
            }
            else if (ville! == null && room === null) {
                // C'est ici que vous pouvez valider la ville et soit déléguer les créneaux horaires à Lex afin que nous puissions collecter le type de salle, soit obtenir à nouveau le créneau ville.
            }
            
            autre{
                  // C’est là que vous pouvez valider les deux entrées si nécessaire et déléguer les créneaux valides à Lex afin que nous puissions remplir l’intention ou obtenir à nouveau les créneaux nécessaires.
            }
        }
        
        else if (source === "FulfillmentCodeHook") {
            
            // C'est ici que vous entrerez le code qui remplira cette intention et ferez enfin savoir à Lex que cette demande a été clôturée avec succès.
        callback (close (outputSessionAttributes, 'Fulfilled', réalisé), {contentType: 'PlainText', content: "Votre hôtel a été réservé."});
        }
    } catch (err) {
        rappel (err);
    }
};

Bien que plusieurs morceaux soient manquants à dessein et que le nuage du gestionnaire principal soit simplifié, espérons-le, cette fonction vous a donné une bonne idée de la manière dont vous devriez structurer vos propres fonctions Lambda. Pour plus d’idées sur la façon d’améliorer vos flux de contacts et l’aide pour déployer vos robots Lex, veuillez envoyer un courrier électronique à Craig Reishus .






Source link