لقد أصبح استخدام الرسوم البيانية المعرفية لتحسين نتائج تطبيقات التوليد المعزز بالاسترجاع (RAG) موضوعًا ساخنًا. توضح معظم الأمثلة كيفية إنشاء رسم بياني للمعرفة باستخدام عدد صغير نسبيًا من المستندات. قد يكون هذا لأن النهج النموذجي - استخراج معلومات دقيقة ومركزة على الكيان - لا يمكن تطبيقه على نطاق واسع. يستغرق تشغيل كل مستند من خلال نموذج لاستخراج الكيانات (العقد) والعلاقات (الحواف) وقتًا طويلاً (ويتكلف الكثير) لتشغيله على مجموعات بيانات كبيرة.
لقد جادلنا بأن
تم تحميل المستندات إلى مخزن رسوم بيانية يركز على الكيان مثل Neo4j باستخدام LLMGraphTransformer من LangChain. يعتمد الكود على LangChain
from langchain_core.documents import Document from langchain_experimental.graph_transformers import LLMGraphTransformer from langchain_openai import ChatOpenAI llm = ChatOpenAI(temperature=0, model_name="gpt-4-turbo") llm_transformer = LLMGraphTransformer(llm=llm) from time import perf_counter start = perf_counter() documents_to_load = [Document(page_content=line) for line in lines_to_load] graph_documents = llm_transformer.convert_to_graph_documents(documents_to_load) end = perf_counter() print(f"Loaded (but NOT written) {NUM_LINES_TO_LOAD} in {end - start:0.2f}s")
إن تحميل البيانات إلى GraphVectorStore يشبه تقريبًا تحميلها إلى مخزن متجه. الإضافة الوحيدة هي أننا نحسب البيانات الوصفية التي تشير إلى كيفية ارتباط كل صفحة بالصفحات الأخرى.
import json from langchain_core.graph_vectorstores.links import METADATA_LINKS_KEY, Link def parse_document(line: str) -> Document: para = json.loads(line) id = para["id"] links = { Link.outgoing(kind="href", tag=id) for m in para["mentions"] if m["ref_ids"] is not None for id in m["ref_ids"] } links.add(Link.incoming(kind="href", tag=id)) return Document( id = id, page_content = " ".join(para["sentences"]), metadata = { "content_id": para["id"], METADATA_LINKS_KEY: list(links) }, )
يعد هذا أيضًا مثالًا جيدًا لكيفية إضافة روابطك الخاصة بين العقد.
from langchain_openai import OpenAIEmbeddings from langchain_community.graph_vectorstores.cassandra import CassandraGraphVectorStore import cassio cassio.init(auto=True) TABLE_NAME = "wiki_load" store = CassandraGraphVectorStore( embedding = OpenAIEmbeddings(), node_table=TABLE_NAME, insert_timeout = 1000.0, ) from time import perf_counter start = perf_counter() from datasets.wikimultihop.load import parse_document kg_documents = [parse_document(line) for line in lines_to_load] store.add_documents(kg_documents) end = perf_counter() print(f"Loaded (and written) {NUM_LINES_TO_LOAD} in {end - start:0.2f}s")
عند تشغيل 100 سطر، استغرق النهج المرتكز على الكيان باستخدام GPT-4o 405.93 ثانية لاستخراج GraphDocuments و10.99 ثانية لكتابتها في Neo4j، بينما استغرق النهج المرتكز على المحتوى 1.43 ثانية. وبالاستقراء، سيستغرق الأمر 41 أسبوعًا لتحميل جميع الصفحات البالغ عددها 5,989,847 باستخدام النهج المرتكز على الكيان وحوالي 24 ساعة باستخدام النهج المرتكز على المحتوى. ولكن بفضل التوازي، يعمل النهج المرتكز على المحتوى في 2.5 ساعة فقط! وبافتراض أن نفس فوائد التوازي، فسيستغرق الأمر أكثر من أربعة أسابيع لتحميل كل شيء باستخدام النهج المرتكز على الكيان. لم أجربه لأن التكلفة المقدرة ستكون 58700 دولارًا - بافتراض أن كل شيء يعمل في المرة الأولى!
خلاصة القول: إن النهج القائم على الكيان لاستخراج الرسوم البيانية المعرفية من المحتوى باستخدام برنامج LLM كان مكلفًا من حيث الوقت والتكلفة على نطاق واسع. من ناحية أخرى، كان استخدام GraphVectorStore سريعًا وغير مكلف.
في هذا القسم، يتم طرح بعض الأسئلة، المأخوذة من مجموعة فرعية من المستندات المحملة، لمعالجة جودة الإجابات.
استخدمت Entity-centric 7324 رمزًا سريعًا وتكلف 0.03 دولارًا لإنتاج إجابات عديمة الفائدة بشكل أساسي، بينما استخدمت Content-centric 450 رمزًا سريعًا وتكلف 0.002 دولارًا لإنتاج إجابات موجزة تجيب مباشرة على الأسئلة.
قد يكون من المدهش أن الرسم البياني الدقيق لـ Neo4j يعطي إجابات عديمة الفائدة. بالنظر إلى التسجيل من السلسلة، نرى بعض الأسباب التي تجعل هذا يحدث:
> Entering new GraphCypherQAChain chain... Generated Cypher: cypher MATCH (a:Album {id: 'The Circle'})-[:RELEASED_BY]->(r:Record_label) RETURN a.id, r.id Full Context: [{'a.id': 'The Circle', 'r.id': 'Restless'}] > Finished chain. {'query': "When was 'The Circle' released?", 'result': "I don't know the answer."}
لذا، لم يقدم المخطط التفصيلي سوى معلومات حول شركة التسجيلات. ومن المنطقي أن لا يتمكن برنامج الماجستير في القانون من الإجابة على السؤال بناءً على المعلومات المسترجعة.
إن استخراج الرسوم البيانية الدقيقة للمعرفة الخاصة بالكيانات أمر مكلف من حيث الوقت والتكلفة على نطاق واسع. فعند طرح أسئلة حول مجموعة فرعية من البيانات التي تم تحميلها، فإن التفاصيل الإضافية (والتكلفة الإضافية لتحميل الرسم البياني الدقيق) أعادت المزيد من الرموز لتشمل المطالبة ولكنها أنتجت إجابات عديمة الفائدة!
يتبنى GraphVectorStore نهجًا دقيقًا يركز على المحتوى مما يجعل إنشاء رسم بياني للمعرفة أمرًا سريعًا وسهلاً. يمكنك البدء بالكود الحالي الخاص بك لملء VectorStore باستخدام LangChain وإضافة روابط (حواف) بين الكتل لتحسين عملية الاسترجاع.
Graph RAG هي أداة مفيدة لتمكين تطبيقات RAG التوليدية للذكاء الاصطناعي من استرداد سياقات ذات صلة أعمق. ولكن استخدام نهج دقيق يركز على الكيان لا يتناسب مع احتياجات الإنتاج. إذا كنت تتطلع إلى إضافة قدرات الرسم البياني المعرفي إلى تطبيق RAG الخاص بك، فحاول
بقلم بن تشامبرز ، DataStax