top of page

🚀 Un mini chatbot che “capisce” le tue richieste di volo: come funziona e perché è importante

Aggiornamento: 26 giu

Hai mai provato a scrivere a un assistente virtuale “Vorrei annullare il mio biglietto” e, invece di capire subito, ti ha chiesto di spiegare tutto di nuovo?Il Proof of Concept (PoC) che ti presento è stato costruito proprio per evitare questi fraintendimenti, ma solo per le prenotazioni aeree.


In questo post scopriremo:

  • Cosa fa il PoC (e in che modo lo fa).

  • Come utilizza spaCy per la ricerca semantica.

  • I pro e i contro di un sistema hard‑coded e deterministico.

  • Un demo live (in Python) per vedere il risultato con un paio di esempi.


1. Che cos’è la “ricerca semantica” e perché serve?

Concetto

Spiegazione in 3 parole

Esempio pratico

Ricerca

Trova parole

“cerca volo”

Semantica

Significato vero

“cancella” = “annulla” = “revoca”

Semantica + Ricerca

Capire l’intento

“Vorrei revocare la mia prenotazione” → cancellazione

In parole povere, non basta guardare le parole esatte che scrivi, ma bisogna capire cosa vuoi davvero. La ricerca semantica fa proprio questo: analizza i verbi, i sostantivi e le frasi per riconoscere l’intento cancellare o prenotare anche se lo esprimi in modi diversi.


2. Il PoC in azione: prenotazioni e cancellazioni aeree


2.1. Qual è l’obiettivo?

Il sistema deve gestire due operazioni:

  1. Prenotare un volo.

  2. Cancellare una prenotazione già esistente.


Tutto il resto (date, orari, numeri di volo, aeroporti) è estratto automaticamente dal testo dell’utente.


2.2. Come è stato costruito?

  • Libreria: spaCy (modello italiano “it_core_news_lg” o “sm”).

  • Logica: hard‑coded → regole fisse, nessun modello generativo (come un LLM).

  • Tecnica di elaborazione: ACON (Algoritmo Deterministico di Controllo).

Deterministico = prevedibile: per la stessa frase ottieni sempre la stessa risposta.

3. Passo per passo: cosa succede quando scrivi qualcosa?


3.1. Analisi dell’input


- Raccoglie *verbi* e *sostantivi* (es. “cancellare”, “volo”).

- Unisce tutti i termini per facilitare il confronto.



# Carica il modello spaCy (usa sm se lg non è disponibile)
    try:
        nlp = spacy.load("it_core_news_lg")
    except:
        nlp = spacy.load("it_core_news_sm")
    
    # Parole semanticamente importanti
    parole_cancellazione = [
        "cancellare", "cancellazione", "eliminare", "eliminazione", 
        "annullare", "annullamento", "rimuovere", "rimozione",
        "disdire", "disdetta", "revocare", "revoca"
    ]
    
    parole_prenotazione = [
        "prenotare", "prenotazione", "riservare", "riserva",
        "prendere", "acquistare", "acquisto", "prenotarmi"
    ]
  
    # Cerca verbi e sostantivi significativi
    verbi_trovati = []
    sostantivi_trovati = []
	doc = nlp(testo_input.lower())
	verbi = [t.lemma_ for t in doc if t.pos_ == "VERB"]
	sostantivi = [t.lemma_ for t in doc if t.pos_ == "NOUN"]
	tutti_i_termini = verbi + sostantivi + testo_input.lower().split()

3.2. Riconoscimento dell’intento


if any(parola in termine for termine in tutti_i_termini
       for parola in parole_cancellazione):
    cancellazione_trovata = True
elif any(parola in termine for termine in tutti_i_termini
         for parola in parole_prenotazione):
    prenotazione_trovata = True

in questo PoC si dà **Priorità** a *cancellazione*: se trovi parole come “cancellare”, “annullare”, ecc., il sistema risponde subito con “Hai chiesto una cancellazione”.



3.3. Estrarre le informazioni indispensabili


Tipo di dato

Funzione Python

Esempio di espressione che riconosce

Numero volo

`cerca_numero_volo()`

`AZ123`, `LH4567`, `volo 1234`

Data

`cerca_data()`

`15 luglio`, `10 agosto`

Ora

`cerca_ora()`

`16:30`, `alle 14`

Luogo (da…a…)

`cerca_luoghi()`

`da Roma a Milano`


Se manca qualcosa, il bot chiede all’utente di specificare il dato mancante (es. “Non ho trovato la data. Potresti specificarla?”).


# Se trova cancellazione, ha priorità
    if cancellazione_trovata:
        print("Hai chiesto una cancellazione.")
        print("Per favore, inserisci il codice di prenotazione:")
        return "cancellazione"
    
    # Altrimenti è una prenotazione
    elif prenotazione_trovata:
        print("Hai chiesto una prenotazione.")
        
        # Cerca numero del volo, data, ora e luoghi
        numero_volo = cerca_numero_volo(testo_input)
        data_trovata = cerca_data(testo_input)
        ora_trovata = cerca_ora(testo_input)
        da, a = cerca_luoghi(testo_input)
        
        if numero_volo:
            print(f"Numero volo trovato: {numero_volo}")
        else:
            print("Non ho trovato il numero del volo. Potresti specificarlo?")
        
        if data_trovata:
            print(f"Data trovata: {data_trovata}")
        else:
            print("Non ho trovato la data. Potresti specificarla?")
        
        if ora_trovata:
            print(f"Ora trovata: {ora_trovata}")
        else:
            print("Non ho trovato l'ora. Potresti specificarla?")
            
        if da and a:
            print(f"Percorso: da {da} a {a}")
        elif da:
            print(f"Partenza da: {da}")
        elif a:
            print(f"Destinazione: {a}")
        else:
            print("Non ho trovato i luoghi. Potresti specificare da dove a dove?")
        
        return "prenotazione"
    else:
        print("Non ho capito cosa vuoi fare. Posso aiutarti con prenotazioni o cancellazioni.")
        return "sconosciuto" 

def cerca_luoghi(testo):
    """Cerca 'da ... a ...' """
    match = re.search(r"da\s+(\w+)\s+a\s+(\w+)", testo, re.IGNORECASE)
    if match:
        return match.group(1), match.group(2)
    return None, None


def cerca_data(testo):
    """Cerca date nel formato '15 luglio', '10 agosto', ecc."""
    mesi = ["gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno",
            "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"]
    
    pattern = r"\b\d{1,2}\s+(" + "|".join(mesi) + r")\b"
    match = re.search(pattern, testo, re.IGNORECASE)
    return match.group() if match else None

def cerca_ora(testo):
    """Cerca ore nel formato '16:30', 'alle 14', ecc."""
    pattern1 = r"\b\d{1,2}[:.]\d{2}\b"
    pattern2 = r"alle\s+\d{1,2}"
    
    match1 = re.search(pattern1, testo)
    match2 = re.search(pattern2, testo)
    
    if match1:
        return match1.group()
    elif match2:
        return match2.group()
    return None

def cerca_numero_volo(testo):
    """Cerca numeri di volo nel formato XY123, AZ789, ecc."""
    # Pattern per codici volo: 2 lettere + numeri o lettere mescolate
    pattern = r"\b[A-Z]{2}\d+[A-Z]*\b"
    match = re.search(pattern, testo, re.IGNORECASE)
    if match:
        return match.group().upper()
    
    # Pattern alternativo: solo numeri (es. volo 1234)
    pattern2 = r"\b(?:volo\s+)?(\d{2,6})\b"
    match2 = re.search(pattern2, testo, re.IGNORECASE)
    if match2:
        return match2.group(1) if match2.group(1) else match2.group()
    
    return None

3.4. Output finale


- **Cancellazione**: stampa “Hai chiesto una cancellazione” + richiede il codice di prenotazione.

- **Prenotazione**: stampa tutti i dati trovati o richiede quelli mancanti, quindi conferma la prenotazione.


# Funzione principale di interazione
def chatbot_interattivo():
    print("🤖 Come posso esserti utile?")
    
    while True:
        user_input = input("\n💬 Scrivi il tuo messaggio (o 'esci' per uscire): ")
        
        if user_input.lower() in ['esci', 'exit', 'quit']:
            print(" Arrivederci!")
            break
        
        # Analizza e guida l'utente
        tipo_richiesta = analizza_stringa_e_guida_utente(user_input)
        
        # Se è una cancellazione, chiedi il codice
        if tipo_richiesta == "cancellazione":
            codice = input("🔢 Inserisci il codice di prenotazione: ")
            if codice:
                print(f" Sto cercando la prenotazione con codice: {codice}")
                # Qui andrebbe la logica di cancellazione reale
                print("✅ Cancellazione completata con successo!")

# Esempio di utilizzo
if __name__ == "__main__":
    
    chatbot_interattivo()  

4. Pro & Contro di un approccio **hard‑coded**


✅ Vantaggi (i “pro”)


- **Determinismo**: ogni volta lo stesso input produce lo stesso output. Perfetto per ambienti dove la prevedibilità è obbligatoria (es. test di sistema, contesti regolamentati).

- **Controllo totale**: puoi aggiungere, rimuovere o modificare le regole a piacere.

- **Nessun costo di “training”**: non serve un’enorme quantità di dati né GPU per addestrare un modello.


❌ Limiti (i “contro”)


Limite

Perché è un problema

Zero intelligenza contestuale

Se l’utente scrive “Mi potresti dare un volo per domani?” il bot non capisce.

Rigidità

Non si adatta a formulazioni nuove o slang giovanile.

Scalabilità limitata

Aggiungere nuove funzionalità richiede più codice “hard‑coded”.

Gestione ambiguità

Se la frase è poco chiara (es. “cancella il volo 123”, ma non è chiaro il numero di prenotazione), il bot può fallire.

> **In pratica:** il PoC è ottimo per dimostrare *come* funziona la ricerca semantica, ma in un’app reale vorresti un mix tra regole fisse e un modello più flessibile.


5. Cosa potresti migliorare?


1. **Aggiungere un livello di “fallback”** con un piccolo modello di Language Model che gestisca le frasi non riconosciute.

2. **Gestire sinonimi** più complessi (es. “volare verso”) usando WordNet o i vectori di spaCy.

3. **Implementare un’interfaccia grafica** (web o mobile come Gradio) per rendere l’interazione più user‑friendly.

4. **Logging intelligente**: salvare le frasi non capite per analizzarle e perfezionare le regole.


6. Conclusioni


Il PoC che ho mostrato è un **esempio concreto di come la ricerca semantica possa trasformare una semplice frase in una serie di azioni automatiche**, tutto senza l’uso di grandi modelli di intelligenza artificiale.


Se sei uno studente curioso o un giovane sviluppatore, prova a **modificare le liste di parole chiave** (`parole_cancellazione`, `parole_prenotazione`) o a **estendere le regex** per date/ore. Scoprirai quanto è divertente “insegnare” al computer a capire il linguaggio umano, passo dopo passo.


Buon coding e buona “volata” nel mondo della **NLU (Natural Language Understanding)**! ✈️💬


🎓 Risorse consigliate


Risorsa

Perché è utile

Guida ai modelli italiani (lg vs sm).

Tutorial pratico su spaCy per principianti.

Dove scaricare i modelli se il tuo PC non li ha.


> **Divertiti a sperimentare!** Se ti va, condividi i tuoi miglioramenti su GitHub o nei commenti qui sotto...


 
 
 

Commenti


© 2024 texservice.tech   -  facilitatore informatico  -   mail: texservice13@gmail.com Tel: 353-468-73-15

bottom of page