AACsearch
Relevance Studio

Learning to Rank

Die LTR-Pipeline im Relevance Studio — Click-Feedback, Position-Bias-Korrektur, Training, Modell-Versionierung, A/B-Tests und Aktivierung. Wie man z-Test-Signifikanz interpretiert und einen Sieger wählt.

Learning to Rank (LTR) ist die geschlossene Feedback-Loop, die echte User-Klicks in ein gelerntes Ranking-Modell überführt. Studio liefert die vier Panels, die zu den vier Stufen der Pipeline passen: Click-Feedback, Training Runs, Modelle und A/B-Tests.

Pipeline auf einen Blick

clicks (SearchUsageEvent)

   ▼   Position-Bias-Korrektur (Debias)

   ▼   Training (LightGBM-Shim heute, natives LightGBM/XGBoost zurückgestellt)

   ▼   Modell-Artefakt + Metriken (NDCG, MRR, AUC)

   ▼   A/B-Test: Traffic-Split, z-Test-Signifikanz

   ▼   Sieger aktivieren → Ranking am Read-Pfad

Jede Stufe ist reversibel. Ein schlechtes Modell ist einen Klick weit von der De-Aktivierung entfernt — das vorherige aktive Modell bleibt immer erhalten.

1 · Click-Feedback

Das Panel Click-Feedback fasst das Rohsignal zusammen, das den Trainer speist. Drei Zahlen pro Index:

  • Klicks mit Kontext — wie viele click-Events mit gültigem queryId und position ankamen. Ohne queryId kann ein Klick keiner Query zugeordnet werden.
  • Position-Bias-Korrektur — die aktuell wirkende Debias-Kurve. Position- Bias ist das bekannte Phänomen, dass Position 1 unabhängig von Relevanz geklickt wird. Der korrigierte Score ist grob observed_ctr / propensity[position], wobei propensity pro Index gefittet wird.
  • Verwertbare Trainings-Zeilen — nach Debias und Zero-Result-Filter, wie viele Zeilen für den Trainer in Frage kommen.

Sind verwertbare Zeilen unter ~5k, weigert sich Training und zeigt ein "nicht genügend Signal"-Banner. Unterhalb dieser Schwelle überfittet das Modell und ist schlechter als der statische Ranker.

2 · Training Runs

Ein Trainings-Run erzeugt ein Modell-Artefakt aus einem gewählten Click- Feedback-Fenster. In Studio wählen Sie:

  • Fenster — letzte 7, 30 oder 90 Tage.
  • Algorithmus — derzeit shim (einzige Option in produktiven Releases). Natives LightGBM und XGBoost sind zurückgestellt — siehe Hinweis unten.
  • Features — vordefinierter Feature-Satz (Textrelevanz, Aktualität, Preis, Popularität, Kategorie-Kohorte). Custom-Features sind auf der Roadmap.

Der Run zeigt Fortschritt und nach Abschluss drei Metriken:

MetrikBedeutung
NDCG@10Normalized Discounted Cumulative Gain bei Top-10 — Primärmetrik
MRRMean Reciprocal Rank des ersten geklickten Treffers
AUCFläche unter der Klick-vs-Nichtklick-Kurve

Aktueller Shim-Status (Mai 2026)

Der ausgelieferte LTR-Trainer ist ein Shim-Algorithmus: ein vereinfachter Linear-Combiner, der wenige Gewichte über die vorberechneten Features fittet. Er ist bewusst konservativ und läuft hinter dem Feature- Flag ltr.shim.

Die vollwertigen nativen LightGBM- und XGBoost-Trainer sind zurückgestellt. Sie sind hinter dem Flag ltr.native implementiert, aber nicht GA — sie brauchen zusätzlichen Lasttest und ein Model-Registry-Rollout. Derzeit gilt der Shim als einziger unterstützter Algorithmus, und Sie sollten 5–15% NDCG@10-Lift gegenüber der unranked Baseline erwarten, nicht die 25–40% mancher Paper. Kunden, die natives LightGBM heute brauchen, können sich an den Support für eine private Preview wenden.

3 · Modelle

Jeder erfolgreiche Run produziert ein Modell im Panel Modelle. Modelle sind unveränderlich und tragen:

  • versionierte ID (mdl_<random>), Erstellungs-Zeitstempel, Source-Trainings-Run,
  • das Metrik-Tupel (NDCG@10, MRR, AUC),
  • Feature-Satz und Fenster, auf dem trainiert wurde,
  • Deployment-Status: draft, in_ab_test, active, oder archived.

Ein Modell in active ist das, was der Read-Pfad bei jeder Suchanfrage für diesen Index konsultiert. Es gibt zu jedem Zeitpunkt genau ein aktives Modell pro Index.

4 · A/B-Tests

Sie befördern ein Modell nicht von draft direkt zu active. Stattdessen starten Sie einen A/B-Test, der Live-Traffic zwischen Kandidat (Arm B) und aktivem Modell (Arm A, Kontrolle) splittet.

A/B-Test starten

Von Studio → LTR → A/B-Tests → Neuer Test:

// Was Studio intern macht — auch direkt aufrufbar
import { client } from "@repo/api/client";

const test = await client.ltr.abTests.create.call({
  indexSlug: "products",
  controlModelId: "mdl_active_now",
  variantModelId: "mdl_candidate",
  trafficSplit: 0.10, // 10% des Live-Suchverkehrs sehen Arm B
  primaryMetric: "ctr", // ctr | cvr | ndcg10
  minSampleSize: 50_000, // Suchen pro Arm bevor Signifikanz berechnet wird
});

Der Traffic-Split erfolgt pro Suchanfrage, nicht pro User — derselbe User kann über Sessions in unterschiedlichen Armen landen. Das Variant-Modell gilt für Arm B; Arm A nutzt weiterhin das aktive Modell.

Ergebnisse lesen

Während der Test läuft, zeigt das Panel Live-Counter pro Arm:

  • n — dem Arm zugewiesene Suchen.
  • clicks, ctr, cvr — Primärmetriken, alle 5 Minuten aktualisiert.
  • z-Score — standardisierte Differenz von Arm B zu Arm A auf der Primärmetrik.
  • p-Wert — zweiseitig.
  • Entscheidungrunning, significant_win, significant_loss, ±borderline oder no_effect.

Wie man Signifikanz interpretiert

Der Trainer nutzt einen Standard-Two-Proportion-z-Test und behandelt jede Suche als unabhängiges Bernoulli-Experiment auf der Primärmetrik. Schwellen:

Entscheidungz-BereichBedeutung
significant_winz ≥ +1,96 (p ≤ 0,05)Kandidat schlägt Kontrolle mit 95% Konfidenz.
significant_lossz ≤ −1,96Kandidat verliert mit 95% Konfidenz — Test abbrechen.
±borderline1,65 ≤ |z| < 1,9690–95% Konfidenz — auf mehr Daten warten oder vorab entscheiden.
no_effect|z| < 1,65 und n ≥ minSampleSizeKein erkennbarer Unterschied bei dieser Stichprobe.
runningn < minSampleSizeNoch nicht genügend Daten.

Das ±borderline-Band wird bewusst als eigene Entscheidung gezeigt, weil viele Produktteams eine Vor-Test-Regel haben wie "Ship bei 90%, wenn Delta positiv; Halten bei 95%, wenn negativ". Studio promoviert bei Borderline nicht automatisch — ein Mensch muss Sieger aktivieren klicken.

Stichproben-Größen-Leitfaden

Default für minSampleSize ist 50.000 Suchen pro Arm. Bei 10% Split erreicht ein Index mit 50k Suchen/Tag in etwa 11 Tagen Signifikanz bei einem Effekt von 2 Prozentpunkten CTR. Kleinere Indizes brauchen 3–4 Wochen. Das Studio-Panel zeigt eine Live-ETA.

Sieger aktivieren

Bei significant_win (oder Entschluss zum Ship bei ±borderline) klicken Sie Sieger aktivieren im A/B-Panel. Das:

  1. Setzt das Variant-Modell auf active.
  2. Stuft das vorherige aktive Modell auf archived (Ein-Klick-Reaktivieren, falls das neue Modell in Produktion regrediert).
  3. Schließt den A/B-Test mit Endbericht.
  4. Routet 100% Live-Traffic durch das neue Modell binnen ~60 Sekunden (Policy-Cache-LRU-TTL).
await client.ltr.abTests.activateWinner.call({
  testId: test.id,
  // optionaler Safety-Check — verweigert, falls Live-Entscheidung
  // zwischen Fetch und Call von `significant_win` abgewichen ist
  expectedDecision: "significant_win",
});

Falls Sie nach Aktivierung zurückrollen müssen, hält das Modelle-Panel das vorherige aktive Modell als archived und bietet Ein-Klick-Reaktivieren.

Best Practices

  • Immer einen A/B-Test fahren. Selbst Modelle, die offline auf NDCG gewinnen, können live auf CTR regredieren — Position-Bias und Präsentation zeigen sich nicht in Offline-Metriken.
  • Wählen Sie die Metrik, die zum Geschäft passt. CTR ist Default; conversion-getriebene Kataloge setzen primaryMetric: "cvr".
  • Nicht "Peek-and-Stop". Der z-Test geht von fester Stichprobengröße aus — Früh-Stoppen bei guten Zwischenständen treibt die Falsch-Positiv-Rate hoch. Stichprobe festlegen, weggehen, danach entscheiden.
  • Aggressiv archivieren. Halten Sie pro Index 5–10 archivierte Modelle — der Registry ist günstig, aber das Audit-Log wird mit weniger Zeilen übersichtlicher.

Verwandt

On this page