DSPy 파이프라인 평가
자동 평가를 위한 지표, 개발 세트, evaluate() 함수를 알아봅니다.
DSPy 파이프라인 평가은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
DSPy에서 평가가 중요한 이유
DSPy 최적화의 품질은 평가에 달려 있습니다. 약한 평가 지표를 사용하면 해당 지표에서는 높은 점수를 받지만 실제 운영에서는 실패하는 컴파일된 프로그램이 만들어집니다. 적절한 평가 도구를 사용하면 최적화하지 않은 프로그램과 최적화된 프로그램을 비교하고, 처리 흐름을 업데이트할 때 회귀 문제를 발견할 수 있습니다.
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 매개변수가 None이 아닌 값이 됩니다(평가 중에는 해당하지 않음). 이를 사용하여 컴파일 중일 때와 평가 중일 때 서로 다른 로직을 적용할 수 있습니다.
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데이터 분할: 학습, 개발, 테스트
DSPy에서는 표준 머신러닝 데이터 분할 방식을 따르십시오.
- 학습 세트: 최적화 도구가 예시 시연을 부트스트랩하는 데 사용합니다(예시 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를 사용한 병렬 처리
대규모 평가 세트를 순차적으로 처리하면 몇 시간이 걸릴 수 있습니다. dspy.Evaluate의 num_threads는 예측을 병렬로 실행하여 실제 경과 시간을 비례해서 줄여 줍니다.
num_threads를 API 속도 제한에 맞추십시오. 스레드가 너무 많으면 속도 제한 오류가 발생합니다.
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이면 DSPy가 각 예시, 예측 결과, 그리고 해당 결과가 평가 지표를 통과했는지를 자세히 보여 주는 표를 표시합니다. 이는 실패 패턴을 진단하는 데 매우 유용합니다.
다음 항목을 확인하십시오. 특정 질문 유형에서 반복되는 실패, 평가 지표의 경계 사례, 또는 학습 세트가 다루지 못하는 예시입니다.
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을 사용하여 품질을 평가하십시오. DSPy를 사용하면 이 작업을 쉽게 수행할 수 있습니다. 평가 지표 함수 자체에서 DSPy 예측기를 호출할 수 있습니다.
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)평가를 통한 회귀 테스트
DSPy 평가 모음을 테스트 모음처럼 다루십시오. 서명, 모듈 구조 또는 학습 데이터를 업데이트할 때마다 평가를 다시 실행하고 점수를 비교하여 회귀 문제를 발견하십시오.
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평가 모범 사례
DSPy 처리 흐름의 핵심 평가 원칙은 다음과 같습니다.
- 테스트 세트를 엄격하게 분리해 두고 그 세트로는 절대 최적화하지 마십시오.
- 신뢰할 수 있는 점수를 얻으려면 테스트 예시를 최소 50~100개 사용하십시오.
- 평가 지표를 실제 운영 목표에 맞추십시오.
- 여러 최적화 도구를 비교하십시오. 작업에 따라 결과가 달라집니다.
- 시간에 따른 점수를 추적하여 회귀 문제를 감지하십시오.
- 실패 사례를 직접 살펴 학습 데이터를 개선하십시오.
지식 확인: 평가 지표 함수의 Trace 매개변수
DSPy 평가 지표 함수에서 None이 아닌 trace 매개변수는 무엇을 나타냅니까?
복습: DSPy 처리 흐름 평가
dspy.Evaluate는 레이블이 지정된 개발 세트에서 프로그램을 실행하고, 평가 지표 함수를 적용한 뒤, 종합 점수를 보고합니다. 평가 지표 함수는 (example, prediction, trace=None) -> float 패턴을 따릅니다. 병렬 평가에는 num_threads를 사용하고, 실패를 진단하려면 display_table=True를 사용하십시오. 항상 분리해 둔 테스트 세트에서 최적화된 프로그램과 최적화하지 않은 프로그램을 비교하십시오. 개방형 출력에서는 LLM으로 평가하는 지표가 정확한 문자열 일치보다 더 뛰어난 성능을 보입니다.
자주 묻는 질문
“DSPy 파이프라인 평가” 강의는 무료인가요?
네 — “DSPy 파이프라인 평가” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Prompt Engineering 강의 전체를 잠금 해제할 수 있습니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
“DSPy 파이프라인 평가”에서 뭘 배우나요?
자동 평가를 위한 지표, 개발 세트, evaluate() 함수를 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 AI Prompt Engineering을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Prompt Engineering을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Prompt Engineering은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“DSPy 파이프라인 평가” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- DSPy 프레임워크 소개
- 시그니처와 모듈 정의
- 프롬프트 컴파일 및 최적화
- DSPy 파이프라인 평가