السلام عليكم يا جماعة، معكم أخوكم أبو عمر.
قبل كم شهر، كنا شغالين على مشروع لشركة محاماة كبيرة. الفكرة كانت بناء مساعد ذكي (Chatbot) يساعد المحامين الجدد في البحث السريع داخل أرشيف ضخم من القضايا والتشريعات الداخلية للشركة. الحماس كان في السحاب، والعميل كان شايف فينا الأمل لرقمنة جزء كبير من عملهم. جبنا أقوى نموذج لغوي كبير (LLM) وقتها، ودربناه على أسلوب الحوار القانوني، والأمور كانت تبشر بالخير.
في يوم العرض التقديمي الأولي، الأمور كانت ماشية زي الحلاوة. النموذج كان بجاوب على أسئلة عامة بطلاقة مذهلة. لكن الكارثة حصلت لما واحد من المحامين الكبار سأل سؤال محدد جداً: “ما هي السابقة القضائية المتبعة في الشركة بخصوص قضايا الملكية الفكرية التي تم رفعها في آخر 6 أشهر؟”
صمت للحظات… ثم بدأ المساعد الذكي بالإجابة بثقة مطلقة، مستشهداً بقضايا وأرقام وتواريخ… المشكلة؟ كل المعلومات كانت “من كيسه”. كانت هلوسة كاملة الأركان. النموذج اخترع قضايا وهمية وأعطاها أسماء محامين من الشركة لتبدو حقيقية. شعرت وقتها كأنه الأرض انشقت وبلعتني. يا فضيحتي قدام الناس! موقف لا أحسد عليه.
هذه الحادثة، رغم إحراجها، كانت نقطة تحول. كانت الصرخة التي جعلتنا ندرك أن الاعتماد على ذاكرة النموذج اللغوي المدربة مسبقاً هو وصفة لكارثة في التطبيقات الجادة. ومن هنا، بدأت رحلتنا الحقيقية مع تقنية غيرت قواعد اللعبة: الاسترجاع المعزز للتوليد (Retrieval-Augmented Generation) أو RAG. وفي هذه المقالة، سأحكي لكم كيف أنقذتنا هذه التقنية، وكيف يمكنكم استخدامها لترويض نماذجكم اللغوية.
ما هي “هلوسة” الذكاء الاصطناعي؟ وليش بتصير؟
قبل ما نغوص في الحل، خلينا نفهم المشكلة من جذورها. “الهلوسة” (Hallucination) مصطلح بنستخدمه لوصف ميل النماذج اللغوية الكبيرة (LLMs) لاختراع معلومات وتقديمها كحقائق مؤكدة. هي لا تكذب عن قصد، لأنها أصلاً لا “تفهم” أو “تعي” ما تقوله.
الفكرة ببساطة أن هذه النماذج هي محركات تنبؤ بالكلمات على مستوى خارق. تم تدريبها على كميات هائلة من نصوص الإنترنت (مثل ويكيبيديا، الكتب، المقالات). هي تعلمت الأنماط اللغوية والعلاقات بين الكلمات. لما تسألها سؤال، هي لا “تبحث” عن إجابة في ذاكرتها، بل تقوم بتوليد سلسلة من الكلمات التي تبدو “إحصائياً” هي الإجابة الأكثر احتمالاً بناءً على تدريبها.
المشكلة تكمن في نقطتين رئيسيتين:
- المعرفة المقطوعة (Knowledge Cutoff): تدريب النموذج يتوقف عند تاريخ معين. أي معلومة جديدة بعد هذا التاريخ، هو لا يعرف عنها شيئاً.
- المعرفة الخاصة (Private Data): النموذج لا يعرف أي شيء عن بيانات شركتك الداخلية، ملفاتك الشخصية، أو أي قاعدة بيانات خاصة لم تكن جزءاً من بيانات تدريبه العامة.
لما تسأله عن شيء لا يعرفه (مثل بيانات شركتك الحديثة)، هو يحاول “يرضيك” ويولد إجابة تبدو منطقية لغوياً، حتى لو كانت خاطئة تماماً من ناحية المحتوى. وهذا بالضبط ما حدث معنا.
محاولاتنا الأولى: “تلقيم” النموذج وحربنا مع السياق المحدود
في البداية، حاولنا حل المشكلة بالطرق التقليدية التي يعرفها الكثيرون في مجال هندسة الموجهات (Prompt Engineering).
الهندسة الفورية (Prompt Engineering): حل مؤقت ومحدود
أول فكرة خطرت ببالنا: “ليش ما نعطي النموذج المعلومات اللي بحتاجها داخل السؤال نفسه؟”. حاولنا نلصق أجزاء من مستندات الشركة في الموجه (Prompt) قبل السؤال. هذا الأسلوب نجح مع كميات صغيرة جداً من المعلومات. لكنه فشل فشلاً ذريعاً لسببين:
- نافذة السياق المحدودة (Limited Context Window): كل نموذج لغوي له حد أقصى من الكلمات (Tokens) التي يمكنه معالجتها في المرة الواحدة. أرشيف شركة المحاماة كان يحتوي على آلاف المستندات. كان من المستحيل وضع كل هذه المعلومات في موجه واحد.
- عدم الفعالية: حتى لو استطعنا وضع مستند كامل، كيف سيعرف النموذج أي فقرة بالضبط تحتوي على الإجابة؟ كنا كمن يرمي كتاباً كاملاً في وجه طالب ويطلب منه إيجاد جملة معينة.
إعادة التدريب (Fine-Tuning): مكلف وغير عملي
الفكرة الثانية كانت: “خلينا نعمل Fine-Tuning للنموذج على بيانات الشركة”. إعادة التدريب تعني أخذ نموذج مدرب مسبقاً وتدريبه مرة أخرى على مجموعة بيانات صغيرة ومتخصصة لتعليمه أسلوباً أو معرفة جديدة.
هذا الخيار أيضاً كان غير عملي لأسباب جوهرية:
- التكلفة والوقت: عملية الـ Fine-Tuning مكلفة حسابياً وتحتاج لوقت طويل وخبرة تقنية عالية.
- مشكلة البيانات الجديدة: ماذا لو أضافت الشركة قضايا جديدة غداً؟ هل سنقوم بإعادة تدريب النموذج كل يوم؟ هذا مستحيل. إعادة التدريب لا تحل مشكلة المعرفة الآنية (Real-time knowledge).
هنا وصلنا إلى حائط مسدود. كنا بحاجة لطريقة تجعل النموذج يصل إلى المعرفة الصحيحة، في الوقت المناسب، دون الحاجة لتغيير النموذج نفسه. كنا بحاجة لـ RAG.
المنقذ وصل: ‘الاسترجاع المعزز للتوليد’ (RAG) – كيف يعمل؟
تخيل أن النموذج اللغوي طالب ذكي جداً ولكنه دخل الامتحان معتمداً على ذاكرته فقط. أما RAG، فهو كأنك سمحت لنفس الطالب بإدخال “كتاب مفتوح” (Open Book) معه إلى قاعة الامتحان. قبل أن يجيب على أي سؤال، يمكنه البحث في الكتاب للعثور على المعلومة الدقيقة ثم صياغة الإجابة بأسلوبه الذكي. هذا هو جوهر RAG.
تقنية RAG تقسم العملية إلى مرحلتين رئيسيتين: الفهرسة (Indexing) والاسترجاع والتوليد (Retrieval & Generation).
المرحلة الأولى: الفهرسة (Indexing) – تجهيز “المكتبة”
هذه هي المرحلة التحضيرية، حيث نقوم ببناء قاعدة المعرفة التي سيعتمد عليها النموذج. تتم هذه العملية مرة واحدة في البداية، ويمكن تحديثها كلما أضيفت بيانات جديدة. تشمل الخطوات التالية:
- تحميل المستندات (Loading): نقوم بسحب جميع مصادر البيانات الخاصة بنا. يمكن أن تكون ملفات PDF، صفحات ويب، ملفات نصية، أو حتى بيانات من قاعدة بيانات.
- التقسيم (Chunking): نقوم بتقسيم المستندات الكبيرة إلى “قطع” (Chunks) أصغر. هذه الخطوة حيوية جداً. إذا كانت القطع صغيرة جداً، قد تفقد السياق. وإذا كانت كبيرة جداً، قد تحتوي على معلومات غير ضرورية وتكون أقل دقة في البحث.
- التضمين (Embedding): هنا يحدث السحر الحقيقي. نستخدم نموذج تضمين (Embedding Model) لتحويل كل “قطعة” نصية إلى متجه رياضي (Vector)، وهو عبارة عن قائمة طويلة من الأرقام. الفكرة هي أن النصوص ذات المعاني المتقاربة سيكون لها متجهات متقاربة في الفضاء الرياضي.
- التخزين (Storing): نقوم بتخزين هذه المتجهات النصية في قاعدة بيانات متخصصة تسمى “قاعدة بيانات المتجهات” (Vector Database) مثل Pinecone, ChromaDB, أو FAISS. هذه القاعدة مفهرسة بطريقة تسمح بالبحث السريع جداً عن المتجهات المتقاربة.
الآن، أصبحت “مكتبتنا” جاهزة ومفهرسة وجاهزة للاستعلام.
المرحلة الثانية: الاسترجاع والتوليد (Retrieval & Generation) – وقت الإجابة
هذه هي المرحلة التي تحدث في كل مرة يسأل فيها المستخدم سؤالاً. وهي عملية سريعة جداً:
- استعلام المستخدم (User Query): المستخدم يكتب سؤاله، مثلاً: “ما هي السابقة القضائية بخصوص الملكية الفكرية في آخر 6 أشهر؟”
- تضمين الاستعلام (Query Embedding): نأخذ سؤال المستخدم ونقوم بتحويله هو أيضاً إلى متجه رياضي باستخدام نفس نموذج التضمين الذي استخدمناه في مرحلة الفهرسة.
- البحث عن المتشابه (Vector Search): نقوم بالبحث في قاعدة بيانات المتجهات عن “القطع” النصية التي متجهاتُها هي الأقرب رياضياً لمتجه السؤال (عادة باستخدام مقياس مثل “تشابه جيب التمام” أو Cosine Similarity). هذا يعطينا أكثر أجزاء المستندات صلة بالسؤال.
- تعزيز الموجه (Augmenting the Prompt): الآن، نقوم ببناء موجه جديد للنموذج اللغوي الكبير. هذا الموجه يحتوي على شيئين: السياق المسترجع (القطع النصية التي وجدناها) + سؤال المستخدم الأصلي. قد يبدو الموجه هكذا:
"استناداً إلى السياق التالي: [نص القطعة 1] [نص القطعة 2]... أجب على السؤال التالي: ما هي السابقة القضائية بخصوص الملكية الفكرية في آخر 6 أشهر؟ إذا كانت الإجابة غير موجودة في السياق، قل أنك لا تعرف." - توليد الإجابة (Generation): نرسل هذا الموجه “المعزز” إلى النموذج اللغوي. الآن، بدلاً من أن يهلوس، سيقوم النموذج بصياغة إجابة دقيقة تستند *حصرياً* على المعلومات التي قدمناها له في السياق.
وبهذه الطريقة، نجبر النموذج على الالتزام بالحقائق الموجودة في بياناتنا، ونقضي على الهلوسة من جذورها.
نصيحة من أبو عمر: اختيار حجم القطعة (Chunk Size) والتداخل بينها (Overlap) هو فن وعلم. ابدأ بحجم 1000 حرف مع تداخل 100 حرف كنقطة انطلاق جيدة، ثم قم بالتجربة. للمستندات القانونية أو التقنية، قد تحتاج لقطع أصغر وأكثر دقة. أما للنصوص السردية، فالقطع الأكبر قد تكون أفضل للحفاظ على السياق.
مثال عملي بسيط باستخدام LangChain
حتى تكون الصورة أوضح، إليكم مثال بسيط جداً بلغة بايثون وباستخدام مكتبة LangChain الشهيرة التي تسهل بناء أنظمة RAG.
# أولاً، نقوم بتثبيت المكتبات اللازمة
# pip install langchain openai chromadb tiktoken
import os
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
# ضع مفتاح OpenAI API الخاص بك هنا
os.environ["OPENAI_API_KEY"] = "sk-..."
# 1. مرحلة الفهرسة (Indexing)
# -------------------------
# لنفترض أن هذا هو محتوى مستند داخلي في شركتنا
document_text = """
سياسة العمل عن بعد في شركة 'تقنية المستقبل'
تاريخ التحديث: 1 أغسطس 2023
تسمح الشركة للموظفين في قسمي الهندسة والتسويق بالعمل عن بعد لمدة يومين في الأسبوع (الاثنين والخميس).
يجب على الموظفين التواجد في المكتب في أيام الثلاثاء والأربعاء.
قسم الموارد البشرية والإدارة يتطلب الحضور الكامل في المكتب.
للحصول على استثناء، يجب تقديم طلب رسمي للمدير المباشر.
"""
# 2. التقسيم (Chunking)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
texts = text_splitter.split_text(document_text)
# 3. التضمين والتخزين (Embedding & Storing)
# سنستخدم تضمينات OpenAI وقاعدة بيانات ChromaDB (التي تعمل في الذاكرة هنا)
embeddings = OpenAIEmbeddings()
vector_store = Chroma.from_texts(texts, embeddings)
# الآن قاعدة المعرفة جاهزة للاستعلام
# --------------------------------------
# 2. مرحلة الاسترجاع والتوليد (Retrieval & Generation)
# ----------------------------------------------------
# إعداد سلسلة RAG. هذه السلسلة تربط كل الخطوات معًا
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0),
chain_type="stuff", # "stuff" تعني وضع كل القطع المسترجعة في السياق
retriever=vector_store.as_retriever()
)
# لنطرح الآن أسئلة على نظامنا
question1 = "كم عدد أيام العمل عن بعد المسموحة للمهندسين؟"
answer1 = qa_chain.run(question1)
print(f"سؤال 1: {question1}")
print(f"إجابة: {answer1}n")
# الإجابة المتوقعة ستكون دقيقة ومبنية على النص
question2 = "هل يستطيع موظف الموارد البشرية العمل من المنزل؟"
answer2 = qa_chain.run(question2)
print(f"سؤال 2: {question2}")
print(f"إجابة: {answer2}n")
# الإجابة المتوقعة ستكون دقيقة وتوضح أن هذا القسم يتطلب الحضور الكامل
question3 = "ما هي سياسة الإجازات السنوية؟"
answer3 = qa_chain.run(question3)
print(f"سؤال 3: {question3}")
print(f"إجابة: {answer3}")
# هنا، لأن المعلومة غير موجودة، سيجيب النموذج بما يفيد أنه لا يعرف
هذا الكود يوضح الفكرة الأساسية. في التطبيقات الحقيقية، ستكون المستندات أكثر تعقيداً، وسنستخدم قواعد بيانات متجهات أكثر قوة، لكن المبدأ يبقى نفسه.
نصيحة من أبو عمر: لا تثق بالإجابة العمياء. في تطبيقات RAG المتقدمة، من المفيد جداً أن تعرض للمستخدم المصادر (القطع النصية) التي اعتمد عليها النموذج لتوليد إجابته. هذا يبني الثقة ويسمح بالتحقق البشري السريع. مكتبات مثل LangChain تدعم إرجاع المصادر (return_source_documents=True).
الخلاصة: RAG ليس سحراً، ولكنه علم وهندسة ذكية 🧠
خلاصة الحكي يا جماعة، تقنية RAG هي الجسر الذي يربط بين القدرة اللغوية الهائلة للنماذج اللغوية الكبيرة وبين عالم الحقائق والبيانات المتغيرة والخاصة. هي لا تستبدل النموذج، بل تزوده بالأدوات الصحيحة ليقوم بعمله على أكمل وجه.
بالنسبة لمشروعنا مع شركة المحاماة، بعد تطبيقنا لنظام RAG، تحول المساعد الذكي من مصدر إحراج إلى أداة لا تقدر بثمن. أصبح المحامون يثقون بإجاباته لأنه يقدم لهم المعلومة الدقيقة مع رابط مباشر للمستند الأصلي الذي استقى منه المعلومة.
عالم الذكاء الاصطناعي يتغير بسرعة، والهلوسة كانت من أكبر التحديات التي واجهت تبني هذه التقنيات في بيئات العمل الجادة. RAG يقدم حلاً عملياً وأنيقاً لهذه المشكلة. لا تخافوا من “هلوسة” النماذج، بل تعلموا كيف تروضونها وتجعلونها تعمل لصالحكم.
ابدأوا اليوم، جربوا بناء نظام RAG بسيط. خذوا أي مستند لديكم، طبقوا الخطوات، وشاهدوا الفرق بأنفسكم. هذه المهارة أصبحت أساسية لكل مطور يعمل في مجال الذكاء الاصطناعي التوليدي. بالتوفيق!