Im git log unseres Seminarprojekts steht ein Commit mit der Nachricht „prompt besser“. Das war ich, im Oktober, um 23:20 Uhr. Ich hatte einen Satz umgestellt, das Ergebnis gefiel mir besser, und ich habe committet. Zwei Wochen später konnte ich nicht mehr sagen, welcher Satz das war und ob es tatsächlich besser war.

Das ist der Moment, in dem ich angefangen habe, Prompts wie Code zu behandeln. Nicht weil das ein neues Schlagwort ist, sondern weil ich die Frage „ist Version B besser als A“ nicht mit einem Gefühl beantworten wollte. Diese Frage hat eine Methodik, und die Methodik ist älter als die Sprachmodelle.

Drei Versionen, ein Testset

Die Aufgabe war Klassifikation: 150 Support-Anfragen aus einem Studierendenprojekt sollten in fünf Kategorien einsortiert werden. Ich hatte drei Prompt-Versionen. V1 war ein Satz plus Kategorieliste. V2 hatte Struktur, eine Regel pro Kategorie und die Anweisung, bei Unsicherheit „unbekannt“ zurückzugeben. V3 hatte zusätzlich drei Beispiele pro Kategorie, also fünfzehn Beispiele im Prompt.

Alle drei liefen gegen dasselbe Testset, bei Temperatur 0, dreimal pro Fall, und ich habe die Mehrheit genommen. Das ist wichtig, weil ein einzelner Lauf bei einem stochastischen Modell nichts über die Version aussagt, sondern über den Zufall.

Was der Vergleich ergeben hat

Notizbuch mit drei Prompt-Versionen und einer Tabelle mit Trefferquoten
Die drei Versionen untereinander im Notizbuch, daneben die Trefferzahlen. V3 sieht deutlich besser aus – der Unterschied zu V2 ist es aber nicht.

V1 lag bei 104 von 150, V2 bei 118, V3 bei 121. Auf den ersten Blick ist V3 die beste Version, und genau das war mein erster Gedanke. Der zweite Gedanke war: Der Abstand zwischen V2 und V3 sind drei Fälle. Bei 150 Testfällen ist das nichts.

VersionnkorrektQuote95 %-Intervall
V1 (ein Satz)15010469,3 %61,5 – 76,2 %
V2 (Regeln)15011878,7 %71,4 – 84,5 %
V3 (mit Beispielen)15012180,7 %73,6 – 86,2 %

Die Intervalle überschneiden sich breit. Wer daraus „V3 ist besser“ macht, hat die Unsicherheit in eine Rangliste übersetzt, die sie nicht hergibt. Der Unterschied zwischen V1 und V2 ist dagegen so groß, dass er auch bei dieser Fallzahl nicht wegzuerklären ist.

Was ich daraus mitgenommen habe, ist unbequem: Mit 150 Fällen kann ich einen Unterschied von drei Fällen nicht nachweisen, und das gilt für fast alle Prompt-Vergleiche, die ich im Seminar gesehen habe. Nach einer groben Rechnung braucht es ungefähr 250 Fälle, um zehn Prozentpunkte zu trennen. Wer mehr Versionen vergleicht, als sein Testset hergibt, produziert eine Rangliste ohne Substanz.

Warum ich einen gepaarten Test brauche

Die drei Versionen liefen auf denselben 150 Fällen. Das ist ein Vorteil, den ich lange nicht genutzt habe: Ich kann pro Fall vergleichen, statt zwei Quoten gegenüberzustellen. Wenn V2 und V3 auf denselben schwierigen Fällen scheitern, ist der Unterschied kleiner, als er aussieht – und wenn V3 genau die Fälle löst, die V2 verfehlt, ist er größer.

import pandas as pd
from scipy.stats import binomtest

v2 = pd.read_csv("ergebnis_v2.csv")  # spalten: fall_id, korrekt (0/1)
v3 = pd.read_csv("ergebnis_v3.csv")

paar = v2.merge(v3, on="fall_id", suffixes=("_v2", "_v3"))
b = ((paar.korrekt_v2 == 0) & (paar.korrekt_v3 == 1)).sum()  # V3 gewinnt
c = ((paar.korrekt_v2 == 1) & (paar.korrekt_v3 == 0)).sum()  # V2 gewinnt

print(f"n = {len(paar)}, V3 besser: {b}, V2 besser: {c}")
print(binomtest(b, b + c, 0.5).pvalue)   # exakter Test, zweiseitig

# Quote mit Wilson-Intervall, damit die Zahl nicht allein steht
def wilson(k, n, z=1.96):
    p, d = k / n, 1 + 1.96**2 / n
    m = (p + z**2 / (2 * n)) / d
    r = z * (p * (1 - p) / n + z**2 / (4 * n**2)) ** 0.5 / d
    return round((m - r) * 100, 1), round((m + r) * 100, 1)

for name, k in [("V2", 118), ("V3", 121)]:
    print(name, k, wilson(k, 150))

Das Ergebnis: neun Fälle, die V3 löst und V2 nicht, sechs in die andere Richtung, p-Wert 0,61. Der Unterschied ist mit 150 Fällen nicht nachweisbar. Was nicht heißt, dass er nicht existiert – es heißt, dass ich ihn mit diesem Testset nicht zeigen kann, und das ist eine andere Aussage.

Was das für die Praxis bedeutet

Ein Prompt ohne Testset ist eine Meinung. Sobald du eine Änderung committest, brauchst du eine Möglichkeit, sie zu prüfen, sonst wiederholst du meinen Commit von 23:20 Uhr. Das muss kein Framework sein: ein CSV mit Fällen, eine Spalte mit der erwarteten Antwort, ein Skript, das die Quote und das Intervall ausgibt.

Wichtiger als das Werkzeug ist die Frage, was du messen willst. Bei mir war „korrekt klassifiziert“ zu grob, weil die falschen Antworten unterschiedlich teuer sind. Eine Anfrage, die als „unbekannt“ zurückkommt, kostet einen Menschen drei Minuten. Eine, die falsch einsortiert wird, kostet eine falsche Antwort an die Person. Das sind zwei Fehlerarten, und ich habe sie zwei Wochen lang in einer Zahl versteckt.

Fazit

Prompts ändern sich schneller als Code und werden seltener getestet. Ein Testset mit 150 Fällen, ein gepaarter Test und ein Intervall neben jeder Quote kosten einen Tag Arbeit – und sie ersetzen das Gefühl, das mich im Oktober zu einem schlechten Commit verleitet hat.

Meine Frage an dich: Wie viele deiner Prompt-Änderungen der letzten Monate würdest du heute noch verteidigen, wenn jemand nach der Fallzahl fragt, auf der sie beruhen?