تنفيذ Graph RAG باستخدام الرسوم البيانية المعرفية

ظهرت تقنية التوليد المعزز بالاسترجاع القائمة على الرسوم البيانية (Graph RAG) كأسلوب فعَّال لتطبيقات الذكاء الاصطناعي التوليدي، يُتيح الاستفادة من المعرفة المتخصصة في المجالات والمعلومات ذات الصلة. يُعَد Graph RAG بديلًا عن طرق البحث باستخدام المتجهات التي تعتمد على قاعدة بيانات المتجهات.

الرسوم البيانية المعرفية هي أنظمة معرَّفة يمكن لقواعد البيانات الرسومية مثل Neo4j أو Amazon Neptune تمثيل البيانات المنظمة من خلالها. في الرسوم البيانية المعرفية، تُعَد العلاقات بين نقاط البيانات، المعروفة باسم الحواف، ذات معنى بمقدار أهمية الروابط بين نقاط البيانات نفسها، المعروفة باسم الرؤوس أو أحيانًا العُقَد. تسهِّل الرسوم البيانية المعرفية التنقل عبر الشبكة ومعالجة الاستعلامات المعقدة المتعلقة بالبيانات المرتبطة. تُعَد الرسوم البيانية المعرفية مناسبةً بشكل خاص للحالات التي تشمل روبوتات المحادثة وحل الهوية وتحليل الشبكات ومحركات التوصية والعميل 360 والكشف عن الاحتيال.

يستفيد نهج Graph RAG من الطبيعة المنظمة لقواعد البيانات الرسومية لتوفير عمق وسياق أكبر للمعلومات المسترجَعة حول الشبكات أو العلاقات المعقدة. عند اقتران قاعدة بيانات رسومية بنموذج لغوي كبير، يمكن للمطور أتمتة أجزاء كبيرة من عملية إنشاء الرسم البياني من بيانات غير منظمة مثل النصوص. يستطيع النموذج اللغوي الكبير معالجة بيانات النصوص وتحديد الكيانات وفهم علاقاتها وتمثيلها في هيكل رسومي.

هناك العديد من الطرق لإنشاء تطبيق Graph RAG، على سبيل المثال GraphRAG من Microsoft، أو دمج GPT4 مع LlamaIndex. في هذا البرنامج التعليمي، ستستخدم Memgraph، حل قاعدة بيانات رسومية مفتوح المصدر، لإنشاء نظام RAG باستخدام Llama-3 من Meta على watsonx. يستخدم Memgraph لغة Cypher، وهي لغة استعلام إعلانية. تشترك في بعض الخصائص مع SQL، لكنها تركِّز على الرؤوس والعلاقات بدلًا من الجداول والصفوف. سيمكِّنك Llama 3 من إنشاء قاعدة البيانات الرسومية الخاصة بك وملئها من النصوص غير المنظمة، بالإضافة إلى الاستعلام عن المعلومات داخل القاعدة.

الخطوة 1

رغم توفُّر عدة أدوات للاختيار منها، يُرشدك هذا الدليل خلال خطوات إعداد حساب IBM لاستخدام Jupyter Notebook.

سجِّل الدخول إلى watsonx.ai باستخدام حساب IBM Cloud الخاص بك.

أنشئ مشروع watsonx.ai.

يمكنك الحصول على معرِّف المشروع من داخل مشروعك. انقر على علامة التبويب الإدارة (Manage)، ثم انسخ معرِّف المشروع من قسم التفاصيل (Details) في صفحة عام (General). ستحتاج إلى هذا المعرِّف في هذا البرنامج التعليمي.

بعد ذلك، اربط مشروعك ببيئة تشغيل watsonx.ai Runtime.

أ. أنشئ مثيل خدمة watsonx.ai Runtime (اختَر خطة Lite، وهي مثيل مجاني).

ب. أنشئ مفتاح API في watsonx.ai Runtime. احفظ مفتاح API هذا لاستخدامه في هذا البرنامج التعليمي.

ج. انتقِل إلى مشروعك واختَر علامة التبويب "إدارة" (Manage).

د.  في علامة التبويب اليسرى، اختَر الخدمات وعمليات التكامل (Services and Integrations).

هـ. اختَر خدمات IBM.

و. اختَر خدمة Associate ثم اختَر watsonx.ai Runtime.

ز. اربط watsonx.ai Runtime بالمشروع الذي أنشأته في watsonx.ai.

الخطوة 2

الآن، ستحتاج إلى تثبيت Docker.

بمجرد تثبيت Docker، ثبِّت Memgraph باستخدام حاوية Docker الخاصة به. على أنظمة OSX أو Linux، يمكنك استخدام هذا الأمر في المحطة الطرفية:

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

على جهاز كمبيوتر يعمل بنظام Windows، استخدِم:

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

اتَّبِع خطوات التثبيت لتشغيل محرك Memgraph وMemgraph Lab بشكل كامل.

على جهازك، أنشئ بيئة افتراضية جديدة (virtualenv) لهذا المشروع:

virtualenv kg_rag --python=python3.12

في بيئة Python لدفتر الملاحظات الخاص بك، ثبِّت مكتبات Python التالية:

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

أنت الآن جاهز للاتصال بـ Memgraph.

الخطوة 3

إذا قمت بتكوين Memgraph لاستخدام اسم مستخدم وكلمة مرور، فقم بتعيينهما هنا، وإلا يمكنك استخدام الإعدادات الافتراضية بعدم وجود أيٍّ منهما. هذا ليس من الممارسات الجيدة لقاعدة بيانات الإنتاج، لكن في بيئة تطوير محلية لا تخزِّن بيانات حساسة، لا يمثِّل ذلك مشكلة.

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
)

الآن، أنشئ سلسلة نصية نموذجية تَصِف مجموعة بيانات للعلاقات يمكنك استخدامها لاختبار قدرات توليد الرسوم البيانية في نظام النموذج اللغوي الكبير الخاص بك. يمكنك استخدام مصادر بيانات أكثر تعقيدًا ولكن هذا المثال البسيط يساعدنا على توضيح الخوارزمية.

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.
“””

أدخِل مفتاح API الخاص بـ watsonx الذي أنشأته في الخطوة الأولى:

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

الآن، اضبط إعدادات مثيل WatsonxLLM لتوليد النصوص. يجب أن تكون درجة الحرارة منخفضة نسبيًا ويكون عدد الرموز مرتفعًا لتشجيع النموذج على توليد أكبر قدر من التفاصيل دون الهلوسة بكيانات أو علاقات غير موجودة.

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 تحديد أنواع الرؤوس والعلاقات التي تريد أن يُنشئها النموذج اللغوي الكبير. في حالتك، يَصِف النص الموظفين في شركة معينة، والمجموعات التي يعملون بها، ومسمياتهم الوظيفية. تقييد النموذج اللغوي الكبير بهذه الكيانات فقط يزيد من احتمالية الحصول على تمثيل جيد للمعرفة في الرسم البياني.

استدعاء convert_to_graph_documents يجعل LLMGraphTransformer يُنشئ رسمًا بيانيًا معرفيًا من النص. هذه الخطوة تولِّد صياغة Neo4j الصحيحة لإدخال المعلومات في قاعدة البيانات الرسومية لتمثيل السياق والكيانات ذات الصلة.

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)

الآن امسح أي بيانات قديمة من قاعدة بيانات Memgraph وأدخِل العُقَد والحواف الجديدة.

# 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)

يتم تخزين صياغة Cypher التي تم توليدها في كائنات graph_documents. يمكنك فحصه ببساطة عن طريق طباعته كسلسلة.

print(f”{graph_documents}”)

يمكن الاطِّلاع على المخطط وأنواع البيانات التي أنشأها Cypher في خاصية "get_schema" للرسوم البيانية.

graph.refresh_schema()
print(graph.get_schema)

سيظهر ما يلي:

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)

يمكنك أيضًا مشاهدة هيكل الرسم البياني في عارض Memgraph Lab:

 

صورة لشبكة رسومية تعرض العُقد والحواف. شبكة Memgraph التي تم توليدها من النص المُدخل.

قام النموذج اللغوي الكبير بعمل جيد في إنشاء العُقد والعلاقات الصحيحة. حان الوقت الآن للاستعلام عن الرسم البياني المعرفي.

الخطوة 4

لضمان عمل النموذج اللغوي الكبير بشكل صحيح، يلزم إجراء بعض هندسة المطالبات. يوفر LangChain قالب FewShotPromptTemplate الذي يمكن استخدامه لتقديم أمثلة للنموذج اللغوي الكبير في المطالبة لضمان كتابته لصياغة Cypher صحيحة وموجزة. تقدِّم التعليمات البرمجية التالية عدة أمثلة على الأسئلة والاستعلامات التي يجب أن يستخدمها النموذج اللغوي الكبير. كما يوضِّح أيضًا كيفية تقييد مخرجات النموذج لتقتصر على الاستعلام فقط. قد يقوم النموذج اللغوي الكبير المبالِغ في التحدث بإضافة معلومات إضافية تؤدي إلى استعلامات Cypher غير صالحة، لذلك يطلب قالب المطالبة من النموذج إخراج الاستعلام نفسه فقط.

تساعد إضافة بادئة إرشادية أيضًا على تقييد سلوك النموذج، ما يزيد من احتمال أن ينتج النموذج اللغوي الكبير صياغة Cypher صحيحة.

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”],
)

بعد ذلك، ستُنشئ مطالبة للتحكم في كيفية إجابة النموذج اللغوي الكبير على السؤال باستخدام المعلومات المسترجَعة من Memgraph. سنزوِّد النموذج اللغوي الكبير بعدة أمثلة وتعليمات حول كيفية الرد بمجرد حصوله على معلومات السياق من قاعدة البيانات الرسومية.

 

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=” “
)

حان الوقت الآن لإنشاء سلسلة الإجابة عن الأسئلة. يُتيح لك MemgraphQAChain تحديد النموذج اللغوي الكبير الذي تريد استخدامه، ومخطط الرسم البياني الذي سيتم استخدامه، ومعلومات حول التصحيح. استخدام درجة حرارة صفر وعقوبة طول النص يشجع النموذج اللغوي الكبير على إبقاء مطالبة Cypher قصيرة ومباشرة.

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
)

الآن يمكنك استدعاء السلسلة بسؤال بلغة طبيعية (لاحِظ أن إجاباتك قد تختلف قليلًا لأن النماذج اللغوية الكبيرة ليست حتمية تمامًا).

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

سيؤدي ذلك إلى إخراج:

> 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'}]}]}

في السؤال التالي، قدِّم للسلسلة سؤالًا أعقد قليلًا:

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

يجب أن تُظهر النتيجة ما يلي:

> 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’}}]}]}

الإجابة الصحيحة موجودة في الاستجابة. في بعض الحالات، قد يكون هناك نص إضافي تريد حذفه قبل تقديم الإجابة للمستخدم النهائي.

يمكنك سؤال سلسلة Memgraph عن علاقات المجموعة:

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

سيُظهر هذا:

> 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’}]}]}

هذه هي الإجابة الصحيحة.

أخيرًا، اطرح على السلسلة سؤالًا ينتج عنه مخرجين.

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

يجب أن يُنتج هذا:

> 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’}}]}]}

السلسلة تحدِّد بشكل صحيح كِلا المتعاونَين.

الخاتمة

في هذا البرنامج التعليمي، قمت ببناء تطبيق Graph RAG باستخدام Memgraph وwatsonx لإنشاء هياكل البيانات الرسومية والاستعلام عنها. باستخدام نموذج لغوي كبير عبر watsonx، استخرجتَ معلومات العُقد والحواف من نصوص مصدرية طبيعية، وأنشأت صياغة استعلام Cypher لملء قاعدة البيانات الرسومية. بعد ذلك، استخدمتَ watsonx لتحويل الأسئلة بلغة طبيعية حول النص المصدر إلى استعلامات Cypher التي تستخرج المعلومات من قاعدة البيانات الرسومية. باستخدام هندسة المطالبات، حوَّل النموذج اللغوي الكبير النتائج المستخرجة من قاعدة بيانات Memgraph إلى استجابات بلغة طبيعية.

حلول ذات صلة
®IBM® watsonx.ai

تدريب الذكاء الاصطناعي التوليدي والتحقق من صحته وضبطه ونشره، وكذلك قدرات نماذج الأساس والتعلم الآلي باستخدام IBM watsonx.ai، وهو استوديو الجيل التالي من المؤسسات لمنشئي الذكاء الاصطناعي. أنشئ تطبيقات الذكاء الاصطناعي في وقت قصير وباستخدام جزء بسيط من البيانات.

استكشف watsonx.ai
حلول الذكاء الاصطناعي

استفِد من الذكاء الاصطناعي في عملك بالاستعانة بخبرة IBM الرائدة في مجال الذكاء الاصطناعي ومحفظة حلولها التي ستكون بجانبك.

استكشف حلول الذكاء الاصطناعي
الاستشارات والخدمات في مجال الذكاء الاصطناعي

تساعد خدمات IBM Consulting AI في إعادة تصور طريقة عمل الشركات باستخدام حلول الذكاء الاصطناعي من أجل النهوض بأعمالها.

استكشف خدمات الذكاء الاصطناعي
اتخِذ الخطوة التالية

باستخدام الذكاء الاصطناعي، يكشف IBM Concert عن رؤى مهمة حول عملياتك ويقدم توصيات خاصة بالتطبيق من أجل التحسين. اكتشف كيف يمكن لمنصة Concert تعزيز نمو أعمالك.

استكشف Concert® استكشف حلول أتمتة عمليات الأعمال