in Informatica, Intelligenza Artificiale

Ollama, esempio di RAG in python

Per creare un esempio di interrogazione con Ollama e l’utilizzo con RAG (Retrieval Augmented Generation), dobbiamo prima capire come funzionano insieme.

  • Ollama permette di eseguire modelli di linguaggio di grandi dimensioni (LLM) localmente sul tuo computer. Questo è ottimo per la privacy, il costo e la velocità, dato che non dobbiamo inviare i nostri dati a un servizio esterno.
  • RAG è una tecnica che migliora la capacità degli LLM di generare risposte accurate e informate. Invece di fare affidamento solo sulle conoscenze interne del modello, RAG “recupera” informazioni rilevanti da una base di conoscenza esterna (ad esempio, un database di documenti, una pagina web, ecc.) e le fornisce al modello come contesto aggiuntivo per generare la risposta.

Ecco un esempio pratico di come possiamo usarli insieme. Immaginiamo di voler creare un sistema che risponda a domande basate su un set di documenti locali sui sistemi solari.

Esempio di Interrogazione con Ollama e RAG

Prerequisiti

  1. Ollama Installato: Assicuriamoci di aver installato Ollama sul tuo sistema. Puoi scaricarlo dal sito ufficiale di Ollama.
  2. Modello LLM Scaricato: Scarichiamo un modello LLM con Ollama. Per questo esempio llama3.
  3. Ambiente Python: Avremo bisogno di Python e alcune librerie.

Ecco come scaricare il modello llama3

ollama run llama3

Passaggi

1. Preparazione della Base di Conoscenza (Documenti)

Creeremo alcuni semplici file di testo che fungeranno da nostra base di conoscenza.

File: pianeti.txt

Mercurio è il pianeta più vicino al Sole. È il più piccolo dei pianeti nel nostro sistema solare e ha una superficie rocciosa.
Venere è il secondo pianeta dal Sole. È noto per la sua atmosfera densa e calda e per essere il pianeta più caldo del nostro sistema solare.
La Terra è il terzo pianeta dal Sole ed è l'unico pianeta conosciuto per supportare la vita. Ha abbondante acqua liquida sulla sua superficie.
Marte è il quarto pianeta dal Sole, spesso chiamato il "Pianeta Rosso" a causa della sua superficie ricca di ossido di ferro. Ha due piccole lune, Fobos e Deimos.

File: stelle.txt

Il Sole è la stella al centro del nostro sistema solare. È una sfera di plasma caldo, illuminata da reazioni nucleari nel suo nucleo.
Le stelle sono corpi celesti massicci e luminosi composti principalmente da idrogeno ed elio. Generano luce e calore attraverso la fusione nucleare.

2. Implementazione RAG in Python

Useremo Python per leggere questi documenti, trovare le informazioni rilevanti e poi passare queste informazioni a Ollama.

Installazione Librerie:

Bash

pip install langchain langchain-community langchain-core

Codice Python (rag_ollama.py):

Python

import os
from langchain_community.llms import Ollama
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# --- 1. Caricamento e Pre-elaborazione dei Documenti ---
# Percorso dei documenti (assumendo siano nella stessa directory dello script)
document_paths = ["pianeti.txt", "stelle.txt"]
documents = []
for path in document_paths:
    loader = TextLoader(path)
    documents.extend(loader.load())

# Suddivisione dei documenti in chunk più piccoli
text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=0)
texts = text_splitter.split_documents(documents)

# --- 2. Creazione dell'Embedding e Vector Store ---
# Inizializza il modello di embedding di Ollama
print("Generazione degli embedding e creazione del vector store...")
embeddings = OllamaEmbeddings(model="llama3")

# Crea un vector store (FAISS è un buon database vettoriale in-memory per questo esempio)
# Questo indicizza i documenti in modo che possano essere cercati semanticamente
vectorstore = FAISS.from_documents(texts, embeddings)
retriever = vectorstore.as_retriever()
print("Vector store creato.")

# --- 3. Configurazione del Modello Ollama ---
llm = Ollama(model="llama3")

# --- 4. Costruzione della Chain RAG ---
# Il template del prompt istruisce l'LLM su come usare il contesto recuperato
template = """Rispondi alla domanda basandoti SOLO sul seguente contesto:
{context}

Domanda: {question}
"""
prompt = ChatPromptTemplate.from_template(template)

# Combina tutti i componenti in una "chain" LangChain
rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# --- 5. Esecuzione dell'Interrogazione ---
def query_rag_system(question):
    print(f"\nDomanda: {question}")
    response = rag_chain.invoke(question)
    print("Risposta:")
    print(response)

if __name__ == "__main__":
    query_rag_system("Qual è il pianeta più caldo?")
    query_rag_system("Cosa sono le stelle e come generano luce?")
    query_rag_system("Raccontami del terzo pianeta dal Sole.")
    query_rag_system("Qual è il mio colore preferito?") # Domanda non presente nel contesto

Spiegazione del Codice

  1. Caricamento e Pre-elaborazione dei Documenti:
    • Usiamo TextLoader di LangChain per caricare i file pianeti.txt e stelle.txt.
    • CharacterTextSplitter divide i documenti in “chunk” (pezzi) più piccoli. Questo è importante perché gli LLM hanno un limite sulla quantità di testo che possono elaborare in una volta. Inoltre, chunk più piccoli aiutano il retriever a trovare i passaggi più specifici e rilevanti.
  2. Creazione dell’Embedding e Vector Store:
    • OllamaEmbeddings(model="llama3") inizializza un modello di embedding da Ollama. Un embedding è una rappresentazione numerica (un vettore) del significato semantico di un pezzo di testo. Testi con significati simili avranno vettori simili.
    • FAISS.from_documents(texts, embeddings) crea un vector store. Questo è un database che memorizza gli embedding dei tuoi documenti. Quando fai una domanda, la tua domanda viene convertita in un embedding e il vector store trova i chunk di documenti i cui embedding sono semanticamente più vicini all’embedding della tua domanda.
    • retriever = vectorstore.as_retriever() crea un oggetto retriever che useremo per recuperare i documenti rilevanti.
  3. Configurazione del Modello Ollama:
    • llm = Ollama(model="llama3") inizializza il modello Llama3 che hai scaricato con Ollama.
  4. Costruzione della Chain RAG (LangChain):
    • Prompt Template: Definiamo un ChatPromptTemplate che indica all’LLM di rispondere solo basandosi sul contesto fornito. Questo è fondamentale per RAG, perché vogliamo che il modello usi le informazioni recuperate e non “allucini” risposte basate sulle sue conoscenze pre-esistenti se non sono nel contesto.
    • Rag Chain: La rag_chain è una sequenza di operazioni:
      • Prende la domanda dell’utente.
      • Il retriever cerca i documenti più rilevanti nel vectorstore basandosi sulla domanda. Questi documenti diventano il context.
      • Il context e la question vengono passati al prompt.
      • Il prompt viene inviato all’llm (Ollama).
      • StrOutputParser() estrae la stringa di risposta dal modello.
  5. Esecuzione dell’Interrogazione:
    • La funzione query_rag_system prende una domanda, la passa alla rag_chain e stampa la risposta.
    • Abbiamo incluso esempi di domande sia pertinenti alla base di conoscenza che non, per mostrare come il sistema risponda.

Come Eseguire l’Esempio

  1. Salviamo i contenuti dei file pianeti.txt e stelle.txt nelle rispettive posizioni.
  2. Salviamo il codice Python come rag_ollama.py nella stessa directory dei file di testo.
  3. Apriamo il terminale, navighiamo nella directory in cui hai salvato i file ed eseguiamo:
python rag_ollama.py

Output Atteso

EDovremo vedere un output simile a questo (le risposte esatte possono variare leggermente a seconda della versione del modello llama3 e delle impostazioni):

Generazione degli embedding e creazione del vector store...
Vector store creato.

Domanda: Qual è il pianeta più caldo?
Risposta:
Venere è il pianeta più caldo del nostro sistema solare, noto per la sua atmosfera densa e calda.

Domanda: Cosa sono le stelle e come generano luce?
Risposta:
Le stelle sono corpi celesti massicci e luminosi composti principalmente da idrogeno ed elio. Generano luce e calore attraverso la fusione nucleare nel loro nucleo.

Domanda: Raccontami del terzo pianeta dal Sole.
Risposta:
La Terra è il terzo pianeta dal Sole ed è l'unico pianeta conosciuto per supportare la vita. Ha abbondante acqua liquida sulla sua superficie.

Domanda: Qual è il mio colore preferito?
Risposta:
Non è presente nessuna informazione riguardante il tuo colore preferito nel contesto fornito.

Questo esempio dimostra come puoi combinare la potenza di Ollama per l’esecuzione locale degli LLM con la tecnica RAG per migliorare l’accuratezza e la pertinenza delle risposte, basandoti sulle tue fonti di dati specifiche.

  • Articoli Correlati per Tag :