การประเมินไปป์ไลน์ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- บทนำสู่เฟรมเวิร์ก DSPy
- การกำหนดลายเซ็นและโมดูล
- การคอมไพล์และปรับพรอมต์ให้เหมาะที่สุด
- การประเมินไปป์ไลน์ DSPy