AI Prompt Engineering · Aula

Avaliando pipelines do DSPy

Métricas, conjuntos de desenvolvimento e a função evaluate() para avaliação automatizada.

Aula 4 de 413 etapas

Avaliando pipelines do DSPy é uma aula grátis de AI Prompt Engineering no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Prompt Engineering, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Prompt Engineering inclui 4 aulas no total.

Por que a avaliação é importante no DSPy

A otimização do DSPy só é tão boa quanto a sua avaliação. Uma métrica fraca produz um programa compilado que obtém uma boa pontuação nessa métrica, mas falha em produção. Uma estrutura de avaliação adequada permite comparar programas não otimizados e otimizados e detectar regressões quando você atualiza seu fluxo de processamento.

A classe dspy.Evaluate

dspy.Evaluate executa seu programa em um conjunto de dados, aplica uma métrica e informa as pontuações agregadas. Ela oferece paralelismo por meio de num_threads para realizar avaliações rapidamente em conjuntos de dados grandes.

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

Escrevendo funções de métrica

As funções de métrica têm a assinatura (example, prediction, trace=None) -> float. Elas comparam a previsão do programa com a resposta correta de referência presente no exemplo.

O parâmetro trace é diferente de None durante a otimização, mas não durante a avaliação — você pode usá-lo para aplicar lógicas diferentes na compilação e na avaliação.

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)

Padrões de limiar de aprovação e reprovação

Para métricas binárias, você pode definir um limiar: uma previsão é considerada aprovada se atingir um nível mínimo de qualidade. Isso é útil para filtrar demonstrações com poucos exemplos durante a otimização por inicialização.

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

Divisão de dados: treino, desenvolvimento e teste

Siga as práticas padrão de divisão de dados de aprendizado de máquina no DSPy:

  • Conjunto de treino: usado pelo otimizador para inicializar demonstrações (20–200 exemplos)
  • Conjunto de desenvolvimento: usado pelo otimizador para validação durante a busca
  • Conjunto de teste: mantido totalmente separado — usado apenas para a avaliação final
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)}')

Comparando programas otimizados e não otimizados

Sempre compare o desempenho do seu programa compilado com o do programa de referência, não compilado, no mesmo conjunto de teste. Isso comprova que a otimização realmente ajudou e quantifica a melhoria.

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

Paralelismo com num_threads

Conjuntos de avaliação grandes levariam horas para ser processados sequencialmente. num_threads em dspy.Evaluate executa as previsões em paralelo, reduzindo proporcionalmente o tempo real decorrido.

Ajuste num_threads aos limites de taxa da sua API — o excesso de threads provoca erros de limite de taxa.

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

Interpretando a saída da avaliação

Quando display_table=True, o DSPy exibe uma tabela detalhada com cada exemplo, a previsão e a indicação de aprovação ou reprovação na métrica. Isso é extremamente útil para diagnosticar padrões de falha.

Procure por: falhas sistemáticas em um tipo de pergunta, casos extremos da métrica ou exemplos que não são contemplados pelo seu conjunto de treinamento.

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

Usando métricas avaliadas por LLM

Para saídas abertas nas quais a correspondência exata falha, use um LLM para avaliar a qualidade. O DSPy facilita esse processo — sua função de métrica pode chamar um preditor do 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)

Testes de regressão com avaliação

Trate seu conjunto de avaliação do DSPy como um conjunto de testes. Sempre que atualizar sua assinatura, a arquitetura do módulo ou os dados de treinamento, execute novamente a avaliação e compare as pontuações para detectar regressões.

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

Boas práticas de avaliação

Princípios fundamentais de avaliação para fluxos de processamento do DSPy:

  • Mantenha seu conjunto de teste rigorosamente separado — nunca o use para otimização
  • Use pelo menos 50–100 exemplos de teste para obter pontuações confiáveis
  • Alinhe sua métrica ao seu objetivo real em produção
  • Compare vários otimizadores — os resultados variam conforme a tarefa
  • Acompanhe as pontuações ao longo do tempo para detectar regressões
  • Inspecione as falhas manualmente para melhorar seus dados de treinamento

Verificação de conhecimento: parâmetro trace da função de métrica

Em uma função de métrica do DSPy, o que indica um parâmetro trace diferente de None?

Recapitulação: avaliando fluxos de processamento do DSPy

dspy.Evaluate executa seu programa em um conjunto de desenvolvimento rotulado, aplica uma função de métrica e informa as pontuações agregadas. As funções de métrica seguem o padrão (example, prediction, trace=None) -> float. Use num_threads para avaliação paralela e display_table=True para diagnosticar falhas. Sempre compare programas otimizados e não otimizados em um conjunto de teste separado. Para saídas abertas, as métricas avaliadas por LLM superam a correspondência exata de cadeias de texto.

Grátis para começar

Aprenda AI Prompt Engineering com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
53
Aulas
199

Perguntas Frequentes

A aula “Avaliando pipelines do DSPy” é grátis?

Sim — o texto completo de “Avaliando pipelines do DSPy” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Prompt Engineering, atualize para CoddyKit PRO. O curso de AI Prompt Engineering inclui 4 aulas no total.

O que vou aprender em “Avaliando pipelines do DSPy”?

Métricas, conjuntos de desenvolvimento e a função evaluate() para avaliação automatizada. Você pratica AI Prompt Engineering com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Prompt Engineering?

Nenhuma experiência prévia é necessária. AI Prompt Engineering no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Avaliando pipelines do DSPy”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Prompt Engineering?

Sim. Cada aula de AI Prompt Engineering inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Introdução ao framework DSPy
  2. Definindo assinaturas e módulos
  3. Compilando e otimizando prompts
  4. Avaliando pipelines do DSPy
← Voltar para AI Prompt Engineering