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

LLM & RAG: L’importanza del dato

Nel precedente articolo abbiamo costruito una piattaforma AI completamente on-premises, eseguendo un Large Language Model locale su Kubernetes tramite Ollama.

Questa configurazione rappresenta un primo passo fondamentale: ci consente di interrogare un modello linguistico senza dipendere da servizi cloud esterni, mantenendo il pieno controllo dei dati.

Tuttavia, un limite importante rimane.

Il modello, per quanto potente, non conosce il contesto specifico della nostra organizzazione: documentazione interna, procedure, knowledge base, ticket o dati proprietari.

Il problema: LLM senza contesto

Un LLM locale:

  • non è aggiornato con dati aziendali
  • non può accedere a documenti interni
  • risponde solo in base al training generico

Questo lo rende poco utile in scenari reali enterprise.

La soluzione: Retrieval Augmented Generation (RAG)

Per superare questo limite entra in gioco il paradigma di Retrieval Augmented Generation (RAG).

RAG combina due elementi:

  1. Retrieval → recupero di informazioni rilevanti da una base dati
  2. Generation → generazione della risposta usando il modello LLM

In pratica:

Domanda utente
↓
Ricerca nei dati aziendali (vector DB)
↓
Contesto rilevante
↓
LLM (Ollama)
↓
Risposta arricchita e contestualizzata
Il ruolo del Vector Database

Per rendere possibile il retrieval, i documenti devono essere trasformati in vettori tramite embeddings.

Qui entra in gioco un componente chiave:

➡️ Vector Database

Nel nostro laboratorio utilizzeremo Qdrant , un database ottimizzato per:

  • ricerca semantica
  • gestione embeddings
  • alta performance su workload AI

Evoluzione dell’architettura

Con l’introduzione del RAG, lo stack evolve:

Utente
↓
OpenWebUI
↓
Ollama (LLM)
↓
Qdrant (Vector DB)
↓
Knowledge Base

Ora il modello non risponde più “a memoria”, ma: risponde usando i tuoi dati

Perché il RAG è fondamentale

I motivi principali sono:

  • AI contestualizzata per i dati aziendali
  • maggiore accuratezza delle risposte
  • riduzione delle allucinazioni
  • nessuna necessità di retraining del modello
  • pieno controllo dei dati (on-prem)

Nel prossimo articolo vedremo nel dettaglio:

  1. deployment di Qdrant su Kubernetes
  2. gestione degli embeddings
  3. caricamento della knowledge base
  4. integrazione con OpenWebUI e Ollama