AI Prompt Engineering · Lektion

DSPy-Pipelines evaluieren

Metriken, Entwicklungsdatensätze und die Funktion evaluate() für automatisierte Bewertungen.

Lektion 4 von 413 Schritte

DSPy-Pipelines evaluieren ist eine kostenlose AI Prompt Engineering-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Prompt Engineering-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Prompt Engineering-Kurs umfasst insgesamt 4 Lektionen.

Warum Evaluation in DSPy wichtig ist

Die Qualität der DSPy-Optimierung hängt maßgeblich von Ihrer Evaluation ab. Eine schwache Metrik führt zu einem kompilierten Programm, das bei dieser Metrik gut abschneidet, aber in der Produktion versagt. Mit einem geeigneten Evaluations-Setup können Sie nicht optimierte und optimierte Programme vergleichen und Regressionen erkennen, wenn Sie Ihre Pipeline aktualisieren.

Die Klasse dspy.Evaluate

dspy.Evaluate führt Ihr Programm für einen Datensatz aus, wendet eine Metrik an und gibt aggregierte Bewertungen aus. Über num_threads wird Parallelisierung unterstützt, sodass sich große Datensätze schnell evaluieren lassen.

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%}')

Metrikfunktionen schreiben

Metrikfunktionen haben die Signatur (example, prediction, trace=None) -> float. Sie vergleichen die Vorhersage des Programms mit der Ground Truth im Beispiel.

Der Parameter trace ist während der Optimierung ungleich None (nicht während der Evaluation) — Sie können ihn verwenden, um bei der Kompilierung eine andere Logik als bei der Evaluation anzuwenden.

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)

Muster für Bestanden/Nicht-bestanden-Schwellenwerte

Für binäre Metriken können Sie einen Schwellenwert definieren: Eine Vorhersage gilt als „bestanden“, wenn sie eine Mindestqualität erreicht. Das ist nützlich, um Few-Shot-Demos während der Bootstrap-Optimierung zu filtern.

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

Daten aufteilen: Train, Dev, Test

Befolgen Sie in DSPy die üblichen Vorgehensweisen zum Aufteilen von ML-Daten:

  • Trainset: Wird vom Optimierer verwendet, um Demos zu bootstrappen (20–200 Beispiele)
  • Devset: Wird vom Optimierer während der Suche zur Validierung verwendet
  • Testset: Wird vollständig zurückgehalten und nur für die abschließende Evaluation verwendet
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)}')

Optimierte und nicht optimierte Programme vergleichen

Benchmarken Sie Ihr kompiliertes Programm immer anhand des Baseline-Programms (des nicht kompilierten Programms) auf demselben Testset. So weisen Sie nach, dass die Optimierung tatsächlich geholfen hat, und können die Verbesserung quantifizieren.

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%}')

Parallelisierung mit num_threads

Große Evaluationsdatensätze würden bei einer sequenziellen Verarbeitung Stunden benötigen. num_threads in dspy.Evaluate führt Vorhersagen parallel aus und verkürzt dadurch die benötigte Zeit proportional.

Richten Sie num_threads an den Rate Limits Ihrer API aus — zu viele Threads lösen Fehler aufgrund von Rate Limits aus.

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

Evaluationsergebnisse interpretieren

Wenn display_table=True gesetzt ist, zeigt DSPy eine detaillierte Tabelle mit jedem Beispiel, der Vorhersage und der Information, ob die Metrik erfüllt wurde. Das ist äußerst hilfreich, um Fehlermuster zu diagnostizieren.

Achten Sie auf systematische Fehler bei einem Fragetyp, Sonderfälle der Metrik oder Beispiele, die von Ihrem Trainingsdatensatz nicht abgedeckt werden.

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-bewertete Metriken verwenden

Bei offenen Ausgaben, für die ein exakter Abgleich nicht funktioniert, können Sie die Qualität von einem LLM bewerten lassen. DSPy macht das einfach — Ihre Metrikfunktion kann selbst einen DSPy-Prädiktor aufrufen.

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)

Regressionstests mit Evaluation

Behandeln Sie Ihre DSPy-Evaluationssuite wie eine Testsuite. Führen Sie jedes Mal, wenn Sie Ihre Signatur, Modularchitektur oder Trainingsdaten aktualisieren, die Evaluation erneut aus und vergleichen Sie die Bewertungen, um Regressionen zu erkennen.

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

Bewährte Verfahren für die Evaluation

Wichtige Grundsätze für die Evaluation von DSPy-Pipelines:

  • Halten Sie Ihr Testset strikt zurück — optimieren Sie niemals darauf
  • Verwenden Sie mindestens 50–100 Testbeispiele, um zuverlässige Bewertungen zu erhalten
  • Richten Sie Ihre Metrik an Ihrem tatsächlichen Produktionsziel aus
  • Vergleichen Sie mehrere Optimierer — die Ergebnisse unterscheiden sich je nach Aufgabe
  • Verfolgen Sie die Bewertungen im Zeitverlauf, um Regressionen zu erkennen
  • Untersuchen Sie Fehler manuell, um Ihre Trainingsdaten zu verbessern

Wissenscheck: Trace-Parameter der Metrikfunktion

Was zeigt ein trace-Parameter ungleich None in einer DSPy-Metrikfunktion an?

Zusammenfassung: DSPy-Pipelines evaluieren

dspy.Evaluate führt Ihr Programm für ein annotiertes Devset aus, wendet eine Metrikfunktion an und gibt aggregierte Bewertungen aus. Metrikfunktionen folgen dem Muster (example, prediction, trace=None) -> float. Verwenden Sie num_threads für die parallele Evaluation und display_table=True, um Fehler zu diagnostizieren. Vergleichen Sie optimierte und nicht optimierte Programme immer auf einem zurückgehaltenen Testset. Bei offenen Ausgaben liefern LLM-bewertete Metriken bessere Ergebnisse als der exakte Abgleich von Zeichenketten.

Kostenlos starten

Lerne AI Prompt Engineering mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
53
Lektionen
199

Häufig gestellte Fragen

Ist die Lektion „DSPy-Pipelines evaluieren“ kostenlos?

Ja — der vollständige Text von „DSPy-Pipelines evaluieren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Prompt Engineering-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Prompt Engineering-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „DSPy-Pipelines evaluieren“?

Metriken, Entwicklungsdatensätze und die Funktion evaluate() für automatisierte Bewertungen. Du übst AI Prompt Engineering mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um AI Prompt Engineering zu starten?

Keine Vorkenntnisse erforderlich. AI Prompt Engineering auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „DSPy-Pipelines evaluieren“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser AI Prompt Engineering-Lektion Code schreiben und ausführen?

Ja. Jede AI Prompt Engineering-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Einführung in das DSPy Framework
  2. Signaturen und Module definieren
  3. Prompts kompilieren und optimieren
  4. DSPy-Pipelines evaluieren
← Zurück zu AI Prompt Engineering