AIML e teoria dei chatbot – Seconda parte
AIML
Quando si parla di intelligenza artificiale, si fa riferimento alla scienza che studia sistemi in grado di simulare il pensiero umano, ovvero di risolvere problemi con un approccio tipico di un essere umano e di agire autonomamente su categorie di problemi normalmente molto difficili da affrontare per le macchine. Questa definizione lascia intendere che in realtà l’AI non è una una scienza relegata ad un contesto ristretto di tecnologie, ma abbraccia diverse tecniche e conoscenze necessarie per raggiungere l’obiettivo enunciato.
In merito, qualche tempo fa, avevo scritto un articolo, in cui cercavo di spiegare proprio questo concetto; ad ogni modo mi risoffermo sul tema, perché deve essere chiaro che parlare di IA, non significa parlare esclusivamente di reti neurali. L’area dell’IA, ad esempio, che si occupa dello studio dell’interazione uomo-macchina attraverso il linguaggio naturale (NLP) è una delle più interessanti ed in merito sono stati utilizzati approcci diversi per risolvere le complessità legate alla lingua, quali ad esempio la disambiguazione dei concetti espressi o la contestualizzazione di parole legate i problemi di polisemia della lingua; in merito possiamo sicuramente annoverare tecniche basate su reti neurali ricorsive RNN o su algoritmi in grado di valutare statisticamente le ricorrenze delle parole; a questo tipo di tecniche, si affiancano anche metodi più tradizionali basati su linguaggi specializzati nella modellazione della lingua naturale. Tra i più diffusi possiamo sicuramente annoverare l’AIML che sarà oggetto di studio di questo articolo.
Che cosa è L’AIML
L’AIML (Artificial intelligence markup language) è un linguaggio XML compliant, ideato da Richard S. Wallace per facilitare la scrittura di regole al fine di modellizzare un sistema in grado di intrattenere dialoghi in linguaggio naturale. L’AIML viene spesso utilizzato per la creazione di CHATBOT e devo dire che per lo scopo è uno strumento efficace, ma solo nel caso in cui si voglia realizzare un sistema in grado di rispondere, esclusivamente a domande in un contesto definito, accettando il limite di un livello di auto apprendimento praticamente nullo. Prima di infilarci, pertanto, in esempi e strutture AIML cerchiamo di capirne la filosofia e comprenderne le regole generali.
Come funziona
L’AIML funziona grazie ad un meccanismo di stimolo e risposta. La risposta verrà restituita solo se esisterà nei files di configurazione una regola in grado di “intercettare” lo stimolo o domanda. Essendo L’AIML un markup language XML compliant è ovvio immaginare, pertanto, che la struttura delle regole sarà costruita attraverso l’uso di tag. Tra i più importanti abbiamo:
- <aiml>: è il tag che apre e chiude un document AIML
- <category>: è il blocco base ed racchiude la singola regola
- <pattern>: racchiude un pattern semplice che corrisponde a cosa dice o scrive un utente
- <template>: racchiude la risposta ad un input utente
Una configurazione AIML sarà costituita in generale da strutture di conoscenza elementari <category> in ognuna delle quali sarà sempre presente l’elemento <pattern> ed il <template>. D’ora in avanti, pertanto, chiameremo questa struttura semplicemente categoria.
Esempio di categoria:
<category>
<pattern> TESTO </pattern>
<template> TESTO </template>
</category>
Sintassi AIML tag
Come in altri markup language anche nell’AIML i tag sono sempre delimitati da “<” e “>” ed in generale nella struttura formale di un contesto ci sarà sempre un tag di apertura ed un tag di chiusura :
<tag> informazione </tag>
Solo in alcuni casi, dove tra i tag non dovrà essere inserita un’informazione, si potrà scrivere direttamente in forma abbreviata qualcosa del genere:
<tag/>
Cerchiamo di capire la struttura di una configurazione AIML attraverso un primo esempio :
Esempio 1
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <aiml> <category> <pattern>chi sei</pattern> <template>sono un assistente virtuale</template> </category> </aiml>
In questo esempio alla domanda : chi sei il sistema risponderà -> sono un assistente virtuale. Ovviamente il sistema non sarà in grado di rispondere ad input diversi da quello configurato. Se scrivessi ad esempio : tu chi sei –> il sistema non sarà in grado di rispondere. Come risolvere questo primo problema? Banalmente introducendo il concetto di wildcard di cui riporto un’immagine che ne spiega bene l’uso evidenziando altresì i livelli di priorità che introducono le stesse durante la fase di matching dell’input.
In altre parole HELLO * avrà meno priorità ad esempio di HELLO THERE che avrà meno priorità di HELLO #
Riscriviamo l’esempio
Esempio 2
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <aiml>
<category> <pattern>* chi sei</pattern> <template>sono un assistente virtuale</template> </category> </aiml>
in questo caso se scrivessi chi sei non otterrei risposta mentre otterrei risposta a: tu chi sei oppure ma chi sei. Se volessi usare una sola regola per intercettare i due casi, basterà usare la wildcard #
Esempio 3
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <aiml> <category> <pattern># chi sei</pattern> <template>sono un assistente virtuale</template> </category> </aiml>
La wildcard # infatti come descritto nella figura precedente identifica zero o più parole a differenza di * che identifica una o più parole.
Esempi di pattern AIML validi
<pattern>*</pattern>
<pattern>HOW ARE YOU</pattern>
<pattern>How are you</pattern>
<pattern>HoW aRe YoU</pattern> -- AIML patterns sono case invariant
<pattern><set>color</set></pattern>
<pattern><SET>COLOR</SET></pattern> <pattern>I LIKE <set>color</set></pattern> <pattern>_ THANK YOU</pattern> <pattern>_ MUSIC *</pattern> <pattern># MUSIC #</pattern> <pattern>I LIKE # MUSIC</pattern>
<pattern>_ * _ * _</pattern> regola potenzialmente valida anche se senza significato
Esempi di pattern AIML non validi
<pattern></pattern> Pattern senza contenuto non sono validi
<pattern>How are you?</pattern> -- Pattern con punti di punteggiatura non sono validi
<pattern>I LIKE*</pattern> -- wildcard devono essere sempre separati dalla spazio
<pattern><set>*</set></pattern> -- nei set non posso essere usati wildcard
<pattern>_*_*_</pattern> -- le wildcard dovrebbero avere spazi che li separano
Lista TAG AIML
Iniziamo a fissare la lista dei tag AIML più importanti, che via via impareremo ad usare.
<aiml> | Definisce l’inizio e la fine di un documento AIML |
<category> | Definisce l’unità di conoscenza AIML |
<pattern> | Definisce il pattern utente che sarà valutato |
<template> | Definisce il risultato ad un input |
<star> | Identifica in template l’elemento wildcard del pattern |
<srai> | Identifica un sinonimo o alias |
<random> | Utilizzato per creare risposte random |
<li> | Elemento in risposte multiple usato insieme al tag random o in condition |
<set> | Tag per configurare il valore di nuove variabili |
<get> | Tag per ottenere il valore di una variabile |
<that> | Consente di contestualizzare le risposte in base al contesto della risposta precedente |
<topic> | Definisce un context |
<think> | Esegue dei tag AIML senza fornire risposte agli stimoli. Usato per settare variabili. |
<condition> | Tag usato per creare delle risposte condizionate |
Struttura base: <pattern> e <template>
Proviamo ad approfondire le strutture AIML disponibili iniziando da quella base <pattern> e <template>
<?xml version="1.0" encoding="UTF-8"?> <aiml version="1.0">
<category>
<pattern>CIAO</pattern>
<template>Buon giorno.</template>
</category>
<category>
<pattern>*</pattern>
<template>Cosa vuoi dire?</template>
</category>
</aiml>
L’esempio, appena descritto è in grado di rispondere al saluto “CIAO” ed a qualunque altro stimolo con la risposta cosa vuoi dire? proviamo a migliorarne la dinamicità utilizzando un nuovo tag <srai> che ci consentirà di gestire i sinonimi
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0">
<category>
<pattern>CIAO</pattern>
<template>Buon giorno.</template>
</category>
<category>
<pattern>SALVE</pattern>
<template><srai>CIAO</srai></template>
</category>
<category>
<pattern>BUON GIORNO</pattern>
<template><srai>CIAO</srai></template>
</category>
<category>
<pattern>*</pattern>
<template>Cosa vuoi dire?</template>
</category>
</aiml>
L’elemento <srai> può essere usato solo all’interno di un elemento <template> ed introduce una ricorsione. In questo caso, quando lo stimolo è «salve» o «buon giorno», si va a produrre la stessa risposta che si avrebbe con lo stimolo «ciao». Le risposte agli stimoli, come intuito, posso essere composte anche da strutture complesse e quindi non necessariamente solo testo. Iniziamo in tal senso a comprendere l’uso del tag <star>. Il tag <star> indica l’elemento che “matcha” la wildcard o un <set> nel pattern. Proviamo a capire il tag con degli esempi.
<category>
<pattern>Salve</pattern>
<template>Salve, come ti chiami?</template>
</category>
<category>
<pattern>Il mio nome è *</pattern>
<template>Piacere di conoscerti <star/> </template>
</category>
L’esempio introduce un semplice concetto di domanda e risposta; in tal caso il tipico dialogo potrebbe essere qualcosa del tipo :
Utente: Salve
Bot: Salve, come ti chiami?
Utente: il mio nome è Domenico
Bot: Piacere di conoscerti Domenico
In pratica con lo <star/> intercettiamo il valore corrispondente alla prima wildcard. Complichiamo un pò l’esempio:
<category>
<pattern>Salve</pattern>
<template>Salve, come ti chiami?</template>
</category>
<category>
<pattern>Il mio nome è * ed il mio cognome è *</pattern>
<template>Piacere di conoscerti <star index=1> <star index=2> </template>
</category>
In questo ultimo caso il dialogo risultante sarà qualcosa del tipo:
Utente: Salve
Bot: Salve, come ti chiami?
Utente: il mio nome è Domenico e dil mio cognome è Soriano
Bot: Piacere di conoscerti Domenico Soriano
Facciamo qualche altro esempio usando il tag <srai>
<category>
<pattern>DIMMI *</pattern>
<template><star/></template>
</category>
utente : dimmi ciao
bot: ciao
utente: dimmi ti voglio bene
bot: ti voglio bene
<category>
<pattern>DIMMI *</pattern>
<template><star/></template>
</category>
<category>
<pattern>GENTILMENTE DIMMI *</pattern>
<template><srai>DIMMI <star/></srai></template>
</category>
utente: gentilmente dimmi ti voglio bene
-> dimmi ti voglio bene
bot: ti voglio bene
Categoria con variabili
In una category è possibile dichiarare e leggere delle variabili , attraverso l’uso degli elementi set e get. Le variabili dichiarate in questo modo hanno valore globale e se si tenta di leggere una variabile non ancora dichiarata, si ottiene la stringa «unknown», nel caso contrario si ottiene l’ultimo valore configurato.
<category>
<pattern>MI CHIAMO *</pattern>
<template>Ciao <set name="nome"><star/></set>, come va?</template>
</category>
nell’esempio precedente se l’utente scrivesse Mi chiamo Domenico la variabile name=”nome” verrebbe valorizzata con il contenuto di <star> che sappiamo essere in tal caso il valore intercettato dallo * nel nostro caso Domenico.
MI CHIAMO * -> MI CHIAMO DOMENICO
<category>
<pattern>TI RICORDI DI ME</pattern>
<template> <get name="nome"/>, come potrei dimenticarmi di te!</template>
</category>
unknown come potrei dimenticarmi di te!
<category>
<pattern>TI RICORDI DI ME</pattern>
<template><srai>TIRICORDIDIME <get name="nome"/></template>
</category>
<category>
<pattern>TIRICORDIDIME UNKNOWN</pattern>
<template>No, non mi ricordo.</template>
</category>
<category>
<pattern>TIRICORDIDIME *</pattern>
<template><get name="nome"/>, come potrei dimenticarmi di te!</template>
</category>
Con l’esempio precedente si intuisce che, nel momento in cui l’utente farà la domanda ti ricordi di me, il sistema risponderà trasformando il responso in<srai>TIRICORDIDIME <get name=”nome”/> per cui se la variabile name=”nome” sarà valorizzata verrà via <srai> invocata la categoria con pattern TIRICORDIDIME * altrimenti la categoria TIRICORDIDIME UNKNOWN in accordo anche all’ordine delle priorità delle wildcard.
Sono amante della tecnologia e delle tante sfumature del mondo IT, ho partecipato, sin dai primi anni di università ad importanti progetti in ambito Internet proseguendo, negli anni, allo startup, sviluppo e direzione di diverse aziende; Nei primi anni di carriera ho lavorato come consulente nel mondo dell’IT italiano, partecipando attivamente a progetti nazionali ed internazionali per realtà quali Ericsson, Telecom, Tin.it, Accenture, Tiscali, CNR. Dal 2010 mi occupo di startup mediante una delle mie società techintouch S.r.l che grazie alla collaborazione con la Digital Magics SpA, di cui sono Partner la Campania, mi occupo di supportare ed accelerare aziende del territorio .
Attualmente ricopro le cariche di :
– CTO MareGroup
– CTO Innoida
– Co-CEO in Techintouch s.r.l.
– Board member in StepFund GP SA
Manager ed imprenditore dal 2000 sono stato,
CEO e founder di Eclettica S.r.l. , Società specializzata in sviluppo software e System Integration
Partner per la Campania di Digital Magics S.p.A.
CTO e co-founder di Nexsoft S.p.A, società specializzata nella Consulenza di Servizi in ambito Informatico e sviluppo di soluzioni di System Integration, CTO della ITsys S.r.l. Società specializzata nella gestione di sistemi IT per la quale ho partecipato attivamente alla fase di startup.
Sognatore da sempre, curioso di novità ed alla ricerca di “nuovi mondi da esplorare“.