Come funziona una query RAG

Con l’articolo di oggi chiudiamo il cerchio vedendo cosa accade quando l’utente pone una domanda:

Qual è il colore segreto del laboratorio AI?

il sistema esegue queste operazioni:

1️⃣ la domanda viene convertita in embedding
2️⃣ Qdrant cerca i vettori più simili
3️⃣ vengono recuperati i documenti rilevanti
4️⃣ il contesto viene inviato all’LLM
5️⃣ il modello genera la risposta

Flusso:

Domanda utente
|||

Embedding
|||

Qdrant search
|||

Documenti rilevanti
|||

LLM (Ollama)
|||

Risposta finale

Questo modello permette di ottenere risposte basate sui propri dati, non solo sulle conoscenze del modello.

Conclusioni

Con l’introduzione di Qdrant il laboratorio AI su Kubernetes diventa una vera piattaforma RAG completa.

L’architettura ora è composta da:

  • Ollama → esecuzione dei modelli LLM
  • Qdrant → database vettoriale
  • Open WebUI → gestione knowledge base e interfaccia utente

Questo stack consente di costruire rapidamente assistenti AI che rispondono utilizzando documentazione aziendale, manuali tecnici o dati proprietari.

Nel prossimo articolo vedremo come:

  • creare dataset strutturati
  • migliorare il chunking dei documenti
  • ottimizzare la qualità delle risposte del modello.

Nell’immagine in calce il riassunto di quello che è stato messo in esercizio nel laboratorio

Modello AI

Configurare OpenWebUI per generare allenamenti con RAG

Nei precedenti articoli abbiamo visto come funziona il Retrieval Augmented Generation (RAG) nel nostro laboratorio AI basato su Kubernetes.

In questo articolo vedremo come configurare OpenWebUI per permettere al modello di generare allenamenti di nuoto realistici utilizzando una knowledge base costruita con allenamenti reali.

Obiettivo: trasformare OpenWebUI in un assistente di coaching basato su AI.

Architettura del sistema

Il flusso di lavoro creato è il seguente:

Utente

OpenWebUI

RAG Engine

Qdrant (knowledge base)

Ollama (LLM locale)

Quando l’utente chiede di generare un allenamento:

  1. OpenWebUI interroga la knowledge base
  2. Qdrant restituisce i documenti più simili
  3. Il modello LLM utilizza quei documenti come contesto
  4. Viene generata una nuova seduta di allenamento

Preparazione della Knowledge Base

Il primo passo consiste nel caricare nella piattaforma gli allenamenti reali; nel nostro caso la libreria contiene diverse sedute organizzate per settimana:

week21_sessionA, week22_sessionB, week23_sessionC, week24_sessionA, week25_sessionB, week26_sessionA, week27_sessionA

Ogni documento contiene una seduta completa con la seguente struttura:

  • WARMUP
  • SENSITIVITY
  • TECHNIQUE
  • ACTIVATION
  • MAIN SET
  • COOLDOWN

Questi documenti costituiscono il corpus di conoscenza che il sistema utilizzerà per generare nuovi allenamenti.

Caricare i documenti nella sezione Knowledge

Dall’interfaccia di OpenWebUI:

  1. Aprire il menu laterale
  2. Selezionare Workspace
  3. Entrare nella sezione Knowledge
  4. Creare una nuova knowledge base

Nel mio lab dove le sessioni di allenamento sono specifiche per il nuoto la libreria è stata nominata swim_training_library.

Una volta creata la knowledge base è possibile caricare i documenti:

  • coach_training_rules.txt
  • week21_sessionA.txt
  • week22_sessionB.txt
  • week23_sessionC.txt

Durante l’upload OpenWebUI esegue automaticamente:

  • creazione degli embeddings
  • indicizzazione nel vector database Qdrant

In questo modo i documenti diventano interrogabili tramite ricerca semantica.

Creare un Prompt Skill

Una volta caricata la libreria è utile creare uno skill dedicato alla generazione degli allenamenti.

Gli Skills permettono di definire prompt riutilizzabili che guidano il comportamento del modello.

Nel nostro caso creiamo uno skill chiamato:

swim_workout_generator

All’interno dello skill possiamo inserire un prompt come il seguente.

“Generate a swim workout using the CSS methodology.

Rules:
– use only patterns from the knowledge base
– use zones A1 A2 B1 B2 C1 C2
– include sections:
WARMUP
SENSITIVITY
TECHNIQUE
ACTIVATION
MAIN SET
COOLDOWN
– total distance between 2000m and 2800m
– rest intervals between 10 and 30 seconds
– avoid generic descriptions”

Questo prompt permette di stabilizzare il comportamento del modello.

Collegare la Knowledge allo Skill

Durante la configurazione dello skill è possibile specificare la knowledge base da utilizzare.

Nel nostro caso selezioniamo:

swim_training_library

In questo modo ogni volta che lo skill viene utilizzato:

  • OpenWebUI esegue una ricerca nella knowledge base
  • i documenti più rilevanti vengono passati al modello

Questo è il cuore del RAG workflow.

Utilizzo dei Tools

OpenWebUI permette anche di aggiungere Tools.

I tools sono funzioni che il modello può richiamare per eseguire operazioni esterne.

Nel laboratorio verranno utilizzati per:

  • generare allenamenti
  • convertire gli allenamenti in formato Garmin
  • esportare i workout

Ad esempio nel prossimo step verrà aggiunto un tool Python per generare file di tipo .tcx compatibili con Garmin Connect.

Creare una Workspace dedicata

Per organizzare il lavoro è utile creare un workspac dedicato.

Ad esempio: AI Swim Coach

All’interno della workspace possiamo raccogliere:

  • la knowledge base degli allenamenti
  • gli skills di generazione
  • i tools di esportazione

Così facendo possiamo trasformare OpenWebUI in un vero ambiente di coaching AI.

Test del sistema

Una volta completata la configurazione possiamo testare il sistema.

Ad esempio con una richiesta come:

“Generate a 2500m swim workout using the CSS training methodology”.

Il sistema recupererà i documenti più rilevanti dalla libreria e produrrà un nuovo allenamento coerente con gli esempi reali.

NB: Il file coach_training_rules.txt è quello che spiega al modello come ragiona l’allenatore. Non contiene allenamenti, ma le regole del metodo

  • come sono strutturate le sedute
  • cosa significano le zone
  • quali esercizi sono ammessi
  • che stile deve avere l’allenamento

Integrazione tra Open WebUI, Ollama e Qdrant

Nel deployment Kubernetes, Open WebUI deve conoscere:

  • endpoint Ollama
  • endpoint Qdrant
  • modello di embeddings

Nel nostro laboratorio la configurazione è definita tramite variabili d’ambiente:

  • OLLAMA_BASE_URL=http://ollama:11434
  • VECTOR_DB=qdrant
  • QDRANT_URI=http://qdrant:6333
  • RAG_EMBEDDING_ENGINE=ollama
  • RAG_EMBEDDING_MODEL=nomic-embed-text:latest

Possiamo verificarle direttamente nel deployment:

  • kubectl -n ai exec deploy/open-webui printenv | grep QDRANT

Output:

  • QDRANT_URI=http://qdrant:6333

In questo modo Open WebUI utilizza automaticamente Qdrant come database vettoriale.

Caricamento della Knowledge Base

La knowledge base viene caricata attraverso Open WebUI, che si occupa di:

  1. analizzare i documenti
  2. suddividerli in chunk
  3. generare embeddings
  4. salvare i vettori in Qdrant

Il flusso è il seguente:

Documento

Open WebUI

|— chunking
|— embedding generation

Qdrant

Formati supportati:

  • PDF
  • TXT
  • Markdown
  • pagine web
  • documenti Office

Durante il caricamento:

  1. Open WebUI invia il testo a Ollama
  2. Ollama genera gli embeddings
  3. gli embeddings vengono salvati in Qdrant

Gestione degli embeddings

Gli embeddings sono rappresentazioni vettoriali dei testi.

Un modello di embedding trasforma una frase in un vettore numerico che rappresenta il significato semantico del contenuto.

Esempio semplificato:

“nuoto stile libero”
→ [0.12, -0.45, 0.98, …]

Testi con significato simile producono vettori simili.

Nel laboratorio utilizziamo il modello:

  • nomic-embed-text, distribuito tramite Ollama.

Verifica dei modelli disponibili:

kubectl exec -n ai deploy/ollama ollama list

Output:

  • nomic-embed-text
  • qwen2.5:1.5b

Ruoli dei modelli:

Modello Funzione
qwen2.5 LLM che genera le risposte
nomic-embed-text genera embeddings

 

Deployment di Qdrant su Kubernetes

Dopo aver installato un LLM locale con Ollama su Kubernetes, il passo successivo per costruire un sistema AI realmente utile è permettere al modello di consultare una knowledge base personalizzata.

Questo approccio prende il nome di RAG – Retrieval Augmented Generation: il modello non si limita alle conoscenze con cui è stato addestrato, ma recupera informazioni da un database vettoriale contenente documenti indicizzati tramite embeddings.

Nel laboratorio Kubernetes utilizzato in questo articolo la pipeline è composta da:

  • Ollama → esecuzione del modello LLM
  • Qdrant → database vettoriale per gli embeddings
  • Open WebUI → interfaccia grafica e gestione della knowledge base
  • Embedding model → trasformazione dei documenti in vettori

Architettura semplificata:

User


Open WebUI

|– Query → Ollama (LLM)

└── Search → Qdrant (vector DB)


Knowledge Base
Deploy Qdrant su k8s

Per il deployment di Qdrant è possibile utilizzare il chart Helm ufficiale.

Repository Helm: https://qdrant.github.io/qdrant-helm

Aggiungiamo il repository:

  • helm repo add qdrant https://qdrant.github.io/qdrant-helm
  • helm repo update

Installazione nel namespace dedicato all’AI:

helm install qdrant qdrant/qdrant \
–namespace ai \
–create-namespace

Dopo pochi secondi verifichiamo lo stato dei pod:

  • kubectl get pods -n ai  — Output atteso: qdrant-0 1/1 Running

Il servizio Kubernetes esposto sarà:

kubectl get svc -n ai

Esempio:

qdrant ClusterIP 10.43.x.x 6333/TCP

La porta 6333 espone l’API REST di Qdrant.

Verifica rapida:

kubectl exec -n ai qdrant-0 wget -qO- http://localhost:6333/healthz

Risposta attesa: healthz check passed