Vai al contenuto
Pagine

Concetti

Metriche e scorer

Scrivi la funzione di punteggio che indica al motore che cosa significa «migliore».

La metrica indica a Skynet quanto è buono un output. È una funzione Python in metric.py. Ogni motore chiama la stessa funzione. Questa pagina descrive il contratto, il valore restituito e alcuni esempi.

Il contratto

def score(input, output, expected=None):
    ...
    return score_value, {"feedback": "..."}
ArgomentoChe cosa contiene
inputUn dict con i campi di input del caso
outputCiò che la tua run(artifact, input) ha restituito per il caso
expectedIl valore atteso del caso, oppure None se il caso non ne ha uno

Se la tua funzione accetta solo due argomenti, Skynet chiama score(input, output).

Per un programma DSPy, Skynet adatta la chiamata della metrica DSPy a questa stessa funzione. Scrivi una sola metrica per ogni tipo di artefatto. Leggi Come funziona l'ottimizzazione.

Il valore restituito

score deve restituire una coppia (una tupla o una lista di due elementi):

  1. Il punteggio. Un numero. L'ottimizzatore cerca di aumentarlo.
  2. Le informazioni aggiuntive. Un dict. Deve avere una chiave "feedback" con un valore stringa.

Le informazioni aggiuntive possono avere anche una chiave "scores". Associa nomi a numeri, ad esempio {"format": 1.0, "accuracy": 0.5}.

Se il valore restituito ha una forma diversa, il controllo del contratto non supera Valore restituito dalla metrica.

Valore restituitoValido
(0.8, {"feedback": "Close. Missing the date."})Sì
[1.0, {"feedback": "OK", "scores": {"format": 1.0}}]Sì
0.8No. Mancano le informazioni aggiuntive.
(0.8, "Close.")No. Le informazioni aggiuntive non sono un dict.
(0.8, {})No. Manca la stringa di feedback.
("0.8", {"feedback": "OK"})No. Il punteggio è una stringa.
(0.8, {"feedback": "OK", "scores": {"a": "high"}})No. Un punteggio con nome non è un numero.

Scrivere un feedback utile

GEPA, DSPy GEPA e Auto leggono il testo del feedback per scrivere la versione successiva. Indica che cosa è sbagliato e com'è un output corretto.

Feedback deboleFeedback utile
«Sbagliato.»«Atteso 'billing', ottenuto 'other'. Il messaggio parla di un addebito.»
«Formato errato.»«L'output non è JSON valido. Ha una virgola finale dopo l'ultimo campo.»

Esempi

Corrispondenza esatta

def score(input, output, expected=None):
    want = expected["label"]
    if output == want:
        return 1.0, {"feedback": "Correct."}
    return 0.0, {"feedback": f"Expected {want!r}, got {output!r}."}

expected è un dict con il nome della tua colonna Output come chiave. Leggi Dataset e suddivisioni.

Più controlli

import json


def score(input, output, expected=None):
    try:
        data = json.loads(output)
    except ValueError as exc:
        return 0.0, {"feedback": f"Output is not valid JSON: {exc}", "scores": {"format": 0.0, "fields": 0.0}}
    want = expected["fields"]
    found = [key for key in want if key in data]
    fields = len(found) / len(want) if want else 1.0
    missing = [key for key in want if key not in data]
    feedback = "All fields present." if not missing else f"Missing fields: {', '.join(missing)}."
    return 0.5 + 0.5 * fields, {"feedback": feedback, "scores": {"format": 1.0, "fields": fields}}

Modello come giudice

La metrica può chiamare un modello. Importa llm dal modulo di supporto skynet. Una chiamata dalla metrica va al modello della metrica.

from skynet import llm


def score(input, output, expected=None):
    verdict = llm(
        "Answer PASS or FAIL, then give one sentence of reasons.",
        input=f"Question: {input['question']}\nAnswer: {output}",
    )
    passed = str(verdict).strip().upper().startswith("PASS")
    return (1.0 if passed else 0.0), {"feedback": str(verdict)}

Se non selezioni un Modello della metrica, la metrica usa lo stesso modello del modello di riflessione.

Accuratezza, velocità e costo

Una metrica può combinare l'accuratezza con il tempo di esecuzione misurato e il costo del modello. Definisci REWARD_SPEC a livello di modulo e restituisci il valore di reward.

from skynet import reward

REWARD_SPEC = {
    "weights": {"accuracy": 0.7, "speed": 0.2, "cost": 0.1},
    "accuracy": {},
    "speed": {"reference": 2000},
    "cost": {"reference": 0.01},
}


def score(input, output, expected=None):
    ok = output == expected["label"]
    return reward(REWARD_SPEC, 1.0 if ok else 0.0, "Correct." if ok else "Wrong label.")
  • weights deve contenere accuracy, speed e cost. Ogni peso è 0 o maggiore, e non possono essere tutti 0. Skynet li normalizza in modo che la somma sia 1.
  • speed.reference è in millisecondi. cost.reference è in dollari USA. Entrambi devono essere positivi.
  • Senza accuracy.reference, l'accuratezza è un punteggio da 0 a 1. Con esso, l'accuratezza è un errore, e un valore più basso è migliore.

Skynet misura direttamente il tempo e il costo. Il codice di esecuzione non può modificarli. Se Skynet non riesce a misurare il tempo o il costo, quella parte ottiene 0 e il feedback lo segnala.

La metrica può anche leggere direttamente le misurazioni con observation() e service_cost() di skynet.

Limiti

ElementoValore
Timeout della metrica60 secondi per impostazione predefinita, al massimo 600
Campioni del controllo del contratto3 casi

Pagine correlate