Le potenzialità dei modelli LLM come ChatGPT, PALM2 (Google Bard) e LLaMa 2 sono evidenti ormai a tutti, ma ci siamo scontrati tutti con i limiti del prompt e di fornire conoscenza “utile” a questi assistenti per compiti specifici come, ad esempio, a rispondere a domande puntuali su regolamenti o procedure che non sono parte dei dati usati per l’addestramento del modello.
La risposta è quella di fornire informazioni specifiche che il modello userà insieme alla propria conoscenza per produrre le risposte ai quesiti che riceve, questo è lo scopo del progetto open source da me sviluppato Oraculum (con Sibylla, un voluto mispelling della parola latina sybilla per prendere in giro gli errori dei chatbot). Scopriamo come funziona questo sistema per capire cosa vuol dire “programmare un sistema basato su AI” e quali sono le leve per controllare, almeno in parte, il comportamento dell’AI.
Indice degli argomenti
Il progetto Oraculum Sibylla
Il progetto nasce dalla necessità di istruire un assistente AI basato su ChatGPT alle procedure e ai regolamenti dell’Università di Pisa in modo da consentire, in modo sostenibile, di fornire conoscenza superando i limiti del prompt e consentire di rispondere a domande su servizi specifici a domande poste in qualsiasi lingua il modello LLM supporti.
Già dai primi esperimenti con ChatGPT mi era evidente che se nel prompt si includevano informazioni in italiano e poi si cambiava lingua l’AI era capace di includere le informazioni ricevute per rispondere nell’altra lingua. Si tratta di una capacità straordinaria che ha una potenzialità incredibile nella realizzazione di servizi poiché è possibile immaginare servizi la cui conoscenza è creata e manutenuta da uffici in italiano e utenti vi possono accedere utilizzando la propria lingua. L’Università di Pisa accoglie molti studenti internazionali a cui sarà possibile offrire un accesso molto più pervasivo alle informazioni dell’Ateneo senza distinzione rispetto a chi parla italiano.
I due elementi fondamentali
Il progetto è composto da due elementi fondamentali: Oraculum, ovverosia il sistema di gestione della conoscenza, e Sibylla l’assistente AI personalizzabile che userà la conoscenza per iniettarla nei prompt e fornire al modello AI la conoscenza puntuale per rispondere.
Concettualmente il sistema, come mostrato in figura, è semplice: ogni volta che riceve una domanda da un utente Sibylla cerca nella base di conoscenza i fatti più rilevanti alla domanda e li include nella propria “memoria”. Aggiorna quindi il prompt includendo le informazioni che conserva all’interno della sua memoria ed invoca il modello LLM (ChatGPT nel nostro caso) per ottenere la risposta.

Nella mente di Sibylla
Sibylla appartiene a quella classe di sistemi che è identificata dall’acronimo RAG: Retrieval-Augmented Generation. In questi sistemi l’AI generativa viene “arricchita” di informazioni utili alla generazione senza dover ricorrere a processi complessi come il raffinamento del modello. Inoltre, potendo controllare il contenuto della base di conoscenza è molto più facile controllare il comportamento dell’intelligenza artificiale riducendo significativamente il rischio di “allucinazione” e che quindi fornisca risposte errate.
I fatti rilevanti alla richiesta che pone un utente vengono memorizzati e opportunamente selezionati per essere inclusi nel prompt, in questo modo il modello di AI generativa ha accesso a molta più informazione rispetto alla dimensione massima del prompt che, nel caso di ChatGPT, si estende al più a 32 mila token (ovvero tra 96 e 128 kylobyte di testo). La selezione dei fatti consente inoltre di contenere le dimensioni del prompt e questo contribuisce a tenere sotto controllo la spesa, visto che anche il modello dei costi del servizio è legato al numero dei token della richiesta della risposta.
Una Sibylla in corso di testing riguarda la procedura e il regolamento missioni. In questo caso con soli 76 fatti (di cui 57 sono i commi del regolamento missioni) si ottiene un assistente che offre un notevole livello di interazione rispondendo generalmente correttamente a meno che non abbia le informazioni necessarie.
Se si considera la seguente domanda l’assistente non si limita solo a rispondere ma include anche il riferimento al regolamento da cui ha preso le informazioni.

Utilizzando Oraculum è facile ottenere il fatto utilizzato (non è l’unico come vedremo) per rispondere:

Se continuiamo cambiando lingua Sibylla risponde nuovamente citando il regolamento ma rispondendo nella lingua in cui è posta la domanda:

Utilizzando i comandi di Oraculum possiamo investigare quali fatti sono nella memoria di Sibylla tenendo conto che nell’attuale implementazione la politica di gestione della sua memoria è molto semplice e si limita a caricare, se non già presenti, i 5 fatti più rilevanti (sono in corso di sviluppo gestioni più sofisticate della memoria). La prima domanda individua i seguenti fatti:

La distanza, come scopriremo a breve, è una misura della rilevanza di un particolare fatto rispetto alla domanda posta. Come si può notare già con la prima domanda sono entrati nella memoria entrambi i commi del regolamento usati per rispondere.
Con la seconda domanda in inglese si aggiungono altri fatti:

Come si può notare in questo caso i primi due sono delle risposte a domande frequenti e non commi di regolamento. È altrettanto interessante osservare come se poniamo la stessa domanda in italiano invece che in inglese il risultato varia leggermente ma vengono individuati comunque i fatti rilevanti:

Una volta ottenute le informazioni nella memoria Sibylla genera una rappresentazione XML dei fatti rilevanti e la passa a Chat GPT dopo aver informato nel prompt:
“Per rispondere userai solo fatti veri e le informazioni relative ai fatti in XML che seguiranno al posto della tua conoscenza. I fatti con elemento ‘faq’ rispondono a domande frequenti, i fatti con elemento ‘reg’ si riferiscono a commi di regolamento. Se usi le informazioni di un fatto XML che ha un attributo ‘cit’ includi la citazione tra parentesi nella risposta.”
L’uso di XML consente di fornire informazioni all’intelligenza artificiale sia sui dati (il contenuto del comma o di una risposta ad una FAQ) che sui meta-dati (ad esempio la citazione del comma di regolamento).
Come vedremo in seguito il prompt ha altri elementi ma questa parte determina le istruzioni che indicano che la conoscenza che forniamo ha precedenza su quella propria e in questo modo riusciamo a ridurre significativamente il rischio di allucinazioni.
È comunque importante sottolineare che ciascuna Sibylla ha un suo prompt che va pensato per uno scopo specifico, e si tratta di un aspetto molto importante nella configurazione del sistema.
Confinare una AI: il red teaming
Il prompt utilizzato è centrale al comportamento dell’assistente e come abbiamo appena commentato contribuisce in modo determinante ad evitare che il sistema fornisca informazioni sbagliate. Per confinare le risposte ad esempio il prompt contiene anche la seguente affermazione:
“Rispondi solamente a domande riguardanti le missioni per conto dell’Universit\u00E0 di Pisa, a tutte le altre domande risponderai ‘sono autorizzato a rispondere solo a questioni riguardanti le missioni’.”
Ecco quindi che se si rivolgono domande non pertinenti l’assistente cortesemente si rifiuta di rispondere.
Quando ho cominciato questo progetto ero molto preoccupato dalla possibilità che il l’AI deviasse dal comportamento atteso fornendo risposte completamente errate. Mi sono dovuto ricredere: se si confina ad un ambito molto specifico la sua azione e si forniscono le conoscenze opportune si ottengono risposte puntuali e difficilmente errate. Addirittura l’assistente si raccomanda di consultare l’amministrazione per verificare le informazioni in caso di incertezza. In assenza di informazioni invece inventa di sana pianta la risposta come, ad esempio, nel seguente caso dove avevo eliminato alcuni fatti relativamente a codici del modulo per il rimborso (sono codici come PASTG o PASTS) e l’acronimo è stato inventato di sana pianta:

Una preoccupazione in questo tipo di sistemi è quindi quella di verificare la copertura delle informazioni, poiché altrimenti l’assistente interpreterà la risposta.
Un modo per evitarlo può essere quello di rafforzare il prompt dicendo che deve rispondere solo usando la conoscenza fornita, ma a questo punto si perdono elementi molto importanti che sono utili per ottenere un comportamento “intelligente”. In una delle prime versioni del prompt di fatto si comportava come un sistema che ti stampa la FAQ più vicina alla richiesta, senza esibire il comportamento articolato che ci aspettiamo da una AI.
È quindi essenziale il processo di verifica del comportamento, non solo durante lo sviluppo ma anche quando si modifica la conoscenza in Oraculum che ne determina il comportamento.
La gestione della conoscenza di Oraculum
Sibylla è il componente più piccolo del sistema, è responsabile di implementare la memoria e supportare configurazioni differenti sia in termini di prompt che delle porzioni della base di conoscenza contenuta in Oraculum.
La conoscenza abbiamo detto che è organizzata in fatti. Ciascun fatto è caratterizzato da alcuni campi e sarà convertito in un elemento XML per contribuire potenzialmente ad una risposta. Oraculum è costruito sul sistema open source Weaviate, un sistema che indicizza la conoscenza in vettori utilizzando la capacità delle reti neurali di associare un vettore al testo (embedding) che in qualche modo ne rappresenti il significato indipendentemente dalla lingua. Nel nostro caso, usando comunque i servizi di OpenAI, abbiamo configurato Weaviate perché faccia uso degli embeddings di OpenAI, e quindi quando vengono aggiunti nuovi fatti come testo, il software invoca il servizio di OpenAI e ottiene il vettore corrispondente. Allo stesso modo quando viene posta una domanda questa viene convertita in un vettore e poi confrontata con i vettori presenti nel DB per trovare quelli più vicini (come lascia intuire la distanza che abbiamo incontrato in precedenza).
Poiché la gestione della conoscenza è essenziale per il funzionamento di questi sistemi Oraculum mette a disposizione un insieme di CmdLet Power Shell (nella versione open source di Power Shell) per analizzare il contenuto di Weaviate e filtrare e modificare i fatti. La scelta di usare una shell non è casuale: la popolazione della conoscenza assomiglia molto al processo di indicizzazione dei documenti di un motore di ricerca, e capita spesso di dover elaborare l’input invocando comandi sia per reperirlo che per ripulirlo.
Oraculum offre inoltre l’integrazione con .NET interactive, è quindi possibile interagire con Oraculum e Sibylla sia all’interno di Visual Studio Code che in notebook Jupyter. Si tratta di una funzionalità molto importante poiché in questo modo è possibile salvare delle sessioni “eseguibili” e monitorare l’evoluzione del comportamento dell’AI nel tempo conservando le domande e le relative risposte all’interno dello stesso file.

Perché non usare progetti esistenti?
Si tratta di una domanda che ci si deve sempre porre quando si comincia lo sviluppo di un nuovo progetto. Esistono framework open source (e non), anche sofisticati come Haystack, che consentono di fare assistenti basati sull’approccio RAG. Ho scelto di sviluppare un nuovo progetto perché trovavo questi sistemi complessi da comprendere e da utilizzare, inoltre la loro inclusione in altri sistemi non era semplice.
Oraculum al contrario ha un’architettura molto lineare e abbastanza semplice, e fornisce strumenti per la gestione della conoscenza che abbiamo visto essere un aspetto centrale per il funzionamento. Inoltre, il progetto è una libreria .NET, può essere quindi facilmente incorporato in progetti sia Web che applicativi multipiattaforma.
Il progetto per ora usa ChatGPT come LLM, ma non è troppo complesso sostituirlo con LLaMa 2 se lo si ha in esecuzione in casa o con qualche altro LLM come ad esempio Claude. L’architettura del sistema rimane la stessa anche se la capacità di gestire prompt complessi potrebbe variare al cambio di modello.
La messa in funzione del sistema la si fa in qualche ora, quindi per chi vuole iniziare può essere decisamente un buon punto di partenza.
Conclusioni
Troppo spesso si pensa che l’AI fa tutto da sola, al contrario, come si vede anche in un sistema non troppo complesso come Oraculum, sono molti gli aspetti di cui bisogna preoccuparsi affinché il sistema non si limiti ad essere un’interfaccia Web diversa al solito modello di AI. Penso che i sistemi RAG diverranno rapidamente dominanti poiché consentono di combinare la conoscenza generale dei modelli LLM con quella di un dominio specifico con risultati assolutamente stupefacenti.
Spero sempre che qualcuno si unisca e contribuisca al progetto, ma ormai so che in Italia si preferisce commentare l’open source piuttosto che contribuire a svilupparlo. Per Oraculum ho già trovato alcuni compagni di viaggio, ma sarebbe bello che un progetto open source si sviluppasse partendo dall’Italia, cosa che purtroppo avviene troppo raramente.