الانتقال إلى المحتوى الرئيسي
التوليد المعزَّز بالاسترجاع، أو RAG، هو أحد أكثر الأنماط فائدةً لبناء تطبيقات الذكاء الاصطناعي التي تحتاج إلى الإجابة من مستنداتك الخاصة. فبدلًا من مطالبة نموذج بالاعتماد على الذاكرة وحدها، تسترجع أولًا المواد المصدرية ذات الصلة، وترسل ذلك السياق إلى النموذج، وتطلب منه الإجابة مع الاستشهاد بالمراجع. في هذا الدرس، سنبني روبوت RAG خاصًا باستخدام Python، و Venice للتضمينات وإكمال المحادثات، و Qdrant للبحث المتجهي، و FastEmbed لإعادة الترتيب محليًا. بنهاية الدرس، ستملك القطع الأساسية لمساعد مستندات محلي يستطيع استيعاب ملفاتك، واسترجاع المقاطع ذات الصلة، وإعادة ترتيبها، والإجابة مع الاستشهادات. روبوت RAG قيد العمل قبل المتابعة: إن أردت تشغيل الكود في هذه المقالة، ستحتاج إلى مفتاح Venice API. صدّره كمتغيّر بيئة:
هل تهتم بالتنفيذ الكامل للكود؟ راجع مستودع GitHub.

كيف يعمل روبوت RAG حديث

خط أنابيب RAG الجيد أكثر من مجرد «ضع المستندات في قاعدة بيانات متجهية». يبدو التدفق الأساسي هكذا: خطوة إعادة الترتيب هي الترقية التي تجعل هذا أكثر فائدةً من عرض RAG الأساسي. البحث المتجهي سريع وجيد في إيجاد المقاطع المتشابهة دلاليًا، لكنه قد يُرجع مقاطع قريبة من الموضوع بدلًا من أن تكون مفيدة مباشرة. أما cross-encoder فيقرأ السؤال وكل مقطع مرشح معًا، ثم يسجّل مدى إجابة ذلك المقطع للسؤال فعليًا.

تثبيت التبعيات

سنستخدم OpenAI Python SDK لأن Venice يكشف واجهة متوافقة مع OpenAI. وسنستخدم أيضًا عميل Qdrant بـ Python مع دعم FastEmbed:
إن فضّلت إبقاء التبعيات في ملف، أنشئ requirements.txt بنفس الحزم:

اختيار النماذج

أنشئ ملفًا باسم rag_bot.py، ثم ابدأ بإضافة الاستيرادات وهياكل البيانات ورابط API وأسماء النماذج:
اسم نموذج التضمين متوافق عمدًا مع OpenAI. يقوم Venice بربط أسماء نماذج التضمين المتوافقة بنماذج تضمين مستضافة على Venice، لذا يمكن لكود OpenAI SDK الحالي الانتقال عادةً بتغيير base_url ومفتاح API. يمكنك سرد نماذج Venice المتاحة بـ:
لنماذج المحادثة:

إنشاء عميلَي Venice و Qdrant

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

تحميل المستندات وتقسيمها

في هذا الدرس، سنسمح للروبوت باستيعاب ملفات أو مجلدات محلية. ابدأ بملفات .md و.rst و.txt:
بعد تحميل الملفات، نحتاج إلى تقسيم النص بـ«تجزئته» — تفريقه إلى أجزاء من البيانات. استراتيجية ساذجة قد تُقسّم الأجزاء بالتساوي. لكن في معظم الحالات، هذا قد يفقد معلومات عند حدود دلالية معيّنة مما قد يُقلّل فاعلية نظام RAG الخاص بك. استراتيجية التجزئة التي سنستخدمها تفضّل حدود الفقرة أو الجملة بحيث يحصل النموذج على سياق متماسك:
حجم تجزئة بدائي قدره 1000 حرف مع تداخل 150 حرف هو افتراضي جيد لمستندات Markdown ونصوص مختلطة. التجزئات الأصغر يمكن أن تحسّن الدقّة. التجزئات الأكبر يمكن أن تحافظ على سياق أكبر. الإعداد المناسب سيعتمد غالبًا على نوع المستندات التي تخزّنها.

تضمين المستندات باستخدام Venice

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

تخزين المتجهات في Qdrant

قبل إدراج النقاط، أنشئ مجموعة Qdrant بحجم متجه صحيح. أسهل طريقة لمعرفة حجم المتجه هي تضمين الدفعة الأولى ثم استخدام len(embeddings[0]).
كل نقطة تخزّن المتجه إضافة إلى بيانات وصفية. تتضمن الحمولة النص الأصلي ومسار المصدر بحيث تستطيع الإجابة الاستشهاد بمصدر السياق:
استخدم UUIDs محدّدة مشتقّة من source وchunk_index والمحتوى. هذا يجعل الاستيعاب المتكرّر متعاديًا (idempotent) للتجزئات التي لم تتغيّر.

استرجاع التجزئات المرشّحة

عند طرح السؤال، يضمّن الروبوت سؤال المستخدم ويسأل Qdrant عن أعلى المطابقات المتجهية:
limit هنا هو عدد المرشحين. ينبغي أن يكون أعلى من عدد التجزئات التي تنوي إرسالها إلى النموذج، لأن الخطوة التالية ستعيد ترتيبها. افتراضي جيّد هو استرجاع 8 مرشحين وإرسال أفضل 4 إلى نموذج المحادثة.

إعادة الترتيب باستخدام FastEmbed

الآن نضيف الجزء الذي يجعل الاسترجاع يبدو أذكى بكثير.
الفرق المهم بين البحث بالتضمين وإعادة ترتيب cross-encoder هو كيفية حدوث التسجيل. البحث بالتضمين يقارن متجهًا واحدًا للسؤال بمتجه واحد لكل تجزئة. وهو سريع وقابل للتوسّع. أما cross-encoder فيقيّم السؤال والتجزئة معًا. وهو أبطأ، لكنه يستطيع الحكم على الصلة بشكل أكثر مباشرة. لهذا فإن النمط المعتاد هو:
  1. استرجاع مجموعة أكبر من المرشحين بالبحث المتجهي.
  2. إعادة ترتيب أولئك المرشحين فقط محليًا.
  3. إرسال أعلى بضع تجزئات إلى نموذج اللغة.
نقطة بداية جيدة هي candidate_k=8 وtop_k=4. زِد candidate_k إذا كان المصدر الصحيح قريبًا غالبًا لكنه لا يصل إلى السياق النهائي.

الإجابة باستخدام إكمال محادثات Venice

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

تشغيل الروبوت

بعد أن تجمّع القطع في سكربت، احفظه باسم rag_bot.py. تشغيل أول بسيط يمكنه استخدام بعض المستندات النموذجية المدمجة كي تتحقّق من خط الأنابيب قبل استيعاب ملفاتك الخاصة:
لاستيعاب مستنداتك الخاصة:
للحفاظ على مجموعة Qdrant محلية على القرص وبدء محادثة تفاعلية:
يطبع السكربت الإجابة، ثم يطبع المصادر مع كل من درجة المتجه ودرجة إعادة الترتيب:
إن أردت فحص النص الفعلي المُمرّر إلى النموذج، أضف:

خيارات CLI مفيدة

اكشف مفاتيح الاسترجاع الرئيسية كخيارات CLI حتى تتمكن من ضبط الروبوت دون تعديل الكود: للتطوير المحلي المتكرّر، التدفق الشائع هو:
ثم اطرح أسئلة متابعة دون استيعاب مرة أخرى:

ملاحظات الخصوصية

لإعداد RAG خاص، فكّر في كل طبقة على حدة: أكثر الافتراضات خصوصيةً في هذا الدرس هي Venice للاستدلال، وQdrant محلي على القرص، وإعادة ترتيب FastEmbed محلية. هذا يمنحك روبوت RAG عمليًا دون إرسال حمولات قاعدة البيانات المتجهية إلى متجر متجهات تابع لطرف ثالث.

أخطاء شائعة ينبغي التعامل معها مبكرًا

إذا غيّرت نماذج التضمين، أعد إنشاء مجموعة Qdrant. قد تنتج نماذج التضمين المختلفة متجهات بأبعاد مختلفة، ومجموعات Qdrant تتوقع حجم متجه ثابتًا.

إلى أين تتجه بعد ذلك

بمجرد تشغيل خط الأساس، فإن أكثر التحسينات تأثيرًا تكون عادةً:
  • إضافة محمّلات خاصة بالمستندات لملفات PDF أو HTML أو التذاكر أو صفحات الويكي الداخلية.
  • تخزين بيانات وصفية أغنى مثل العناوين والترويسات والتواريخ والمالكين والروابط.
  • ضبط candidate_k وtop_k وحجم التجزئة والتداخل على أسئلة حقيقية.
  • إضافة أسئلة تقييم لتتمكن من قياس جودة الاسترجاع قبل التغييرات وبعدها.
  • بث إكمال محادثة Venice النهائي لتجربة محادثة تفاعلية أفضل.
أنظمة RAG سهلة العرض ومتوسطة الجودة بشكل مفاجئ. نمط البحث المتجهي مع إعادة الترتيب أساس قوي لأنه يبقي الاسترجاع سريعًا مع إعطاء الروبوت فرصة أفضل لإرسال السياق الصحيح إلى نموذج اللغة.