لقد قمت ببناء RAG من الصفر باستخدام Python لفهمه
استخدمت LangChain في بيئة الإنتاج لمدة ستة أشهر، لكنني لم أستطع شرح كيفية عملها. لم أكن أعرف لماذا اخترت مقاييس معينة أو كيف تحول النص إلى متجهات (vectors). لقد كانت المكتبة تخفي المنطق البرمجي.
ولإصلاح ذلك، قمت بحذف الإطار البرمجي (framework). وكتبت خط أنابيب (pipeline) لـ RAG من الصفر باستخدام 500 سطر من لغة Python البسيطة.
إليكم ما تعلمته من بناء هذه البنية (stack) يدويًا.
المشكلة في الصناديق السوداء (Black Boxes)
عندما تستخدم مكتبات عالية المستوى، فإنك تفقد السيطرة. لقد رأيت نماذج تهلوس بالحقائق أو تقدم استشهادات خاطئة. لم أكن أستطيع تحديد ما إذا كان الخطأ يكمن في الـ chunker، أو نموذج الـ embedding، أو الـ prompt.
عندما تبنيه بنفسك، تصبح كل طبقة قابلة للفحص. يمكنك طباعة الـ chunks الدقيقة المرسلة إلى الـ LLM، ويمكنك رؤية المكان الذي تنكسر فيه الجملة بالضبط.
الطبقات الخمس لـ RAG
RAG ليس خوارزمية واحدة، بل هو خمس عمليات مختلفة مكدسة معًا:
- Chunking: تحديد كيفية تقسيم النص.
- Embedding: تحويل النص إلى رياضيات.
- Retrieval: العثور على الأجزاء الصحيحة.
- Prompt Construction: إخبار النموذج بكيفية التصرف.
- Generation: الحصول على الإجابة النهائية.
دروس من عملية البناء
الـ Chunking هو الخطوة الأهم معظم الشروحات تتجاهل هذا الأمر. إذا لم تستخدم التداخل (overlap)، فستفقد السياق عند الحدود. لقد استخدمت نافذة منزلقة (sliding window) مع تداخل على مستوى الحروف، مما يضمن رؤية النموذج للارتباط بين قطعتين (chunks).
مقاييس المسافة (Distance metrics) مهمة قضيت ساعات في تصحيح نتائج البحث السيئة. لم تكن المشكلة في البيانات، بل في المقياس. يعتمد ChromaDB افتراضيًا على مسافة L2، ولكن للبحث الدلالي (semantic search)، تحتاج إلى Cosine similarity. سطر واحد من الكود غير كل شيء.
الـ Prompts تحتاج إلى قيود الـ LLM هو أداة لإكمال النصوص وليس عرافًا. إذا طرحت سؤالًا غامضًا، فسيخترع إجابة. تعلمت استخدام قالب رفض صارم، حيث قلت للنموذج: "إذا لم يتضمن السياق الإجابة، فقل إنك لا تعرف". أدى ذلك إلى خفض الهلوسة من 40% إلى 5%.
قم بمعالجة الطلبات في دفعات (Batching) إرسال طلب HTTP واحد لكل chunk هو أمر بطيء، بينما إرسالها في دفعات أسرع بكثير، حيث يسمح للنموذج المحلي بتنظيم العمل في خطوط أنابيب (pipeline).
اختبر من الأسفل إلى الأعلى لا تكتب الاختبارات في النهاية. اختبر الـ chunker أولاً، ثم اختبر الـ embedder، ثم اختبر المخزن (store). إذا اختبرت في النهاية، فستقوم باختبار الأخطاء (bugs) بدلاً من اختبار المنطق.
إذا كنت تشعر أنك لا تفهم بنية الذكاء الاصطناعي (AI stack) الخاصة بك حقًا، فقم ببنائها بنفسك. الكود ليس هو الهدف، بل التفكير هو الهدف.
مجتمع تعليمي اختياري: https://t.me/GyaanSetuAi
