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

هذا الانفصال موجود لأن اختبار الأداء التقليدي صُمم لأنظمة "الطلب والاستجابة" (request-response)، وليس للأنظمة التي "تفكر". عندما ترسل ألف طلب متوازٍ إلى نقطة نهاية REST، فإنك تكتشف ما إذا كانت خوادمك ستصمد أم لا. لكنك لا تتعلم شيئًا عن ما إذا كانت طبقة الاسترجاع (retrieval layer) تجلب الأجزاء (chunks) الصحيحة، أو ما إذا كان قالب المطالبة (prompt template) يحافظ على السياق، أو ما إذا كان النموذج يبتكر مصادر عندما يكون مخزن المتجهات (vector store) فارغًا. يقيس اختبار الحمل القياسي السرعة، بينما تتطلب تطبيقات RAG منك قياس الفهم.

ما وراء رمز الحالة 200

يتحقق اختبار حمل API النموذجي من ثلاثة أشياء: التوافر (availability)، وزمن الاستجابة (latency)، والإنتاجية (throughput). فهو يسأل عما إذا كان الخادم قد أجاب، وكم استغرق الأمر، وكم عدد المستخدمين المتزامنين الذين صمد أمامهم. بالنسبة لتطبيق RAG، فإن هذه الأرقام هي متطلبات أساسية وليست نتائج نهائية. فالإجابة الخاطئة السريعة تظل إجابة خاطئة، والإجابات الخاطئة على نطاق واسع تكلفتها أكبر من الإجابات البطيئة.

تضيف RAG مرحلتين متميزتين لكل طلب. أولاً، يحول النظام سؤال المستخدم إلى تضمين (embedding)، ويستعلم من مخزن المتجهات (vector store)، ويسترجع مجموعة من أجزاء السياق (context chunks). ثانياً، يضع تلك الأجزاء في مطالبة (prompt)، ويرسل كل شيء إلى نموذج لغوي (language model)، ثم يبث النتيجة النهائية. غالبًا ما تدمج الاختبارات التقليدية هذه المراحل في مقياس واحد لـ "زمن الاستجابة". فهي تعامل محرك الاسترجاع والمولد (generator) كصندوق أسود واحد.

أنت بحاجة إلى فتح ذلك الصندوق. إذا تباطأ نظام قواعد بيانات المتجهات الخاص بك تحت الحمل، فسوف يرتفع زمن استجابة الاسترجاع. قد يظل نموذج LLM يستجيب بسرعة، لكنه يستجيب بناءً على سياق رديء (garbage context) تم جلبه على عجل. وبدلاً من ذلك، قد يظل البحث في المتجهات سريعًا بينما يتراكم طابور الـ LLM، مما يزيد من "زمن الوصول إلى أول رمز" (time-to-first-token) حتى يحدق المستخدمون في مؤشر الكتابة الوامض. إن مؤقتًا واحدًا من البداية إلى النهاية (end-to-end) يخفي كلا الفشلين.

اختبر الاسترجاع، وليس قاعدة البيانات فحسب

تقوم معظم الفرق بإجراء اختبار مرجعي سريع للبحث في المتجهات وتعتبر أن طبقة الاسترجاع قد تم اختبارها. يقيس هذا الاختبار المرجعي عادةً مدى سرعة قاعدة البيانات في إرجاع "أقرب الجيران" (nearest neighbors) لاستعلام مختار بعناية. ولكنه نادرًا ما يقيس ما إذا كان هؤلاء الجيران يحتويون بالفعل على الإجابة.

تتغير جودة الاسترجاع مع زيادة الحمل بطرق دقيقة. ففي ظل الضغط المتزامن، يمكن أن تتصرف فهارس "أقرب الجيران التقريبيين" (approximate nearest neighbor indexes) بشكل مختلف عما تفعله في حالة العزل. كما أن استراتيجيات تقسيم النصوص (chunking strategies) التي بدت مثالية في دفتر ملاحظات (notebook) تبدأ في تسريب السياق عبر الحدود عندما تتنافس عشرة آلاف وثيقة على نفس مساحة التضمين (embedding space). والاستعلام الذي يعيد الفقرة المثالية في بيئة هادئة قد يظهر شريحة تسويقية مضللة عندما يكون الفهرس قيد إعادة البناء أو عندما يتم تجريد تصفية البيانات الوصفية (metadata) تحت ضغط الطلبات.

لاختبار ذلك بشكل صحيح، تحتاج إلى مجموعة بيانات "الحقيقة الأرضية" (ground-truth dataset). قم بإعداد أسئلة تعرف مسبقًا الوثائق المصدرية التي يجب أن تظهر للإجابة عليها. قم بتشغيل هذه الأسئلة بمستويات تزامنية متفاوتة وتحقق مما إذا كانت الأجزاء المتوقعة تظهر ضمن نتائج "top-k". تتبع معدل الإصابة (hit rate)، وليس فقط مدة الاستعلام. إذا كانت أفضل خمسة أجزاء لديك تفتقد المصدر الحاسم تمامًا، فقد فشل خط أنابيب الاسترجاع الخاص بك حتى قبل أن يستيقظ نموذج LLM.

يجب عليك أيضًا إجراء اختبار جهد (stress-test) للحالات الحدية. أرسل استعلامات ليس لها إجابة في المتن (corpus). أرسل أسئلة غامضة يمكن أن تنطبق على مجالات متعددة. أرسل أسئلة طويلة تتجاوز حد الرموز (token limit) لنموذج التضمين الخاص بك ويتم بترها بصمت. راقب ما تعيده طبقة الاسترجاع. في كل حالة، يهم نمط الفشل (failure mode) أكثر من عدد الملي ثانية المنقضية.

عندما يختنق النموذج بصمت

بمجرد وصول الأجزاء إلى نموذج LLM، يستمر اختبار الحمل القياسي في الكذب