EmailAI: come creare un assistente AI locale per le proprie email con Python e Ollama

EmailAI è un progetto Python pensato per trasformare una normale casella Gmail in una base di conoscenza interrogabile attraverso l’intelligenza artificiale.

L’idea è semplice: invece di cercare manualmente tra centinaia o migliaia di messaggi, possiamo rivolgere una domanda in linguaggio naturale, come:

“Ci sono email riguardanti corsi di guida?”

EmailAI recupera le email pertinenti, costruisce un contesto e lo sottopone a un modello di intelligenza artificiale eseguito localmente sul computer.

Nel nostro caso utilizziamo Ollama e il modello Qwen 2.5 7B.

Il vantaggio principale è che non è necessario acquistare un abbonamento a un servizio AI cloud: il modello viene eseguito direttamente sul proprio computer.


1. Che cos’è EmailAI?

EmailAI è un piccolo sistema di ricerca e analisi delle email composto da diversi componenti:

             ┌─────────────────────┐
             │        Gmail        │
             └──────────┬──────────┘
                        │
                        ▼
             ┌─────────────────────┐
             │     Gmail API       │
             └──────────┬──────────┘
                        │
                        ▼
             ┌─────────────────────┐
             │   EmailAI / Python  │
             │                     │
             │  ricerca locale     │
             │  filtraggio         │
             └──────────┬──────────┘
                        │
                        ▼
             ┌─────────────────────┐
             │       Ollama        │
             │                     │
             │     Qwen 2.5 7B     │
             └──────────┬──────────┘
                        │
                        ▼
             ┌─────────────────────┐
             │ Risposta in lingua  │
             │ naturale             │
             └─────────────────────┘

Il progetto non è quindi semplicemente una “chat con un modello AI”.

È un’applicazione che mette in comunicazione:

  • Gmail;
  • Python;
  • ricerca delle email;
  • un modello linguistico locale;
  • un sistema di prompt;
  • Git per il controllo del codice.

2. Perché utilizzare un modello AI locale?

Una delle caratteristiche più interessanti di EmailAI è l’utilizzo di un modello locale.

Servizi come ChatGPT, Claude o Gemini richiedono normalmente l’invio delle richieste a server remoti e, a seconda del servizio e del piano utilizzato, possono richiedere un abbonamento o un sistema di API a pagamento.

Con Ollama il modello viene invece scaricato sul computer.

L’architettura diventa:

Computer
│
├── Python
│
├── EmailAI
│
├── Ollama
│     └── Qwen 2.5 7B
│
└── Gmail API

L’intelligenza artificiale viene quindi eseguita localmente.

Questo permette di sperimentare con gli LLM senza dover acquistare una chiave API per ogni richiesta.

Naturalmente Gmail rimane un servizio online e l’accesso alle email avviene attraverso la Gmail API.


3. Prerequisiti

Per seguire questa guida sono necessari:

  • Linux, macOS oppure Windows;
  • Python 3;
  • pip;
  • Git;
  • un account Google/Gmail;
  • accesso alla Gmail API;
  • Ollama;
  • un modello compatibile con Ollama;
  • sufficiente RAM e spazio su disco.

Per il nostro progetto abbiamo utilizzato:

Python 3.13
Ollama 0.34.0
Qwen 2.5 7B
Git

Il progetto è stato sviluppato all’interno di un ambiente virtuale Python.


4. Installare Ollama

Ollama permette di eseguire modelli linguistici direttamente sul proprio computer.

Dopo l’installazione possiamo verificare che sia disponibile:

ollama --version

Un risultato valido sarà simile a:

ollama version is 0.34.0

È importante distinguere tra il comando ollama e il servizio HTTP fornito da Ollama.

Il nostro programma Python non esegue direttamente il modello.

Comunica invece con Ollama attraverso:

http://localhost:11434

Possiamo verificare che il server risponda:

curl http://localhost:11434/api/tags

Se tutto funziona, Ollama restituirà l’elenco dei modelli installati.


5. Installare Qwen

Nel nostro progetto utilizziamo:

qwen2.5:7b

Possiamo scaricarlo con:

ollama pull qwen2.5:7b

Successivamente possiamo verificare che sia presente:

ollama list

Oppure interrogarlo direttamente:

ollama run qwen2.5:7b

A questo punto possiamo scrivere:

Spiega in italiano in una frase cosa sei.

Il modello dovrebbe rispondere utilizzando il linguaggio naturale.

Per uscire:

/bye

6. Testare Ollama tramite HTTP

EmailAI comunica con Ollama utilizzando la sua API HTTP.

Possiamo effettuare una prima prova direttamente dal terminale:

curl -s http://localhost:11434/api/generate \
  -d '{"model":"qwen2.5:7b","prompt":"Rispondi in italiano con una sola frase: cos'\''è un'\''email?","stream":false}'

Ollama restituirà un JSON contenente la risposta del modello.

Un esempio:

{
  "model": "qwen2.5:7b",
  "response": "Un'email è un messaggio elettronico inviato e ricevuto tramite internet.",
  "done": true
}

Questo test è molto importante.

Se questo comando funziona, significa che:

Python/EmailAI
       │
       ▼
localhost:11434
       │
       ▼
Ollama
       │
       ▼
Qwen

è un’architettura possibile e funzionante.


7. Creare il progetto Python

Creiamo la directory:

mkdir -p ~/Lab/Programming/emailai
cd ~/Lab/Programming/emailai

Creiamo un ambiente virtuale:

python -m venv .venv

Attiviamolo:

source .venv/bin/activate

Il prompt del terminale dovrebbe mostrare qualcosa come:

(.venv)

8. Installare Requests

EmailAI deve comunicare con Ollama tramite HTTP.

Installiamo quindi requests:

pip install requests

Possiamo verificare:

pip show requests

9. Il primo test Python

Un programma minimale può comunicare con Ollama utilizzando:

import requests

url = "http://localhost:11434/api/generate"

data = {
    "model": "qwen2.5:7b",
    "prompt": "Dimmi in una frase chi sei",
    "stream": False
}

response = requests.post(
    url,
    json=data,
    timeout=120
)

response.raise_for_status()

result = response.json()

print(result["response"])

Questo rappresenta il cuore della comunicazione tra EmailAI e il modello.

Python invia:

prompt

a Ollama.

Ollama esegue:

Qwen 2.5 7B

e restituisce:

response

10. La struttura del progetto

La struttura del nostro progetto è:

emailai/
├── .gitignore
├── ai_assistant.py
├── email_database.py
├── gmail_reader.py
├── requirements.txt
├── test_ai.py
├── test_ollama.py
│
├── .env                 # NON versionato
├── credentials.json     # NON versionato
├── token.json           # NON versionato
├── emails.json          # dati locali, NON versionato
└── .venv/               # ambiente Python, NON versionato

I file principali hanno responsabilità diverse.

gmail_reader.py

Gestisce la lettura e la ricerca delle email.

email_database.py

Gestisce la parte relativa ai dati locali delle email.

ai_assistant.py

Contiene la comunicazione con Ollama e la logica del prompt.

test_ollama.py

Serve per verificare che Python riesca a comunicare correttamente con Ollama.

test_ai.py

Esegue un test completo:

ricerca email
      ↓
selezione risultati
      ↓
creazione contesto
      ↓
Qwen
      ↓
risposta

11. Collegare Gmail

Per permettere a EmailAI di leggere Gmail è necessario utilizzare la Gmail API.

Il principio è:

EmailAI
   │
   ▼
Google OAuth
   │
   ▼
Gmail API
   │
   ▼
Casella Gmail

Google richiede l’autenticazione OAuth.

Questo significa che EmailAI non deve conoscere la password dell’account Gmail.


12. credentials.json

Per utilizzare Gmail API occorre creare le credenziali OAuth tramite Google Cloud.

Il file ottenuto viene normalmente chiamato:

credentials.json

Questo file deve rimanere privato.

Non deve essere pubblicato su Git.

Per questo motivo il nostro .gitignore contiene regole per evitare di versionare dati sensibili.


13. Il token OAuth

Al primo accesso Google richiede l’autorizzazione dell’applicazione.

Dopo l’autorizzazione viene normalmente generato:

token.json

Anche questo file deve rimanere privato.

È infatti associato all’autorizzazione dell’applicazione ad accedere all’account.


14. Perché .gitignore è fondamentale

Uno degli errori più pericolosi quando si lavora con API e servizi cloud consiste nel caricare accidentalmente credenziali su Git.

Nel progetto utilizziamo quindi un .gitignore che esclude, tra gli altri:

.env
.venv/
__pycache__/
credentials.json
token.json
emails.json

Prima di effettuare un commit è sempre opportuno controllare:

git status

e:

git status --ignored

Ancora meglio:

git diff --cached --name-only

In questo modo possiamo verificare esattamente quali file finiranno nel commit.


15. La ricerca delle email

EmailAI non invia necessariamente tutta la casella Gmail al modello.

Prima viene effettuata una ricerca.

Per esempio:

Ci sono email riguardanti corsi di guida?

può produrre una serie di risultati:

1. Corsi nazionali Trainer Specializzato Guida in Emergenza-Urgenza
2. Bando Corso Nazionale MTAG – Modulo Trasversale di Abilitazione alla Guida per Patenti Superiori
3. Newsletter CRI

La ricerca locale serve a ridurre il numero di email da analizzare.

Questo è importante sia per le prestazioni sia per la qualità della risposta.


16. Dal testo delle email al contesto AI

Dopo la ricerca, EmailAI costruisce un contesto.

Per ogni email vengono utilizzati elementi come:

DATA
MITTENTE
OGGETTO
CORPO

Il risultato viene trasformato in un prompt strutturato.

Per esempio:

DATA: 4 settembre 2026
MITTENTE: Croce Rossa Italiana
OGGETTO: Bando Corso Nazionale MTAG

CORPO:
...

Questo permette al modello di sapere non soltanto il contenuto, ma anche la provenienza dell’informazione.


17. Il ruolo del prompt

Il prompt è una parte fondamentale di EmailAI.

Non vogliamo semplicemente chiedere:

Rispondi alla domanda.

Vogliamo invece stabilire precise regole.

Per esempio:

Sei EmailAI, un assistente personale per la ricerca nelle email.

Devi rispondere alla domanda dell'utente utilizzando
esclusivamente le informazioni contenute nelle email fornite.

Non inventare informazioni.

Se trovi un'email pertinente alla domanda,
segnalalo esplicitamente.

Se l'email è correlata ma non identica alla richiesta,
spiegalo chiaramente.

Rispondi in italiano.

Questo riduce il rischio che il modello utilizzi conoscenze esterne per costruire la risposta.


18. Un esempio reale

Supponiamo di chiedere:

Ci sono email riguardanti corsi di guida?

La ricerca trova:

Corsi nazionali Trainer Specializzato Guida in Emergenza-Urgenza

e:

Bando Corso Nazionale MTAG – Modulo Trasversale di Abilitazione
alla Guida per Patenti Superiori

EmailAI può quindi distinguere tra le due informazioni.

La prima riguarda la formazione di trainer specializzati nella guida in emergenza.

La seconda riguarda invece un modulo di abilitazione alla guida per patenti superiori.

Il sistema può quindi rispondere che esistono email pertinenti, specificando però che non si tratta necessariamente di corsi di guida di base per ottenere una patente.

Questo è un esempio importante di differenza tra:

ricerca per parola

e:

comprensione del contesto

19. Ollama come server locale

Dal punto di vista tecnico Ollama espone un’API HTTP locale.

L’indirizzo utilizzato da EmailAI è:

http://localhost:11434

L’applicazione Python invia una richiesta POST:

POST /api/generate

con informazioni come:

{
    "model": "qwen2.5:7b",
    "prompt": "...",
    "stream": false
}

Ollama carica il modello e genera la risposta.

EmailAI riceve quindi un JSON e ne estrae il campo:

response

20. Perché a volte Qwen può essere lento?

Un modello da circa 7 miliardi di parametri è molto più pesante rispetto a un normale programma Python.

La prima richiesta può richiedere tempo perché Ollama deve caricare il modello in memoria.

Inoltre la velocità dipende da:

  • CPU;
  • GPU;
  • VRAM;
  • RAM;
  • quantizzazione;
  • dimensione del prompt;
  • numero di token generati.

Nel nostro caso Qwen 2.5 7B viene utilizzato in una versione quantizzata:

Q4_K_M

Questo permette di ridurre considerevolmente le risorse necessarie.


21. Gestire i timeout

Quando Python comunica con Ollama è opportuno utilizzare un timeout adeguato:

timeout=120

Un modello locale può infatti impiegare diversi secondi, soprattutto durante il caricamento iniziale.

Un timeout troppo basso potrebbe provocare:

requests.exceptions.ReadTimeout

senza che Ollama sia realmente guasto.

Per verificare la situazione possiamo sempre testare direttamente:

curl http://localhost:11434/api/tags

e successivamente:

ollama run qwen2.5:7b

22. Versionamento con Git

EmailAI è stato trasformato in un vero progetto Git.

Inizializzazione:

git init

Primo commit:

git add .
git commit -m "Initial EmailAI project"

Successivamente abbiamo registrato le modifiche:

git add ai_assistant.py gmail_reader.py test_ai.py
git commit -m "Improve email search and AI assistant"

Il repository è stato poi collegato a Forgejo:

git remote add origin https://git.athena-net.org/Alessandro/emailai.git

e pubblicato:

git push -u origin master

Il progetto è quindi disponibile nel repository Git di AthenaNet.


23. Sicurezza

Quando si costruiscono applicazioni che lavorano con email e AI, la sicurezza deve essere considerata fin dall’inizio.

I principali elementi da proteggere sono:

credentials.json
token.json
.env
emails.json

Non bisogna mai fare:

git add credentials.json

oppure:

git add token.json

e non bisogna mai pubblicare password, token OAuth o API key all’interno del codice.

È buona pratica verificare sempre:

git status

prima di ogni commit.


24. EmailAI non è ancora un sistema RAG completo

La versione attuale rappresenta una prima architettura funzionante.

Possiamo descriverla come:

Gmail
  ↓
ricerca testuale
  ↓
email pertinenti
  ↓
prompt
  ↓
Qwen
  ↓
risposta

Un sistema RAG più avanzato funzionerebbe invece in questo modo:

Gmail
  ↓
indicizzazione
  ↓
embedding
  ↓
database vettoriale
  ↓
ricerca semantica
  ↓
documenti rilevanti
  ↓
LLM
  ↓
risposta

Questa sarà una possibile evoluzione naturale di EmailAI.


25. La futura ricerca semantica

La ricerca tradizionale potrebbe cercare parole come:

guida
corso
patente

Una ricerca semantica potrebbe comprendere invece che:

"formazione per ottenere una patente superiore"

e:

"abilitazione alla guida per categorie superiori"

sono concetti strettamente correlati anche se le parole utilizzate sono differenti.

Per ottenere questo risultato sarà possibile introdurre modelli di embedding locali e un database vettoriale.

In questo modo EmailAI diventerebbe molto più potente.


26. Possibili evoluzioni del progetto

Il progetto può essere sviluppato in molte direzioni.

Interfaccia grafica

Una GUI potrebbe permettere di scrivere:

Cerca email...

e visualizzare direttamente la risposta dell’AI.

Interfaccia web

Potremmo realizzare:

Browser
   ↓
EmailAI Web UI
   ↓
Python
   ↓
Gmail + Ollama

Ricerca semantica

Possiamo aggiungere embedding e vector database.

Riassunti automatici

EmailAI potrebbe generare:

Riassunto delle email ricevute oggi

Classificazione

Potrebbe classificare automaticamente le email:

Lavoro
Università
Croce Rossa
Tecnologia
Newsletter
Personale

Priorità

Potrebbe identificare:

Urgente
Importante
Normale
Newsletter

Assistente conversazionale

L’utente potrebbe continuare la conversazione:

Quali email parlano di corsi?

→ Ho trovato 3 email.

Qual è quella più recente?

→ Quella del 4 settembre 2026.

Qual è la scadenza?

→ Il 14 ottobre 2026.

Questo trasformerebbe EmailAI da semplice motore di ricerca a vero assistente personale per la posta elettronica.


27. Installazione rapida

Riassumendo, una nuova installazione può partire da:

git clone https://git.athena-net.org/Alessandro/emailai.git

cd emailai

python -m venv .venv

source .venv/bin/activate

pip install -r requirements.txt

Poi occorre configurare le credenziali Gmail e installare il modello:

ollama pull qwen2.5:7b

Verifichiamo Ollama:

curl http://localhost:11434/api/tags

e infine possiamo eseguire:

python test_ollama.py

e:

python test_ai.py

28. Conclusione

EmailAI dimostra come sia possibile costruire un’applicazione di intelligenza artificiale utile senza necessariamente dipendere da API AI commerciali a pagamento.

La combinazione:

Python
+
Gmail API
+
Ollama
+
Qwen
+
Git

permette di costruire una piattaforma completamente personalizzabile.

Il punto più interessante non è soltanto utilizzare un modello linguistico, ma integrarlo all’interno di un’applicazione reale.

EmailAI parte da un problema concreto — trovare informazioni all’interno della propria posta elettronica — e costruisce sopra di esso una pipeline composta da ricerca, recupero dei dati, elaborazione del contesto e generazione della risposta.

La versione attuale è soltanto il punto di partenza.

Con l’introduzione della ricerca semantica, degli embedding, di un database vettoriale e di un’interfaccia web, EmailAI può evolvere in un vero assistente personale locale per la gestione intelligente della posta elettronica.

AthenaNet — Uno spazio dedicato alla conoscenza.

Lascia una risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *