Cognitor: un assistente conversazionale NLU costruito da zero
La forza di Cognitor risiede nella capacità di comprendere l’intenzione dell’utente, di estrarre le entità rilevanti e di gestire il contesto della conversazione con una politica di dialogo ben definita. Tutto avviene grazie a una singola rete neurale condivisa per intent e NER, integrata da un layer CRF per garantire la coerenza delle etichette e da un motore di regole scritto in YAML, facilmente estensibile da chiunque. Questa architettura permette di avere un assistente conversazionale efficace, trasparente e personalizzabile.
Nel resto dell’articolo approfondiremo le funzionalità chiave di Cognitor, i motivi per cui non si è scelto un LLM, il suo funzionamento interno, le possibilità di estensione e il perché è un tema importante da condividere su questo blog. Scopri come questo framework può diventare la base solida per i tuoi progetti di chatbot e assistenti vocali.
Cosa fa, in breve
Cognitor è un assistente conversazionale che classifica le intenzioni dell’utente (intent classification) con un alto livello di accuratezza. Il modello è in grado di distinguere tra centinaia di intent, coprendo sia il core del framework sia gli overlay specifici di dominio, garantendo così una copertura completa dei casi d’uso più comuni.
Oltre alla classificazione, il sistema estrae le entità dal testo (Named Entity Recognition). Sono supportati quindici tipi di entità, tra cui date, orari, luoghi, persone, piatti, numeri, prodotti ed e‑mail. Questa precisione consente al bot di raccogliere rapidamente le informazioni necessarie per rispondere in modo pertinente e contestuale.
La gestione del contesto è affidata a una politica di dialogo che monitora le ultime mosse della conversazione e prevede la prossima azione del bot. Le risposte vengono generate secondo regole dichiarative configurabili in YAML, eliminando la necessità di scrivere codice Python per ogni nuovo scenario. Questo approccio rende l’interazione fluida, prevedibile e facilmente modificabile.
Perché non un LLM
Un Large Language Model (LLM) è estremamente potente, ma la sua opacità può diventare un limite. Non è sempre chiaro perché l’LLM abbia fornito una certa risposta, il che rende difficile monitorare e correggere errori in contesti sensibili o regolamentati. Inoltre, le richieste ad un LLM sono costose in termini di tempo e risorse, soprattutto quando si deve interrogare il modello ad ogni turno della conversazione.
Per domini verticali — come prenotazioni, supporto clienti o siti con un numero limitato di intent — un LLM rappresenta spesso una forza bruta sovradimensionata. Cognitor punta sulla trasparenza: ogni predizione è accompagnata da una confidenza misurabile, e una soglia esplicita decide quando rispondere in modo appropriato o ammettere di non aver capito. Questo livello di controllo è fondamentale per garantire coerenza e affidabilità.
L’approccio di Cognitor si ispira al venerato framework Rasa, che per anni ha rappresentato lo standard nella gestione dei dialoghi prima dell’avvento dei LLM. Mantenendo una architettura leggera e modulare, Cognitor offre lo stesso controllo del flusso conversazionale, ma con un peso computazionale ridotto e una maggiore facilità di debug. Il risultato è una soluzione adatta a chi necessita di controllo, non solo di fluidità.
Come è fatto, sotto il cofano
Il primo tassello tecnico è FastText, che genera gli embedding delle parole con 300 dimensioni usando il metodo skip‑gram. Gli embedding vengono allenati direttamente sul dominio del bot, creando un vocabolario su misura che include gergo e nomi propri specifici. Durante l’inferenza, la matrice di embedding è esportata in formato word2vec e caricata come layer congelato, rendendo il servizio più leggero e più semplice da mettere in produzione.
Su questi embedding opera una BiGRU condivisa tra i due compiti principali. Legge la frase in entrambe le direzioni, producendo per ogni token una rappresentazione contestuale. Da qui la rete si biforca in due teste: la prima, dedicata all’intent classification, utilizza un layer di Attention (un singolo linear + softmax) per pesare i token più rilevanti; la seconda, dedicata al NER, impiega un layer CRF (Conditional Random Field) per garantire coerenza sequenziale nelle etichette assegnate.
Le due teste condividono la stessa rappresentazione e vengono allenate con una loss combinata (classificazione dell’intento + CRF sulla sequenza di tag), pesata diversamente per ciascun compito. Lo split tra training e validation è group‑aware, così le frasi generate per data augmentation dallo stesso esempio originale finiscono sempre nello stesso lato dello split, evitando di gonfiare artificialmente l’accuratezza. Questo design costringe il modello a imparare una rappresentazione della frase utile a entrambi i compiti simultaneamente, migliorando efficienza e performance.
La gestione del dialogo è affidata a una rete GRU ispirata alla Transformer Embedding Dialogue Policy di Rasa, ma implementata con un’architettura ricorrente più leggera. Mantiene traccia delle ultime mosse del bot e predice la prossima azione e l’obiettivo della conversazione. Se i dati sono insufficienti o i modelli non sono disponibili, un fallback euristico cerca tra le conversazioni di esempio il percorso più simile e propone la mossa successiva osservata in quel contesto.
Il motore di regole è un linguaggio dichiarativo in YAML. Ecco un esempio semplificato:
rules:
ask_recipe:
slots:
query:
required: true
type: string
entity: DISH
default: __web_search
wait: ask_recipe_wait_responseSi dichiarano gli slot richiesti, i tipi di entità NER da riempire, le risposte di default e di fallback, il tutto senza scrivere una singola riga di codice Python. Le operazioni esterne (ricerca web, calcolo, query) sono riconosciute dal prefisso __ e gestite dall’Operations Manager descritto nella sezione successiva.
Cosa lo rende estendibile
L’Operations Manager di Cognitor scandisce automaticamente due cartelle — una per le operazioni generiche del framework e una per quelle specifiche del dominio. Registra qualsiasi classe che eredita da un’interfaccia comune o qualsiasi funzione con un nome convenzionale, eliminando la necessità di registrazioni manuali o di aggiornare file di configurazione. Questo meccanismo di auto‑discovery rende l’aggiunta di nuovi tag per il riconoscimento delle entità estremamente semplice e veloce.
L’intera pipeline di training, dal corpus grezzo ai modelli salvati, può essere avviata con un unico comando, con flag opzionali per allenare solo il classificatore di intent o solo la politica di dialogo. Questa granularità permette di iterare rapidamente su singole componenti, accelerando i cicli di sviluppo e testing. Il risultato è una struttura modulare che può essere ampliata o modificata senza intaccare il cuore del framework.
Il design di auto‑discovery ha già permesso di integrare un modello completamente diverso — un Transformer di traduzione — come nuova operazione, senza modificare il nucleo di Cognitor. Questa flessibilità è cruciale per mantenere il framework aggiornato con le più recenti innovazioni tecniche, garantendo al contempo stabilità e compatibilità.
Perché ne parlo qui
Su questo blog l’intelligenza artificiale non è solo “l’ultimo modello di OpenAI o Anthropic”. È anche ingegneria: architetture pensate per problemi specifici, scelte tecniche motivate e sistemi comprensibili riga per riga. Cognitor rappresenta esattamente questo approccio, offrendo un caso concreto di NLU costruito con cura e già in produzione.
Il framework alimenta assistenti reali, tra cui quello di porusski.it, e il codice è disponibile pubblicamente su GitHub. La documentazione completa è consultabile su cognitor.programmato.it. Condividendo questi dettagli, voglio dimostrare che la qualità dell’ingegneria è fondamentale per creare soluzioni AI affidabili e scalabili.
Continua a seguirci per approfondimenti su come estendere Cognitor, integrarlo con nuovi modelli e sfruttare al meglio le sue potenzialità in contesti diversi. L’obiettivo è fornire una visione pratica e trasparente dell’AI, pronta per essere adottata da sviluppatori e aziende che cercano controllo, efficienza e personalizzazione.