Die richtige Seite steht nicht ganz oben
Neu ordnen (Reranking) heißt, die kurze Liste einer Suche mit einem genaueren Blick in eine bessere Reihenfolge zu bringen. Das ist wichtig, weil der erste Durchgang schnell und grob ist und die passende Seite nicht immer oben steht.
Jemand fragt, wie er sein Geld zurückbekommt. Die passende Erstattungsseite steht erst auf Platz vier, hinter einer Seite über Kartenzahlung. Ein zweiter Blick hebt sie nach oben.
Das Ziel dieser Lektion
Notiz
Ich kann eine kurze Ergebnisliste mit einem zweiten Durchgang neu ordnen und sagen, ob er seine Kosten wert war.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Erster Durchgang | die schnelle Suche über den ganzen Index |
| Zweiter Durchgang | ein langsamerer Blick auf die ersten Treffer |
| Neuordner | das, was die kurze Liste erneut bewertet |
| Kandidat | ein Ergebnis, das der zweite Durchgang umordnen darf |
| Fundgrenze | das Beste, was möglich ist, gesetzt vom ersten Durchgang |
| Treffer bei k | der Anteil der Fragen mit ihrer Quelle unter den ersten k |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Erst breit und billig, dann eng
Jede Seite genau anzusehen wäre zu langsam. Deshalb arbeitet die Suche in zwei Durchgängen. Der erste Durchgang ist billig und breit: Er schrumpft Millionen Seiten auf einige Dutzend. Der zweite Durchgang ist langsam und eng: Er liest nur diese.
Die Zahlen unten sind erfunden, aber die Form ist echt: Ein genauer Blick lässt sich nur auf einer kurzen Liste bezahlen.
Durchgerechnetes Beispiel: was jeder Durchgang kostet
| Durchgang | Angesehene Seiten | Zeit je Seite | Gesamtzeit |
|---|---|---|---|
| Erster Durchgang | 1.000.000 | 0,00002 ms | 20 ms |
| Zweiter Durchgang | 20 | 5 ms | 100 ms |
| Zweiter Durchgang über alles | 1.000.000 | 5 ms | 5.000 Sekunden |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein Neuordner kann eine einfache Regel sein
Ein Neuordner ist, was die kurze Liste erneut bewertet. Das kann ein trainiertes Modell sein, ein Sprachmodell oder eine Regel, die Sie selbst schreiben. Die Regel im Run gibt 3 Punkte für ein Anfragewort im Titel und 1 für eines im Text.
Ein Sprachmodell als Neuordner liest genauer, kostet aber bei jeder Anfrage einen Aufruf, Tokens und Zeit. Beginnen Sie mit einer Regel und messen Sie.
Ein häufiger Fehler
Warnung
Viele glauben, ein Neuordner könne Seiten finden, die der erste Durchgang verpasst hat. Das kann er nicht. Er ordnet nur um, was er bekommt, also setzt der erste Durchgang die Grenze. Steht die Antwort nicht unter den ersten 20, zeigt sie kein zweiter Durchgang.
Den Modell-Helfer 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.
Den Modell-Helfer 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.
Den Neuordner schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { fragen } = require(\"./model\");' 'const anfrage = [\"erstattung\", \"geld\", \"rückgabe\"];' 'const gefunden = [' ' { id: \"c1\", titel: \"Mit Karte oder Überweisung bezahlen\", text: \"Ihr Geld verlässt Ihr Konto beim Bezahlen\" },' ' { id: \"c2\", titel: \"Fristen der Erstattung\", text: \"Ihr Geld ist nach fünf Tagen zurück nach der Rückgabe\" },' ' { id: \"c3\", titel: \"Paket mit der Bestellnummer verfolgen\", text: \"Geben Sie die Nummer ein um den Standort zu sehen\" },' ' { id: \"c4\", titel: \"Erstattung und Geld nach der Rückgabe\", text: \"senden Sie ein Paket binnen dreißig Tagen zurück und beantragen Sie die Erstattung\" },' ' { id: \"c5\", titel: \"E-Mail-Adresse ändern\", text: \"öffnen Sie Ihr Konto und bearbeiten Sie die Adresse\" },' '];' > neuordnen1.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.
Den Neuordner schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function zaehlen(text) {' ' const w = text.toLowerCase().split(\" \");' ' return anfrage.filter(function (q) { return w.includes(q); }).length;' '}' 'function punkte(c) { return 3 * zaehlen(c.titel) + zaehlen(c.text); }' 'function ids(liste) { return liste.map(function (c) { return c.id; }).join(\" \"); }' >> neuordnen1.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.
Den Neuordner schreiben, Teil 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' console.log(\"erster Durchgang:\", ids(gefunden));' ' const zweiter = gefunden.slice().sort(function (a, b) { return punkte(b) - punkte(a); });' ' console.log(\"zweiter Durchgang:\", zweiter.map(function (c) { return c.id + \"=\" + punkte(c); }).join(\" \"));' ' console.log(\"vom zweiten Durchgang gelesene Abschnitte:\", gefunden.length);' ' const oben = zweiter.slice(0, 3);' ' const zeilen = oben.map(function (c, i) { return (i + 1) + \". \" + c.titel; });' ' const auftrag = \"Welcher Abschnitt beantwortet: Wie bekomme ich mein Geld zurück? Antworten Sie nur mit einer Nummer. \" + zeilen.join(\" \");' ' const antwort = await fragen([{ role: \"user\", content: auftrag }], \"1\", 5);' ' const wahl = Number(antwort.text.trim().charAt(0));' ' console.log(\"das Modell wählt:\", wahl >= 1 && wahl <= 3 ? oben[wahl - 1].id : \"keine klare Wahl\");' '}' 'main();' >> neuordnen1.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.
Starten und die Reihenfolgen vergleichen
docker exec -w /home/node/project agent node neuordnen1.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Wann sich ein zweiter Durchgang nicht lohnt
Messen Sie die Trefferquote auf den ersten Plätzen vorher und nachher. Bewegt sie sich kaum, lassen Sie den Durchgang weg. Tun Sie das auch, wenn der erste Durchgang schon stimmt, die Liste kurz ist oder die Verzögerung Ihr Zeitbudget sprengen würde.
Der Run ist ein Platzhalter: fünf aufgezeichnete Kandidaten und eine Regel. Ein echtes System nutzt einen echten Index und ein echtes Modell.
Eine mögliche Ausgabe
| Zeile | Was sie zeigt |
|---|---|
| erster Durchgang: c1 c2 c3 c4 c5 | Die aufgezeichnete Reihenfolge des ersten Durchgangs |
| zweiter Durchgang: c4=10 c2=5 c1=1 ... | Die Regel hebt c4 an die Spitze |
| vom zweiten Durchgang gelesene Abschnitte: 5 | Die Kosten, in Abschnitten gezählt |
| das Modell wählt: c4 | Eine echte Wahl oder eine aufgezeichnete Probe |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.