Einen Build an einem schlechten Prompt scheitern lassen
Ein Team ändert am Freitag einen Prompt. Am Montag sehen Kundinnen und Kunden schlechtere Antworten. Niemand hat auf den Wert geschaut, weil nichts dazu zwang.
Ein Regressionstest im Build verhindert das. Das Modul über Evals und Tests für modellbasierte Funktionen vergleicht zwei Läufe von Hand. Diese Lektion lässt den Vergleich eine Änderung selbst stoppen.
Am Ende dieser Lektion
Notiz
Ich kann einen schlechteren Prompt einen Build scheitern lassen.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Build | die automatischen Prüfungen, die bei einer Änderung laufen | |
| Eingefrorene Menge | eine Referenzmenge, die sich zwischen Läufen nicht ändert | |
| Schranke | die niedrigste Erfolgsquote, die eine Änderung haben darf | 80 |
| Pflichtfall | ein Fall, der nie von bestanden auf nicht bestanden fallen darf | |
| Exitcode | die Zahl, mit der ein Programm endet; null heißt in Ordnung |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Eine eingefrorene Menge und eine Schranke
Der Build lässt Ihre Funktion jedes Mal über dieselbe eingefrorene Menge laufen. Änderte sich die Menge mit dem Prompt, könnten Sie zwei Läufe nicht vergleichen.
Dann wählen Sie eine Schranke, zum Beispiel 80 Prozent. Eine Änderung, die darunter bleibt, lässt den Build scheitern.
Die geänderten Fälle zählen am meisten
Eine Quote versteckt Bewegung. Ein Fall kann kaputtgehen, während ein anderer repariert wird, und die Quote bleibt gleich.
Darum listet der Build auch die geänderten Fälle auf. Ein kaputter Fall bestand vorher und scheitert jetzt. Ein reparierter Fall ist das Gegenteil.
Durchgerechnetes Beispiel: zwölf Fälle, zwei Läufe
| Messgröße | Alter Lauf | Neuer Lauf |
|---|---|---|
| Bestandene Fälle | 10 von 12 | 9 von 12 |
| Erfolgsquote, ganze Prozent | 83 | 75 |
| Kaputte Fälle | - | 4 und 7 |
| Reparierte Fälle | - | 6 |
| Pflichtfall kaputt | - | Ja, Fall 4 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein häufiger Fehler
Warnung
Viele denken, eine Quote über der Schranke heiße, die Änderung sei sicher. Ein Pflichtfall kann kaputtgehen, während die Quote hoch bleibt. Prüfen Sie zuerst die Pflichtfälle und danach die Quote.
Ein Exitcode steuert den Build
Ein Programm endet mit einer Zahl. Null heißt in Ordnung, jede andere Zahl heißt Problem. Der Build hält an, sobald er eine Zahl sieht, die nicht null ist.
Wir nehmen 2 für einen kaputten Pflichtfall, 1 für eine Quote unter der Schranke und 0 fürs Bestehen. Die Prüfung der Pflichtfälle kommt zuerst.
Die Modellhilfe schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const basis = process.env.AI_URL || \"http://ai:4000\";' '// Die Token einer Antwort oder null, wenn sie keine nennt.' 'function zaehlen(daten, name) {' ' return daten.usage && typeof daten.usage[name] === \"number\" ? daten.usage[name] : null;' '}' > model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Modellhilfe schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function fragen(nachrichten, probe, max) {' ' try {' ' const res = await fetch(basis + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: nachrichten, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"Status \" + res.status);' ' const d = await res.json();' ' return { text: d.choices[0].message.content, eingabe: zaehlen(d, \"prompt_tokens\"), ausgabe: zaehlen(d, \"completion_tokens\"), aufgezeichnet: false };' ' } catch (fehler) {' ' console.log(\"Aufgezeichnete Probe: Kein Modell hat geantwortet (\" + fehler.message + \").\");' ' return { text: probe, eingabe: null, ausgabe: null, aufgezeichnet: true };' ' }' '}' 'module.exports = { fragen };' >> model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Build-Schranke schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { fragen } = require(\"./model\");' 'const schranke = 80;' 'const zeilen = [' ' \"1 p 1 1\", \"2 n 1 1\", \"3 n 1 1\", \"4 p 1 0\",' ' \"5 n 1 1\", \"6 n 0 1\", \"7 n 1 0\", \"8 n 1 1\",' ' \"9 p 1 1\", \"10 n 0 0\", \"11 n 1 1\", \"12 n 1 1\",' '].map(function (z) {' ' const t = z.split(\" \");' ' return { id: Number(t[0]), pflicht: t[1] === \"p\", alt: t[2] === \"1\", neu: t[3] === \"1\" };' '});' > schranke.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Build-Schranke schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function quote(schluessel) {' ' const n = zeilen.filter(function (z) { return z[schluessel]; }).length;' ' return Math.floor(n * 100 / zeilen.length);' '}' 'const kaputt = zeilen.filter(function (z) { return z.alt && z.neu === false; });' 'const repariert = zeilen.filter(function (z) { return z.alt === false && z.neu; });' 'function nummern(liste) {' ' return liste.length === 0 ? \"keine\" : liste.map(function (z) { return z.id; }).join(\", \");' '}' >> schranke.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Build-Schranke schreiben, Teil 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function exitcode() {' ' if (kaputt.some(function (z) { return z.pflicht; })) return 2;' ' if (quote(\"neu\") < schranke) return 1;' ' return 0;' '}' 'async function main() {' ' console.log(\"Quote: \" + quote(\"alt\") + \" -> \" + quote(\"neu\") + \" (Schranke \" + schranke + \")\");' ' console.log(\"kaputt: \" + nummern(kaputt) + \" repariert: \" + nummern(repariert));' ' console.log(\"Exitcode: \" + exitcode());' ' const q = \"Schreiben Sie einen ruhigen Satz für einen Pull-Request: Fall 4 bestand vorher und scheitert jetzt.\";' ' const probe = \"Fall 4 bestand mit dem alten Prompt und scheitert mit diesem, daher wird der Build gestoppt.\";' ' const antwort = await fragen([{ role: \"user\", content: q }], probe, 60);' ' console.log(\"Kommentar: \" + antwort.text);' '}' 'main();' >> schranke.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Build-Schranke ausführen
docker exec -w /home/node/project agent node schranke.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Was die Schranke ausgibt
| Zeile | Was sie zeigt |
|---|---|
| Quote: 83 -> 75 (Schranke 80) | Alte und neue Quote und die Schranke |
| kaputt: 4, 7 repariert: 6 | Die Fälle, die sich geändert haben |
| Exitcode: 2 | Fall 4 ist ein Pflichtfall, also stoppt der Build |
| Kommentar: ... | Ein Satz aus dem Labor. Eine Aufgezeichnete Probe, wenn kein Modell antwortet |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.