0Pricing
AI Prompt Engineering · บทเรียน

แนวทางการแก้ไขข้อบกพร่องอย่างเป็นระบบ

ค้นหาแบบทวิภาคในส่วนต่าง ๆ ของพรอมต์: ลบออกครึ่งหนึ่ง ทดสอบ แล้วจำกัดขอบเขตของปัญหาให้แคบลง

แนวทางการแก้ไขข้อบกพร่องอย่างเป็นระบบ เป็นบทเรียน AI Prompt Engineering ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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)

เมื่อใดควรหยุดแก้ไขข้อบกพร่องและเปลี่ยนกลยุทธ์

บางครั้งการแก้ไขข้อบกพร่องของพรอมต์ให้ผลตอบแทนลดลง สัญญาณที่บ่งบอกว่าถึงเวลาเปลี่ยนกลยุทธ์:

  • คุณใช้เวลามากกว่า 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)

ตรวจสอบความเข้าใจ

ในการแก้ไขข้อบกพร่องของพรอมต์ด้วยการค้นหาแบบทวิภาค หลังจากนำครึ่งแรกของพรอมต์ออกแล้วความล้มเหลวหายไป สิ่งนี้บอกอะไรคุณ

สรุป: การแก้ไขข้อบกพร่องอย่างเป็นระบบ

แนวทางอย่างเป็นระบบสำหรับการแก้ไขข้อบกพร่องของพรอมต์:

  • ทำให้เกิดซ้ำ: ตั้งค่าความสุ่มเป็น 0 เรียกใช้ 5 ครั้ง และยืนยันว่าความล้มเหลวเกิดขึ้นอย่างสม่ำเสมอ
  • ทำให้กระชับ: ค้นหาแบบทวิภาคในส่วนต่าง ๆ ของพรอมต์เพื่อค้นหาพรอมต์ขั้นต่ำที่ทำให้เกิดความล้มเหลว
  • ทดสอบ A/B: เปรียบเทียบถ้อยคำทางเลือกของส่วนที่ทำให้เกิดความล้มเหลว
  • เปรียบเทียบความแตกต่าง: เปรียบเทียบพรอมต์เวอร์ชันที่ทำงานได้กับเวอร์ชันที่ล้มเหลวเพื่อค้นหาการถดถอย
  • บันทึก: บันทึกการทดสอบ สมมติฐาน และผลลัพธ์แต่ละรายการ
  • เสริมความทนทาน: เพิ่มกรณีที่แก้ไขแล้วลงในชุดการทดสอบ

บทเรียนถัดไป: กลยุทธ์การบันทึกข้อมูลและการจัดทำเอกสารสำหรับการบำรุงรักษาพรอมต์ระยะยาว

คำถามที่พบบ่อย

บทเรียน “แนวทางการแก้ไขข้อบกพร่องอย่างเป็นระบบ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “แนวทางการแก้ไขข้อบกพร่องอย่างเป็นระบบ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Prompt Engineering ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “แนวทางการแก้ไขข้อบกพร่องอย่างเป็นระบบ”

ค้นหาแบบทวิภาคในส่วนต่าง ๆ ของพรอมต์: ลบออกครึ่งหนึ่ง ทดสอบ แล้วจำกัดขอบเขตของปัญหาให้แคบลง คุณปฏิบัติ AI Prompt Engineering ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Prompt Engineering หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Prompt Engineering บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “แนวทางการแก้ไขข้อบกพร่องอย่างเป็นระบบ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Prompt Engineering นี้ได้ไหม

ได้ บทเรียน AI Prompt Engineering ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การวินิจฉัยผลลัพธ์ที่ไม่คาดคิด
  2. การวิเคราะห์สาเหตุรากของพรอมป์ต
  3. แนวทางการแก้ไขข้อบกพร่องอย่างเป็นระบบ
  4. กลยุทธ์การบันทึกข้อมูลและจัดทำเอกสาร
← กลับไปที่ AI Prompt Engineering