0Pricing
AI Prompt Engineering · درس

نهج منهجي لتصحيح الأخطاء

البحث الثنائي في أقسام المطالبة: احذف النصف، اختبر، ثم ضيّق نطاق المشكلة

نهج منهجي لتصحيح الأخطاء درس مجاني في AI Prompt Engineering على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Prompt Engineering، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Prompt Engineering 4 دروس في المجموع.

عقلية تصحيح الأخطاء

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

الخطوة 1: إعادة إنتاج الفشل

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

شغّل المطالبة 5 مرات على المدخل نفسه. إذا فشلت في كل مرة: فهذا فشل حتمي — ومن السهل تصحيحه. وإذا فشلت أحيانًا: فهذا فشل احتمالي — اضبط temperature=0 أولًا لإزالة العشوائية، ثم أعد الاختبار.

import openai
client = openai.OpenAI(api_key='sk-...')

def run_prompt(prompt, user_input, temperature=0):
    resp = client.chat.completions.create(
        model='gpt-4o',
        messages=[
            {'role': 'system', 'content': prompt},
            {'role': 'user', 'content': user_input}
        ],
        temperature=temperature
    )
    return resp.choices[0].message.content

# Reproduce with temperature=0 to eliminate randomness
for i in range(5):
    output = run_prompt(failing_prompt, test_input, temperature=0)
    print(f'Run {i+1}:', output[:100])

الخطوة 2: إنشاء مطالبة دنيا قابلة لإعادة الإنتاج

المطالبة الدنيا القابلة لإعادة الإنتاج (MRP) هي أقصر مطالبة لا تزال تؤدي إلى الفشل. تؤدي إزالة الأجزاء غير ذات الصلة إلى عزل القسم المسبب للمشكلة وتجعل الفشل واضحًا بلا شك.

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

def binary_search_prompt(prompt_lines, user_input, fail_fn):
    '''Binary search: find the minimal set of lines that causes the failure.'''
    if len(prompt_lines) == 1:
        return prompt_lines  # Minimal failing unit found

    mid = len(prompt_lines) // 2
    first_half = prompt_lines[:mid]
    second_half = prompt_lines[mid:]

    # Test first half
    if fail_fn('\n'.join(first_half), user_input):
        return binary_search_prompt(first_half, user_input, fail_fn)
    # Test second half
    elif fail_fn('\n'.join(second_half), user_input):
        return binary_search_prompt(second_half, user_input, fail_fn)
    else:
        # Both halves pass — interaction effect between halves
        return prompt_lines

اختبار الإزالة

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

sections = {
    'role_instruction': 'You are a precise JSON API. Respond only with valid JSON.',
    'context': 'The user is asking about our product catalog.',
    'format_spec': 'Return a JSON object with keys: name, price, available.',
    'examples': 'Example: {"name": "Widget", "price": 9.99, "available": true}',
    'safety': 'Do not reveal internal pricing strategy.'
}

def test_without(section_to_remove, user_input):
    reduced = {k: v for k, v in sections.items() if k != section_to_remove}
    prompt = '\n'.join(reduced.values())
    output = run_prompt(prompt, user_input)
    print(f'Without {section_to_remove}: {evaluate(output)}')

for section in sections:
    test_without(section, 'What is the price of a Widget?')

اختبار A/B لأقسام المطالبة

يعني اختبار A/B للمطالبات إنشاء نسختين من قسم واحد ومقارنة ناتجيهما باستخدام المدخلات نفسها. وعلى خلاف اختبارات الإزالة، تقيّم اختبارات A/B صيغًا بديلة بدلًا من تقييم وجود القسم أو غيابه.

# A/B test: vague vs precise format instruction
variant_A = 'Return a JSON object.'
variant_B = 'Return a valid JSON object. No markdown, no code fences, no prose. Only the raw JSON.'

test_inputs = [
    'What is the price of Widget A?',
    'List all available products.',
    'Is Widget B in stock?'
]

def run_ab_test(base_prompt, variant, inputs, n_runs=5):
    pass_count = 0
    for inp in inputs:
        for _ in range(n_runs):
            prompt = base_prompt.replace('{{FORMAT}}', variant)
            output = run_prompt(prompt, inp)
            if is_valid_json(output):
                pass_count += 1
    return pass_count / (len(inputs) * n_runs)

print('A pass rate:', run_ab_test(template, variant_A, test_inputs))
print('B pass rate:', run_ab_test(template, variant_B, test_inputs))

الاختبار التفريقي

يقارن الاختبار التفريقي بين مطالبتين متطابقتين تقريبًا للعثور على التغيير الذي تسبب في التراجع. ويفيد ذلك عندما «كانت تعمل الأسبوع الماضي» لكنها لا تعمل الآن.

قارن المطالبة القديمة بالجديدة، وحدّد الأقسام التي تغيّرت، ثم اختبر كل قسم متغيّر بمعزل عن الأقسام الأخرى.

import difflib

def show_prompt_diff(prompt_v1, prompt_v2):
    diff = difflib.unified_diff(
        prompt_v1.splitlines(),
        prompt_v2.splitlines(),
        fromfile='v1',
        tofile='v2',
        lineterm=''
    )
    for line in diff:
        print(line)

show_prompt_diff(working_prompt, failing_prompt)
# Output shows exactly which lines changed between versions
# Test reverting each changed section individually

اختبار المدخلات مقابل اختبار المطالبات

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

# Input complexity ladder
inputs_by_complexity = [
    'What is 2 + 2?',             # trivially simple
    'Summarize this sentence.',    # simple task
    'Analyze this 500-word essay.',  # moderate
    'Compare 10 documents and extract contradictions.'  # complex
]

# Find the complexity level where the prompt starts failing
for inp in inputs_by_complexity:
    output = run_prompt(failing_prompt, inp)
    result = 'PASS' if evaluate(output) else 'FAIL'
    print(f'{result}: {inp[:60]}')
# First FAIL indicates where the prompt breaks down

نمط المطالبة الدنيا القابلة لإعادة الإنتاج

يتبع MRP لجلسة تصحيح أخطاء المطالبة البنية التالية:

  1. تحديد الدور في جملة واحدة (عند الحاجة)
  2. تعليمة المهمة في جملة واحدة
  3. تعليمة التنسيق
  4. المدخل الأدنى الذي يعيد إنتاج الفشل

إذا استمرت هذه المطالبة المؤلفة من 4 أسطر في الفشل، فالمشكلة في النموذج أو التنسيق. أعد التعقيد قسمًا واحدًا في كل مرة حتى يظهر الفشل من جديد — ذلك القسم هو المسؤول.

# Start minimal
MINIMAL_PROMPT = (
    'You are a data extractor.\n'
    'Extract the product name and price from the text.\n'
    'Respond with JSON: {"name": "...", "price": ...}\n'
)

minimal_input = 'Widget Pro costs $49.'

# Test: if this works, the problem is in something added on top
output = run_prompt(MINIMAL_PROMPT, minimal_input)
print(output)
# Expected: {"name": "Widget Pro", "price": 49.0}

تتبّع جلسة تصحيح الأخطاء

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

debug_log = [
    {
        'test': 'base_prompt_v5',
        'hypothesis': 'failing due to format conflict',
        'result': 'FAIL',
        'notes': 'JSON prefix still present'
    },
    {
        'test': 'base_prompt_v5_no_markdown_hint',
        'hypothesis': 'removing markdown hint from user message fixes conflict',
        'result': 'PASS',
        'notes': 'Output is clean JSON. Root cause confirmed: format conflict.'
    }
]

import json
with open('debug_session.json', 'w') as f:
    json.dump(debug_log, f, indent=2)

متى تتوقف عن تصحيح الأخطاء وتغيّر الاستراتيجية

يصل تصحيح أخطاء المطالبة أحيانًا إلى مرحلة تتناقص فيها الفائدة. ومن المؤشرات على أن الوقت قد حان لتغيير الاستراتيجية:

  • أن تكون قد أمضيت أكثر من ساعتين في تضييق نطاق الفشل نفسه
  • أن تظل المطالبة الدنيا تفشل رغم وجود تعليمة واضحة وبسيطة
  • أن تُظهر اختبارات A/B عدم وجود فرق ذي دلالة إحصائية

البدائل: انتقل إلى استدعاء الدوال (المخرجات المهيكلة)، أو أضف خطوة للتحقق من المخرجات بعد المعالجة، أو فكّك المهمة إلى مطالبتين أبسط، أو رقِّ النموذج.

الإصلاح مقابل التحصين

بعد العثور على السبب الجذري وإصلاحه، حصّن المطالبة لمنع حالات الفشل المشابهة:

  • أضف حالة الاختبار الفاشلة إلى مجموعة اختباراتك باعتبارها اختبار تراجع
  • أضف تعليمة دفاعية: «حتى إذا كان المدخل غير معتاد، أعِد دائمًا JSON»
  • أضف تحققًا من المخرجات حتى يُكتشف الفشل برمجيًا لا في بيئة الإنتاج

ستفشل المطالبة التي أُصلحت ولم تُحصّن مجددًا عند ظهور حالة حافة تالية.

def safe_run_prompt(prompt, user_input):
    output = run_prompt(prompt, user_input)
    try:
        parsed = json.loads(output)
        return parsed
    except json.JSONDecodeError:
        # Fallback: ask the model to fix its own output
        fix_prompt = f'The following is not valid JSON. Rewrite it as valid JSON only:\n{output}'
        fixed = run_prompt('', fix_prompt)
        return json.loads(fixed)

اختبار المعرفة

في تصحيح أخطاء المطالبة باستخدام البحث الثنائي، إذا أزلت النصف الأول من المطالبة واختفى الفشل، فما الذي يخبرك به ذلك؟

مراجعة: تصحيح الأخطاء المنهجي

نهج منهجي لتصحيح أخطاء المطالبات:

  • إعادة الإنتاج: اضبط temperature=0، وشغّل المطالبة 5 مرات، وتأكد من اتساق الفشل
  • التقليل: استخدم البحث الثنائي في أقسام المطالبة للعثور على المطالبة الدنيا التي يظهر فيها الفشل
  • اختبار A/B: قارن بين صيغ بديلة للقسم الفاشل
  • الاختبار التفريقي: قارن إصداري المطالبة العامل والفاشل للعثور على التراجع
  • التوثيق: سجّل كل اختبار وفرضية ونتيجة
  • التحصين: أضف الحالة المُصلحة إلى مجموعة اختباراتك

الدرس التالي: استراتيجيات التسجيل والتوثيق لصيانة المطالبات على المدى الطويل.

الأسئلة الشائعة

هل درس «نهج منهجي لتصحيح الأخطاء» مجاني؟

نعم — نص درس «نهج منهجي لتصحيح الأخطاء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Prompt Engineering، انتقل إلى CoddyKit PRO. تتضمن دورة AI Prompt Engineering 4 دروس في المجموع.

ماذا ستتعلم في «نهج منهجي لتصحيح الأخطاء»؟

البحث الثنائي في أقسام المطالبة: احذف النصف، اختبر، ثم ضيّق نطاق المشكلة تتمرن على AI Prompt Engineering مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ AI Prompt Engineering؟

لا تُشترط خبرة سابقة. AI Prompt Engineering على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «نهج منهجي لتصحيح الأخطاء»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس AI Prompt Engineering هذا؟

نعم. كل درس في AI Prompt Engineering يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تشخيص المخرجات غير المتوقعة
  2. تحليل السبب الجذري للمطالبات
  3. نهج منهجي لتصحيح الأخطاء
  4. استراتيجيات التسجيل والتوثيق
← العودة إلى AI Prompt Engineering