انتقل إلى المحتوى الرئيسي

الوحدة 1 — لماذا نثبّت النموذج اللغوي في المستندات الخاصّة

انتهت الدورتان السابقتان إلى نموذج لغوي قوي يعرف الكثير عمّا يوجد على الشبكة، ويعرف قليلًا جدًّا عن مؤسّستك. تفتح هذه الدورة الفجوة القائمة بين المعرفة العامّة للنموذج والمعرفة المحلّية التي تحتاجها الإجابة الفعلية، وتُقدّم الحلّ العملي المهيمن اليوم: التوليد المعزَّز بالاسترجاع، أو RAG. الفيل الأحمر الذي سيرافقنا هو مساعد يجيب موظّفي مؤسّسة عن نحو ثلاثمئة مستند داخلي: لوائح، إجراءات جودة، مذكّرات إدارية.

المعرفة المُجمَّدة وحدود «ما يعرفه النموذج»

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

يمكن أن تسأله «ما مدّة عطلة الأمومة عند صاحب العمل الفلاني؟» فيعطيك جوابًا يبدو موزونًا مصاغًا بعناية، مأخوذًا من قانون بلد آخر، أو من إجراء اختفى منذ سنتين. تسمّى هذه الظاهرة الهلوسة: النموذج يُنتج نصًّا مقبولًا شكلًا خاطئًا مضمونًا، لأنّه مُدرَّب على إكمال الجمل بلغة معقولة لا على قول الحقيقة. وعلى مساعد مستندي، الهلوسة ليست إزعاجًا أكاديميًا، بل مصدر أخطاء تشغيلية حقيقية: موظّف يعمل بمعلومة مُخترَعة قد يُخالف إجراءً واجبًا.

RAG مقابل التخصيص مقابل السياق الطويل

أمام هذه الفجوة، ثلاثة حلول ممكنة، ويتعيّن الاختيار بينها بعقل بارد:

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

الخلط بين الأوّل والثالث شائع. فالتخصيص يُلقّن النموذج كيف يقول، لكنّه لا يعطيه ذاكرة قابلة للتفتيش؛ وسؤاله عن معلومة دقيقة سيولّد إجابة قد لا تكون في بيانات التدريب. أمّا RAG فيقلب المشكلة: قبل أن يجيب النموذج، نبحث نحن في المستندات عن المقاطع ذات الصلة، ثم نمرّرها له في التعليمة، فيبني إجابته منها.

أمّا السياق الطويل — أي إلحاق ثلاثمئة مستند دفعة واحدة في التعليمة — فيبدو حلًّا مغريًا، ولا يصمد للممارسة. تكلفة الاستدعاء تتناسب مع طول التعليمة، والدراسات تُظهر أنّ استرجاع معلومة صغيرة داخل سياق طويل جدًّا يفقد الدقّة تدريجيًا حتّى بالنسبة للنماذج التي تعلن سياقات هائلة.

الحجّة السرّية: البيانات لا تخرج من المؤسّسة

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

يقلب RAG المعادلة: البحث يتمّ داخل المؤسّسة، ولا يُرسَل إلى نموذج التوليد إلّا المقاطع الثلاثة أو الأربعة الضرورية للإجابة، مع إمكان تنقيتها من المعطيات الحسّاسة قبل الإرسال. وحين يكون النموذج نفسه مُستضافًا محلّيًا، لا تخرج البيانات من الشبكة قطّ. وهذه في الغالب الحجّة التي تحسم النقاش في المؤسّسات المُلزَمة بأنظمة حماية البيانات.

معمارية RAG في نظرة واحدة

يعمل نظام RAG على مرحلتين متمايزتين ينبغي عدم الخلط بينهما.

المرحلة الأولى — الفهرسة (offline): مرّة واحدة، ثم دوريًّا عند تعديل المستندات. تُقرأ الملفّات، ويُستخرج النصّ، ويُقطَّع إلى مقاطع بحجم مناسب، ويُحسَب لكلّ مقطع تضمين (شعاع عددي يمثّل معناه)، ثم يُخزَّن كلّ ذلك في قاعدة بيانات متّجهية.

المرحلة الثانية — الاستفسار (online): عند كلّ سؤال من المستخدم. يُحسَب تضمين السؤال، ويُستخرَج من الفهرس عدد قليل من المقاطع الأقرب دلاليًا، ثم تُبنى تعليمة تحوي السؤال والمقاطع، ويستدعى النموذج للإجابة.

# رسم مبسَّط لسلسلة RAG بعد الفهرسة
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
store = Chroma(persist_directory="./index", embedding_function=embeddings)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

question = "ما مدّة إشعار الاستقالة في اللائحة الداخلية؟"
passages = store.similarity_search(question, k=4)
context = "\n\n".join(p.page_content for p in passages)

prompt = f"""أجب اعتمادًا على المقاطع التالية فقط.
إن لم يكن الجواب فيها، قل «لا يوجد في المستندات».

المقاطع:
{context}

السؤال: {question}"""

answer = llm.invoke(prompt).content
print(answer)

هذه العشرون سطرًا هي المُخطَّط العامّ للدورة كلّها. ستُفصَّل كلّ جزئية في وحدة: الاستخراج (الوحدة 2)، التقطيع (3)، التضمينات والفهرس (4)، البحث (5)، إعادة الترتيب (6)، التعليمة النهائية والاستشهاد (7)، التقييم (8)، الكلفة (9)، ثم المشروع الكامل (10).

متى لا يكون RAG هو الجواب

الوفاء العلمي يفرض الاعتراف بحالات لا يُحسِن RAG علاجها. حين يكون السؤال عن حساب دقيق يستدعي وصف قواعد (احتساب ضريبة مع استثناءات كثيرة)، فقاعدة أعمال منظّمة أنفع من نصّ في مقطع. وحين تكون الأسلوبية هي المطلوبة (توليد نصّ يشبه أسلوب مؤسّستك دون معلومات معيَّنة)، فالتخصيص أولى. وحين تكون البيانات جدولية بحتة، فمحرّك SQL يعطي إجابات أدقّ.

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

قاعدة القرار في سطر

اسأل نفسك: هل الجواب مكتوب حرفيًّا في مستند لديك؟ إن كان نعم، فـRAG. وإن كان الجواب يتطلّب تركيبًا عبر عدّة مستندات، فـRAG مع إعادة ترتيب وتعليمة تُشجّع التركيب. وإن كان الجواب يتطلّب حسابًا منظّمًا، فقاعدة أعمال أو استعلام SQL، لا نموذج لغوي.

الخطأ الأشيع في البداية

عدم فصل الفهرسة عن الاستفسار في الشيفرة. حين يعيد المشروع فهرسة كلّ شيء عند كلّ سؤال، تصير كلّ استفسار بطيئًا ومكلفًا بلا سبب. الفهرس يُبنى مرّة، ثم يُقرأ من القرص عند كلّ استفسار.

في الخلاصة

  • النموذج اللغوي مُجمَّد عند تاريخ التدريب ويعرف القليل جدًّا عن مستنداتك الداخلية، ومن هنا الهلوسات.
  • التخصيص يُلقّن الأسلوب، والسياق الطويل مكلف وينهار مع الطول، أمّا RAG فيسترجع المقاطع الضرورية ثم يجيب.
  • الحجّة السرّية حاسمة: لا يخرج من المؤسّسة إلّا مقاطع قليلة منتقاة، لا الكتلة كلّها.
  • معمارية RAG على مرحلتين: فهرسة offline ثم استفسار online، ولا يُخلَط بينهما في الشيفرة.

الوحدة التالية: استخراج النصّ من ملفّات PDF وHTML ومستندات مكتبية، أي المرحلة الأولى في سلسلة الفهرسة، حيث يبدأ كلّ شيء وأكثر الأعطال تحدث.