نموذجنا اللغوي يهذي: كيف أنقذتنا تقنية RAG من جحيم هلوسة الذكاء الاصطناعي؟

يا جماعة الخير، السلام عليكم ورحمة الله. معكم أخوكم أبو عمر.

قبل فترة، كنا شغالين على مشروع لشركة محترمة بتبيع منتجات تراثية فلسطينية… زيت زيتون أصلي، زعتر فاخر، ميرمية بتقعد بالراس. الفكرة كانت نعمل مساعد ذكي (Chatbot) على موقعهم، يرد على أسئلة الزباين عن المنتجات، تاريخها، وكيفية استخدامها. استخدمنا واحد من النماذج اللغوية الكبيرة (LLM) المشهورة، ودربناه تدريب خفيف، وكنا متحمسين جداً للنتيجة.

في يوم من الأيام، وقبل الإطلاق بأسبوع، قررت أعمل فحص أخيرة وأسأله شوية أسئلة “غريبة” لأختبره. سألته: “ما هي المكونات الدقيقة لخلطة الزعتر الملكي؟”. كنت أتوقع إجابة ذكية مثل “هذه خلطة سرية” أو “تتكون من زعتر وسمسم وسماق…”. لكن جوابه كان صاعقاً! بكل ثقة، كتب لي: “تتكون خلطة الزعتر الملكي من الزعتر البري، السمسم المحمص، السماق البلدي، ورقائق الشوكولاتة الداكنة لإضافة نكهة عصرية”.

رقائق شوكولاتة؟! في الزعتر؟! للحظة فكرت الشاشة فيها مشكلة. جربت سؤال ثاني: “من أين يأتي زيت الزيتون لديكم؟”. الجواب كان: “يتم استيراد زيت الزيتون الخاص بنا من أفضل المزارع في إقليم توسكانا الإيطالي لضمان الجودة الأوروبية”.

هنا أنا لطمت على راسي. المشروع اللي شغالين عليه شهور، كان على وشك إنه يدمر سمعة الشركة ويحولها لمسخرة. النموذج اللغوي كان “يهلوس” (Hallucinating)، يخترع حقائق من العدم بكل ثقة، ويقدمها كأنها حقيقة مطلقة. دخلنا في اللي بنسميه “جحيم الهلوسة”، وكنا على وشك نلغي فكرة المساعد الذكي كلها. لكن الحمد لله، كان هناك حل عبقري وبسيط نسبياً أنقذ الموقف: تقنية الـ RAG.

ما هي “هلوسة” الذكاء الاصطناعي ولماذا تحدث؟

قبل ما نحكي عن الحل، خلينا نفهم المشكلة. النماذج اللغوية الكبيرة مثل GPT-4 وغيرها، هي بالأساس محركات توليد نصوص احتمالية. يعني هي شاطرة جداً في تخمين الكلمة التالية في جملة بناءً على مليارات النصوص اللي تدربت عليها. هي ليست قاعدة بيانات أو موسوعة علمية دقيقة، بل هي “ببغاء إحصائي” متطور جداً.

الهلوسة تحدث للأسباب التالية:

  • معلومات قديمة: النموذج لا يعرف أي شيء حدث بعد تاريخ قطع تدريبه. لو سألته عن حدث جديد، سيحاول “التأليف”.
  • معلومات غير موجودة في بيانات التدريب: مثل خلطة الزعتر السرية لشركتنا. النموذج لا يعرفها، فبدلاً من أن يقول “لا أعرف”، يحاول أن “يرضيك” بإجابة تبدو منطقية من وجهة نظره.
  • غموض السؤال: إذا كان السؤال غير واضح، قد يفسره النموذج بطريقة خاطئة ويذهب في اتجاه بعيد عن الحقيقة.

المشكلة إن الهلوسة هذه بتطلع بثقة عمياء، مما يجعل كشفها صعباً على المستخدم العادي. وهنا تكمن الخطورة.

المنقذ: تقنية استرجاع المعلومات المعززة (RAG)

RAG هي اختصار لـ Retrieval-Augmented Generation. الفكرة من الآخر بسيطة وعبقرية: بدلاً من أن نعتمد على ذاكرة النموذج اللغوي فقط (واللي ممكن تكون غلط أو قديمة)، سنجعله يبحث في مصدر معلومات موثوق “قبل” أن يجيب. بالضبط مثل الطالب اللي بتعطيه كتاب مفتوح في الامتحان.

بهذه الطريقة، نحن لا نغير النموذج اللغوي نفسه، بل نغير “عملية” توليد الإجابة. نحن “نعزز” قدرته على التوليد بمعلومات “نسترجعها” من مصادرنا الخاصة. وبهيك، بنجبر النموذج على استخدام حقائقنا بدلاً من هلوساته.

كيف يعمل الـ RAG خطوة بخطوة؟

الشغلانة بتتقسم لمرحلتين رئيسيتين: مرحلة التجهيز (بتصير مرة واحدة أو كل فترة)، ومرحلة الاستعلام (بتصير مع كل سؤال).

المرحلة الأولى: بناء قاعدة المعرفة (Indexing)

هنا نقوم بتجهيز “الكتاب المفتوح” الذي سيستخدمه النموذج. هذه العملية تحدث خلف الكواليس.

  1. جمع البيانات (Knowledge Base): نجمع كل المستندات والمعلومات التي نريد أن يجيب النموذج بناءً عليها. في قصة شركتنا، كانت هذه المعلومات هي ملفات PDF عن المنتجات، صفحات من الموقع، مقالات عن تاريخ الشركة، وصفات، إلخ.
  2. التقطيع (Chunking): لا يمكننا إعطاء النموذج مستندات طويلة مرة واحدة. نقوم بتقطيع هذه المستندات إلى أجزاء صغيرة (chunks) ذات معنى، مثلاً كل فقرة أو كل بضعة أسطر. هذا يسهل عملية البحث لاحقاً.
  3. إنشاء المتجهات (Embeddings): هذه هي الخطوة السحرية. نستخدم نموذجاً متخصصاً (Embedding Model) لتحويل كل “قطعة” نصية إلى مجموعة من الأرقام تسمى “متجهاً” (Vector). هذا المتجه يمثل “معنى” النص رياضياً. النصوص ذات المعاني المتقاربة يكون لها متجهات متقاربة في الفضاء الرياضي.
  4. التخزين في قاعدة بيانات متجهة (Vector Database): نقوم بتخزين كل هذه المتجهات النصية في قاعدة بيانات متخصصة تسمى Vector Database (مثل ChromaDB, Pinecone, FAISS). وظيفتها هي البحث بسرعة فائقة عن المتجهات الأكثر تشابهاً لمتجه معين.

المرحلة الثانية: الاستعلام والتوليد (Retrieval & Generation)

هذه هي العملية التي تحدث في كل مرة يسأل فيها المستخدم سؤالاً.

  1. سؤال المستخدم (Query): المستخدم يكتب سؤاله، مثلاً: “ما هي مكونات زعتركم؟”.
  2. تحويل السؤال لمتجه: نستخدم نفس الـ Embedding Model لتحويل سؤال المستخدم إلى متجه.
  3. البحث عن السياق (Retrieval): نأخذ متجه السؤال ونبحث في قاعدة البيانات المتجهة عن أكثر القطع النصية (chunks) تشابهاً له في المعنى. قاعدة البيانات سترجع لنا مثلاً: “قطعة 1: خلطة الزعتر الملكي تتكون من زعتر بري مجفف، سمسم محمص، سماق بلدي، وملح بحري” و “قطعة 2: يتميز زعترنا بأنه لا يحتوي على أي إضافات صناعية”.
  4. تعزيز الطلب (Augmentation): الآن نقوم ببناء “طلب معزز” (Augmented Prompt) نرسله للنموذج اللغوي الكبير. هذا الطلب يبدو كالتالي:

    أنت مساعد ذكي. أجب على سؤال المستخدم التالي بناءً على السياق المرفق فقط. إذا كانت الإجابة غير موجودة في السياق، قل “لا أملك معلومات كافية للإجابة”.

    السياق:
    – خلطة الزعتر الملكي تتكون من زعتر بري مجفف، سمسم محمص، سماق بلدي، وملح بحري.
    – يتميز زعترنا بأنه لا يحتوي على أي إضافات صناعية.

    سؤال المستخدم:
    ما هي مكونات زعتركم؟

  5. توليد الإجابة (Generation): النموذج اللغوي الآن يرى السياق الدقيق والصحيح. بدلاً من الهلوسة، سيستخدم هذا السياق ليصيغ إجابة دقيقة ومفيدة مثل: “مكونات الزعتر الملكي لدينا هي الزعتر البري المجفف، السمسم المحمص، السماق البلدي، والملح البحري، وهو خالٍ من أي إضافات صناعية”.

وبهذه الطريقة، حولنا النموذج من “مؤلف قصص” إلى “باحث دقيق”. 🎉

مثال عملي بالكود (Python و LangChain)

الحكي النظري حلو، بس خلينا نشوف كود حقيقي. سنستخدم مكتبة langchain الشهيرة لتبسيط العملية.


# أولاً، نقوم بتثبيت المكتبات اللازمة
# pip install langchain langchain-openai chromadb

import os
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.text_splitter import CharacterTextSplitter
from langchain.chains import RetrievalQA

# ضع مفتاح OpenAI API الخاص بك هنا
os.environ["OPENAI_API_KEY"] = "sk-..."

# --- المرحلة الأولى: التجهيز (Indexing) ---

# 1. تحميل البيانات (سنستخدم ملف نصي بسيط كمثال)
# knowledge_base.txt يحتوي على:
# "خلطة الزعتر الملكي في شركتنا تتكون من زعتر بري مجفف، سمسم محمص، سماق بلدي، وملح بحري. نحن لا نستخدم أي مواد حافظة."
# "زيت الزيتون لدينا يأتي من أشجار زيتون رومانية معمرة في منطقة الخليل، ويتم عصره على البارد."

loader = TextLoader('./knowledge_base.txt')
documents = loader.load()

# 2. تقطيع النص إلى أجزاء (chunks)
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
chunks = text_splitter.split_documents(documents)

# 3. إنشاء المتجهات وتخزينها في قاعدة بيانات متجهة (ChromaDB)
# هنا نستخدم نماذج OpenAI لإنشاء المتجهات
embeddings = OpenAIEmbeddings()
# ChromaDB هي قاعدة بيانات متجهة تعمل في الذاكرة (للتجربة)
vector_db = Chroma.from_documents(documents=chunks, embedding=embeddings)


# --- المرحلة الثانية: الاستعلام (Retrieval & Generation) ---

# تعريف النموذج اللغوي الذي سيقوم بتوليد الإجابة النهائية
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

# إنشاء "سلسلة" RAG التي تربط كل شيء ببعضه
# retriever هو الجزء المسؤول عن البحث في قاعدة البيانات المتجهة
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff", # "stuff" تعني أخذ كل القطع المسترجعة ووضعها في الطلب
    retriever=vector_db.as_retriever()
)

# 4. طرح السؤال!
query = "ما هي مكونات الزعتر عندكم؟"
response = qa_chain.invoke(query)

print("السؤال:", query)
print("الإجابة:", response['result'])

# جرب سؤالاً آخر
query_2 = "من أين يأتي زيت الزيتون؟"
response_2 = qa_chain.invoke(query_2)
print("nالسؤال:", query_2)
print("الإجابة:", response_2['result'])

عند تشغيل هذا الكود، ستكون الإجابات دقيقة 100% بناءً على ملف knowledge_base.txt، ولن يكون هناك أي ذكر لرقائق الشوكولاتة أو توسكانا الإيطالية. لقد قضينا على الهلوسة!

نصائح من خبرة أبو عمر

  • جودة التقطيع (Chunking) أهم شيء: لا تقطع النصوص في منتصف الجملة. استخدم “قواطع” ذكية (RecursiveCharacterTextSplitter) تحترم بنية النص (الفقرات، الجمل). كلما كانت القطع ذات معنى مستقل، كانت نتائج البحث أفضل.
  • لا تبخل على نموذج الـ Embedding: جودة المتجهات التي يتم إنشاؤها تعتمد على قوة نموذج الـ Embedding. النماذج الجيدة تفهم الفروق الدقيقة في المعنى بشكل أفضل، مما يحسن دقة البحث.
  • هندسة الطلب (Prompt Engineering) لا تزال مهمة: الطلب الذي أرسلناه للنموذج اللغوي (LLM) في خطوة التعزيز مهم جداً. كن واضحاً في تعليماتك: “أجب بناءً على السياق فقط”، “لا تخترع معلومات”، “إذا كانت الإجابة غير موجودة قل لا أعرف”.
  • فكر في ما بعد البحث (Re-ranking): أحياناً، البحث الأولي قد يأتي بقطع نصية غير دقيقة 100%. يمكنك إضافة خطوة تالية تسمى “إعادة الترتيب” (Re-ranking) حيث يقوم نموذج أصغر وأسرع بإعادة تقييم القطع المسترجعة واختيار الأفضل منها قبل إرسالها للنموذج الكبير.

الخلاصة: من الهلوسة إلى الثقة

تقنية RAG ليست مجرد حل تقني، بل هي نقلة نوعية في كيفية تفكيرنا وبنائنا للتطبيقات المعتمدة على الذكاء الاصطناعي. إنها تحول النماذج اللغوية من “عالم بكل شيء” قد يكذب أحياناً، إلى “باحث مجتهد” يتأكد من مصادره قبل أن يتكلم. وهذا بالضبط ما نحتاجه لبناء أنظمة ذكاء اصطناعي موثوقة وآمنة يمكننا الاعتماد عليها.

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

نصيحتي الأخيرة لكل مطور يعمل في هذا المجال: قبل أن تقع في “جحيم الهلوسة”، ابدأ بالبحث في RAG. قد تكون هي أبسط وأقوى أداة في ترسانتك لبناء الجيل القادم من التطبيقات الذكية. وكما يقول المثل الشعبي عندنا: “اللي بعرفش، بقول عدس”. مع RAG، نحن نضمن أن نماذجنا “تعرف” قبل أن تتكلم.

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

​معمارية البرمجيات

كان كودنا لا يفهم طبيعة عملنا: كيف أنقذنا ‘التصميم الموجه بالمجال’ (DDD) من جحيم ‘ماذا تفعل هذه الدالة؟’

كودنا كان يتحدث لغة لا يفهمها خبراء العمل، مما خلق فوضى عارمة. في هذه المقالة، أشارككم قصة كيف ساعدنا التصميم الموجه بالمجال (DDD) في بناء...

26 مايو، 2026 قراءة المزيد
خوارزميات

كانت دوالنا تعاني من فقدان الذاكرة: كيف أنقذتنا ‘البرمجة الديناميكية’ من جحيم إعادة الحسابات المتكررة؟

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

26 مايو، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

كان تطبيقنا جميلاً ولكن أعمى: كيف أنقذتنا ‘إمكانية الوصول’ من جحيم استبعاد 15% من المستخدمين؟

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

26 مايو، 2026 قراءة المزيد
الشبكات والـ APIs

كانت تطبيقاتنا تعتمد على التحديث اليدوي: كيف أنقذتنا WebSockets من جحيم ‘الاستقصاء المستمر’ (Polling)؟

مقالة تستعرض تجربة عملية في الانتقال من تقنية الاستقصاء المستمر (Polling) المرهقة إلى استخدام WebSockets لتطبيقات الوقت الحقيقي. اكتشف كيف يمكن لهذا التغيير أن يحسّن...

26 مايو، 2026 قراءة المزيد
الحوسبة السحابية

كانت خوادمنا تلتهم الميزانية وهي خاملة: كيف أنقذتنا الحوسبة بدون خوادم (Serverless) من جحيم الفواتير؟

أنا أبو عمر، مبرمج فلسطيني، وأروي لكم قصتي مع الفواتير السحابية المرتفعة وكيف كانت "الحوسبة بدون خوادم" أو Serverless هي طوق النجاة. اكتشفوا معي كيف...

26 مايو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

كان ملفي على GitHub مقبرة للمشاريع: كيف أنقذتني المصادر المفتوحة من جحيم “ليس لديك خبرة عملية”؟

هل ملفك على GitHub مليء بالمشاريع غير المكتملة؟ في هذه المقالة، أشارككم تجربتي الشخصية كأبو عمر، وكيف حولتني المساهمة في المصادر المفتوحة من مبرمج يواجه...

26 مايو، 2026 قراءة المزيد
التوسع والأداء العالي والأحمال

خدماتنا كانت تنتظر في طابور طويل: كيف أنقذتنا ‘طوابير الرسائل’ من جحيم ‘الرجاء الانتظار’؟

أشارككم قصة حقيقية من تجربتي كمبرمج، وكيف كاد مشروعنا أن يفشل بسبب بطء الاستجابة. اكتشفوا معنا كيف غيّرت "طوابير الرسائل" (Message Queues) طريقة عملنا، وحوّلت...

26 مايو، 2026 قراءة المزيد
البودكاست