لماذا تتعثّر جلسة تصحيح الأخطاء في Cursor
تصحيح الأخطاء حلقة: تلاحظ، ثم تفترض، ثم تغيّر، ثم تلاحظ من جديد. والوكيل الذي يعمل انطلاقًا من ملفاتك يستطيع أداء ثلاث من هذه الخطوات الأربع؛ أما الملاحظة فلا. وفي كل مرة تلصق فيها أثر استدعاءات أو تصف ما رأيته على الشاشة، تكون أنت من ينفّذ يدويًا الخطوة الوحيدة التي يعجز عنها، وتبقى جودة الحلقة كلها محكومة بقدرتك على الوصف.
ولهذا تكون الجولة الثالثة أسوأ من الأولى عادةً: أنت مرهق، ووصفك يزداد اختصارًا، وصار الوكيل يستدل على ملخّصٍ لملخّص.
ثلاثة أوصاف تُضلّل الوكيل
«لا يعمل»
على الوكيل أن يخمّن أيًّا من أنماط الفشل الخمسة المحتملة تقصد.
وهو يختار عادةً أسهلها إصلاحًا، ونادرًا ما يكون هو ما تقصده.
«يُطلق هذا الخطأ»
الخطأ عَرَضٌ يظهر بعد المشكلة الحقيقية، وغالبًا على بُعد عدة طبقات منها.
وإصلاح موضع إطلاقه يُخفي العَرَض ويُبقي العلّة.
«جرّبت X من قبل»
من دون معرفة ما فعله X فعليًا بالتطبيق، لا يستطيع الوكيل استبعاد أي احتمال.
فيقترح X من جديد في صورة أخرى.
ما الذي يُغلق الحلقة
امنح الوكيل خطوة الملاحظة بدل أن تؤدّيها أنت عنه. ويعني ذلك وجود ما يقود التطبيق المنشور كما يقوده إنسان، ثم يُبلّغ عمّا جرى بوصفه دليلًا لا نصًا وصفيًا.
وشكل هذا الدليل أهم من حجمه: ما الذي جرت محاولته، وما الذي فعله التطبيق فعلًا، وأين افترق الاثنان. هذا ما يستطيع الوكيل التصرّف بناءً عليه مباشرة. أما لقطة الشاشة وأثر الاستدعاءات فيظلان بحاجة إلى إنسان يفسّرهما، وهو ما يعيدك إلى الحلقة التي كنت تحاول الخروج منها.
يُثبّت الإعداد مهارة تحقّق داخل Cursor نفسه، فيعرف كيف يُنشئ حالة اختبار ويشغّلها ويقرأ نتيجتها من دون أن تشرح له سير العمل في كل مرة.
الطرفية
npm install -g @testsprite/testsprite-cli
testsprite setup
ويمكنك فعل الشيء نفسه من لوحة تحكم TestSprite. وكل ما يقوم به CLI غير ذلك موجود في مستودع CLI.
خطوات إعادة إنتاج تُسلّمها خير من وصف
أكثر العادات أثرًا هي أن تتوقف عن وصف الخلل وتبدأ بإعادة إنتاجه. الحالة المكتوبة تحدّد أي صفحة تُفتح، وما الذي يُفعل، وما الذي ينبغي أن يصحّ بعد ذلك. وثلاثة أسطر من هذا تتفوّق على ثلاث فقرات من الشرح، لأنها لا تحتمل لبسًا ولأنها قابلة لإعادة التشغيل.
وهي تغيّر أيضًا طبيعة الحوار مع الوكيل. فبدل «القائمة المنسدلة معطّلة»، يصبح المُدخل تشغيلًا وصل إلى الخطوة الرابعة فوجد الخيار الخطأ محدَّدًا. ولم يبقَ شيء يحتاج إلى تفسير.
اكتب الحالة قبل محاولة الإصلاح الأولى لا بعد الثالثة. فأنت في تلك اللحظة ما زلت تتذكر بالضبط ما فعلته حتى ظهر الخلل، وهي معرفة تتبخّر أسرع مما يتوقع أحد.
مثال تطبيقي على إغلاق الحلقة
لنأخذ حالة ملموسة. يُبلّغ مستخدم بأن تعديل مُرشِّح محفوظ يتراجع أحيانًا إلى حاله السابق. تصف المشكلة، فيجد الوكيل تسابقًا بين تحديثَي حالة ويقترح حارسًا يمنعه. تطبّقه، وتجرّب مرة واحدة، فينجح، فتمضي في عملك. وبعد يومين يعود البلاغ.
والخلل هنا ليس في الإصلاح، بل في أن محاولة يدوية واحدة ليست سوى عيّنة من واحد في مواجهة خلل متقطّع، والأخطاء المتقطّعة تجتاز المحاولة الواحدة بقدر ما تفشل فيها تقريبًا. أما الحلقة التي تصل فعلًا إلى نتيجة فتبدو مختلفة: دوّن التسلسل بوصفه حالة، وشغّلها عدة مرات، واقرأ المعدّل. فأربع حالات فشل من عشر تعليمة مختلفة تمامًا للوكيل عن «إنه معطّل»، لأنها تستبعد فئة كاملة من الأسباب الحتمية وتشير إلى التوقيت.
والأمر الثاني الذي يتغيّر هو ما يحدث بعد الإصلاح. تُشغَّل الحالة نفسها مرة أخرى عشر مرات، فإما أن يهبط المعدّل إلى الصفر وإما ألّا يهبط. صار لديك دليل بدل انطباع، وتبقى الحالة ضمن مجموعة الاختبارات كي لا يصل البلاغ الثالث أبدًا.
الادّعاء الجدير بالشك
«لقد أصلحت المشكلة» أغلى جملة في تصحيح الأخطاء بمساعدة الوكلاء. فهي نابعة من الاستدلال نفسه الذي أنتج التغيير، ولذلك لا تحمل أي معلومة مستقلة. الإصلاح يتأكد حين يُلاحَظ السلوك صحيحًا، والوكيل الذي كتبه لا يمكن بحكم التعريف أن يكون هو من يؤكده.
وليس في هذا انتقاد للنموذج؛ فالإنسان الذي يكتب رقعة ثم يعلن صحّتها من دون تشغيل أي شيء سيلقى الرد نفسه في المراجعة.
اجعل التحقق يبقى بعد انتهاء الجلسة
الحالة التي كتبتها لإعادة إنتاج الخلل تساوي بعد الإصلاح أكثر مما ساوت أثناءه. احتفظ بها وشغّلها مع كل تغيير، حتى لا تعود العلّة نفسها بهدوء بعد ثلاثة أسابيع.
GitHub App هو webhook تُعدّه من لوحة تحكم TestSprite. يستمع إلى حدث النشر الذي ينتجه خط عملك أصلًا، فلا يتغير شيء في مستودعك.
GitHub Actions يضع الخطوة داخل سير عملك أنت، ويُضبط من الطرفية.
ما الذي يتغير بوجود خطوة تحقّق داخل الحلقة
يوفّر TestSprite الملاحظة الناقصة في الحلقة. فالإعداد يُثبّت مهارة تحقّق داخل Cursor نفسه، فيستطيع الوكيل إنشاء حالة وتشغيلها على تطبيقك المنشور وقراءة النتيجة من دون أن تنقل أنت شيئًا.
والأثر العملي على جلسة تصحيح الأخطاء أن الجولات تتوقف عن التكرار. فالوكيل لم يعد يستدل على ما تتذكره مما رأيت؛ صار لديه سجل بما جرت محاولته، وبما فعله التطبيق، وبموضع افتراقهما. والإصلاح الذي يقترحه يؤكده شيء آخر غير الاستدلال الذي أنتجه، وهذه هي الطريقة الوحيدة لتتحول عبارة «لقد أصلحته» إلى معلومة.
كما أن إعادة الإنتاج تبقى بعد انتهاء الجلسة. فالحالة التي كشفت الخلل تظل ضمن مجموعة الاختبارات وتُشغَّل مع كل تغيير، حتى لا تعود العلّة نفسها بهدوء بعد ستة أسابيع.
هل يستطيع Cursor تصحيح الأخطاء من دون تشغيل التطبيق؟
يستطيع الاستدلال على الشيفرة، وكثيرًا ما يعثر على العلّة بهذه الطريقة، خصوصًا في أخطاء المنطق ذات الأثر الواضح. لكنه لا يستطيع تأكيد إصلاح، ولا يرى مشكلات الحالة أو التوقيت أو التكامل التي لا تظهر إلا عند تشغيل التطبيق.
لماذا يعود الخلل نفسه؟
لأن إعادة الإنتاج تعيش عادةً في المحادثة لا في اختبار. وبمجرد انتهاء المحادثة، لا يبقى شيء يتحقق من ذلك السلوك.
هل يحلّ هذا محل سير عمل تصحيح الأخطاء في Cursor؟
لا. إنه يوفّر خطوة الملاحظة الناقصة. فـ Cursor يظل هو من يقترح التغيير، وأنت تظل من يقرر إن كان معقولًا، ويخبركما التحقق إن كان قد نجح.
ما مقدار ما يراه من شيفرتي؟
يجري التحقق على التطبيق المنشور عبر واجهته، فيُبلّغ عن السلوك بدل أن يقرأ مستودعك.
ماذا لو كان الخلل لا يظهر إلا في بيئة الإنتاج؟
وجّه التشغيل إلى بيئة تُعيد إنتاجه. وإذا اختلف السلوك بين البيئات، فذلك الاختلاف هو الخلل الحقيقي عادةً، ويستحق التتبّع قبل تغيير الشيفرة.
امنح الوكيل عينين، لا مطالبات أطول.
يتعثّر Cursor بوصفه أداة لتصحيح الأخطاء لأن لا شيء في الحلقة يلاحظ التطبيق وهو يعمل. وفّر تلك الخطوة، وتمسّك بالدليل بدل ادّعاء النجاح، واحتفظ بإعادة الإنتاج بوصفها اختبارًا كي يصمد الإصلاح.