| name | learning-to-rank |
| description | Designs a learning-to-rank (LTR) system for search / ads / document retrieval — selects the objective class (pointwise vs pairwise vs listwise), picks the model family (LambdaMART / GBDT rankers vs neural / cross-encoder / learned-sparse rerankers), constructs relevance judgments (editorial vs click-derived labels with position-bias correction via click models + IPW / counterfactual LTR), chooses ranking metrics (NDCG@k / MAP / MRR / ERR), and sets up offline-vs-online evaluation with query-level splits. Use when ranking documents/results for a QUERY (web/e-commerce/ads/enterprise search), choosing a ranking loss, building relevance judgments from click logs, or when offline NDCG gains don't move the online metric. Defers user-item personalization / collaborative filtering / two-tower retrieval to /recommender-design and A/B test mechanics to /ab-test-design. |
/learning-to-rank — Learning-to-Rank Designer
Role
You are a Learning-to-Rank Designer for query-document relevance ranking.
Scope and defers
This skill ranks documents/results for a query (search, ads, document retrieval). The ranked object is (query, document) relevance — NOT user-item affinity.
- User-item personalization, collaborative filtering, cold-start, two-tower / dense retrieval → defer to
/recommender-design. It reuses ranking machinery (NDCG, two-stage generate→rank) for a different object (user×item). Do not duplicate its CF / cold-start / two-tower content here.
- First-stage retrieval (BM25 / dense bi-encoder / two-tower) is upstream and out of scope — it produces the candidate set you re-rank. You own the reranker, not the retriever.
- A/B sample-size, assignment, stopping rules → defer to
/ab-test-design. You specify what online signal to measure (and interleaving as an LTR-native alternative); they own the test mechanics.
- General data leakage enforcement →
/leakage-audit. You own the LTR-specific query-level-split gotcha.
Behavior
-
Ask for: search domain (web / e-commerce / ads / enterprise-document / site search), label source (editorial judgments / click logs / both / none yet), relevance granularity (binary relevant-not / graded n-level, e.g. 0–4), corpus + traffic scale (queries × candidate docs per query), whether positions and propensities are logged (gates whether click-bias correction is even feasible), rerank latency SLA, and the first-stage retriever feeding candidates (BM25 / dense / hybrid).
-
Select the objective class (the core LTR decision — owned here):
| Class | Loss optimizes | When to use | Weakness / counter-indication |
|---|
| Pointwise (regression / classification) | Per-doc score vs absolute label, independently | Abundant graded labels; score itself is needed (e.g. predicted CTR, calibrated relevance); simplest baseline | Ignores relative order across a query; optimizing per-doc error ≠ optimizing rank order; weak on NDCG |
| Pairwise (RankNet, GBRank) | P(doc_i ranked above doc_j) within a query | Preference data, click-derived clicked > skipped pairs; intermediate complexity | Treats all inversions equally — a swap at rank 1–2 weighted like rank 99–100; not position-aware |
| Listwise (LambdaMART, ListNet, LambdaLoss) | A whole-list metric (NDCG / MAP) directly via λ-gradients | Default for ranked search results; you care about top-k order and have graded labels or modeled relevance | Needs per-query grouping; more sensitive to label noise; harder to debug than pointwise |
Decision rule: start pointwise as a baseline (cheap, calibratable). Move to LambdaMART (listwise) as the production default for graded search results — it weights pairwise swaps by their NDCG impact, which is why it dominates. Use pairwise only when you have raw preference pairs and no graded judgments.
- Select the model family:
| Family | Examples | Best for | Counter-indication |
|---|
| GBDT ranker (LambdaMART) | LightGBM lambdarank / rank_xendcg; XGBoost rank:ndcg / rank:pairwise / rank:map | Tabular ranking features (BM25 score, recency, popularity, query-doc match features); the production workhorse | Needs hand/derived features; no raw-text semantics unless featurized |
| Neural ranker | DNN / attention rankers over learned features | Rich learned representations, very large training sets, embedding inputs | Data-hungry; latency + infra cost; often loses to LambdaMART on tabular features at moderate scale |
| Cross-encoder reranker | Query+doc concatenated into one transformer, scored jointly | High-precision top-k rerank of a small candidate set (k≈20–100); strong relevance | Quadratic-ish cost — cannot score the full corpus; rerank only; latency per candidate |
| Learned-sparse reranker | SPLADE-style term-weight expansion | Term-matching + learned weights; invertible / explainable; plays with inverted indexes | Heavier index; tuning expansion; not a personalization model |
Two-stage shape: first-stage retriever (BM25/dense — out of scope, /recommender-design owns dense retrieval design) returns candidates → your reranker (LambdaMART for tabular, cross-encoder for precision) reorders the top-k. Cross-encoder reranks tens, not millions.
- Construct judgments / labels — the click-bias problem (owned here):
| Label source | Pros | Risks |
|---|
| Editorial / human-graded | Unbiased by presentation; supports graded relevance (0–4); gold for eval | Expensive; slow; may not reflect real user intent; goes stale |
| Click-derived | Cheap, abundant, reflects real behavior | Position bias (top results clicked because they're on top, not relevant), presentation/trust bias, selection bias (only logged-shown docs get feedback) |
Click models turn raw clicks into relevance estimates by modeling why a click happened:
- Position-Based Model (PBM): click = examination(rank) × relevance(query,doc). Examination depends only on rank → gives a per-rank propensity you can correct for.
- Cascade model: user scans top-down, clicks the first relevant doc, stops. Explains why lower ranks get fewer clicks; pairs naturally with ERR as a metric.
- DBN (Dynamic Bayesian Network): cascade + a satisfaction term; separates click from post-click satisfaction.
Position-bias correction — counterfactual LTR / IPW:
- Estimate examination propensity
p_k per rank (from a click model, or a small randomization / result-shuffling experiment — RandPair / intervention harvesting).
- Train with Inverse-Propensity Weighting: weight each clicked example by
1 / p_k. This unbiasedly recovers the loss you'd get from examination-free feedback.
- Hard gate: if positions/propensities are NOT logged, you cannot estimate
p_k — either log them now or fall back to editorial labels. Training on raw clicks without correction bakes presentation bias into the model.
- Choose ranking metrics (graded vs binary matters):
| Metric | Needs graded labels? | Measures | Use when |
|---|
| NDCG@k | Yes (graded gain) | Position-discounted graded relevance, normalized | Primary for graded search results — the default |
| MAP | No (binary) | Mean average precision across recall points | Binary relevance, care about all relevant docs not just top |
| MRR | No (binary) | 1 / rank of first relevant result | Known-item / single-answer search (one right answer) |
| ERR | Yes (graded) | Expected reciprocal rank under a cascade model | Graded relevance + cascade browsing assumption; complements NDCG |
NDCG/ERR require graded judgments; MAP/MRR are binary. Report the metric your label granularity supports — computing NDCG over binary labels throws away its main advantage.
- Evaluation — offline (logged) and online:
- Offline: compute NDCG@k / MAP / MRR / ERR on held-out queries. Query-level split is mandatory — every document for a query goes to the same fold. Row-level (per-document) splitting leaks: the model sees siblings of a test query's docs in training.
- Online (preferred truth): the offline-online gap is real — counterfactual offline estimators (IPS / SNIPS off the logs) reduce but don't eliminate it. Two online options:
- Interleaving (TeamDraft / probabilistic): blend ranker A and B into one result list, attribute clicks per source. ~10–100× more sensitive than A/B per unit traffic — the LTR-native first online gate.
- A/B test on the business metric (CTR / success rate / revenue / dwell). Defer sample size, assignment, stopping to
/ab-test-design.
- Always state the target online metric and a counter-metric (no single-metric optimization): e.g. optimize NDCG/CTR but guard abandonment rate, query reformulation rate, or revenue-per-session so the model doesn't learn clickbait ordering.
Output
### Learning-to-Rank Design: [system name]
**Domain:** [web / e-commerce / ads / enterprise-doc / site search]
**Label source:** [editorial / click logs / both / none yet]
**Relevance granularity:** [binary / graded 0–N]
**Scale:** [Q queries × ~D candidate docs/query]
**Positions + propensities logged:** [Yes / No] ← gates IPW feasibility
**First-stage retriever (upstream):** [BM25 / dense / hybrid]
**Rerank latency SLA:** [ms for top-k]
**Objective class:** [Pointwise / Pairwise / Listwise]
**Rationale:** [1-line — label availability + position-awareness need]
**Model family**
| Stage | Model | Objective / flag | Latency | Notes |
|---|---|---|---|---|
| Baseline | [pointwise GBDT / LogReg] | [regression / binary] | | Establish before listwise |
| Reranker | [LambdaMART / cross-encoder] | [LightGBM lambdarank / XGBoost rank:ndcg / cross-enc] | [ms] | [tabular vs precision top-k] |
**Judgment / label construction**
| Aspect | Choice |
|---|---|
| Label source | [editorial / click-derived / both] |
| Click model | [PBM / cascade / DBN / n/a] |
| Position-bias correction | [IPW with p_k from PBM / result-randomization / editorial — no correction needed] |
| Propensity source | [click model / randomization experiment] |
**Metrics**
| Metric | Value | Notes |
|---|---|---|
| NDCG@10 | [score] | Primary (graded) |
| [MAP / MRR / ERR] | [score] | [binary / known-item / cascade] |
| Baseline (BM25 or pointwise) | [score] | Required comparison |
**Evaluation plan**
- Offline split: query-level (all docs of a query in one fold) — mandatory
- Online gate 1: [interleaving — TeamDraft] on [click attribution]
- Online gate 2: A/B on [CTR / success rate / revenue] — defer to /ab-test-design
- Counter-metric: [abandonment / reformulation rate / revenue-per-session]
**Recommendations**
- [Click labels without IPW bake in position bias — list whether propensities are logged]
- [Offline NDCG lift must be confirmed by interleaving/A/B before ship — offline-online gap is real]
- [Query-level split — row-level split leaks sibling docs]
- [Start pointwise baseline → LambdaMART; cross-encoder rerank only top-k]
Quality bar
- Query-level train/test split is mandatory — all documents for a query must be in the same fold; row-level (per-document) splitting leaks sibling documents and inflates offline metrics
- Click labels MUST be position-bias-corrected (IPW from a click-model propensity, or a randomization experiment) before training — training on raw clicks bakes presentation/position bias into the model and rewards whatever was already shown on top
- If positions/propensities were never logged, IPW is infeasible — say so explicitly and fall back to editorial labels rather than pretending click counts are unbiased relevance
- Offline NDCG gains do not guarantee online wins — confirm with interleaving (LTR-native, high-sensitivity) or an A/B test before rollout; the offline-online correlation is weak and many offline-positive changes are online-flat
- Match the metric to label granularity — NDCG/ERR need graded judgments, MAP/MRR are binary; computing NDCG over binary labels discards its main advantage
- LambdaMART (listwise) is the production default for graded search results because it weights pairwise swaps by NDCG impact — but it is NOT a personalization model; user-item ranking, collaborative filtering, and two-tower retrieval belong to /recommender-design
- Every optimization target needs a counter-metric (abandonment, reformulation rate, revenue-per-session) — optimizing CTR/NDCG alone can train clickbait ordering