OpenOCR يرصد الآن النتائج الفارغة من Gemini 3.1 Flash-Lite ومن أي محرك يليه
8 أكتوبر 2026. بات OpenOCR يرصد الآن الحالات التي يقرأ فيها المحرك صفحتك ولا يُرجع أي نص. ستحصل على رسالة خطأ واضحة تبيّن السبب بدلاً من نتيجة فارغة تبدو وكأنها عملية ناجحة. ولن تدفع أبدًا أكثر مما فرضه المزود مقابل المحاولة، كما يتم الاحتفاظ بكل صفحة تمت قراءتها بنجاح في ملفات PDF متعددة الصفحات.
بدأ هذا النمط مع Gemini 3.1 Flash-Lite، غير أن هذه الحماية تسري على كافة المحركات في OpenOCR.
ما رصدناه
أظهرت أنظمة المراقبة لدينا نمطًا متكررًا في نموذج Gemini 3.1 Flash-Lite من Google، وهو أحد أكثر المحركات استخدامًا على OpenOCR. ففي نسبة ضئيلة من المستندات الفعلية (نماذج وبطاقات ورسائل تحتوي على نصوص مطبوعة واضحة)، لم يُرجع النموذج أي نص على الإطلاق، في حين أبلغت واجهة برمجة تطبيقات Google (API) عن نجاح الطلب. وخلال الأيام الثلاثين الماضية، حدث ذلك في نحو 3 بالمئة من صفحات Flash-Lite، ومثّل ذلك ما يقارب جميع النتائج الفارغة التي شهدناها عبر المنصة بالكامل: نحو 97 بالمئة.
من السهل التغاضي عن نسبة ثلاثة بالمئة في عدد قليل من الطلبات، ولكن عند معالجة المستندات على نطاق واسع، فهذا يعني أن سير العمل قد يتلقى كميات وافرة من النصوص الجيدة مع فقدان صفحات كاملة قابلة للقراءة — وهو تحدٍ تتضاعف حساسيته مع خصوصية الخط العربي ذي الطبيعة المتصلة والاتجاه من اليمين إلى اليسار وتعدد أشكال الحروف والتراكيب والتشكيل التي تزيد بطبيعتها من صعوبة التعرف الضوئي (OCR)؛ إذ جعلت إشارة النجاح الصادرة من المزود تلك الصفحات المفقودة تبدو كأنها مهام اكتملت بنجاح.
لم تكن إعادة المحاولة مجدية كثيرًا؛ إذ كانت الصورة نفسها تعود فارغة بنسبة تتراوح بين 80 و93 بالمئة من الحالات، مما جعل تكرار الطلب هدرًا للوقت في الغالب.
وفي حالات الرفض المصحوبة بسبب معلن، تكون الخطوة التالية هي التبديل إلى محرك آخر.
كيف تبدو الاستجابة الآن
قبل هذا التغيير، كان من الممكن لصفحة قابلة للقراءة أن تُنتج مهمة ناجحة دون استخراج أي نص. إليك مثالاً مختصرًا يوضح الحقول ذات الصلة:
{
"status": "succeeded",
"extracted_text": ""
}
أصبح رفض المزود الآن صريحًا. إليك مثالاً مختصرًا فرضت فيه Google علينا تكلفة المحاولة، وبالتالي يتحمل الطلب تلك التكلفة دون أي زيادة:
{
"status": "failed_charged",
"error_code": "provider_refused",
"cost_debited": 0.000327,
"provider_error": "Google declined to read this image (reason: SAFETY). Sending it to this engine again will give the same result; try a different engine."
}
لم تعد المهمة تدعي تسليم نص OCR صالح للاستخدام. وتتبع الفوترة التكلفة الفعلية للمزود كما هو موضح أدناه.
صُمم لكافة المحركات، وليس لمحرك واحد فقط
كان Gemini هو المحرك الذي رصدنا فيه هذه المشكلة، لكن هذا الخلل ليس حكرًا على Google بأي حال. فأي نموذج بصري (vision model) معرض لحدوث ذلك، وقد أظهرت محركات أخرى هذه الظاهرة في أوقات متفرقة. لذا، بدلاً من معالجة محرك واحد فقط، قمنا بتغيير طريقة تعامل OpenOCR مع الإجابات الفارغة الواردة من أي محرك:
إجابة واضحة بدلاً من نتيجة فارغة. يتم الإبلاغ عن النتيجة الفارغة كحالة فشل مصحوبة بأحد رمزين:
provider_refused: رفض المزود الطلب وأوضح السبب، مثل فلتر الأمان (safety filter). وتحدد رسالة الخطأ السبب وتنبهك إلى أن إرسال الصفحة إلى المحرك نفسه مجددًا سيعطي النتيجة ذاتها.provider_empty: لم يُرجع النموذج أي نص ولم يذكر سببًا. يقوم OpenOCR بقراءة الصفحة تلقائيًا مرة أخرى قبل الإبلاغ عن الفشل.
تتيح هذه الرموز لتطبيقك التمييز بين الرفض المعروف والنتيجة الفارغة غير المفسرة؛ حيث يقوم OpenOCR بمحاولة إضافية في الحالة الأخيرة قبل إرجاع الخطأ.
فوترة عادلة. إذا فرض المزود علينا تكلفة المحاولة، فإنك تدفع تلك التكلفة بالتحديد دون أي هامش ربح إضافي ولن تدفع أبدًا أكثر من السعر التقديري المحدد لك (quote). وإذا لم يفرض المزود تكلفة، فلن تدفع شيئًا. وهذا يماثل تمامًا استدعاء المزود مباشرة.
ملفات PDF تحتفظ بصفحاتها الناجحة. إذا عادت صفحة واحدة فارغة من أصل ملف PDF مكوّن من 30 صفحة، فستظل تحصل على الصفحات الـ 29 الأخرى، مع وضع علامة على الصفحة الفارغة برقمها. ولا يُعد المستند فاشلاً بالكامل إلا إذا لم تُرجع أي صفحة منه أي نص.
افترض إرسال مستند ممسوح ضوئيًا مكوّن من 30 صفحة إلى Flash-Lite؛ عادت الصفحات من 1 إلى 11 بنصوص، وعادت الصفحة 12 فارغة، ثم عادت الصفحات من 13 إلى 30 بنصوص. يُرجع OpenOCR الصفحات الـ 29 الناجحة مع تحذير يحدد الصفحة 12 بالاسم. يمكنك حينها إرسال تلك الصفحة إلى محرك آخر أو فحصها يدويًا، مع ضمان عدم تجاوز الرسوم للسعر التقديري إطلاقًا.
مراقبة مستمرة لكافة المحركات. نتتبع الآن معدل النتائج الفارغة لكل محرك باستمرار، حتى نتمكن من رصد أي نموذج آخر يبدأ بهذا السلوك في غضون ساعة واحدة.
Gemini يوضح أسباب الرفض الآن
يعمل Gemini 3.1 Flash-Lite الآن عبر واجهة برمجة التطبيقات الأصلية (native API) من Google. وكانت نقطة النهاية (endpoint) التي استخدمناها سابقًا تبلغ عن حالات الرفض هذه تحت مسمى "أخرى" ("other") فقط. أما واجهة برمجة التطبيقات الأصلية فتوضح سبب رفض الصفحة، ويصلك هذا السبب الآن ضمن رسالة الخطأ.
كما تتوقف الطلبات العالقة بعد 60 ثانية بدلاً من ثلاث دقائق، مما يتيح لك التبديل إلى محركات أخرى بشكل أسرع. يبلغ زمن الاستجابة المعتاد لنموذج Flash-Lite نحو 3.6 ثوانٍ، ويصل المئين 99 (99th percentile) إلى نحو 12 ثانية. وكانت مهلة الانتظار البالغة 180 ثانية تحتجز الطلبات العالقة لفترة أطول بكثير من الأوقات المرصودة، بينما يتيح تحديدها بـ 60 ثانية هامشًا كافيًا يتجاوز النطاق المعتاد.
كيف نراقب هذا الأمر الآن
نتتبع معدل النتائج الفارغة لكل محرك كل ساعة، وننبه الفريق عندما يصل المعدل إلى 5 بالمئة. فقد يظل معدل النجاح الإجمالي للمنصة سليمًا ومستقرًا بينما يُرجع أحد النماذج إجابات فارغة؛ لذا توضح لنا هذه المؤشرات المخصصة لكل محرك موضع الخلل بدقة للتحقيق فيه.
للمطورين
لن يتعطل أي شيء في تكاملك البرمجي؛ فكل ما في الأمر أنك لن تتلقى بعد الآن نتائج فارغة تبدو كناجحة. وإذا كنت تعيد محاولة الطلبات الفاشلة، فتحقق من رمز الخطأ: قم بتوجيه الصفحة التي تحمل الرمز provider_refused إلى محرك مختلف بدلاً من تكرار الطلب على المحرك نفسه. ومع وجود عشرات المحركات خلف مفتاح API واحد ورصيد موحد في OpenOCR، فإن ذلك لا يتطلب سوى تعديل كلمة واحدة في حقل engine.
بالنسبة لملفات PDF، احتفظ بتحذير الصفحة إلى جانب النص المُرجع لتتمكن من تحديد موضع النقص واتخاذ القرار المناسب بشأن تلك الصفحة.
أسئلة قد تراودك
هل سيتعطل تكاملي البرمجي؟ لا. فلن تظهر الصفحة الخالية من النصوص المستخرجة كنتيجة OCR ناجحة بعد الآن. وإذا كانت تعليماتك البرمجية تعيد محاولة كل فشل، فاستخدم error_code لتجنب تكرار طلب provider_refused على المحرك نفسه.
هل أدفع مقابل الصفحات المرفوضة؟ فقط بالقدر الذي فرضه المزود على OpenOCR مقابل تلك المحاولة. ستدفع تلك التكلفة بالضبط، دون أي زيادة ولن تتجاوز السعر التقديري (quote) أبدًا. وإذا لم يفرض المزود رسومًا علينا، فلن تدفع أي شيء.
لماذا لا يتم التبديل تلقائيًا بين المحركات؟ لأنك اخترت هذا النموذج عن قصد؛ وقد يكون لمحرك آخر تسعير مختلف أو مخرجات مختلفة. نحن نوضح لك ما حدث ونترك لك اتخاذ القرار.
ما هي المحركات المتأثرة؟ رصدنا هذا النمط بشكل أساسي في Gemini 3.1 Flash-Lite، والذي شكّل نحو 97 بالمئة من النتائج الفارغة على المنصة خلال الأيام الثلاثين الماضية. كما أظهرت بضعة محركات أخرى هذا السلوك بين الحين والآخر. وتشمل آليات الرصد والإبلاغ الآن جميع المحركات بلا استثناء.
ماذا عليّ أن أفعل مع الصفحات الفاصلة الفارغة؟ تعامل مع الفواصل المعروفة كجزء من سير عمل المستندات لديك. وبالنسبة للأوراق الفارغة أو الجوانب الخلفية للمسح الضوئي، استخدم محرك OCR مخصصًا لتلك الصفحات. كما نقوم أيضًا باختبار الحالات التي تختلق فيها النماذج البصرية نصوصًا عليها.
الخطوة التالية: قياس النصوص المختلقة
أثناء اختبار هذا الإصدار، قمنا بتزويد Gemini 3.1 Flash-Lite بصفحة بيضاء فارغة تمامًا. ولم تكن النتيجة فارغة؛ بل اختلق النموذج نصوصًا في المرات الأربع جميعها: فقرة عن الأعمال، وبرهانًا رياضيًا، ورسالة من عميل، وعبارة "THE END OF THE CHAPTER" ("نهاية الفصل"). ويحدث هذا عبر نقطتي النهاية التابعتين لـ Google، مما يثبت أن المشكلة نابعة من النموذج نفسه.
إن اكتشاف المحرك الذي يختلق النصوص أصعب بكثير من اكتشاف المحرك الذي لا يُرجع شيئًا، لأن المخرجات تبدو حقيقية. لذلك نعمل على إضافة اختبار للصفحات الفارغة يُدعى HallucinationBench إلى مقياس أداء OpenOCR؛ وهو اختبار علني يحدد نماذج OCR التي تتخيل نصوصًا على صفحة فارغة. وستظهر النتائج قريبًا في تصنيفات OpenOCR مصحوبة بأيقونة الشبح، بحيث يمكن قياس معدل النصوص المختلقة لكل محرك ونشره إلى جانب مقياس دقته. وإلى ذلك الحين، إذا كانت مستنداتك تتضمن أوراقًا فارغة، كصفحات الفواصل أو ظهور المسح الضوئي، فاستخدم محرك OCR مخصصًا لتلك الصفحات.