Un piccolo esperimento RAG locale con Ollama e PostgreSQL

Negli ultimi tempi termini come LLM, embedding e database vettoriali sono usciti rapidamente dall’ambito della ricerca e sono diventati argomenti quasi quotidiani. sono mattoni nocoi quai possiamo costruire sistemi capaci di interrogare grandi collezioni di documenti non più tramite ricerca lessicale tradizionale, ma attraverso la vicinanza semantica tra i testi.

In questi giorni ho realizzato un piccolo prototipo sperimentale di sistema RAG (Retrieval-Augmented Generation) utilizzando esclusivamente strumenti locali: PostgreSQL con l’estensione pgvector, Ollama, Python e una macchina Linux piuttosto modesta, un Intel i5 con 16 GB di RAM e senza alcuna GPU CUDA.

L’obiettivo era capire davvero cosa succede dentro queste architetture che oggi vengono spesso presentate in modo un po’ magico.

Il funzionamento generale è relativamente semplice. I documenti PDF vengono letti, suddivisi in piccoli frammenti e trasformati in embedding numerici tramite un modello locale. Questi vettori vengono memorizzati in PostgreSQL. Quando l’utente pone una domanda, anche la domanda viene convertita in un embedding e il database cerca i frammenti semanticamente più vicini. Solo a quel punto il modello linguistico riceve il contesto recuperato e prova a costruire una risposta.

La parte interessante è che il database non cerca parole identiche come farebbe un classico LIKE, ma effettua una ricerca geometrica nello spazio degli embedding. In altre parole, il sistema tenta di individuare testi “concettualmente vicini” alla domanda.

La sorpresa più grande dell’esperimento è stata probabilmente PostgreSQL. Anche con oltre sedicimila chunk indicizzati, le interrogazioni vettoriali risultavano rapidissime, dell’ordine di pochi decimi di secondo. Il vero collo di bottiglia si è invece manifestato nella generazione finale della risposta da parte del modello linguistico locale.

Qui si entra nel territorio dell’algebra lineare pesante: matrici enormi, meccanismi di attenzione, inferenza autoregressiva token per token. Su CPU tutto questo funziona, ma i tempi crescono rapidamente. In alcuni casi Ollama arrivava addirittura in timeout durante la generazione della risposta.

È stato quindi necessario introdurre varie ottimizzazioni: ridurre il numero di chunk passati al modello, limitare la lunghezza dell’output e rendere più robusta la gestione degli errori. Anche così, le risposte ottenute rimangono talvolta “maccheroniche” o affette da piccole allucinazioni semantiche, ma nel complesso la direzione sembra corretta, soprattutto considerando il setup estremamente limitato.

L’aspetto più istruttivo dell’esperimento è forse proprio questo: osservare concretamente dove finisca il retrieval e dove inizi la generazione linguistica. Un sistema RAG non è semplicemente “un chatbot collegato a un database”, ma una pipeline piuttosto delicata in cui chunking, retrieval, ranking e costruzione del prompt influenzano pesantemente il risultato finale.

Poyete scaricare la breve relazione tecnica più dettagliata con diagrammi, codice ed esempi reali ottenuti durante questi test.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.