Menerapkan grafik RAG menggunakan grafik pengetahuan

Grafik retrieval augmented generation (Graph RAG) muncul sebagai teknik yang efektif untuk aplikasi AI generatif yang menggunakan pengetahuan spesifik domain dan informasi yang relevan. Graph RAG adalah alternatif dari metode pencarian vektor yang menggunakan basis data vektor

Grafik pengetahuan adalah sistem pengetahuan di mana basis data grafik seperti Neo4j atau Amazon Neptune dapat menunjukkan data terstruktur. Dalam grafik pengetahuan, hubungan antara titik data yang disebut garis penghubung sama berartinya dengan koneksi antara titik data yang disebut verteks atau terkadang node. Grafik pengetahuan memudahkan untuk melintasi jaringan dan memproses kueri kompleks tentang data yang terhubung. Grafik pengetahuan sangat cocok untuk contoh penggunaan yang melibatkan chatbot, resolusi identitas, analisis jaringan, mesin rekomendasi, gambaran terpadu tentang pelanggan, dan deteksi penipuan.

Pendekatan Graph RAG memanfaatkan sifat terstruktur dari basis data grafik untuk memberikan kedalaman dan konteks yang lebih besar dari informasi yang diambil tentang jaringan atau hubungan yang kompleks.  Basis data grafik dipasangkan dengan model bahasa besar (LLM), pengembang dapat mengotomatiskan bagian penting dari proses pembuatan grafik dari data tidak terstruktur seperti teks. LLM dapat memproses data teks dan mengidentifikasi entitas, memahami hubungan mereka, dan menunjukkannya dalam struktur grafik.

Ada banyak cara untuk membuat aplikasi Graph RAG, misalnya GraphRAG dari Microsoft, atau memasangkan GPT4 dengan LlamaIndex. Untuk tutorial ini Anda akan menggunakan Memgraph, solusi basis data grafik sumber terbuka untuk membuat sistem RAG menggunakan Llama-3 dari Meta di watsonx. Memgraph menggunakan Cypher, bahasa kueri deklaratif. Bahasa ini memiliki beberapa kesamaan dengan SQL, tetapi berfokus pada node dan hubungan, bukan tabel dan baris. Anda akan menggunakan Llama 3 untuk membuat dan mengisi basis data grafik Anda dari teks tidak terstruktur dan informasi kueri dalam basis data.

Langkah 1

Meskipun terdapat pilihan beberapa alat, tutorial ini akan memandu Anda untuk menyiapkan akun IBM menggunakan Jupyter Notebook.

Masuk ke watsonx.ai menggunakan akun IBM Cloud Anda.

Buat proyek watsonx.ai.

Anda mendapatkan ID proyek Anda dari dalam proyek Anda. Klik tab Kelola. Kemudian, salin ID proyek dari bagian Detail di halaman Umum. Anda memerlukan ID Proyek ini untuk tutorial ini.

Selanjutnya, kaitkan proyek Anda dengan Waktu Proses watsonx.ai

a.  Buat instans layanan Waktu Proses watsonx.ai (pilih paket Lite, yang merupakan instans gratis).

b.  Buat Kunci API di waktu proses watsonx.ai. Simpan kunci API ini untuk digunakan dalam tutorial ini.

c. Buka proyek Anda dan pilih tab Kelola

d.  Di tab kiri, pilih Layanan dan Integrasi

e. Pilih layanan IBM

f. Pilih Tautkan layanan dan pilih waktu proses watsonx.ai.

g. Kaitkan waktu proses watsonx.ai ke proyek yang Anda buat di watsonx.ai

Langkah 2

Sekarang, Anda harus menginstal Docker.

Setelah Anda menginstal Docker, instal Memgraph menggunakan kontainer Docker mereka. Di OSX atau Linux, Anda dapat menggunakan perintah ini di terminal:

curl https://install.memgraph.com | sh

Pada komputer Windows gunakan:

iwr https://windows.memgraph.com | iex

Ikuti langkah-langkah instalasi untuk mengaktifkan dan menjalankan mesin Memgraph dan lab Memgraph.

Di komputer Anda, buat virtualenv baru untuk proyek ini:

virtualenv kg_rag --python=python3.12

Di lingkungan Python untuk notebook Anda, instal pustaka Python berikut:

./kg_rag/bin/pip install langchain langchain-openai langchain_experimental langchain-community==0.3.15 neo4j langchain_ibm jupyterlab json-repair getpass4

Sekarang Anda siap untuk terhubung ke Memgraph.

Langkah 3

Jika Anda telah mengonfigurasi Memgraph untuk menggunakan nama pengguna dan kata sandi, atur di sini, jika tidak, Anda bisa menggunakan pengaturan default tanpa keduanya. Ini bukan praktik yang baik untuk basis data produksi, namun untuk lingkungan pengembangan lokal yang tidak menyimpan data sensitif, hal ini tidak menjadi masalah.

import os
from langchain_community.chains.graph_qa.memgraph import MemgraphQAChain
from langchain_community.graphs import MemgraphGraph

url = os.environ.get("MEMGRAPH_URI", "bolt://localhost:7687")
username = os.environ.get("MEMGRAPH_USERNAME", "")
password = os.environ.get("MEMGRAPH_PASSWORD", "")

#initialize memgraph connection
graph = MemgraphGraph(
    url=url, username=username, password=password, refresh_schema=True
)

Sekarang buat untai sampel yang menjelaskan kumpulan data hubungan yang dapat Anda gunakan untuk menguji kemampuan menghasilkan grafik sistem LLM Anda. Anda dapat menggunakan sumber data yang lebih kompleks tetapi contoh sederhana ini membantu kami mendemonstrasikan algoritma.

graph_text = “””
John’s title is Director of the Digital Marketing Group.
John works with Jane whose title is Chief Marketing Officer.
Jane works in the Executive Group.
Jane works with Sharon whose title is the Director of Client Outreach.
Sharon works in the Sales Group.
“””

Masukkan kunci API watsonx yang Anda buat di langkah pertama:

from getpass import getpass

watsonx_api_key = getpass()
os.environ[“WATSONX_APIKEY”] = watsonx_api_key
watsonx_project_id = getpass()
os.environ[“WATSONX_PROJECT_ID”] = watsonx_project_id

Sekarang konfigurasikan instans WatsonXLLM untuk menghasilkan teks. Parameter harus cukup rendah dan jumlah token tinggi untuk mendorong model menghasilkan detail sebanyak mungkin tanpa berhalusinasi akan entitas atau hubungan yang tidak ada.

from langchain_ibm import WatsonxLLM
from ibm_watsonx_ai.metanames import GenTextParamsMetaNames

graph_gen_parameters = {   
    GenTextParamsMetaNames.DECODING_METHOD: “sample”,
    GenTextParamsMetaNames.MAX_NEW_TOKENS: 1000,
    GenTextParamsMetaNames.MIN_NEW_TOKENS: 1,
    GenTextParamsMetaNames.TEMPERATURE: 0.3,
    GenTextParamsMetaNames.TOP_K: 10,
    GenTextParamsMetaNames.TOP_P: 0.8
}
watsonx_llm = WatsonxLLM(
    model_id=”meta-llama/llama-3-3-70b-instruct”,
    url=”https://us-south.ml.cloud.ibm.com”,
    project_id=os.getenv(“WATSONX_PROJECT_ID”),
    params=graph_gen_parameters,
)

LLMGraphTransformer memungkinkan Anda mengatur jenis node dan hubungan apa yang Anda inginkan untuk dihasilkan oleh LLM. Dalam kasus Anda, teks tersebut menggambarkan karyawan di perusahaan, kelompok tempat mereka bekerja, dan judul pekerjaan mereka. Membatasi LLM hanya pada entitas tersebut akan membuat Anda mendapatkan representasi pengetahuan yang baik dalam sebuah grafik.

Panggilan ke convert_to_graph_documents menyebabkan LLMGraphTransformer membuat grafik pengetahuan dari teks. Langkah ini menghasilkan sintaks Neo4j yang benar untuk memasukkan informasi ke dalam basis data grafik untuk menunjukkan konteks yang relevan dan entitas yang relevan.

from langchain_experimental.graph_transformers.llm import LLMGraphTransformer
from langchain_core.documents import Document

llm_transformer = LLMGraphTransformer(
    llm=watsonx_llm,
    allowed_nodes=[“Person”, “Title”, “Group”],
    allowed_relationships=[“TITLE”, “COLLABORATES”, “GROUP”]
)
documents = [Document(page_content=graph_text)]
graph_documents = llm_transformer.convert_to_graph_documents(documents)

Sekarang hapus data lama dari basis data Memgraph dan masukkan node dan garis penghubung baru.

# make sure the database is empty
graph.query(“STORAGE MODE IN_MEMORY_ANALYTICAL”)
graph.query(“DROP GRAPH”)
graph.query(“STORAGE MODE IN_MEMORY_TRANSACTIONAL”)

# create knowledge graph
graph.add_graph_documents(graph_documents)

Sintaks Cypher yang dihasilkan disimpan dalam objek graph_documents. Anda dapat memeriksanya hanya dengan mencetaknya sebagai untai.

print(f”{graph_documents}”)

Skema dan jenis data yang dibuat oleh Cypher dapat dilihat pada grafik properti 'get_schema'.

graph.refresh_schema()
print(graph.get_schema)

Ini akan mencetak:

Node labels and properties (name and type) are:
- labels: (:Title)
properties:
- id: string
- labels: (:Group)
properties:
- id: string
- labels: (:Person)
properties:
- id: string

Nodes are connected with the following relationships:
(:Person)-[:COLLABORATES]->(:Person)
(:Person)-[:GROUP]->(:Group)
(:Person)-[:TITLE]->(:Title)

Anda juga dapat melihat struktur grafik di penampil lab Memgraph:

 

Gambar jaringan grafik yang menunjukkan node dan garis penghubung Jaringan Memgraph yang dihasilkan dari teks input

LLM telah melakukan pekerjaan yang masuk akal untuk menciptakan node dan hubungan yang benar. Sekarang saatnya untuk menanyakan grafik pengetahuan.

Langkah 4

Mengajukan prompt pada LLM dengan benar membutuhkan sejumlah rekayasa prompt. LangChain menyediakan FewShotPromptTemplate yang dapat digunakan untuk memberikan contoh kepada LLM dalam prompt untuk memastikan bahwa ia menulis sintaks Cypher yang benar dan ringkas. Kode berikut memberikan beberapa contoh pertanyaan dan kueri yang harus digunakan LLM. Ini juga menunjukkan pembatasan output model hanya pada kueri. LLM yang terlalu cerewet mungkin menambahkan informasi tambahan yang akan menyebabkan kueri Cypher tidak valid, sehingga templat prompt meminta model untuk hanya memberikan output kueri itu sendiri.

Menambahkan awalan instruktif juga membantu membatasi perilaku model dan membuat LLM lebih mungkin menghasilkan output sintaksis Cypher yang benar.

from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate

examples = [
{
“question”: “<|begin_of_text|>What group is Charles in?<|eot_id|>“,
“query”: “<|begin_of_text|>MATCH (p:Person {{id: ‘Charles’}})-[:GROUP]->(g:Group) RETURN g.id<|eot_id|>“,
},
{
“question”: “<|begin_of_text|>Who does Paul work with?<|eot_id|>“,
“query”: “<|begin_of_text|>MATCH (a:Person {{id: ‘Paul’}})-[:COLLABORATES]->(p:Person) RETURN p.id<|eot_id|>“,
},
{
“question”: “What title does Rico have?<|eot_id|>“,
“query”: “<|begin_of_text|>MATCH (p:Person {{id: ‘Rico’}})-[:TITLE]->(t:Title) RETURN t.id<|eot_id|>“,
}
]

example_prompt = PromptTemplate.from_template(
“<|begin_of_text|>{query}<|eot_id|>“
)

prefix = “””
Instructions:
- Respond with ONE and ONLY ONE query.
- Use provided node and relationship labels and property names from the
schema which describes the database’s structure. Upon receiving a user
question, synthesize the schema to craft a precise Cypher query that
directly corresponds to the user’s intent.
- Generate valid executable Cypher queries on top of Memgraph database.
Any explanation, context, or additional information that is not a part
of the Cypher query syntax should be omitted entirely.
- Use Memgraph MAGE procedures instead of Neo4j APOC procedures.
- Do not include any explanations or apologies in your responses. Only answer the question asked.
- Do not include additional questions. Only the original user question.
- Do not include any text except the generated Cypher statement.
- For queries that ask for information or functionalities outside the direct
generation of Cypher queries, use the Cypher query format to communicate
limitations or capabilities. For example: RETURN “I am designed to generate Cypher queries based on the provided schema only.”

Here is the schema information

{schema}

With all the above information and instructions, generate Cypher query for the
user question.

The question is:

{question}

Below are a number of examples of questions and their corresponding Cypher queries.”””

cypher_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix=prefix,
    suffix=”User input: {question}\nCypher query: “,
    input_variables=[“question”, “schema”],
)

Selanjutnya, Anda akan membuat prompt untuk mengontrol bagaimana LLM menjawab pertanyaan dengan informasi yang ditampilkan dari Memgraph. Kami akan memberikan beberapa contoh dan instruksi kepada LLM tentang cara merespons setelah mendapatkan informasi konteks dari basis data grafik.

 

qa_examples = [
    {
        “question”: “<|begin_of_text|>What group is Charles in?<|eot_id|>“,
        “context”: “[{{‘g.id’: ‘Executive Group’}}]”,
        “response”: “Charles is in the Executive Group<|eot_id|>“
    },
    {
        “question”: “<|begin_of_text|>Who does Paul work with?<|eot_id|>“,
        “context”: “[{{‘p.id’: ‘Greg’}}, {{‘p2.id’: ‘Norma’}}]”,
        “response”: “Paul works with Greg and Norma<|eot_id|>“
    },
    {
        “question”: “What title does Rico have?<|eot_id|>“,
        “context”: “[{{‘t.id’: ‘Vice President of Sales’}}]”,
        “response”: “Vice President of Sales<|eot_id|>“
    }
]

qa_template = “””
Use the provided question and context to create an answer.Question: {question}

Context: {context}
Use only names departments or titles contained within {question} and {context}.
“””
qa_example_prompt = PromptTemplate.from_template(“”)

qa_prompt = FewShotPromptTemplate(
    examples=qa_examples,
    prefix=qa_template,
    input_variables=[“question”, “context”],
    example_prompt=qa_example_prompt,
    suffix=” “
)

Sekarang saatnya untuk membuat rantai penjawab pertanyaan. MemgraphQAChain memungkinkan Anda untuk mengatur LLM mana yang ingin Anda gunakan, skema grafik yang akan digunakan dan informasi tentang debug. Menggunakan parameter 0 dan penalti panjang akan mendorong LLM untuk menjaga prompt Cypher tetap pendek dan sederhana.

query_gen_parameters = {
    GenTextParamsMetaNames.DECODING_METHOD: “sample”,
    GenTextParamsMetaNames.MAX_NEW_TOKENS: 100,
    GenTextParamsMetaNames.MIN_NEW_TOKENS: 1,
    GenTextParamsMetaNames.TEMPERATURE: 0.0,
    GenTextParamsMetaNames.TOP_K: 1,
    GenTextParamsMetaNames.TOP_P: 0.9,
    GenTextParamsMetaNames.LENGTH_PENALTY: {‘decay_factor’: 1.2, ‘start_index’: 20}
}

chain = MemgraphQAChain.from_llm(
        llm = WatsonxLLM(
        model_id=”meta-llama/llama-3-3-70b-instruct”,
        url=”https://us-south.ml.cloud.ibm.com”,
        project_id=”dfe8787b-1f6f-4e18-b36a-e22c00f141d1”,
        params=query_gen_parameters
    ),
    graph = graph,
    allow_dangerous_requests = True,
    verbose = True,
    return_intermediate_steps = True, # for debugging
    cypher_prompt=cypher_prompt,
    qa_prompt=qa_prompt
)

Sekarang Anda dapat memanggil rantai dengan pertanyaan bahasa alami (perhatikan bahwa jawaban Anda mungkin sedikit berbeda karena LLM tidak murni deterministik).

chain.invoke(“What is Johns title?”)

Ini akan menghasilkan output:

> Entering new MemgraphQAChain chain...
Generated Cypher:
 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'}]}]}

Dalam pertanyaan berikutnya, ajukan pertanyaan yang sedikit lebih kompleks kepada rantai:

chain.invoke(“Who does John collaborate with?”)

Ini seharusnya menampilkan:

> Entering new MemgraphQAChain chain...
Generated Cypher:
MATCH (p:Person {id: ‘John’})-[:COLLABORATES]->(c:Person) RETURN c
Full Context:
[{‘c’: {‘id’: ‘Jane’}}]

> Finished chain.
{‘query’: ‘Who does John collaborate with?’,
‘result’: ‘ \nAnswer: John collaborates with Jane.’,
‘intermediate_steps’: [{‘query’: “ MATCH (p:Person {id: ‘John’})-[:COLLABORATES]->(c:Person) RETURN c”},
{‘context’: [{‘c’: {‘id’: ‘Jane’}}]}]}

Jawaban yang benar terkandung dalam tanggapan. Dalam beberapa kasus mungkin ada teks tambahan yang ingin Anda hapus sebelum menampilkan jawaban ke pengguna akhir.

Anda dapat menanyakan rantai Memgraph tentang hubungan Grup:

chain.invoke(“What group is Jane in?”)

Ini akan menampilkan:

> Entering new MemgraphQAChain chain...
Generated Cypher:
MATCH (p:Person {id: ‘Jane’})-[:GROUP]->(g:Group) RETURN g.id
Full Context:
[{‘g.id’: ‘Executive Group’}]

> Finished chain.
{‘query’: ‘What group is Jane in?’,
‘result’: ‘Jane is in Executive Group.’,
‘intermediate_steps’: [{‘query’: “ MATCH (p:Person {id: ‘Jane’})-[:GROUP]->(g:Group) RETURN g.id”},
{‘context’: [{‘g.id’: ‘Executive Group’}]}]}

Ini adalah jawaban yang benar.

Terakhir, ajukan pertanyaan kepada rantai dengan dua output:

chain.invoke(“Who does Jane collaborate with?”)

Ini seharusnya memberikan output:

> Entering new MemgraphQAChain chain...
Generated Cypher:
MATCH (p:Person {id: ‘Jane’})-[:COLLABORATES]->(c:Person) RETURN c
Full Context:
[{‘c’: {‘id’: ‘Sharon’}}]

> Finished chain.
{‘query’: ‘Who does Jane collaborate with?’,
‘result’: ‘ Jane collaborates with Sharon.’,
‘intermediate_steps’: [{‘query’: “ MATCH (p:Person {id: ‘Jane’})-[:COLLABORATES]->(c:Person) RETURN c”},
{‘context’: [{‘c’: {‘id’: ‘Sharon’}}]}]}

Rantai mengidentifikasi kedua kolaborator dengan benar.

Kesimpulan

Dalam tutorial ini, Anda telah membuat aplikasi Graph RAG menggunakan Memgraph dan watsonx untuk membuat struktur data grafik dan mengajukan kueri. Menggunakan LLM melalui watsonx, Anda mengekstraksi informasi node dan garis penghubung dari teks sumber bahasa alami dan menghasilkan sintaks kueri Cypher untuk mengisi basis data grafik. Anda kemudian menggunakan watsonx untuk mengubah pertanyaan bahasa alami tentang teks sumber tersebut menjadi kueri Cypher yang mengekstraksi informasi dari basis data grafik. Menggunakan rekayasa prompt, LLM mengubah hasil dari basis data Memgraph menjadi respons bahasa alami.

Solusi terkait
IBM® watsonx.ai

Latih, validasi, lakukan tuning, dan terapkan AI generatif, model dasar, dan kemampuan machine learning dengan IBM watsonx.ai, studio perusahaan generasi berikutnya untuk pembangun AI. Bangun aplikasi AI dalam waktu singkat, dengan sedikit data.

Jelajahi watsonx.ai
Solusi kecerdasan buatan (AI)

Manfaatkan AI di bisnis Anda dengan perpaduan antara keahlian AI terdepan di industri dari IBM dan portofolio solusi Anda.

Jelajahi solusi AI
Konsultasi dan layanan kecerdasan buatan (AI)

Layanan IBM Consulting AI membantu merancang ulang cara kerja bisnis dengan AI untuk transformasi.

Jelajahi layanan AI
Ambil langkah selanjutnya

Dengan menggunakan AI, IBM Concert mengungkap insight penting tentang operasi Anda dan memberikan rekomendasi spesifik aplikasi untuk perbaikan. Temukan cara Concert dapat memajukan bisnis Anda.

Jelajahi Concert Jelajahi solusi otomatisasi proses bisnis