% Parte 2 \part{} % Azzerare la numerazione dei capitoli per la Parte 2 \setcounter{chapter}{0} \chapter{\href{https://Intervistestoriche.Tech}{Intervistestoriche.Tech}} Dopo aver esaminato lo stato dell'arte dell’IA Generativa e le sue implicazioni per l'educazione, soprattutto riguardo ai principi di trasparenza e alla necessità di una guida da parte dei docenti, questa seconda parte della tesi illustra un approccio concreto per integrare queste tecnologie nella didattica. Sono stati sviluppati negli ultimi anni alcuni strumenti che si basano su modelli linguistici di grandi dimensioni (LLM) per esplorare percorsi storici educativi alternativi. Per esempio, \textit{Hello History} e \textit{Character.AI} offrono modalità innovative di interazione con personaggi storici. Queste applicazioni, tuttavia, ma sono difficilmente adattabili all'uso didattico. Al contrario, le applicazioni qui presentate si propongono quali strumenti efficaci per attività didattiche, come la ricerca di fonti primarie, e sfruttano lo scraping dinamico di contenuti da Wikipedia tramite la libreria Python Beautiful Soup. Invece di creare un database strutturato di informazioni, questo metodo prevede l'estrazione in tempo reale dei dati necessari direttamente da Wikipedia, inserendoli poi nel contesto del modello linguistico. Il tutto è dinamico: viene effettuato lo scraping, salvato in una variabile e poi inserito direttamente nel contesto dell'LLM. Per questo sono stati scelti modelli Google Gemini: hanno un contesto molto grande e quindi non si sarebbe mai presentato il problema dell'esaurimento del contesto disponibile da parte del modello. È stato scelto di copiare e incollare testo da Wikipedia, in quanto, trattandosi di un'enciclopedia libera, non sussistono problemi di copyright. Le applicazioni sono state sviluppate con Streamlit, una libreria Python open-source, che gestisce sia l'interfaccia utente (front-end) sia l'interazione con il modello linguistico (back-end). Si possono creare strumenti web complessi con poche righe di codice Python, senza bisogno di competenze specifiche in HTML, CSS o JavaScript. Le applicazioni si appoggiano sulle API di Google Gemini AI, che offrono un accesso gratuito con un piano sperimentale. In questo modo si evitano costi per gli utenti, tranne in caso di uso intensivo. Per garantire trasparenza e controllo, le applicazioni mostrano sempre il prompt utilizzato e il contesto, non raccolgono dati degli utenti, hanno un accesso diretto alle API e consentono al docente di impostare i propri filtri di sicurezza. L'accesso alle API è riservato da Google ai maggiorenni per ragioni di sicurezza, così da prevenire un uso non autorizzato da parte degli studenti. Questa misura garantisce inoltre che l'accesso alle informazioni avvenga nel rispetto della privacy. Le applicazioni sono state sviluppate per consentire un'interazione diretta, tramite chiamata API, senza bisogno di intermediari. Ogni docente deve creare la propria chiave API accedendo con il suo account Google a questo link: https://aistudio.google.com/apikey. Per questo progetto si è potuto scegliere tra diversi modelli linguistici di Google, in particolare si consiglia di scegliere \textit{Gemini 1.5 Pro}, un modello multimodale di medie dimensioni ottimizzato per attività di ragionamento complesse. È presente anche \textit{Gemini 1.5 Flash}, un modello più leggero progettato per attività con complessità inferiore. La differenza principale che deve essere presa in considerazione riguarda i costi e i tempi di risposta. Con \textit{Gemini 1.5 Flash} si possono fare più chiamate API al minuto e le risposte sono generate più velocemente, a discapito di una maggiore accuratezza che comunque nella maggioranza delle app non è necessaria. Particolare attenzione è stata posta alla gestione dei \textit{guardrail}, i filtri di sicurezza di Google Gemini. Il docente può scegliere tra tre livelli di sicurezza (Alto, Medio, Basso) per adattare l'interazione del modello al contesto. È possibile scegliere modelli più o meno restrittivi, per consentire un'esperienza più libera o più controllata, evitando temi inadatti al contesto, come guerre, morti o epidemie. Queste applicazioni sono pensate per un uso in classe, sotto la guida del docente, e non sostituiscono lo studio individuale o il confronto diretto. Si pongono piuttosto come un supporto per ripensare le modalità di apprendimento, stimolando attività interattive e coinvolgenti ad esempio per iniziare discussioni o interrogazioni parlate. Si tratta di un \textit{Minimum Viable Product (MVP)}, un punto di partenza per esplorare le potenzialità didattiche dei modelli linguistici, non di applicazioni definitive. L'obiettivo è quello di stimolare un nuovo approccio all'apprendimento e di dimostrare che le allucinazioni dei modelli, spesso considerate un problema, possono essere viste come uno strumento utile ad accrescere lo spirito critico e l'attenzione alla qualità dell'informazione. Per questo motivo è stato usato in alcuni casi anche un semplice \textit{Chain of Thoughts (CoT)} per aumentare l'accuratezza delle risposte ma sopratutto per mostrare agli studenti il ragionamento del modello e individuare fallacie ed errori nel suo ragionamento \section{Aspetti tecnici e librerie utilizzate} Questo progetto si basa su Python e alcune librerie chiave. Di seguito, un approfondimento su ciascuna di esse. \subsection{Python} Python è stato scelto come linguaggio di programmazione principale per la sua semplicità, versatilità e per l’ampia disponibilità di librerie per l’intelligenza artificiale e il web scraping. La sua sintassi chiara e leggibile facilita lo sviluppo e la manutenzione del codice, rendendolo accessibile anche a chi non ha una vasta esperienza di programmazione. Inoltre, Python è ampiamente utilizzato nella comunità scientifica e didattica, il che rende il progetto accessibile a un pubblico più ampio. \subsection{I modelli Gemini e l'interazione tramite API} I modelli Gemini di Google, lanciati nel 2024, rappresentano una famiglia di modelli linguistici multimodali di ultima generazione. Si distinguono per la loro capacità di elaborare e generare non solo testo, ma anche immagini, audio e video. I modelli Gemini 1.5 Pro e Gemini 1.5 Flash, utilizzati in questo progetto, supportano un contesto fino a 2 milioni di token, ovvero diverse centinaia di pagine di un libro («Tutorial: inizia a utilizzare l’API Gemini | Gemini API», s.d.). Questa capacità è particolarmente utile quando si fornisce al modello il testo di una pagina di Wikipedia, che può essere anche molto lungo. Tutta la famiglia Gemini si basa sull'architettura MoE, e Google rilascia, per gli utenti finali, una libreria per interagire in maniera rapida e gratuita con i propri modelli. Come accennato in precedenza, la piattaforma di riferimento è Google AI Studio. Prevede un piano gratuito e la chiave API può essere creata solo da maggiorenni, prevenendo così usi impropri da parte dei minori. Per capire meglio come interagire con i modelli Gemini tramite codice, l'esempio seguente mostra una chiamata API in Python: \begin{lstlisting}[language=Python, caption=Esempio di chiamata API con Python] import os import google.generativeai as genai genai.configure(api_key=os.environ["GEMINI_API_KEY"]) generation_config = { "temperature": 1, "top_p": 0.95, "top_k": 40, "max_output_tokens": 8192, "response_mime_type": "text/plain", } safety_settings = { "HARM_CATEGORY_HARASSMENT": "BLOCK_MEDIUM_AND_ABOVE", "HARM_CATEGORY_HATE_SPEECH": "BLOCK_MEDIUM_AND_ABOVE", "HARM_CATEGORY_SEXUALLY_EXPLICIT": "BLOCK_MEDIUM_AND_ABOVE", "HARM_CATEGORY_DANGEROUS_CONTENT": "BLOCK_MEDIUM_AND_ABOVE", } system_instruction = """Sei un assistente psicologo che ha studiato ad Harvard e aiuta l'utente a calmarsi, suggerendogli le migliori strategie di rilassamento.""" model = genai.GenerativeModel( model_name="gemini-2.0-flash-exp", generation_config=generation_config, safety_settings=safety_settings, ) chat_session = model.start_chat( history=[ ], system_instruction=system_instruction ) response = chat_session.send_message("INSERT_INPUT_HERE")s print(response.text) \end{lstlisting} Questo codice illustra una semplice chiamata API ai modelli Gemini. Prima di eseguirlo, è necessario installare la libreria \lstinline|google-generativeai| con \lstinline|pip install google-generativeai| e configurare la variabile d'ambiente \lstinline|GEMINI_API_KEY| con la propria chiave API. Il codice inizia configurando l'accesso al modello, specificando i parametri di generazione (come temperature, \lstinline|top_p|, \lstinline|top_k|, \lstinline|max_output_tokens|), i filtri di sicurezza tramite \lstinline|safety_settings| e la \lstinline|system_instruction|. Quest'ultima funge da prompt principale, definendo il ruolo del modello e influenzando tutte le interazioni successive. In questo caso, istruisce il modello a comportarsi come uno psicologo di Harvard che aiuta gli utenti a rilassarsi. Il modello usato è stato \lstinline|gemini-2.0-flash-exp|. Il codice svolge le seguenti azioni: importa le librerie necessarie, configura l'API, definisce i parametri di generazione, imposta i filtri di sicurezza e definisce l'istruzione di sistema che guida il comportamento del modello. Sostituendo il placeholder "\lstinline|INSERT_INPUT_HERE|" ed eseguendo il codice si invia un messaggio al modello e viene stampato in console la risposta ottenuta. È fondamentale installare la libreria e configurare la chiave API. Tra i settaggi cruciali, temperature regola la casualità del modello, \lstinline|model_name| permette di scegliere quale modello usare, le \lstinline|safety_settings| applicano filtri di sicurezza e bloccano contenuti inappropriati, mentre la \lstinline|system_instruction| plasma il ruolo del modello. Google permette di impostare diversi livelli di blocco per le categorie delle \lstinline|safety_settings|, o di disabilitarli del tutto. \subsection{Streamlit} Streamlit è una libreria Python open-source progettata per semplificare la creazione di applicazioni web interattive, particolarmente utili per progetti di machine learning e data science. Lanciata nel 2019, Streamlit è stata concepita per essere intuitiva e facile da usare, anche per chi non ha esperienza di sviluppo web (<>, s.d.). Streamlit permette di trasformare script Python in app web con poche righe di codice aggiuntive, rendendo il processo di sviluppo accessibile anche a chi non ha competenze avanzate di programmazione. Questo avviene grazie a una serie di widget (come pulsanti, slider e caselle di testo) che permettono agli utenti di interagire con l’app e di modificarne il comportamento in tempo reale. Questi widget facilitano l’esplorazione e l’analisi dei dati in modo dinamico e coinvolgente. La vasta libreria e i continui aggiornamenti permettono di creare diverse web-app responsive, come dashboard, report interattivi o strumenti di visualizzazione dati. Queste caratteristiche rendono Streamlit una scelta ottimale per la prototipazione rapida di applicazioni basate su modelli linguistici. In questo progetto, Streamlit gestisce l’intera interfaccia utente, dalla richiesta della chiave API all’inserimento dei link di Wikipedia, fino alla visualizzazione della risposta generata dal modello. Inoltre, permette di integrare facilmente i controlli per la gestione dei filtri di sicurezza e per la selezione del modello (come \textit{Gemini 1.5 Pro} o \textit{Gemini 1.5 Flash}). La libreria semplificando il lato front-end e back end permette agli sviluppatori di concentrarsi sulla logica applicativa senza doversi preoccupare della complessità dello sviluppo. Di seguito un esempio di una web app che che utilizza le API di Gemini: \begin{lstlisting}[language=Python, caption=App Streamlit con API Gemini] import streamlit as st import google.generativeai as genai import os # Configura l'API di Gemini genai.configure(api_key=os.environ["GEMINI_API_KEY"]) # Inizializza il modello Gemini model = genai.GenerativeModel(model_name="gemini-2.0-flash-exp") st.title("Gemini Chatbot") # Inizializza la cronologia dei messaggi nella sessione if "messages" not in st.session_state: st.session_state.messages = [] # Visualizza la cronologia dei messaggi al caricamento della app for message in st.session_state.messages: with st.chat_message(message["role"]): st.markdown(message["content"]) # Gestione dell'input dell'utente if prompt := st.chat_input("Scrivi il tuo messaggio:"): st.session_state.messages.append({"role": "user", "content": prompt}) # Mostra il messaggio dell'utente nella chat with st.chat_message("user"): st.markdown(prompt) # Ottiene una risposta da Gemini chat = model.start_chat(history=[ {"role": m["role"], "parts": m["content"]} for m in st.session_state.messages if m["role"] != "assistant" ]) response = chat.send_message(prompt) # Mostra la risposta di Gemini nella chat with st.chat_message("assistant"): st.markdown(response.text) # Aggiunge la risposta di Gemini alla cronologia st.session_state.messages.append({"role": "assistant", "content": response.text}) \end{lstlisting} Grazie al componente \lstinline|st.chat_message|, è possibile creare interfacce di chat conversazionali. Questo componente si occupa di gestire la visualizzazione dei messaggi, sia dell'utente che dell'assistente, in un layout intuitivo. I messaggi vengono presentati in contenitori di chat distinti, con avatar predefiniti o personalizzati, rendendo l'interazione più chiara e coinvolgente. Un'altra caratteristica fondamentale di Streamlit è la gestione dello stato della sessione tramite \lstinline|st.session_state|. Questo meccanismo permette all'applicazione di ricordare le informazioni tra le diverse interazioni dell'utente, garantendo un'esperienza utente fluida e coerente. Se si ritiene necessario mantenere la cronologia dei messaggi precedenti per consentire al modello di comprendere il contesto della conversazione \lstinline|st.session_state| permette di memorizzare questa cronologia e renderla disponibile durante l'interazione con l'utente. In questo modo, l'app può "ricordare" le domande e le risposte passate, offrendo un'esperienza simile ai chatbot a cui siamo abituati. Analizzando il codice, si può notare come: Vengono importate le librerie necessarie, in particolare streamlit per l'interfaccia utente, \lstinline|google.generativeai| per le API di Gemini e os per la gestione delle variabili d'ambiente. \begin{itemize} \item Viene configurata l'API di Gemini con la chiave API ottenuta da Google AI Studio e viene istanziato il modello. \item Si definisce un titolo per l'applicazione con \lstinline|st.title("Gemini Chatbot"|.. \item Viene creato il componente \lstinline|st.session_state.messages| dove vengono salvati i messaggi della chat. \item Si cicla sul componente \lstinline|st.session_state.messages| per far comparire la cronologia della chat al caricamento della pagina. \item Si utilizza il componente \lstinline|st.chat_input| per permettere all'utente di inserire un input e si controlla che non sia vuoto. \item Si usa \lstinline|st.chat_message| per visualizzare sia i messaggi dell'utente che quelli del bot. \item Viene creata una sessione di chat con l'API di gemini tramite la funzione \lstinline|model.start_chat(history=[...])| fornendogli uno storico della chat (senza la risposta del bot). \item Si invia il prompt all'API di Gemini con response = \lstinline|chat.send_message(prompt)| e viene visualizzata la risposta. \item Viene salvata la risposta del bot all'interno della cronologia della chat. \end{itemize} \subsection{Beautiful Soup} Beautiful Soup è una libreria Python progettata per il web scraping, cioè per raccogliere dati e testi da pagine web in modo automatico (<>, s.d.). In questo progetto, Beautiful Soup è impiegata per estrarre il testo delle pagine di Wikipedia per poter fornire contesto al modello linguistico. Il processo di scraping si attiva quando l'utente inserisce un link di Wikipedia. Dopo di che, Beautiful Soup analizza il codice HTML della pagina, estrae il testo rilevante della wiki (escludendo menu, immagini e altri elementi non testuali) e, tramite una variabile, viene poi inserito nel prompt di sistema dell'app. Per utilizzare Beautiful Soup, è necessario prima ottenere il contenuto HTML della pagina web tramite una richiesta \textit{.get}, utilizzando la libreria requests. Una volta ottenuto il contenuto, Beautiful Soup viene utilizzato per analizzare la struttura HTML e dunque creare un oggetto soup, che permette di navigare e cercare elementi specifici all'interno del documento HTML. \section{Funzioni principali delle applicazioni di \href{https://intervistestoriche.tech}{IntervisteStoriche.Tech}} Pur avendo ognuna le proprie peculiarità, tutte le applicazioni hanno delle funzioni in comune: \begin{itemize} \item Controllo della validità della chiave API: La prima funzione consiste nella verifica della validità della chiave API fornita dall'utente. Questo avviene tramite una semplice chiamata API a Google Gemini con un testo di prova. Se la chiamata ha successo, significa che la chiave è valida e l'applicazione può procedere. In caso contrario, viene visualizzato un messaggio di errore. \item Controllo dell'URL di Wikipedia: l'applicazione verifica che l'URL inserito dall'utente sia effettivamente un link a una pagina di Wikipedia e che corrisponda a una voce esistente. Questo controllo previene errori e assicura che il modello riceva un contesto valido. Vengono accettate pagine di Wikipedia in qualsiasi lingua. \item Scraping e invio del contesto a Gemini: una volta validato l'URL, Beautiful Soup estrae il testo dalla pagina di Wikipedia. Questo testo viene poi inserito nel prompt inviato a Gemini, insieme alla domanda formulata dal docente. L'ampio contesto dei modelli Gemini (2 milioni di token) permette di includere l'intero testo della pagina, senza bisogno di riassumerlo o di selezionarne solo alcune parti. Anche nel caso di pagine molto lunghe, è improbabile che si superi il limite di token. Volendo, si potrebbero includere nel contesto anche i link presenti nella pagina, per un'analisi ancora più approfondita. \item Visualizzazione della risposta tramite Streamlit: la risposta generata da Gemini viene infine visualizzata nell'interfaccia Streamlit. La risposta tiene conto del contesto fornito (la pagina di Wikipedia) e delle impostazioni di sicurezza selezionate dal docente. \end{itemize}