{"id":834,"date":"2019-08-09T11:13:43","date_gmt":"2019-08-09T09:13:43","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=834"},"modified":"2021-03-17T12:51:56","modified_gmt":"2021-03-17T11:51:56","slug":"amazon-lex-anatomia-di-un-chatbot","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/","title":{"rendered":"Amazon Lex: anatomia di un chatbot"},"content":{"rendered":"

Con il crescente impiego dell\u2019intelligenza artificiale e con l\u2019avvento di nuove interfacce uomo-macchina, diventa sempre pi\u00f9 importante esplorare le nuove tecnologie ed impiegarle al meglio per trarne la massima utilit\u00e0 ed il massimo valore.<\/span><\/p>\n

Uno degli impieghi dell\u2019intelligenza artificiale e del deep learning pi\u00f9 orientato all\u2019utente finale \u00e8 certamente la realizzazione di nuovi tipi di <\/span>interfacce uomo-macchina<\/b> basate sul riconoscimento degli intenti, sia su messaggi di testo sia da interazioni vocali.<\/span><\/p>\n

Per avere alcuni esempi di questa tipologia di applicazioni basta pensare agli assistenti vocali sugli smartphone, a quelli domestici come ad esempio Amazon Alexa e a tutti i servizi con cui \u00e8 possibile interagire via chat.<\/span><\/p>\n

In questo articolo vi mostreremo come realizzare uno <\/span>Slack bot usando Amazon Lex.<\/b><\/p>\n

In ambito informatico, riconoscimento vocale e comprensione del linguaggio naturale sono tra i problemi pi\u00f9 complessi affrontati, tanto da necessitare algoritmi di deep learning molto complessi. Tali algoritmi richiedono enormi quantit\u00e0 di dati per essere addestrati efficacemente, oltre ad apposite infrastrutture di calcolo dai costi particolarmente elevati. <\/span>Amazon Lex rende queste tecnologie accessibili a tutti<\/b> aprendo la strada verso una categoria completamente nuova di prodotti.<\/span><\/p>\n

Amazon Lex \u00e8 un servizio per la creazione di interfacce di comunicazione tramite voce e testo realizzato per essere sufficientemente generico da essere impiegato in qualsiasi applicazione. Offre funzionalit\u00e0 avanzate di apprendimento per il riconoscimento vocale e la dettatura, nonch\u00e9 per il riconoscimento del linguaggio naturale e per la comprensione di testi, consentendo la creazione di applicazioni con una user-experience coinvolgente, basata su conversazioni realistiche. Con Amazon Lex, le stesse tecnologie di apprendimento approfondito su cui si basa Amazon Alexa sono a disposizione di tutti gli sviluppatori, consentendo cos\u00ec la creazione di <\/span>bot di conversazione<\/b> (\u201cchatbot\u201d) sofisticati e naturali in modo semplice, veloce e a basso effort.<\/span><\/p>\n

Lex consente una facile integrazione con Facebook Messenger, Slack e Twilio SMS.\u00a0<\/span><\/p>\n

Attualmente, Lex supporta solamente la lingua Inglese, ma \u00e8 possibile realizzare bot in altre lingue costruendo una soluzione ad-hoc che sfrutti Amazon Translate.<\/span><\/p>\n

Prima di entrare nei dettagli di implementazione occorre definire il gergo ed i concetti fondamentali di Lex.<\/span><\/p>\n

Un bot realizzato mediante Lex si compone sostanzialmente di 3 parti:<\/span><\/p>\n

    \n
  1. Modello di interazione;<\/b><\/li>\n
  2. Funzioni Lambda<\/b> (back-end) per elaborare le richieste;<\/span><\/li>\n
  3. Una o pi\u00f9 interfacce\/canali di interazione<\/b> (Slack, SMS, telefono).<\/span><\/li>\n<\/ol>\n

    Ora definiamo meglio i concetti sopra citati.<\/span><\/p>\n

    Modello di interazione<\/span><\/h2>\n

    Il modello di interazione consiste di un file json che modellizza tutti gli <\/span>intenti<\/b>, cio\u00e8 il tipo di azioni rese possibili agli utenti e che il bot pu\u00f2 gestire. Per ogni <\/span>intento<\/b> \u00e8 necessario definire anche quali siano i <\/span>parametri<\/b> necessari e il loro <\/span>tipo<\/b>.<\/span><\/p>\n

    Questo file pu\u00f2 essere redatto testualmente e fornito a Lex, oppure essere realizzato per via grafica utilizzando la web console di AWS.<\/span><\/p>\n

    Il modello contiene anche molte frasi di esempio per ogni intento (<\/span>utterances<\/b>), frasi che verranno utilizzate dalla IA per riconoscere le richieste degli utenti verso il bot ed indirizzarle opportunamente alle specifiche funzioni Lambda per essere processate.<\/span><\/p>\n

    Lambda Back-end<\/span><\/h2>\n

    Il back-end di un bot Lex, ovvero la parte di computazione che permette di soddisfare gli intenti e che contiene quindi tutta la business logic, deve essere realizzato con <\/span>AWS Lambda.<\/b> Attualmente, al contrario di amazon Alexa, non sono previste modalit\u00e0 di integrazione generiche e cross provider.<\/span><\/p>\n

    AWS garantisce la sicurezza delle invocazioni mediante <\/span>IAM policy e trust relationship.<\/b><\/p>\n

    Interfacce\/Canali di comunicazioni<\/span><\/h2>\n

    I canali sono le vie di comunicazione con il bot.<\/b> Al momento vengono supportati Facebook Messenger, Slack e Twilio SMS.<\/span><\/p>\n

    \u00c8 possibile definire uno o pi\u00f9 canali direttamente dalle impostazioni del bot; per tutti i canali gestiti non \u00e8 necessario implementare funzioni, n\u00e9 effettuare il provisioning di risorse. \u00c8 sufficiente configurare l\u2019integrazione con i servizi esterni.<\/span><\/p>\n

    Sono altres\u00ec disponibili guide ufficiali dettagliate per integrare tutti i servizi supportati con Lex.<\/span><\/p>\n

    Infrastruttura<\/span><\/h2>\n

    \"\"<\/p>\n

    L\u2019infrastruttura \u00e8 molto semplice e si compone di <\/span>soli servizi gestiti.<\/b><\/p>\n

    Il trigger tra Lex e Lambda \u00e8 completamente gestito da AWS<\/b>; per configurarlo basta indicare l\u2019arn della funzione nel modello del bot, ed abbinarlo all\u2019intento desiderato.<\/span><\/p>\n

    Anche i canali supportati non richiedono il provisioning di risorse all\u2019interno dell\u2019account AWS. La gestione di eventuali endpoint o canali di comunicazioni con servizi esterni sono gestiti automaticamente da Lex.<\/span><\/p>\n

    Interazione con il bot<\/span><\/h2>\n

    Una volta definito il modello e configurato un canale, il bot \u00e8 pronto a ricevere input dall\u2019utente. Ogni input verr\u00e0 scandagliato in cerca dell\u2019intento; Lex guider\u00e0 poi la conversazione per reperire tutti gli <\/span>slot<\/b>, o <\/span>parametri<\/b>, definiti nel modello per poter elaborare l\u2019intento individuato.<\/span><\/p>\n

    Ottenuti tutti i <\/span>parametri<\/b> necessari, Lex invocher\u00e0 la funzione lambda indicata passandogli un oggetto in cui sono definiti <\/span>l\u2019intento<\/b> ed i <\/span>parametri<\/b> raccolti.<\/span><\/p>\n

    Il risultato della lambda sar\u00e0 il messaggio di risposta fornito all\u2019utente.<\/span><\/p>\n

    Un bot triviale<\/span><\/h2>\n

    Abbiamo definito tutti i concetti chiave di Lex e possiamo cominciare ad entrare nel merito della realizzazione di un bot.<\/span><\/p>\n

    Quello che segue \u00e8 un esempio di bot funzionante realizzato utilizzando esclusivamente Amazon Lex.<\/span><\/p>\n

    Si tratta di un bot triviale, al solo fine di dimostrare i concetti ed il principio di funzionamento.<\/span><\/p>\n

    Per questo primo bot non saranno utilizzate funzioni di back-end in quanto ci limiteremo a riconoscere l\u2019intento di salutare o di essere salutati e rispondere con un messaggio preimpostato.<\/span><\/p>\n

    Modello di interazione<\/span><\/h3>\n

    Questo \u00e8 l\u2019aspetto di un <\/span>modello di interazione.<\/b> Come gi\u00e0 accennato si tratta di un file json che contiene l\u2019elenco di tutti gli intenti, nel nostro esempio\u00a0 \u201cgreetings\u201d.<\/span><\/p>\n

    Per ogni intento vengono definite le frasi di esempio, definite nell\u2019array \u201csampleUtterances\u201d e anche il tipo di azione da intraprendere per soddisfare l\u2019intento, definito nel campo \u201cfulfillmentActivity\u201d e valorizzato a ReturnIntent\u201d nel nostro esempio, per rispondere al client con un messaggio fisso.<\/span><\/p>\n

    Il messaggio preimpostato viene scelto casualmente tra quelli indicati in \u201cconclusionStatement\u201d.\u201dmessages\u201d.<\/span><\/p>\n

    {<\/span>\r\n\u00a0<\/span>\"metadata\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"schemaVersion\"<\/span>: <\/span>\"1.0\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"importType\"<\/span>: <\/span>\"LEX\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"importFormat\"<\/span>: <\/span>\"JSON\"<\/span>\r\n },<\/span>\r\n\u00a0<\/span>\"resource\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"name\"<\/span>: <\/span>\"TestBot\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"version\"<\/span>: <\/span>\"1\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"intents\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"name\"<\/span>: <\/span>\"greetings\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"version\"<\/span>: <\/span>\"2\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"fulfillmentActivity\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"type\"<\/span>: <\/span>\"ReturnIntent\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"sampleUtterances\"<\/span>: [<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"greet me\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"please greet me\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"greetings\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"make the greetings for me\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"would you greet me please\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"would you greet me\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"slots\"<\/span>: [],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"conclusionStatement\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"groupNumber\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Hello\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"groupNumber\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Greetings\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"groupNumber\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Hi :-)\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"voiceId\"<\/span>: <\/span>\"Salli\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"childDirected\"<\/span>: <\/span>false<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"locale\"<\/span>: <\/span>\"en-US\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"idleSessionTTLInSeconds\"<\/span>: <\/span>300<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"clarificationPrompt\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Sorry, can you please repeat that?\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"maxAttempts\"<\/span>: <\/span>5<\/span>\r\n \u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"abortStatement\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Sorry, I could not understand. Goodbye.\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0}<\/span>\r\n }<\/span>\r\n}\r\n<\/span><\/pre>\n

    A questo punto, basta configurare un canale, ad esempio Slack, per poi pubblicare e testare il bot.<\/span><\/p>\n

    Per maggiori informazioni su come configurare un canale qui \u00e8 disponibile una guida passo a passo.<\/a><\/span><\/p>\n

    Che ci crediate o no, questo modello \u00e8 del tutto sufficiente a produrre un bot funzionante \ud83d\ude42<\/strong>
    \n<\/span><\/p>\n

    Un bot con backend<\/span><\/h2>\n

    Ora che abbiamo messo in produzione il bot con le funzionalit\u00e0 minime, possiamo passare ad un esempio pi\u00f9 completo.<\/span><\/p>\n

    In questo test andremo ad estendere il bot precedentemente illustrato aggiungendo un intento per il calcolo del fattoriale di un numero.\u00a0<\/span><\/p>\n

    Per poter soddisfare la richiesta, sar\u00e0 utilizzato un back-end basato su AWS Lambda.<\/span><\/p>\n

    Modello di interazione<\/span><\/h3>\n

    Il modello \u00e8 identico a quello precedente, ma con l\u2019aggiunta di un nuovo intento \u201cfactorial\u201d.<\/span><\/p>\n

    Del nuovo intento sono anche definiti gli slot nell\u2019apposito array e il tipo di \u201cfulfillmentActivity\u201d \u00e8 un oggetto \u201cCodeHook\u201d contenente a sua volta il parametro \u201curi\u201d, che \u00e8 l\u2019arn della funzione lambda da invocare.<\/span><\/p>\n

    Per utilizzare i parametri all\u2019interno delle frasi di esempio, i nomi degli slot vanno indicati tra parentesi graffe {slot}.<\/span><\/p>\n

    Ecco il modello completo:<\/span><\/p>\n

    {<\/span>\r\n\u00a0<\/span>\"metadata\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"schemaVersion\"<\/span>: <\/span>\"1.0\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"importType\"<\/span>: <\/span>\"LEX\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"importFormat\"<\/span>: <\/span>\"JSON\"<\/span>\r\n },<\/span>\r\n\u00a0<\/span>\"resource\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"name\"<\/span>: <\/span>\"TestBot\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"version\"<\/span>: <\/span>\"2\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"intents\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"name\"<\/span>: <\/span>\"factorial\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"version\"<\/span>: <\/span>\"4\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"fulfillmentActivity\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"codeHook\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"uri\"<\/span>: <\/span>\"arn:aws:lambda:eu-west-1:XXXXXXXXXXXX:function:besharp-testbot\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messageVersion\"<\/span>: <\/span>\"1.0\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"type\"<\/span>: <\/span>\"CodeHook\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"sampleUtterances\"<\/span>: [<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"{n} factorial\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"compute {n} factorial\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"please calc {n} factorial\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"factorial of {n}\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"what is the factorial of {n}\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"what is {n}\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"slots\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"sampleUtterances\"<\/span>: [],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"slotType\"<\/span>: <\/span>\"AMAZON.NUMBER\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"slotConstraint\"<\/span>: <\/span>\"Required\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"valueElicitationPrompt\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"What is the input number?\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"maxAttempts\"<\/span>: <\/span>2<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"priority\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"name\"<\/span>: <\/span>\"n\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"name\"<\/span>: <\/span>\"greetings\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"version\"<\/span>: <\/span>\"3\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"fulfillmentActivity\"<\/span>: {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"type\"<\/span>: <\/span>\"ReturnIntent\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"sampleUtterances\"<\/span>: [<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"greet me\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"please greet me\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"greetings\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"make the greetings for me\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"would you greet me please\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"would you greet me\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"hello\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"hi\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"slots\"<\/span>: [],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"followUpPrompt\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"prompt\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"groupNumber\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Hello\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"groupNumber\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Greetings\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"groupNumber\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Hi :-)\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"maxAttempts\"<\/span>: <\/span>3<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"rejectionStatement\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"groupNumber\"<\/span>: <\/span>1<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Yes, yes, whatever\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"voiceId\"<\/span>: <\/span>\"Salli\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"childDirected\"<\/span>: <\/span>false<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"locale\"<\/span>: <\/span>\"en-US\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"idleSessionTTLInSeconds\"<\/span>: <\/span>300<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"clarificationPrompt\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Sorry, can you please repeat that?\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0],<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"maxAttempts\"<\/span>: <\/span>5<\/span>\r\n \u00a0\u00a0},<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"abortStatement\"<\/span>: {<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"messages\"<\/span>: [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"contentType\"<\/span>: <\/span>\"PlainText\"<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\"content\"<\/span>: <\/span>\"Sorry, I could not understand. Goodbye.\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0}<\/span>\r\n }<\/span>\r\n}\r\n<\/span><\/pre>\n

    Funzione Lambda<\/span><\/h3>\n

    Per poter rispondere con il fattoriale occorre ora programmare il back-end del bot.<\/span><\/p>\n

    Quella che segue \u00e8 una semplice funzione lambda in Python 2.7.<\/span><\/p>\n

    Abbiamo reso grigio tutto il boilerplate e le funzioni helper, il fulcro del backend sono i metodi: lambda_handler<\/b>, che fa da entry point, la funzione dispatch<\/b> che si occupa di invocare la funzione corretta in base al nome dell\u2019intento individuato da Lex, e le funzioni factorial e fatt<\/b> che si occupano di calcolare il fattoriale e restituirlo nel formato corretto per Lex.
    \n<\/span><\/p>\n

    import json<\/span>\r\nimport datetime<\/span>\r\nimport time<\/span>\r\nimport os<\/span>\r\nimport dateutil.parser<\/span>\r\nimport logging<\/span>\r\n\r\nlogger = logging.getLogger()<\/span>\r\nlogger.setLevel(logging.DEBUG)<\/span>\r\n\r\n\r\n# --- Helpers that build all of the responses ---<\/span>\r\n\r\ndef elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message):<\/span>\r\n \u00a0\u00a0return {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'sessionAttributes': session_attributes,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'dialogAction': {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'type': 'ElicitSlot',<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'intentName': intent_name,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'slots': slots,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'slotToElicit': slot_to_elicit,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'message': message<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\u00a0\u00a0\u00a0}<\/span>\r\n\r\ndef confirm_intent(session_attributes, intent_name, slots, message):<\/span>\r\n \u00a0\u00a0return {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'sessionAttributes': session_attributes,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'dialogAction': {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'type': 'ConfirmIntent',<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'intentName': intent_name,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'slots': slots,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'message': message<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\u00a0\u00a0\u00a0}<\/span>\r\n\r\ndef close(session_attributes, fulfillment_state, message):<\/span>\r\n \u00a0\u00a0response = {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'sessionAttributes': session_attributes,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'dialogAction': {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'type': 'Close',<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'fulfillmentState': fulfillment_state,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'message': message<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\u00a0\u00a0\u00a0}<\/span>\r\n\r\n\u00a0\u00a0\u00a0return response<\/span>\r\n\r\ndef delegate(session_attributes, slots):<\/span>\r\n \u00a0\u00a0return {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'sessionAttributes': session_attributes,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'dialogAction': {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'type': 'Delegate',<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'slots': slots<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\u00a0\u00a0\u00a0}<\/span>\r\n\r\n\r\n# --- Helper Functions ---<\/span>\r\n\r\n\r\ndef safe_int(n):<\/span>\r\n \u00a0\u00a0\"\"\"<\/span>\r\n \u00a0\u00a0Safely convert n value to int.<\/span>\r\n \u00a0\u00a0\"\"\"<\/span>\r\n \u00a0\u00a0if n is not None:<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return int(n)<\/span>\r\n\u00a0\u00a0\u00a0return n<\/span>\r\n\r\n\r\ndef try_ex(func):<\/span>\r\n \u00a0\u00a0\"\"\"<\/span>\r\n \u00a0\u00a0Call passed in function in try block. If KeyError is encountered return None.<\/span>\r\n\u00a0\u00a0\u00a0This function is intended to be used to safely access dictionary.<\/span>\r\n\r\n \u00a0\u00a0Note that this function would have negative impact on performance.<\/span>\r\n\u00a0\u00a0\u00a0\"\"\"<\/span>\r\n\r\n \u00a0\u00a0try:<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return func()<\/span>\r\n \u00a0\u00a0except KeyError:<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return None<\/span>\r\n\r\n\r\n\"\"\" --- Functions that control the bot's behavior --- \"\"\"<\/span>\r\n\r\n\r\ndef<\/span> factorial<\/span>(<\/span>intent_request<\/span>):<\/span>\r\n\r\n\u00a0\u00a0\u00a0n = safe_int(try_ex(<\/span>lambda<\/span>: intent_request[<\/span>'currentIntent'<\/span>][<\/span>'slots'<\/span>][<\/span>'n'<\/span>]))<\/span>\r\n\r\n\u00a0\u00a0\u00a0<\/span>return<\/span> close(<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{},<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>'Fulfilled'<\/span>,<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>'contentType'<\/span>: <\/span>'PlainText'<\/span>,<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>'content'<\/span>: <\/span>'The result is '<\/span> + <\/span>str<\/span>(fatt(n))<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n\u00a0\u00a0\u00a0)<\/span>\r\n\r\ndef<\/span> fatt<\/span>(<\/span>n<\/span>):<\/span>\r\n\u00a0\u00a0\u00a0r = <\/span>1<\/span>\r\n\u00a0\u00a0\u00a0<\/span>for<\/span> i <\/span>in<\/span> range<\/span>(<\/span>1<\/span>, n + <\/span>1<\/span>):<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0r = r * i<\/span>\r\n\u00a0\u00a0\u00a0<\/span>return<\/span> r<\/span>\r\n\r\n\r\n# --- Intents ---<\/span>\r\n\r\n\r\ndef<\/span> dispatch<\/span>(<\/span>intent_request<\/span>):<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"\"\"<\/span>\r\n\r\n\u00a0\u00a0\u00a0Called when the user specifies an intent for this bot.<\/span>\r\n\r\n\u00a0\u00a0\u00a0\"\"\"<\/span>\r\n\r\n\r\n\u00a0\u00a0\u00a0logger.debug(<\/span>'dispatch userId=<\/span>{}<\/span>, \r\n   intentName=<\/span>{}<\/span>'<\/span>.format(intent_request[<\/span>'userId'<\/span>],\r\n   intent_request[<\/span>'currentIntent'<\/span>][<\/span>'name'<\/span>]))<\/span>\r\n\r\n\u00a0\u00a0\u00a0intent_name = intent_request[<\/span>'currentIntent'<\/span>][<\/span>'name'<\/span>]<\/span>\r\n\r\n\r\n\u00a0\u00a0\u00a0<\/span># Dispatch to your bot's intent handlers<\/span>\r\n\r\n\r\n\u00a0\u00a0\u00a0<\/span>if<\/span> intent_name == <\/span>'factorial'<\/span>:<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>return<\/span> factorial(intent_request)<\/span>\r\n\r\n\u00a0\u00a0\u00a0<\/span>raise<\/span> Exception<\/span>(<\/span>'Intent with name '<\/span> + intent_name + <\/span>' not supported'<\/span>)<\/span>\r\n\r\n\r\n# --- Main handler ---<\/span>\r\n\r\n\r\ndef<\/span> lambda_handler<\/span>(<\/span>event<\/span>, <\/span>context<\/span>):<\/span>\r\n\u00a0\u00a0\u00a0<\/span>\"\"\"<\/span>\r\n \u00a0\u00a0Route the incoming request based on intent.<\/span>\r\n \u00a0\u00a0The JSON body of the request is provided in the event slot.<\/span>\r\n \u00a0\u00a0\"\"\"<\/span>\r\n\u00a0\u00a0\u00a0<\/span># By default, treat the user request as coming from the America\/New_York time zone.<\/span>\r\n\u00a0\u00a0\u00a0os.environ[<\/span>'TZ'<\/span>] = <\/span>'America\/New_York'<\/span>\r\n\u00a0\u00a0\u00a0time.tzset()<\/span>\r\n\r\n\r\n\u00a0\u00a0\u00a0logger.debug(<\/span>'event.bot.name=<\/span>{}<\/span>'<\/span>.format(event[<\/span>'bot'<\/span>][<\/span>'name'<\/span>]))<\/span>\r\n\r\n\r\n\u00a0\u00a0\u00a0<\/span>return<\/span> dispatch(event)\r\n<\/span><\/pre>\n

    Anche in questo caso basta pubblicare la lambda e poi aggiornare il modello del bot precedente per poter subito utilizzare le nuove capacit\u00e0 del bot.<\/span><\/p>\n

    Come potete notare, una volta appresi i concetti chiave, la realizzazione di un bot \u00e8 piuttosto semplice ed assistita dai servizi di Amazon ed AWS.<\/span><\/p>\n

    Un esempio di conversazione:<\/span><\/p>\n

    \"\"<\/p>\n

    In questo articolo abbiamo trattato i concetti fondamentali che stanno alla base del funzionamento di Lex. Abbiamo poi analizzato l\u2019anatomia di un bot semplice e funzionante, il primo passo per la realizzazione di bot pi\u00f9 complessi.<\/span><\/p>\n

    Restate sintonizzati per altri articoli su Lex e per tutte le ultime novit\u00e0!<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"

    Con il crescente impiego dell\u2019intelligenza artificiale e con l\u2019avvento di nuove interfacce uomo-macchina, diventa sempre pi\u00f9 importante esplorare le nuove […]<\/p>\n","protected":false},"author":8,"featured_media":843,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[247],"tags":[321,331,263,333],"yoast_head":"\nAmazon Lex: anatomia di un chatbot - Proud2beCloud Blog<\/title>\n<meta name=\"description\" content=\"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Amazon Lex: anatomia di un chatbot\" \/>\n<meta property=\"og:description\" content=\"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/\" \/>\n<meta property=\"og:site_name\" content=\"Proud2beCloud Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-08-09T09:13:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-03-17T11:51:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/08\/blogslack-05.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1668\" \/>\n\t<meta property=\"og:image:height\" content=\"1250\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Alessio Gandini\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Amazon Lex: anatomia di un chatbot\" \/>\n<meta name=\"twitter:description\" content=\"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/08\/blogslack-05.png\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alessio Gandini\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/\",\"url\":\"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/\",\"name\":\"Amazon Lex: anatomia di un chatbot - Proud2beCloud Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#website\"},\"datePublished\":\"2019-08-09T09:13:43+00:00\",\"dateModified\":\"2021-03-17T11:51:56+00:00\",\"author\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43\"},\"description\":\"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.besharp.it\/it\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Amazon Lex: anatomia di un chatbot\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#website\",\"url\":\"https:\/\/blog.besharp.it\/it\/\",\"name\":\"Proud2beCloud Blog\",\"description\":\"il blog di beSharp\",\"alternateName\":\"Proud2beCloud Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.besharp.it\/it\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43\",\"name\":\"Alessio Gandini\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g\",\"caption\":\"Alessio Gandini\"},\"description\":\"Cloud-native Development Line Manager @ beSharp, DevOps Engineer e AWS expert. Computer geek da quando avevo 6 anni, appassionato di informatica ed elettronica a tutto tondo. Ultimamente sto esplorando l'esperienza utente vocale e il mondo dell'IoT. Appassionato di cinema e grande consumatore di serie TV, videogiocatore della domenica.\",\"url\":\"https:\/\/blog.besharp.it\/it\/author\/alessio-gandini\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Amazon Lex: anatomia di un chatbot - Proud2beCloud Blog","description":"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/","og_locale":"it_IT","og_type":"article","og_title":"Amazon Lex: anatomia di un chatbot","og_description":"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!","og_url":"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/","og_site_name":"Proud2beCloud Blog","article_published_time":"2019-08-09T09:13:43+00:00","article_modified_time":"2021-03-17T11:51:56+00:00","og_image":[{"width":1668,"height":1250,"url":"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/08\/blogslack-05.png","type":"image\/png"}],"author":"Alessio Gandini","twitter_card":"summary_large_image","twitter_title":"Amazon Lex: anatomia di un chatbot","twitter_description":"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!","twitter_image":"https:\/\/blog.besharp.it\/wp-content\/uploads\/2019\/08\/blogslack-05.png","twitter_misc":{"Scritto da":"Alessio Gandini","Tempo di lettura stimato":"10 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/","url":"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/","name":"Amazon Lex: anatomia di un chatbot - Proud2beCloud Blog","isPartOf":{"@id":"https:\/\/blog.besharp.it\/it\/#website"},"datePublished":"2019-08-09T09:13:43+00:00","dateModified":"2021-03-17T11:51:56+00:00","author":{"@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43"},"description":"Utilizzi il sistema di messaggistica Slack? Realizza un bot con Amazon Lex!","breadcrumb":{"@id":"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.besharp.it\/it\/amazon-lex-anatomia-di-un-chatbot\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.besharp.it\/it\/"},{"@type":"ListItem","position":2,"name":"Amazon Lex: anatomia di un chatbot"}]},{"@type":"WebSite","@id":"https:\/\/blog.besharp.it\/it\/#website","url":"https:\/\/blog.besharp.it\/it\/","name":"Proud2beCloud Blog","description":"il blog di beSharp","alternateName":"Proud2beCloud Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.besharp.it\/it\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/e7262d28e51528c2e420327f9b18cd43","name":"Alessio Gandini","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blog.besharp.it\/it\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/eeb98518768d999bff24f8358b464fe2?s=96&d=mm&r=g","caption":"Alessio Gandini"},"description":"Cloud-native Development Line Manager @ beSharp, DevOps Engineer e AWS expert. Computer geek da quando avevo 6 anni, appassionato di informatica ed elettronica a tutto tondo. Ultimamente sto esplorando l'esperienza utente vocale e il mondo dell'IoT. Appassionato di cinema e grande consumatore di serie TV, videogiocatore della domenica.","url":"https:\/\/blog.besharp.it\/it\/author\/alessio-gandini\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/834"}],"collection":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/comments?post=834"}],"version-history":[{"count":0,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/posts\/834\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media\/843"}],"wp:attachment":[{"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/media?parent=834"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/categories?post=834"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.besharp.it\/it\/wp-json\/wp\/v2\/tags?post=834"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}