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

การประเมินไปป์ไลน์ DSPy

ตัวชี้วัด ชุดพัฒนา และฟังก์ชัน evaluate() สำหรับการประเมินโดยอัตโนมัติ

การประเมินไปป์ไลน์ DSPy เป็นบทเรียน AI Prompt Engineering ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Prompt Engineering และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดการประเมินจึงสำคัญในดีเอสพาย

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

คลาส dspy.Evaluate

dspy.Evaluate จะเรียกใช้โปรแกรมของคุณกับชุดข้อมูล ใช้ตัวชี้วัด และรายงานคะแนนรวม โดยรองรับการประมวลผลแบบขนานผ่าน num_threads เพื่อประเมินชุดข้อมูลขนาดใหญ่ได้อย่างรวดเร็ว

import dspy

# Build a devset of labeled examples
devset = [
    dspy.Example(question='What is 7 * 8?', answer='56').with_inputs('question'),
    dspy.Example(question='Name the largest planet.', answer='Jupiter').with_inputs('question'),
    # ... more examples
]

# Create evaluator
evaluate = dspy.Evaluate(
    devset=devset,
    metric=exact_match_metric,  # Your metric function
    num_threads=4,              # Parallel evaluation
    display_progress=True,      # Show progress bar
    display_table=True,         # Show per-example results
)

# Run
score = evaluate(my_program)
print(f'Overall score: {score:.1%}')

การเขียนฟังก์ชันตัวชี้วัด

ฟังก์ชันตัวชี้วัดมีรูปแบบ (example, prediction, trace=None) -> float โดยจะเปรียบเทียบผลการทำนายของโปรแกรมกับคำตอบจริงในตัวอย่าง

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

import dspy

def exact_match_metric(example, prediction, trace=None):
    return float(
        example.answer.strip().lower() == prediction.answer.strip().lower()
    )

def contains_metric(example, prediction, trace=None):
    """Check if expected answer appears anywhere in prediction."""
    return float(example.answer.lower() in prediction.answer.lower())

def length_penalized_metric(example, prediction, trace=None):
    """Reward correct answers, penalize overly long ones."""
    correct = float(example.answer.lower() in prediction.answer.lower())
    length_ok = float(len(prediction.answer.split()) <= 20)
    return correct * (0.8 + 0.2 * length_ok)

# Use any of these as the metric parameter
evaluate = dspy.Evaluate(devset=devset, metric=contains_metric)

รูปแบบเกณฑ์ผ่านและไม่ผ่าน

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

import dspy

def quality_metric(example, prediction, trace=None):
    """
    Multi-factor metric with pass/fail threshold.
    Returns float 0.0 to 1.0.
    During compilation (trace is not None), DSPy uses this to decide
    which traces to bootstrap as demos.
    """
    score = 0.0

    # Factor 1: Factual correctness (0.6 weight)
    if example.answer.lower() in prediction.answer.lower():
        score += 0.6

    # Factor 2: Conciseness (0.4 weight)
    word_count = len(prediction.answer.split())
    if word_count <= 15:
        score += 0.4
    elif word_count <= 30:
        score += 0.2

    # During optimization: only use examples scoring >= 0.6
    if trace is not None:
        return score >= 0.6

    return score

การแบ่งข้อมูล: ฝึก พัฒนา และทดสอบ

ปฏิบัติตามแนวทางมาตรฐานในการแบ่งข้อมูลสำหรับการเรียนรู้ของเครื่องในดีเอสพาย:

  • ชุดข้อมูลฝึก: ตัวปรับให้เหมาะสมใช้เพื่อเริ่มต้นตัวอย่าง จำนวน 20–200 ตัวอย่าง
  • ชุดข้อมูลพัฒนา: ตัวปรับให้เหมาะสมใช้สำหรับตรวจสอบความถูกต้องระหว่างการค้นหา
  • ชุดข้อมูลทดสอบ: กันไว้นอกกระบวนการทั้งหมด ใช้สำหรับการประเมินขั้นสุดท้ายเท่านั้น
import random

# All labeled examples
all_examples = load_examples()  # Returns list of dspy.Example
random.shuffle(all_examples)

total = len(all_examples)
train_end = int(total * 0.6)
dev_end   = int(total * 0.8)

trainset = all_examples[:train_end]    # 60% for optimization
devset   = all_examples[train_end:dev_end]  # 20% for validation
testset  = all_examples[dev_end:]      # 20% held out

print(f'Train: {len(trainset)}, Dev: {len(devset)}, Test: {len(testset)}')

การเปรียบเทียบโปรแกรมที่ปรับให้เหมาะสมกับโปรแกรมที่ยังไม่ได้ปรับให้เหมาะสม

โปรดเปรียบเทียบประสิทธิภาพของโปรแกรมที่ผ่านการคอมไพล์กับโปรแกรมฐานที่ยังไม่ได้คอมไพล์บนชุดข้อมูลทดสอบเดียวกันเสมอ วิธีนี้ยืนยันได้ว่าการปรับให้เหมาะสมช่วยได้จริง และช่วยวัดขนาดของการปรับปรุง

import dspy

evaluate = dspy.Evaluate(
    devset=testset,
    metric=exact_match_metric,
    num_threads=4,
    display_progress=True,
)

# Baseline: unoptimized program
baseline_score = evaluate(unoptimized_program)
print(f'Baseline (no optimization): {baseline_score:.1%}')

# BootstrapFewShot compiled
bs_score = evaluate(bootstrap_compiled_program)
print(f'BootstrapFewShot compiled:  {bs_score:.1%}')

# MIPRO compiled
mipro_score = evaluate(mipro_compiled_program)
print(f'MIPRO compiled:             {mipro_score:.1%}')

# Pick the winner
print(f'Best improvement: +{max(bs_score, mipro_score) - baseline_score:.1%}')

การประมวลผลแบบขนานด้วย num_threads

หากประเมินชุดข้อมูลขนาดใหญ่แบบลำดับเดียว อาจใช้เวลาหลายชั่วโมง num_threads ใน dspy.Evaluate จะเรียกใช้ผลการทำนายแบบขนาน ช่วยลดเวลาจริงที่ผ่านไปได้ตามสัดส่วน

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

import dspy
import time

devset = [...]  # 200 examples

# Sequential evaluation
start = time.time()
evaluate_seq = dspy.Evaluate(devset=devset, metric=metric, num_threads=1)
score_seq = evaluate_seq(program)
print(f'Sequential: {time.time()-start:.0f}s')

# Parallel evaluation (4 threads)
start = time.time()
evaluate_par = dspy.Evaluate(devset=devset, metric=metric, num_threads=4)
score_par = evaluate_par(program)
print(f'Parallel (4 threads): {time.time()-start:.0f}s')
# Typically ~4x faster — same score, less wait time

การตีความผลลัพธ์การประเมิน

เมื่อกำหนด display_table=True ดีเอสพายจะแสดงตารางรายละเอียดที่มีตัวอย่างแต่ละรายการ ผลการทำนาย และระบุว่าผ่านตัวชี้วัดหรือไม่ ตารางนี้มีประโยชน์อย่างมากสำหรับวิเคราะห์รูปแบบความล้มเหลว

โปรดมองหา: ความล้มเหลวอย่างเป็นระบบในคำถามประเภทใดประเภทหนึ่ง กรณีขอบเขตของตัวชี้วัด หรือตัวอย่างที่ชุดข้อมูลฝึกของคุณไม่ได้ครอบคลุม

import dspy

evaluate = dspy.Evaluate(
    devset=devset,
    metric=exact_match_metric,
    num_threads=2,
    display_progress=True,
    display_table=10,  # Show first 10 rows of results table
    return_outputs=True,  # Return (score, outputs) tuple
)

score, outputs = evaluate(program, return_all_scores=True)

# Find failing examples
failures = [
    (ex, pred, s)
    for ex, pred, s in outputs
    if s == 0.0
]
print(f'Failures: {len(failures)}/{len(devset)}')
for ex, pred, _ in failures[:3]:
    print(f'Q: {ex.question}')
    print(f'Expected: {ex.answer}')
    print(f'Got: {pred.answer}')

การใช้ตัวชี้วัดที่ให้ LLM ให้คะแนน

สำหรับผลลัพธ์ปลายเปิดที่การจับคู่แบบตรงทั้งหมดใช้ไม่ได้ ให้ใช้ LLM ให้คะแนนคุณภาพ ดีเอสพายทำให้เรื่องนี้ทำได้ง่าย โดยฟังก์ชันตัวชี้วัดของคุณสามารถเรียกใช้ตัวทำนายของดีเอสพายได้ด้วยตนเอง

import dspy

class GradeAnswer(dspy.Signature):
    """Grade whether the predicted answer is correct given the reference."""
    question: str = dspy.InputField()
    reference_answer: str = dspy.InputField()
    predicted_answer: str = dspy.InputField()
    is_correct: bool = dspy.OutputField(
        desc='True if the predicted answer is semantically correct'
    )

grader = dspy.Predict(GradeAnswer)

def llm_graded_metric(example, prediction, trace=None):
    result = grader(
        question=example.question,
        reference_answer=example.answer,
        predicted_answer=prediction.answer,
    )
    return float(result.is_correct)

# Use this metric when answers can vary in phrasing
evaluate = dspy.Evaluate(devset=devset, metric=llm_graded_metric)

การทดสอบการถดถอยด้วยการประเมิน

ให้ถือว่าชุดการประเมินของดีเอสพายเป็นชุดการทดสอบ ทุกครั้งที่คุณอัปเดตรูปแบบลายเซ็น สถาปัตยกรรมโมดูล หรือข้อมูลฝึก ให้เรียกใช้การประเมินอีกครั้งและเปรียบเทียบคะแนนเพื่อจับการถดถอย

import json
import dspy

def run_and_save_evaluation(program, program_name, testset, metric):
    evaluate = dspy.Evaluate(
        devset=testset,
        metric=metric,
        num_threads=4,
    )
    score = evaluate(program)

    # Save score to history file
    history_file = 'eval_history.json'
    try:
        with open(history_file) as f:
            history = json.load(f)
    except FileNotFoundError:
        history = []

    history.append({'program': program_name, 'score': score})
    with open(history_file, 'w') as f:
        json.dump(history, f, indent=2)

    print(f'{program_name}: {score:.1%}')
    return score

แนวทางปฏิบัติที่ดีในการประเมิน

หลักการสำคัญในการประเมินกระบวนการประมวลผลของดีเอสพาย:

  • กันชุดข้อมูลทดสอบไว้นอกกระบวนการอย่างเคร่งครัด ห้ามใช้ชุดนี้ในการปรับให้เหมาะสม
  • ใช้ตัวอย่างทดสอบอย่างน้อย 50–100 ตัวอย่างเพื่อให้ได้คะแนนที่น่าเชื่อถือ
  • เลือกตัวชี้วัดให้ตรงกับเป้าหมายการใช้งานจริงของคุณ
  • เปรียบเทียบตัวปรับให้เหมาะสมหลายแบบ เพราะผลลัพธ์แตกต่างกันไปตามงาน
  • ติดตามคะแนนตามเวลาเพื่อสังเกตการถดถอย
  • ตรวจสอบความล้มเหลวด้วยตนเองเพื่อปรับปรุงข้อมูลฝึก

ตรวจสอบความรู้: พารามิเตอร์ trace ในฟังก์ชันตัวชี้วัด

ในฟังก์ชันตัวชี้วัดของดีเอสพาย พารามิเตอร์ trace ที่ไม่เป็นค่าว่างบ่งชี้ถึงอะไร

สรุป: การประเมินกระบวนการประมวลผลของดีเอสพาย

dspy.Evaluate จะเรียกใช้โปรแกรมของคุณกับชุดข้อมูลพัฒนาที่มีป้ายกำกับ ใช้ฟังก์ชันตัวชี้วัด และรายงานคะแนนรวม ฟังก์ชันตัวชี้วัดใช้รูปแบบ (example, prediction, trace=None) -> float ใช้ num_threads สำหรับการประเมินแบบขนาน และใช้ display_table=True เพื่อวิเคราะห์ความล้มเหลว โปรดเปรียบเทียบโปรแกรมที่ปรับให้เหมาะสมกับโปรแกรมที่ยังไม่ได้ปรับให้เหมาะสมบนชุดข้อมูลทดสอบที่กันไว้นอกกระบวนการเสมอ สำหรับผลลัพธ์ปลายเปิด ตัวชี้วัดที่ให้ LLM ให้คะแนนมักให้ผลดีกว่าการจับคู่ข้อความแบบตรงทั้งหมด

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

บทเรียน “การประเมินไปป์ไลน์ DSPy” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การประเมินไปป์ไลน์ DSPy”

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

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

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

บทเรียน “การประเมินไปป์ไลน์ DSPy” ใช้เวลานานแค่ไหน

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

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

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

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

  1. บทนำสู่เฟรมเวิร์ก DSPy
  2. การกำหนดลายเซ็นและโมดูล
  3. การคอมไพล์และปรับพรอมต์ให้เหมาะที่สุด
  4. การประเมินไปป์ไลน์ DSPy
← กลับไปที่ AI Prompt Engineering