Garantire distribuzioni RAG sicure e consapevoli delle autorizzazioni
Nel settore frenetico dell'intelligenza artificiale, Retrieval Augmented Generation (RAG) è emersa come un approccio potente per potenziare le capacità dei modelli generativi come la serie GPT di OpenAI e Gemini di Google. Tuttavia, a un grande potenziale corrisponde una responsabilità significativa, in particolare quando si tratta di proteggere dati sensibili e garantire la conformità alle normative sulla privacy.
Man mano che le organizzazioni si affidano sempre di più a soluzioni basate sull'IA, comprendere le implicazioni di sicurezza di queste tecnologie è fondamentale. Implementare solide misure di sicurezza che non solo proteggano i dati ma creino anche fiducia negli utenti è essenziale per applicazioni RAG pronte per la produzione.
In un recente Unstructured Data Meetup ospitato da Zilliz, Oz Wasserman, Co-Founder di Opsin, ha evidenziato considerazioni chiave sulla sicurezza per le implementazioni RAG, sottolineando l'importanza dell'anonimizzazione dei dati, di una crittografia robusta, della validazione di input/output e di solidi controlli degli accessi, tra le altre misure di sicurezza critiche.
In questo blog, discuteremo gli aspetti chiave delle implementazioni RAG sicure e consapevoli dei permessi. Esamineremo anche un notebook di esempio di una pipeline RAG utilizzando il database vettoriale Milvus e i postprocessor di LlamaIndex progettati per rimuovere informazioni sensibili, garantendo la privacy dei dati e la conformità.
Diagramma dell'architettura RAG
Nel suo intervento, Oz ha iniziato spiegando un'architettura RAG fondamentale simile a quella mostrata nella Figura 1. In sostanza, un sistema RAG potenzia un large language model (LLM) integrando una knowledge base basata su database vettoriale che archivia documenti per recuperare contenuti rilevanti in risposta alla query di un utente. Questo approccio migliora l'accuratezza, garantisce una maggiore rilevanza contestuale e riduce al minimo le allucinazioni spesso osservate negli output degli LLM standalone.
Tuttavia, questa pipeline di base manca di misure di sicurezza specifiche a meno che non vengano integrate nelle varie fasi. Oz ha evidenziato un diagramma del flusso di lavoro RAG (vedi Figura 2) di Ken Huang di DistributedApps.ai, in cui i controlli di sicurezza possono essere implementati lungo tutta la pipeline RAG:
Fase Data Source/VectorDB
Fase di recupero
Fase di generazione
Figura- Database vettoriale che facilita chatbot RAG.png
Figura 1: Architettura RAG di base
Figura 2- Architettura RAG dettagliata (Autore- Ken Huang)
Figura 2: Architettura RAG dettagliata (Autore: Ken Huang)
Fase Data Source/VectorDB
I database vettoriali come Milvus e Zilliz Cloud (il Milvus gestito) archiviano, indicizzano e recuperano embedding vettoriali convertiti da dati non strutturati. Sono repository critici di informazioni preziose. Tuttavia, possono anche diventare bersagli di violazioni dei dati o accessi non autorizzati, rendendo necessaria l'implementazione di strategie di protezione robuste come crittografia, controllo degli accessi o anonimizzazione dei dati.
Figura 3- Fonte dati: controlli di sicurezza VectorDB.png
Figura 3: Controlli di sicurezza della fonte dati/VectorDB
Il primo filone di sicurezza si trova nell’anonimizzazione dei dati. I dati contengono informazioni personali sensibili, comunemente indicate come informazioni di identificazione personale (PII). Questi dati devono essere anonimizzati per proteggere la privacy individuale. Questo passaggio è obbligatorio prima di qualsiasi elaborazione dei dati, per garantire che tali informazioni non possano essere ricondotte a individui specifici.
Una volta che i dati sono stati anonimizzati, possono essere indicizzati e possono essere generati embedding per abilitare la ricerca semantica per recuperare contenuti pertinenti. In questa fase, è importante definire chi può archiviare e recuperare i dati nel e dal database vettoriale, in altre parole, chi ha accesso ad essi. L’implementazione di controlli di accesso rigorosi è essenziale per prevenire accessi non autorizzati, che potrebbero comportare manipolazione o perdita di dati.
Il controllo degli accessi può essere suddiviso in diverse fasi:
Autenticazione: Garantire che l’utente verifichi la propria identità, in genere utilizzando metodi come OAuth 2.0.
Autorizzazione: In base all’identità verificata, all’utente vengono concessi permessi specifici e diritti di accesso.
Tracciabilità: Monitorare l’accesso per garantire che qualsiasi tentativo di accesso ai dati venga registrato e possa essere tracciato, fornendo un audit trail per la conformità alla sicurezza.
Queste misure aiutano a salvaguardare il database vettoriale e garantiscono che solo gli utenti autorizzati possano interagire con dati sensibili.
Un ulteriore livello di sicurezza può essere aggiunto con la crittografia per rendere i dati incomprensibili a riposo (quando sono archiviati) o in transito (quando vengono trasmessi). La crittografia tradizionale utilizza chiavi di crittografia, ma tecniche più avanzate come la privacy differenziale o la decentralizzazione e sharding vengono adottate sempre più spesso per migliorare la sicurezza dei dati.
Zilliz Cloud è un servizio di database vettoriale completamente gestito basato su Milvus. Offre tutte queste misure essenziali di sicurezza dei dati. Può fornire altre soluzioni, come Private Link, per evitare l’accesso a Internet pubblico, backup e ripristino per garantire backup dei dati regolari e sicuri, e il recupero della knowledge base in caso di perdita di dati.
Figura 6- Sicurezza Zilliz multilivello di livello enterprise
Figura 6: Sicurezza Zilliz multilivello di livello enterprise (Fonte)
Fase di recupero
La fase di recupero è un altro passaggio critico in cui le questioni di sicurezza devono essere affrontate. Come nella fase precedente, controllare l’accesso alla knowledge base tramite query è essenziale. Inoltre, durante questa fase, è necessario mitigare anche diversi rischi per la sicurezza:
Validazione delle query: Validare le query è fondamentale per prevenire attacchi di prompt injection. Questo approccio garantisce che gli input degli utenti non sfruttino vulnerabilità del sistema, potenzialmente portando ad accesso non autorizzato o manipolazione dei dati.
Rischi della ricerca per similarità: È inoltre importante gestire i rischi associati alle ricerche per similarità. Dovrebbero essere predisposte misure adeguate per garantire che la ricerca per similarità non esponga inavvertitamente informazioni sensibili né fornisca accesso non autorizzato a dati riservati.
Figura 7- Passaggio di validazione delle query
Figura 7: Passaggio di validazione delle query
Oz ha condiviso un esempio (vedi Figura 8) di prompt injection durante la presentazione di un modello interno. Questo è un buon esempio di manipolazione del prompt, in cui il prompt viene modificato per recuperare dati.
Figura 8- Esempio di Prompt Injection
Figura 8: Esempio di Prompt Injection
Inoltre, Oz ha discusso diversi rischi associati alla ricerca per similarità, tra cui:
Fuga di dati: Manipolando le query di similarità, gli aggressori possono influenzare il meccanismo di ricerca per recuperare indirettamente dati sensibili.
Manipolazione dei risultati di ricerca: Gli aggressori potrebbero modificare il processo di ricerca per influenzare quali risultati vengono recuperati, portando a una potenziale esposizione di informazioni riservate.
Ricognizione e analisi dei pattern: Gli aggressori possono analizzare i pattern nelle query di ricerca e nelle risposte per mappare la struttura del database e ottenere informazioni sui dati archiviati.
Esaurimento delle risorse: Query continue o eccessive potrebbero portare a condizioni di denial-of-service, esaurendo le risorse di sistema e riducendo la disponibilità per altri utenti.
Vediamo che tecniche di sicurezza simili devono essere implementate per la fase di recupero, come il controllo degli accessi o la validazione dei dati. Inoltre, la crittografia (in transito) deve essere considerata poiché i dati vengono trasmessi tra i componenti.
Fase di generazione
La fase finale nella pipeline RAG è la fase di generazione, in cui il Large Language Model (LLM) genera risposte basate sul contenuto recuperato dal database vettoriale. Sebbene l’LLM sia l’attore centrale in questa fase, possono sorgere problemi di sicurezza e conformità a seconda della natura dei dati utilizzati per addestrare il modello. Alcuni rischi chiave includono:
Violazioni della privacy dei dati: L’LLM può rivelare inavvertitamente informazioni sensibili o private se addestrato su dati che includono informazioni di identificazione personale (PII) o altri contenuti riservati. Ciò potrebbe comportare violazioni di normative sulla privacy come GDPR o HIPAA.
Manipolazione dell’output: Gli aggressori potrebbero manipolare l’output dell’LLM influenzando le query di input, portando alla generazione di contenuti dannosi o fuorvianti. Questo è particolarmente preoccupante in ambienti in cui gli output sono considerati affidabili senza verifica.
Bias e contenuti offensivi: Se i dati di addestramento contengono elementi distorti o offensivi, l’LLM potrebbe produrre risposte distorte o offensive, il che potrebbe portare a responsabilità legali, specialmente in ambienti di produzione.
Affrontare questi rischi richiede un’attenta post-elaborazione del contenuto generato, incluse tecniche come:
Filtraggio dei contenuti: Filtrare automaticamente gli output per rilevare e bloccare contenuti sensibili, distorti o offensivi.
Validazione dell’output: Validare la risposta del modello per garantire che sia conforme alle policy di sicurezza e agli standard normativi prima di consegnarla all’utente.
Fine-tuning del modello: Garantire che il modello sia ottimizzato con dati conformi alle normative e applicare strategie di reinforcement learning per evitare output dannosi.
Incorporando queste strategie, la fase di generazione può essere resa più sicura e affidabile e aggiunge un livello di sicurezza.
Approfondiamo ora un esempio di anonimizzazione dei dati, in cui verranno confrontati diversi postprocessor di LlamaIndex e verrà mostrato un esempio di violazioni della privacy dei dati.
RAG sicuro utilizzando LlamaIndex e Milvus
Il seguente notebook è un esempio di pipeline RAG costruita con LlamaIndex come framework LLM, Milvus come database vettoriale e tre diversi moduli specializzati nel mascheramento delle PII: uno che utilizza un modello NER di Hugging Face, un altro che utilizza un LLM (OpenAI) e Presidio, una libreria Microsoft.
Puoi anche consultare il codice completo in questo notebook Colab.
Passaggio 1: Configurare le variabili d’ambiente
Abbiamo bisogno di una chiave OpenAI per testare il modulo usando i modelli OpenAI.
from google.colab import userdata
import os
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')
Passaggio 2: Definire un testo con dati privati
Per prima cosa, definiamo un breve testo che contiene informazioni private come numeri di carte di credito, nomi o date di nascita.
from llama_index.core.postprocessor import NERPIINodePostprocessor
from llama_index.core.schema import TextNode, NodeWithScore
text = """
Hi, I'm Sarah Mitchell, and I just got a new credit card with the number 3714-496089-47322.
My personal email is sarah.mitchell@mailbox.com, and I'm currently based in Sydney.
By the way, I tried paying my utility bill with card number 6011-5832-9109-1726, but it didn't work.
For my bank transactions, I use this IBAN: NL91ABNA0417164300.
Also, can you help me with my Wi-Fi issues? I keep getting blocked by IP address 203.0.113.15.
I've shared a family photo on my personal blog at https://www.sarahs-lifediary.org/.
Oh, and my grandfather, George Stone, was born in 1921, while my grandmother, Emily Clarkson, was born in 1925.
Last question--what's the spending limit on my main card, the one ending in 8473?
"""
node = TextNode(text=text)
Passaggio 3: Modello NER per il mascheramento delle PII: NERPIINodePostprocessor
NERPIINodePostprocessor è un modulo di Llama Index che maschera tali informazioni usando un modello Hugging Face specializzato in NER (named entity recognition).
from llama_index.core.postprocessor import NERPIINodePostprocessor
from llama_index.core.schema import TextNode, NodeWithScore
processor = NERPIINodePostprocessor()
new_nodes = processor.postprocess_nodes([NodeWithScore(node=node)])
print(new_nodes[0].node.get_text())
Vediamo che questo modello specifico maschera alcune informazioni, ma i dati privati sono ancora visibili. Usare questo approccio rappresenterebbe una fuga di dati. Pertanto, dovrebbe essere utilizzato un altro modello o approccio.
"""
Output:
Hi, I'm [PER_9], and I just got a new credit card with the number 3714-496089-47322.
My personal email is sarah.mitchell@mailbox.com, and I'm currently based in [LOC_169].
By the way, I tried paying my utility bill with card number 6011-5832-9109-1726, but it didn't work.
For my bank transactions, I use this IBAN: NL91ABNA0417164300.
Also, can you help me with my Wi-[MISC_374] issues? I keep getting blocked by IP address 203.0.113.15.
I've shared a family photo on my personal blog at https://www.sarahs-lifediary.org/.
Oh, and my grandfather, [PER_545], was born in 1921, while my grandmother, [PER_599], was born in 1925.
Last question--what's the spending limit on my main card, the one ending in 8473?
"""
Passaggio 4: LLM per il mascheramento delle PII: PIINodePostprocessor
PIINodePostprocessor è un modulo di Llama Index che utilizza un modello LLM per mascherare le informazioni sensibili. Per testare l’efficienza di questo approccio, useremo il modello OpenAI predefinito.
from llama_index.core.postprocessor import PIINodePostprocessor
from llama_index.core.schema import TextNode, NodeWithScore
from llama_index.llms.openai import OpenAI
processor = PIINodePostprocessor(llm=OpenAI())
new_nodes = processor.postprocess_nodes([NodeWithScore(node=node)])
print(new_nodes[0].node.get_text())
Seguendo questo approccio, il modello può riconoscere tutte le informazioni sensibili e mascherarle di conseguenza.
"""
Output:
Ciao, sono [NAME1] [NAME2], e ho appena ricevuto una nuova carta di credito con il numero [CREDIT_CARD_NUMBER1].
La mia email personale è [EMAIL], e al momento mi trovo a [CITY].
A proposito, ho provato a pagare la mia bolletta con il numero di carta [CREDIT_CARD_NUMBER2], ma non ha funzionato.
Per le mie transazioni bancarie, uso questo IBAN: [IBAN].
Inoltre, puoi aiutarmi con i miei problemi di Wi-Fi? Continuo a essere bloccato dall'indirizzo IP [IP_ADDRESS].
Ho condiviso una foto di famiglia sul mio blog personale all'indirizzo [URL].
Oh, e mio nonno, [NAME3] [NAME4], è nato il [DATE1], mentre mia nonna, [NAME5] [NAME6], è nata il [DATE2].
Ultima domanda--qual è il limite di spesa sulla mia carta principale, quella che termina con [CREDIT_CARD_ENDING].
"""
Passaggio 5: Presidio per il mascheramento delle PII
Infine, testiamo Presidio, una libreria Microsoft che maschera le informazioni sensibili usando un modello Spacy specializzato in NER.
from llama_index.postprocessor.presidio import PresidioPIINodePostprocessor
from llama_index.core.schema import TextNode, NodeWithScore
from llama_index.llms.openai import OpenAI
processor = PresidioPIINodePostprocessor()
new_nodes = processor.postprocess_nodes([NodeWithScore(node=node)])
print(new_nodes[0].node.get_text())
Questa volta, vediamo che il modello può mascherare tutte le informazioni tranne il numero della carta di credito, poiché viene considerato parte di esso come una patente di guida. Nel passaggio successivo, testeremo diverse query con questo modello e mostreremo come siano possibili violazioni della privacy dei dati perché una parte del numero della carta di credito è disponibile.
"""
Output:
Hi, I'm <PERSON_3>, and I just got a new credit card with the number 3714-<US_DRIVER_LICENSE_1>-47322.
My personal email is <EMAIL_ADDRESS_1>, and I'm currently based in <LOCATION_1>.
By the way, I tried paying my utility bill with card number <IN_PAN_1>9109-1726, but it didn't work.
For my bank transactions, I use this IBAN: <IBAN_CODE_1>.
Also, can you help me with my Wi-Fi issues? I keep getting blocked by IP address <IP_ADDRESS_1>.
I've shared a family photo on my personal blog at <URL_1>
Oh, and my grandfather, <PERSON_2>, was born in <DATE_TIME_2>, while my grandmother, <PERSON_1>, was born in <DATE_TIME_1>.
Last question--what's the spending limit on my main card, the one ending in 8473?
"""
Passaggio 6: Retrieval usando Milvus
Per prima cosa, creiamo un database vettoriale Milvus per archiviare il nostro testo.
from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.milvus import MilvusVectorStore
vector_store = MilvusVectorStore(
uri="./milvus_demo.db", dim=1536, overwrite=True
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex([n.node for n in new_nodes], storage_context=storage_context)
Poi, testiamo alcune query.
Questa prima query funziona correttamente. Ci fornisce la risposta corretta e mantiene le informazioni mascherate.
response = index.as_query_engine().query(
"What is the name of the person?"
)
print(str(response))
"""
Output:
The name of the person is <PERSON_3>.
"""
Ora proviamo a ottenere il numero della carta di credito, e vediamo che otteniamo il numero completo con una parte mascherata come patente di guida.
response = index.as_query_engine().query(
"What is the number of the credit card?"
)
print(str(response))
"""
Output:
The number of the credit card is 3714-<US_DRIVER_LICENSE_1>-47322.
"""
Ma è anche noto che tutti gli emittenti di carte di credito hanno IIN (Issuer Identification Number) assegnati. Le prime cifre definiscono l'emittente. Quindi, in questo caso, 37 significa American Express. Se non lo sai, possiamo verificarlo chiedendolo al modello.
response = index.as_query_engine().query(
"What is the issuer of the credit card number?"
)
print(str(response))
The issuer of the credit card number is American Express
Quindi, vediamo che il modello può riconoscere l'emittente della carta, anche se questa informazione non è stata fornita nel testo. Ciò significa che il modello è stato addestrato con informazioni sulle carte di credito relative agli emittenti e può fornire la risposta con la sua conoscenza. Questo è un esempio di violazioni della privacy dei dati nella fase di generazione, descritte sopra.
Conclusione
Oz ci ha guidati attraverso le varie fasi di una pipeline RAG e ha evidenziato dove possono essere affrontate le preoccupazioni relative alla sicurezza. La prima preoccupazione chiave riguarda l'anonimizzazione dei dati, assicurando che i dati sensibili non possano essere accessibili da terze parti non autorizzate. Tuttavia, è importante ricordare che i foundation models LLM potrebbero essere stati addestrati su questi dati, rendendo i modelli stessi potenziali fonti di fuga di dati.
Per proteggere l'accesso e la trasmissione dei dati, il controllo degli accessi e la crittografia sono fondamentali. Queste tecniche forniscono un alto livello di sicurezza e controllo, ma minacce come prompt injection e manipolazione della ricerca rappresentano ancora rischi per le informazioni sensibili.
Pertanto, aggiungere più livelli di sicurezza lungo tutta la pipeline è essenziale per mitigare le potenziali minacce. Un'applicazione RAG pronta per la produzione deve integrare misure di sicurezza solide in ogni fase per garantire che il sistema sia resiliente agli attacchi e conforme agli standard normativi.
Ulteriori risorse
Continua a leggere

Vector Lakebase: End the AI Data Silo
Learn how Vector Lakebase unifies vector search, data lakes, and AI data operations so teams can serve RAG and agents without copy-and-sync pipelines.

Data Deduplication at Trillion Scale: How to Solve the Biggest Bottleneck of LLM Training
Explore how MinHash LSH and Milvus handle data deduplication at the trillion-scale level, solving key bottlenecks in LLM training for improved AI model performance.

Vector Databases vs. Document Databases
Use a vector database for similarity search and AI-powered applications; use a document database for flexible schema and JSON-like data storage.



