وداعاً للـ `console.log` العشوائي: كيف تتقن فن ‘التنقيح الحواري’ مع نماذج اللغة الكبيرة (LLMs)؟

يا أهلاً وسهلاً فيكم يا جماعة الخير. اسمي أبو عمر، مبرمج فلسطيني قضيت سنين طويلة من عمري بين الأكواد والخوارزميات، وشفت التكنولوجيا وهي بتكبر وبتتطور قدام عيوني، من أيام الـ Dial-up لحد ما وصلنا لعالم الذكاء الاصطناعي اللي بنعيشه اليوم.

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

بلشت أزرع جمل print() في كل زاوية من الكود. print(users)، print(products)، print(current_user_vector)… خلال نص ساعة، شاشة الـ terminal عندي صارت زي جريدة الصبح، مليانة كلام وأرقام ما إلها أول من آخر. زادت حيرتي وضاع تركيزي، وصرت أحكي لحالي “شو هالشغلة هاي؟ كل هالأرقام ومش فاهم وين العلة!”. كنت على وشك أستسلم وأروح أنام.

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

هذا الحوار البسيط غيّر كل إشي. بدأنا نستبعد الأسباب واحد ورا الثاني، زي المحققين. النموذج اقترح عليّ أتأكد من أنواع البيانات، وفعلاً… اكتشفت إنه في عمود ID كنت أتعامل معاه كرقم (integer) وهو في الحقيقة كان نص (string). مشكلة تافهة جداً، لكنها كانت مدفونة تحت كومة من السجلات اللي طبعتها عالفاضي. هاي الليلة، ما تعلمت بس حل المشكلة، تعلمت طريقة جديدة كلياً في التفكير وحل المشاكل: “التنقيح الحواري”.

لماذا لا يكفي الـ `console.log` وحده؟

كلنا بنحب الـ console.log() أو print(). هي الأداة السريعة اللي بتعطينا لمحة عن اللي بصير داخل الصندوق الأسود تبعنا. لكن الاعتماد عليها بشكل كامل، خصوصاً في الأنظمة المعقدة، يشبه محاولة فهم رواية كاملة من خلال قراءة بضع كلمات عشوائية منها.

فوضى السجلات (Log Chaos)

عندما تواجهنا مشكلة غامضة، ردة فعلنا الطبيعية هي إضافة المزيد والمزيد من جمل الطباعة. النتيجة؟ شاشة مليئة بالبيانات غير المنظمة التي تجعل من مهمة إيجاد الإبرة في كومة القش شبه مستحيلة. بدلاً من توضيح المشكلة، نحن نزيد من الضوضاء.

العمى عن السياق (Context Blindness)

الـ console.log يريك قيمة متغير في لحظة زمنية معينة، لكنه لا يخبرك بالقصة الكاملة. لا يخبرك *لماذا* وصل المتغير لهذه القيمة، أو ما هي سلسلة العمليات المنطقية التي أدت إلى هذه الحالة. أنت ترى العَرَض، لكنك لا ترى المرض نفسه.

التحقيقات السطحية (Shallow Investigations)

هذه الأداة ممتازة لتحديد *مكان* حدوث الخطأ (مثلاً، الدالة التي تُرجع null)، لكنها غالباً ما تفشل في شرح *سبب* الخطأ، خصوصاً إذا كان السبب يتعلق بمنطق عمل معقد أو تفاعل غير متوقع بين أجزاء مختلفة من النظام.

مرحباً بـ ‘التنقيح الحواري’: شريكك الذكي في حل المشاكل

هنا يأتي دور نماذج اللغة الكبيرة (LLMs) مثل GPT-4 و Claude وغيرهم. “التنقيح الحواري” هو فن استخدام هذه النماذج كشريك برمجة (Pair Programmer) ذكي. الفكرة ليست في أن ترمي له الكود وتنتظر الحل السحري، بل في أن تدخل معه في حوار منظم ومنهجي لتشخيص المشكلة وحلها معاً.

من “أصلح هذا” إلى “دعنا نفكر معاً”

الفرق شاسع بين النهجين:

  • النهج الكسول: “هذا الكود لا يعمل، أصلحه.” – غالباً ما يعطي نتائج غير دقيقة أو حلولاً لا تفهمها.
  • النهج الحواري: “أنا أحاول تحقيق [الهدف]. الكود يقوم بـ [الوصف]، لكنني أواجه [المشكلة]. أعتقد أن السبب قد يكون [فرضيتك]. هل يمكنك مساعدتي في التحقق من هذه الفرضية أو اقتراح زوايا أخرى للنظر في المشكلة؟”

النهج الثاني يحترم قدراتك كمطور ويستخدم الذكاء الاصطناعي كأداة لتضخيم هذه القدرات، لا استبدالها.

مبدأ “البطة المطاطية” على منشطات (Rubber Duck Principle on Steroids)

لعلكم سمعتم بتقنية “تنقيح البطة المطاطية” (Rubber Duck Debugging)، حيث تشرح الكود والمشكلة لبطة مطاطية على مكتبك. مجرد عملية الشرح بصوت عالٍ غالباً ما تكشف لك عن الخطأ. التنقيح الحواري هو نفس المبدأ، لكن مع فارق جوهري: البطة ترد عليك! وهي لا ترد فقط، بل تقترح فرضيات، وتكتب أكواد اختبار، وتشرح مفاهيم معقدة.

الاستراتيجية العملية للتنقيح الحواري

لكي يكون حوارك مع الـ LLM مثمراً، يجب أن يكون منظماً. إليك استراتيجيتي الشخصية المكونة من ثلاث مراحل:

المرحلة الأولى: تجهيز “مسرح الجريمة”

قبل أن تكتب حرفاً واحداً للنموذج، جهّز ملف قضيتك. هذا يضمن أن الحوار سيبدأ بداية صحيحة.

  1. تحديد الهدف: اكتب جملة واضحة تشرح ما الذي من المفترض أن يفعله الكود. مثال: “يا جماعة، هاي الفنكشن لازم تفلتر قائمة مستخدمين وترجعلي بس المستخدمين النشطين اللي عمرهم فوق سن معين.”
  2. وصف العَرَض: صف السلوك الفعلي وغير المتوقع. مثال: “الفنكشن بترجعلي دايماً قائمة فارغة، حتى لو كان في مستخدمين بتنطبق عليهم الشروط.”
  3. جمع الأدلة:
    • الكود ذو الصلة: انسخ أصغر جزء ممكن من الكود الذي يسبب المشكلة. لا ترسل المشروع كاملاً.
    • المدخلات: قدم عينة بسيطة من البيانات التي تستخدمها لاختبار الكود.
    • المخرجات الخاطئة: أظهر الناتج الفعلي الذي تحصل عليه.
    • الناتج المتوقع: وضح ما كنت تتوقع رؤيته.
    • رسالة الخطأ (إن وجدت): انسخها كما هي.

المرحلة الثانية: بدء الحوار (مع مثال عملي)

الآن، صغ رسالتك الأولى بشكل احترافي. لنأخذ مثالاً عملياً بلغة بايثون. لدينا دالة لا تعمل كما هو متوقع:

# The problematic code
def filter_users_by_age(users, min_age):
    active_users = []
    for user in users:
        # The potential bug is here
        if user['is_active'] and user['age'] > min_age:
            active_users.append(user)
    return active_users

# Sample data
sample_users = [
    {'name': 'عمر', 'age': '35', 'is_active': True},
    {'name': 'سالم', 'age': '25', 'is_active': False},
    {'name': 'خالد', 'age': '40', 'is_active': True}
]

# The call that returns an empty list incorrectly
filtered = filter_users_by_age(sample_users, 30)
print(f"Filtered Users: {filtered}") # Outputs: Filtered Users: []

بدلاً من رمي الكود فقط، يمكنك بدء الحوار كالتالي:

مرحباً، أنا أعمل على دالة بلغة بايثون هدفها فلترة قائمة من المستخدمين بناءً على حالتهم (نشط) وعمرهم.

الهدف: إرجاع قائمة تحتوي فقط على المستخدمين النشطين الذين تزيد أعمارهم عن `min_age`.

المشكلة: عند استدعاء الدالة مع `min_age = 30`، فإنها تُرجع قائمة فارغة، على الرغم من وجود مستخدمين (عمر وخالد) تنطبق عليهم الشروط.

الكود:
[الصق الكود أعلاه هنا]

المدخلات:
[الصق `sample_users` هنا]

الناتج الفعلي: `Filtered Users: []`

الناتج المتوقع: قائمة تحتوي على القاموس الخاص بـ ‘عمر’ و ‘خالد’.

أظن أن المشكلة قد تكون في جملة الشرط `if`، لكنني لست متأكداً. هل يمكنك مساعدتي في تحليل تدفق البيانات داخل الحلقة `for` لنكتشف لماذا لا تتم إضافة أي مستخدم إلى القائمة؟

المرحلة الثالثة: التحقيق التفاعلي

الآن يبدأ الجزء الممتع. الـ LLM سيرد عليك غالباً باقتراح ذكي.

  • الرد المتوقع من الـ LLM: “مرحباً أبو عمر. شكراً على السياق الواضح. بناءً على وصفك، هناك احتمال كبير أن تكون المشكلة متعلقة بنوع البيانات. في بايثون، مقارنة نص برقم (`’35’ > 30`) قد لا تعطي النتيجة المتوقعة دائماً. هل يمكنك التحقق من نوع البيانات للمفتاح `age` داخل الحلقة؟ جرب إضافة `print(type(user[‘age’]))` قبل جملة الشرط.”
  • دورك (التحقق والإبلاغ): تقوم بإضافة السطر المقترح، تشغل الكود، وترى الناتج `<class ‘str’>`. ثم ترد على النموذج: “صدقت! طلع نوع البيانات نص (string) وليس رقماً. ما هي أفضل طريقة لتحويل العمر إلى رقم قبل المقارنة مع مراعاة الأداء وتجنب الأخطاء؟”
  • الـ LLM يقدم الحلول: سيقترح عليك الحل، غالباً مع عدة خيارات.
    # Solution
    def filter_users_by_age(users, min_age):
        active_users = []
        for user in users:
            # Convert age to integer before comparison
            if user['is_active'] and int(user['age']) > min_age:
                active_users.append(user)
        return active_users
        
  • طلب التحسين: لا تتوقف هنا! يمكنك أن تسأل: “شكراً، الحل يعمل. هل هناك طريقة لكتابة هذه الدالة بشكل أكثر أناقة أو كفاءة في بايثون (more Pythonic)؟ ربما باستخدام List Comprehension؟” سيقوم النموذج بتعليمك طريقة جديدة ومحسّنة، محولاً جلسة التنقيح إلى درس تعليمي.

نصائح أبو عمر الذهبية للتنقيح الحواري 💡

  • كن دقيقاً ومختصراً: لا ترسل ملفات كاملة أو أكواداً غير ذات صلة. كلما كان سؤالك مركزاً، كانت الإجابة أفضل.
  • لا تشارك معلومات حساسة: هذه قاعدة ذهبية. لا ترسل أبداً مفاتيح API، كلمات مرور، بيانات مستخدمين حقيقية، أو أي معلومات تجارية سرية. تعامل مع المحادثة على أنها عامة.
  • اعتبره مساعداً وليس ساحراً: الـ LLM أداة لتسريع تفكيرك، وليس بديلاً عنه. تحقق دائماً من الحلول التي يقدمها، وافهمها قبل تطبيقها. لا تثق بالناتج بشكل أعمى.
  • تكلم بلغتك (وبلهجتك): لا تتردد في شرح المشكلة كما تشرحها لزميلك في العمل. استخدام مصطلحات مثل “الكود معلّق”، “الناتج مخربط”، أو “الفنكشن بتضرب” يساعد في توصيل الفكرة بشكل طبيعي.
  • استخدمه كأداة تعلم: إذا اقترح الـ LLM حلاً يستخدم مفهوماً لا تعرفه (مثل `async/await`, `decorators`, `lambda functions`)، اطلب منه ببساطة: “لم أفهم هذا الحل، هل يمكنك شرح مفهوم [المفهوم الجديد] مع مثال بسيط؟”.

الخلاصة: من مصارع أخطاء إلى محقق خبير

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

في المرة القادمة التي تجد فيها نفسك غارقاً في بحر من الـ console.log، توقف للحظة. خذ فنجان شاي أو قهوة، افتح نافذة محادثة مع شريكك الذكي، وابدأ الحوار. قد تتفاجأ من سرعة وصولك للحل… ومن الأشياء الجديدة التي ستتعلمها على الطريق. بالتوفيق يا جماعة! 😉

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

ادارة الفرق والتنمية البشرية

مهندسونا كانوا يرحلون بصمت: كيف أنقذتنا ‘مسارات النمو المهني’ من جحيم الركود الوظيفي؟

كنا نخسر أفضل مهندسينا الواحد تلو الآخر دون أن نفهم السبب الحقيقي. في هذه المقالة، أشارككم قصة كيف اكتشفنا القاتل الصامت "الركود الوظيفي"، وكيف أنقذنا...

15 أبريل، 2026 قراءة المزيد
أتمتة العمليات

عملياتنا كانت تموت في صمت: كيف أنقذتنا ‘محركات تنسيق سير العمل’ (Workflow Engines) من جحيم الأعطال غير المتوقعة؟

أشارككم قصة حقيقية من تجربتي كمبرمج وكيف انتقلنا من الفوضى والأعطال الصامتة في عملياتنا المعقدة إلى نظام مستقر وموثوق. اكتشفوا كيف يمكن لـ "محركات تنسيق...

15 أبريل، 2026 قراءة المزيد
ذكاء اصطناعي

بحثنا كان يعثر على الكلمات، لا على النوايا: كيف أنقذتنا قواعد بيانات المتجهات من جحيم البحث الدلالي الأعمى؟

أشارككم قصة من قلب المعركة البرمجية، يوم كان نظام البحث لدينا أصمًا وأعمى، لا يفهم سوى تطابق الكلمات. سنغوص في عالم قواعد بيانات المتجهات (Vector...

14 أبريل، 2026 قراءة المزيد
خوارزميات

قاعدة بياناتنا كانت تجيب على ‘هل هذا موجود؟’ ببطء قاتل: كيف أنقذنا ‘مرشح بلوم’ (Bloom Filter) من جحيم الاستعلامات المكلفة؟

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

14 أبريل، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

موقعنا كان يستبعد الملايين بصمت: كيف أنقذتنا ‘معايير الوصولية’ (Accessibility) من جحيم التصميم الإقصائي؟

أشارككم قصة حقيقية حول كيف اكتشفنا أن تصميم موقعنا "الرائع" كان يقصي ملايين المستخدمين دون علمنا. هذه المقالة ليست مجرد سرد تقني، بل هي رحلة...

14 أبريل، 2026 قراءة المزيد
البودكاست