بث مباشر 18.11 · الدفعة 318 نوفمبر، 19:00 بتوقيت موسكو — ورشة عملية مجانية لوكلاء الذكاء الاصطناعي · الدفعة 3 تبدأ 23.11ورشة 18 نوفمبر ←الدفعة 3 (23.11)
إصدارAPI / منتج · جاهز للعملHabr AI→ المصدر

حدّان للمحادثة في بوت amoCRM لم يعملا منذ الإطلاق: السبب هو AND بدل OR وفرع معطّل

تضمنت لوحة إدارة بوت Octery لمنصة amoCRM حدّين: الحد الأقصى للردود وعتبة الرسائل عديمة المعنى. لم يعمل أي منهما منذ البداية. جرى بناء شرط التحويل إلى المدير باستخدام AND بدلاً من OR، بينما كان فرع التحويل يكتب القيم في حقول ذات أسماء خاطئة، فكانت الخطوات التالية تقرأ رد النموذج القديم.

معالج بواسطة الذكاء الاصطناعي من Habr AI؛ بتحرير Hamidun News
حدّان للمحادثة في بوت amoCRM لم يعملا منذ الإطلاق: السبب هو AND بدل OR وفرع معطّل
المصدر: Habr AI. كولاج: Hamidun News.
استمع للمقال
بطاقة الحقائق والأرقام
المعيارالتفاصيل
المصدر الأصليHabr AI ↗
رئيس التحرير
حقيقة رئيسية #1كانت المنطقية موجودة في إعدادات خط المعالجة: لا اختبارات وحدات، ولا CI، ولا diff قابل للقراءة
حقيقة رئيسية #2نُقل الحل إلى دالة نقية في API تستخرج الحدود بنفسها من الإعدادات
حقيقة رئيسية #3أصبح كل واحد من سيناريوهات المواصفات الـ16 اختباراً ذا اسم واضح الدلالة

تخيّل أن الأرقام ظاهرة في لوحة الإدارة، وأن الإعداد يُحفظ، وأن الواجهة تبدو كما ينبغي. لكنه في الواقع لا يفعل شيئاً. هذا بالضبط ما اتضح في 30 سبتمبر: كلا الحدّين الخاصين بطول المحادثة في بوت Octery لا يعملان، ويبدو أنهما لم يعملا منذ البداية.

يرد Octery على العملاء المحتملين في محادثات amoCRM، ثم يحوّل الصفقة إلى مدير. وهناك حدّان. يحدد Max Messages عدد الردود التي يقدمها البوت قبل استدعاء شخص. أما Hard Stop Threshold فيحدد عدد الرسائل المتتالية عديمة المعنى التي سيتحملها، مثل «aaa» أو «test» أو «???»، أو حتى رسالة موجهة إلى بوت مختلف تماماً. وكل رسالة من هذا النوع تكلّف استدعاءً للنموذج، لذلك لا جدوى من مواصلة الرد عليها بلا نهاية.

خطآن كان كل منهما يخفي الآخر

كان قرار التحويل يُتخذ بعد رد النموذج داخل خط المعالجة. وكان الشرط يتألف من ثلاثة فحوص تربط بينها AND. لكن وفقاً لمنطق الإعدادات، الحدّان مستقلان: ينبغي التحويل إذا نُفد عداد الردود، أو إذا بلغ تسلسل الرسائل عديمة المعنى العتبة المحددة. ومع AND، لم يكن البوت يستدعي المدير إلا عندما يستنفد العميل حد الرسائل ويرسل في الوقت نفسه عدة رسائل عبثية متتالية. وهذا لم يحدث.

أما الخطأ الثاني فكان في الفرع المفترض تشغيله عند تحقق الشرط. كان هذا الفرع يستبدل الرد بعبارة «أحوّل المحادثة إلى المدير» ويضبط النية على manager. لكن القيم كانت تصل إلى حقول وُضعت فيها تعبيرات بدلاً من الأسماء الصحيحة: أُدرجت القيمة في حقل الاسم وبقيت هناك. وفوق ذلك، كانت عمليتا إرسال الرد وتسجيل السجل تقرآن البيانات مباشرة من نتيجة تحليل رد النموذج، لا من هذا الفرع. وحتى لو استبدل أحدهم AND بـ OR، لكان العميل قد تلقى رداً عادياً، ولما ظهر أي أثر للمشكلة في السجلات.

كان أول تشغيل يدوي سيكشف كل خطأ لو وُجد منفرداً. لكن اجتماعهما جعل الحدّين غير مرئيين.

لماذا لم يلاحظ أحد

كانت المنطقية موجودة في إعدادات خط المعالجة لا في الشيفرة. لا يمكن بسهولة كتابة اختبار وحدة للإعداد أو تشغيله في CI، كما يبدو التعديل أثناء المراجعة وكأنه «إصلاح للشرط» من دون diff يمكن قراءته. ويستغرق دفع محادثة حقيقية يدوياً حتى بلوغ الحد وقتاً طويلاً، لذلك لم تصل الفحوص المعتادة إليه. ولم تكن هناك إجابة إيجابية أو سلبية عن سؤال «هل تعمل الحدود؟».

ما الذي تم فعله

نُقل القرار إلى API في صورة دالة نقية مستقلة. يمرر إليها خط المعالجة رد النموذج وعدادين من حالة المحادثة، بينما تستخرج الدالة بنفسها الحدود من إعدادات الشركة، بحيث لا يستطيع المستدعي تمرير قيم مختلفة. وتُخرج قراراً نهائياً واحداً يتضمن النص والنية وسبب التحويل. ولا تقرأ جميع الخطوات اللاحقة إلا هذه النتيجة.

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

اختبارات مستمدة من المواصفات

وُصف السلوك أولاً في صورة سيناريوهات، ثم تحول كل سيناريو إلى اختبار، بإجمالي 16 اختباراً. وأسماؤها تشرح نفسها: «hands off on the Nth non-meaningful message in a row, counting the current one» و«a meaningful message breaks the non-meaningful streak». وقد أُبقي اختبار «old AND case» عمداً: فالحالة الوحيدة التي كان الشرط القديم يعمل فيها أصبحت الآن حالة خاصة من الشرط الجديد.

مخاطر الإطلاق والخلاصة

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

الخلاصة العملية للفرق التي تستخدم خطوط معالجة no-code وlow-code: إذا كان رقم ما ظاهراً للعميل في الواجهة، فيجب أن يكون سلوكه مغطى باختبار آلي، وأن يعبّر اسم الاختبار عن الوعد المقدم للعميل. ومن الأفضل نقل منطق الأعمال الذي تعتمد عليه الأموال أو عملية تحويل العميل إلى إنسان من الإعدادات إلى الشيفرة، حيث يمكن قراءته في diff وتشغيله في CI.

القصة

أسئلة وأجوبة حول الخبر

ما أبرز التفاصيل حول خطآن كان كل منهما يخفي الآخر؟

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

ما أبرز التفاصيل حول لماذا لم يلاحظ أحد؟

كانت المنطقية موجودة في إعدادات خط المعالجة لا في الشيفرة. لا يمكن بسهولة كتابة اختبار وحدة للإعداد أو تشغيله في CI، كما يبدو التعديل أثناء المراجعة وكأنه «إصلاح للشرط» من دون diff يمكن قراءته. ويستغرق دفع محادثة حقيقية يدوياً حتى بلوغ الحد وقتاً طويلاً، لذلك لم تصل الفحوص المعتادة إليه. ولم تكن هناك إجابة إيجابية أو سلبية عن سؤال «هل تعمل الحدود؟».

ما أبرز التفاصيل حول ما الذي تم فعله؟

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

ZK
جمال حميدون — مدير المنتجات في Alpina Digital ومدير منتج AlpinaGPT. يبني منتجات الذكاء الاصطناعي منذ 2019. بدأ Hamidun News كمشروع شخصي ثم أصبح مُجمِّعًا إنتاجيًا بأكثر من 6000 قارئ.
✦ Unified AI Workspace · Nomad

Test Frontier LLMs & Autonomous Agents in One Workspace

Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.

Try Nomad AI →Launch Nomad Agent
ما رأيك؟
جارٍ تحميل التعليقات…