La retrieval-augmented generation di grafi (Graph RAG) sta emergendo come una potente tecnica per le applicazioni di AI generativa che utilizza conoscenze specifiche del dominio e informazioni pertinenti. La Graph RAG è un'alternativa ai metodi di ricerca vettoriale che utilizzano un database vettoriale.
I knowledge graph sono sistemi di conoscenza in cui database a grafi come Neo4j o Amazon Neptune possono rappresentare dati strutturati. In un knowledge graph, le relazioni tra i punti dati, chiamate edge, sono significative quanto le connessioni tra i punti dati, chiamate vertici o talvolta nodi. Un knowledge graph semplifica l'attraversamento di una rete e l'elaborazione di domande complesse sui dati connessi. I knowledge graph sono particolarmente adatti per casi d'uso che coinvolgono chatbot, risoluzione delle identità, analisi di rete, motori di raccomandazione, customer 360 e rilevamento delle frodi.
Un approccio Graph RAG utilizza la natura strutturata dei database a grafo per fornire maggiore profondità e contesto alle informazioni recuperate su reti o relazioni complesse. Con un database a grafo abbinato a un modello linguistico di grandi dimensioni (LLM), uno sviluppatore può automatizzare parti significative del processo di creazione di grafici a partire da dati non strutturati come il testo. Un LLM può elaborare dati di testo e identificare entità, comprenderne le relazioni e rappresentarle in una struttura grafica.
Esistono molti modi per creare un'applicazione Graph RAG, ad esempio GraphRag di Microsoft o l'abbinamento di GPT4 con LlamaIndex. Per questo tutorial utilizzerai Memgraph, una soluzione di database di grafi open source per creare un sistema rag utilizzando Llama-3 di Meta su watsonx. Memgraph utilizza Cypher, un linguaggio di query dichiarativo. Condivide alcune somiglianze con SQL ma si concentra su nodi e relazioni piuttosto che su tabelle e righe. Farai in modo che Llama 3 crei e compili il suo database grafico a partire da testo non strutturato e informazioni sulle query presenti nel database.
Sebbene sia possibile scegliere tra diversi strumenti, questo tutorial illustra come configurare un account IBM per utilizzare uno Jupyter Notebook.
Accedi a watsonx.ai utilizzando il tuo account IBM® Cloud.
Crea un progetto watsonx.ai.
Puoi ottenere l'ID del tuo progetto dall'interno del tuo progetto. Clicca sulla scheda Gestisci. Quindi, copia l'ID del progetto dalla sezione Dettagli della pagina Generali. Per questo tutorial è necessario questo ID progetto.
A seguire, associa il tuo progetto a watsonx.ai Runtime
a. Crea un'istanza di servizio watsonx.ai Runtime (scegli il piano Lite, che è un'istanza gratuita).
b. Genera una chiave API in watsonx.ai tempo di esecuzione. Salva questa chiave API per utilizzarla in questo tutorial.
c. Vai al tuo progetto e seleziona la scheda Gestisci
d. Nella scheda a sinistra, seleziona Servizi e integrazioni
e. Seleziona i servizi IBM
f. Seleziona Associa servizio e scegli watsonx.ai Runtime.
Associa il servizio watsonx.ai Runtime al progetto che hai creato in watsonx.ai.
Ora dovrai installare Docker.
Dopo aver installato Docker, installa Memgraph utilizzando il loro container Docker. Su OSX o Linux, puoi utilizzare questo comando in un terminale:
Su un computer Windows, utilizza:
Segui i passaggi di installazione per far funzionare il motore Memgraph e il laboratorio Memgraph.
Sul tuo computer, crea un nuovo virtualenv per questo progetto:
Nell'ambiente Python per il tuo notebook, installa le seguenti librerie Python:
Ora sei pronto a collegarti a Memgraph.
Se hai configurato Memgraph per utilizzare un nome utente e una password, impostali qui. In alternativa, puoi utilizzare i valori predefiniti e non impostare nessuno dei due. Non è una buona pratica per un database di produzione ma, per un ambiente di sviluppo locale che non memorizza dati sensibili, non è un problema.
Ora crea una stringa di esempio che descriva un set di dati di relazioni da utilizzare per testare le capacità di generazione di grafi del tuo sistema LLM. È possibile utilizzare origini dati più complesse, ma questo semplice esempio ci aiuta a dimostrare l'algoritmo.
Inserisci la chiave API watsonx che ha creato nel primo passaggio:
Ora configura un'istanza WatsonxLLM per generare testo. Per incoraggiare il modello a generare quanti più dettagli possibile senza entità o relazioni allucinanti che non sono presenti, la temperatura deve essere piuttosto bassa e il numero di token elevato.
LLMGraphTransformer ti consente di impostare i tipi di nodi e relazioni che desideri che l'LLM generi. Nel tuo caso, il testo descrive i dipendenti di un'azienda, i gruppi in cui lavorano e le loro qualifiche. Limitando l'LLM solo a queste entità, è più probabile ottenere una buona rappresentazione della conoscenza in un grafo.
La chiamata a convert_to_graph_documents fa sì che LLMGraphTransformer crei un grafo di conoscenza dal testo. Questo passaggio genera la sintassi Neo4j corretta per inserire le informazioni nel database grafico per rappresentare il contesto pertinente e le entità pertinenti.
Ora cancella tutti i vecchi dati dal database Memgraph e inserisci i nuovi nodi e edge.
La sintassi Cypher generata viene memorizzata negli oggetti graph_documents. Puoi verificarlo semplicemente stampandolo come stringa.
Lo schema e i tipi di dati creati da Cypher sono visibili nella proprietà "get_schema" del grafico.
Il risultato sarà:
È inoltre possibile visualizzare la struttura del grafo nel visualizzatore Memgraph labs:
L'LLM ha svolto un lavoro ragionevole nel creare i nodi e le relazioni corretti. Ora è il momento di interrogare il knowledge graph.
Sollecitare correttamente l'LLM richiede un po' di prompt engineering. LangChain fornisce un FewShotPromptTemplate che può essere utilizzato per fornire esempi all'LLM nel prompt per assicurarsi che scriva una sintassi Cypher corretta e concisa. Il codice seguente fornisce diversi esempi di domande e quesiti che il LLM dovrebbe utilizzare. Mostra anche la limitazione dell'output del modello solo alla query. Un LLM troppo loquace potrebbe aggiungere informazioni aggiuntive che porterebbero a query Cypher non valide, quindi il prompt chiede al modello di output solo la query stessa.
Aggiungere un prefisso istruttivo aiuta anche a limitare il comportamento del modello e rende più probabile che l'LLM output la sintassi Cypher corretta.
Successivamente, creiamo un prompt per controllare il modo in cui l'LLM risponde alla domanda con le informazioni restituite da Memgraph. Forniremo all'LLM diversi esempi e istruzioni su come rispondere una volta che avrà ricevuto informazioni contestuali dal database grafico.
Ora è il momento di creare la catena di risposta alle domande. MemGraphQAchain ti consente di impostare quale LLM desidera utilizzare, lo schema di grafo da utilizzare e le informazioni sul debugging. L'uso di una temperatura di 0 e una penalità di lunghezza incoraggia l'LLM a mantenere il prompt Cypher breve e diretto.
Ora puoi invocare la catena con una domanda in linguaggio naturale (ricorda che le tue risposte potrebbero essere leggermente diverse perché gli LLM non sono puramente deterministici).
Questo produrrà:
> Inserire la nuova catena MemgraphQAChain...
Cypher generato:
MATCH (p:Person {id: 'John'})-[:TITLE]->(t:Title) RETURN t.id
Full Context:
[{'t.id': 'Director of the Digital Marketing Group'}]
> Finished chain.
{'query': 'What is Johns title?',
'result': ' \nAnswer: Director of the Digital Marketing Group.',
'intermediate_steps': [{'query': " MATCH (p:Person {id: 'John'})-[:TITLE]->(t:Title) RETURN t.id"},
{'context': [{'t.id': 'Director of the Digital Marketing Group'}]}]}
Nella domanda successiva, poni alla catena una domanda leggermente più complessa:
Il risultato dovrebbe essere:
La risposta corretta è contenuta nella risposta. In alcuni casi, potrebbe esserci del testo aggiuntivo da rimuovere prima di restituire la risposta a un utente finale.
È possibile chiedere alla catena Memgraph informazioni sulle relazioni di gruppo:
Il risultato sarà:
Questa è la risposta corretta.
Infine, poni alla catena una domanda con due output:
Il risultato sarà:
La catena identifica correttamente entrambi i collaboratori.
In questo tutorial, hai creato un'applicazione Graph RAG usando Memgraph e watsonx per generare le strutture di dati del grafico e interrogarle. Utilizzando un LLM tramite watsonx estrae le informazioni sui nodi e sugli edge dal testo sorgente in linguaggio naturale e genera la sintassi delle query Cypher per popolare un database a grafi. Ha poi usato watsonx per trasformare le domande in linguaggio naturale su quel testo sorgente in query Cypher che hanno estratto informazioni dal database di grafi. Utilizzando la Prompt Engineering, l'LLM ha trasformato i risultati del database Memgraph in risposte in linguaggio naturale.