search_ads_recsys / 26 · llms & generative ai lesson 26 / 39

LLMs & generative AI in recommendation

Every team is being asked "where does the LLM go in our recommender?" The honest answer is mostly "not in the hot path." A single LLM call costs 10²–10⁴× a DLRM forward pass, so the interesting question is not whether LLMs help but at which layer the economics let them help at all. This lesson is a hype filter: four concrete roles, the cost arithmetic that pins each one to a stage of the funnel, and the failure modes that make the naïve version worse than the system it replaced.

First principles: the cost wall decides the layer

Recommenders are a cascade — retrieval narrows millions to thousands, ranking thousands to hundreds, re-ranking hundreds to the handful you show (lessons 02 and 03). Each stage operates at a different QPS-per-candidate, and that single number — how many model invocations per request — sets the per-call budget. A retrieval stage scoring 10⁶ candidates at 10⁵ QPS has a budget of microseconds and fractions of a cent per request. An LLM call is tens of milliseconds and a fraction of a cent per call. Multiply by candidates and the retrieval bill is absurd; at the re-rank stage, where you score 20–200 items once per request, it is merely expensive.

So the layer where an LLM lives is not a modeling choice — it falls out of arithmetic. Let a DLRM forward pass cost c_d ≈ 10⁻⁶ s and an LLM call c_l ≈ 5·10⁻² s. Then c_l / c_d ≈ 5·10⁴. Putting an LLM at retrieval (10⁶ candidates) versus re-rank (10² candidates) is a four-order-of-magnitude difference in spend for the same QPS:

stage candidates model per-request cost LLM verdict ───────────────────────────────────────────────────────────────────────── retrieval ~10^6 ANN / 2-tower ~10 µs (cheap) ✗ never (10^4× too slow) ranking ~10^3 DLRM/DCN ~1 ms ✗ rarely (distill instead) re-rank ~10^2 listwise+LLM ~50 ms (1 LLM call) ✓ shortlist re-rank, explanations eval/offline 0 online LLM-as-judge seconds, batchable ✓ judging, user simulation content 0 online diffusion/LLM seconds, async ✓ creative gen, synthetic data │ │ └── LLM cost grows with candidates ───────────────────────┘ so it lives where candidate count is smallest (or offline)

The whole lesson is an elaboration of that diagram. Four roles, ordered from "most real today" to "most overhyped": evaluation, generative retrieval, re-ranking/reasoning, and AIGC content. For each, the test is the same — does the LLM do something a cheaper model provably cannot, and does the layer's budget allow it?

LLM roleWhere in funnelAdded latency / costWhat it uniquely buysChief risk
LLM-as-judge / user simulatorOffline eval (no serving path)Seconds/call, batchable, $$ per eval run not per requestGraded labels where humans are scarce; long-horizon satisfaction proxyJudge bias & miscalibration; circular if judge ≈ policy
Generative retrieval (semantic IDs)Replaces retrieval indexAutoregressive decode per request; tight latency budgetNo separate ANN index; cold items via semantic codesHallucinated/invalid IDs; decode latency; hard to update freshly
LLM re-ranker / reasonerRe-rank (shortlist of ~10²)~1 LLM call/request, 30–100 msReasoning over a small set; explanations; conversational/agenticCost ceiling caps list size; position/verbosity bias in ordering
AIGC content & synthetic dataOffline / async pipelineAmortized; not in request pathCreative variants, cold-start content, query augmentationHallucinated items; feedback-loop homogenization; provenance

Role 1 · LLM-as-judge and generative user simulators

This is the most production-real role today, precisely because it lives off the serving path: latency and per-request cost don't matter when the LLM runs in a nightly batch. The motivating problem is the one lesson 08 opened with — every offline metric is a summary statistic on logged predictions, biased toward items the old policy already surfaced, and human relevance labels are expensive and slow. An LLM judge promises graded relevance labels at near-zero marginal cost: feed it (query, item) or (user history, recommendation) and ask for a 1–5 relevance score or a pairwise preference.

Two distinct uses, often conflated:

Be skeptical and concrete. An LLM judge is itself a model with systematic biases, and treating its scores as ground truth is how teams ship regressions confidently:

The judge is biased — validate it before you trust it
Documented, reproducible failure modes of LLM judges: position bias (in pairwise comparisons the first-presented item wins more often — mitigate by averaging both orderings); verbosity / length bias (longer, more elaborate item descriptions score higher regardless of relevance); self-preference (a judge favors outputs from its own model family — fatal if your candidate generator and your judge are the same model, which makes the eval circular); poor calibration (the numeric "4/5" does not correspond to any stable relevance rate). The non-negotiable: validate the judge against a human-labeled gold set and report its agreement (Cohen's κ or correlation with human grades) before using it to gate launches. A judge with κ = 0.3 against humans is a random-number generator with a confident tone. And check self-consistency: sample the judge several times at temperature > 0 — if its own scores wobble across samples, the variance floods any real signal.

Where it complements classical evaluation, and where it does not: an LLM judge is a cheap, scalable proxy for human relevance labels, so it slots in exactly where NDCG-style graded labels are scarce and helps you prune the candidate set of A/B tests. It does not replace the A/B test — it has no access to the counterfactual of real user behavior, no measurement of long-term retention, and inherits none of the randomization that makes A/B tests immune to position bias. The senior framing matches lesson 08's spine: LLM judge filters, A/B test decides. A judge that disagrees with your A/B outcome is telling you the judge is miscalibrated for your surface, not that the A/B was wrong.

Role 2 · Generative retrieval and semantic IDs

The two-tower + ANN paradigm of lessons 02/03 retrieves by matching: embed the query, embed every item, find nearest neighbors in a maintained index. Generative retrieval flips this — instead of looking items up, the model generates the identifier of the item to retrieve, autoregressively, like a language model emitting tokens. This is the TIGER line of work, and the key enabling trick is the semantic ID.

A raw item ID (e.g. item_8675309) is an atomic, meaningless token — two similar items have unrelated IDs, so a model must memorize each one. A semantic ID instead factorizes an item's content embedding into a short sequence of discrete codes via residual-quantized VAE (RQ-VAE): quantize the embedding to the nearest codeword in a learned codebook, take the residual, quantize again, and repeat for L levels. An item becomes a tuple of codewords:

item → (c₁, c₂, …, c_L), c_ℓ = argmin over k of ‖ r_(ℓ-1) − e_k^(ℓ) ‖², r_ℓ = r_(ℓ-1) − e_(c_ℓ)^(ℓ)

The codes are coarse-to-fine semantic: items sharing c₁ are in the same broad cluster, sharing (c₁,c₂) a finer one. Now a sequence model trained on user histories (a transformer over the user's past semantic-ID sequence) learns to generate the next item's semantic ID token by token, with retrieval being a beam search over the code vocabulary. The probability factorizes autoregressively:

P(item | history) = ∏ over ℓ=1..L of P(c_ℓ | c_(<ℓ), history)

Two-tower + ANN (lessons 02/03)Generative retrieval (TIGER-style)
Retrieval mechanismEmbed query, nearest-neighbor search over item indexBeam-search decode item's semantic-ID sequence
Separate index?Yes — ANN index (HNSW/IVF) built & maintainedNo — "index" is the model's learned weights
Cold itemsNeed a content-derived embedding to be insertedGet a semantic ID from content immediately; sequence model can emit it without retraining its own row
Adding/updating itemsCheap — insert a vector into the index, near-real-timeHard — new code assignments / knowledge may need retraining; freshness is the weak point
LatencySub-ms ANN lookup, very matureL autoregressive decode steps × beam width — heavier, the open problem
Invalid resultsImpossible — every neighbor is a real itemPossible — beam can emit a code tuple matching no item (hallucinated ID); needs constrained decoding / a trie of valid sequences
MaturityBattle-tested at 10⁵-QPS scalePromising research; few full-scale production deployments

Honest verdict: generative retrieval is genuinely interesting because it collapses "embedding model + ANN index + nightly index rebuild" into one trained artifact and handles cold items naturally through shared semantic codes (the cold-start bridge of lesson 15, now baked into the ID). But the two killers are decode latency (autoregressive generation is inherently serial where ANN is a single parallel lookup) and invalid/hallucinated IDs (you must constrain decoding to a trie of real items, or you retrieve nothing). Freshness is the third: an ANN index ingests a new item in seconds, while a generative model may need retraining to reliably emit a newly-popular item's code. For most production systems in 2026 this is a research bet, not a replacement for the two-tower stack — promising, not proven.

Role 3 · LLM re-rankers and reasoning

This is where the cost arithmetic finally permits a real LLM in the request path — barely. At the re-rank stage you have a shortlist of ~10²; one LLM call per request is ~50 ms and a fraction of a cent, which a re-rank budget can absorb where a retrieval budget cannot. Three flavors:

LLM re-rankers carry the judge's biases into the ranking
The same position and verbosity biases that plague LLM-as-judge resurface when an LLM orders a list: items earlier in the prompt get ranked higher, and items with richer text descriptions get boosted regardless of true relevance — a direct collision with the position-bias debiasing work of earlier lessons. Mitigations: randomize candidate order across calls, normalize description length before prompting, and constrain output to a permutation of the input IDs (so it cannot drop or hallucinate items). And always keep a cheap classical ranker as the fallback for when the LLM times out — at 50 ms p50 the p99 tail will blow your latency budget, so you need a circuit breaker.

The senior point: an LLM at re-rank is justified only when reasoning over the set, multimodal understanding (lesson 14), or natural-language interaction buys something a distilled DLRM cannot. Often the right move is the reverse — distill the LLM's judgments into a cheap student model that runs at rank-stage cost, getting most of the quality at none of the latency. Use the LLM to generate training signal, not to serve it.

Worked numbers — why you distill instead of serve the LLM
An LLM re-ranks the top 100 candidates at ~50 ms and $0.0005 per call, on a 50,000-QPS surface. Serving it live means 50{,}000 × 86{,}400 ≈ 4.3×10⁹ calls/day × $0.0005 ≈ $2.2M/day — and the 50 ms blows the rank-stage latency budget (lesson 1) on its own. Now distill: pay the LLM for one week of traffic to label ~1M re-ranking decisions (a one-time ~$300K), train a small ranking MLP on those labels, and serve that at ~2 ms and negligible marginal cost. You keep most of the LLM's quality, latency drops ~25×, and the payback beats even a single day of live serving. The one ongoing duty is monitoring that the student doesn't decay relative to the teacher as the catalog drifts — re-distill on a schedule. This arithmetic is why the LLM almost always belongs off the hot path.

Role 4 · AIGC content and synthetic data

Generative models can produce content, not just rankings: ad creatives and thumbnails (diffusion), synthetic descriptions for cold items, query rewrites and feature augmentation. This lives in offline/async pipelines, so cost is amortized — the appeal is real. The risks are subtler than latency and they compound over time.

Feedback-loop homogenization — the slow-motion failure
The dangerous risk is not a single bad output, it is the autophagy loop: the model generates content → users interact with it → those interactions become training data → the model trains on its own generations → its distribution narrows toward its own modes. Iterate this and you get mode collapse at the population level — a homogenized catalog, an amplified filter bubble, and progressively less of the long-tail diversity that made the catalog valuable. This is the recommender-scale version of "model collapse" from training on synthetic data. The defenses are provenance and dilution: tag every generated artifact so you can measure how much of served content is synthetic, cap the synthetic fraction in training data, and keep an irreducible floor of real human-generated signal. Also: hallucinated items — an LLM that invents a product or attribute that does not exist is a correctness and trust failure, so generated content must be validated against the real catalog before it can be recommended.

Interactive · where does the LLM belong?

Pick a funnel stage to drop an LLM into, set your traffic and the per-call cost/latency, and the calculator computes the LLM invocations per request, the resulting $/day, the added p99 latency, and a verdict. Retrieval and ranking score one LLM call per candidate (10⁶ and 10³ respectively) — the economics scream. Re-rank is the trick: a single listwise call over the whole shortlist, so it is one call per request regardless of list size. Eval is offline. Try putting it at retrieval and watch the bill go to the billions.

LLM-in-the-funnel cost & placement calculator
Retrieval and ranking score the LLM per candidate (≈ 10⁶ and 10³ calls/request) — that is what kills them. Re-rank uses one listwise call per request over the whole ~10² shortlist (the fraction slider grows the prompt, not the call count). Eval-only is offline (0 online calls). The fraction of requests you route to the LLM scales calls and cost linearly; latency added ≈ one call's p99 (calls within a request overlap), but cost scales with total calls. Order-of-magnitude, not a billing quote.
LLM calls / request
LLM calls / day
cost / day
added p99 latency
latency budget
verdict
Reading
Choose a stage and traffic to see where the economics put the LLM.
The arithmetic the calculator is making concrete
At 50k QPS, an LLM at retrieval (10⁶ candidates/request) is ~5·10¹⁰ calls/second of demand — physically and financially impossible. The same LLM at re-rank (one call/request) is 50k calls/s — expensive but buildable, and the added latency is just one call's p99 because the call happens once. Eval-only severs the online cost entirely: the LLM runs in a batch job, so $/day is per-eval-run, not per-request. This is why the four roles sort the way they do — not by how clever the LLM is, but by how many times per request you have to pay for it.

Crosscutting: train–serve, freshness, and the distillation escape hatch

Two systems concerns recur across all four roles. Freshness: LLMs have a knowledge cutoff and are expensive to retrain, so anything time-sensitive (a new item, a breaking trend, a price change) is a weak spot — which is exactly why generative retrieval struggles with new items and why AIGC content can go stale. The fix is to feed fresh facts at inference (retrieval-augmented prompting) rather than baking them into weights. Train–serve skew: an LLM used offline to generate labels or content but absent at serving creates a gap — the production ranker must be trained to consume what the LLM produced, and you must monitor that the LLM's offline judgments still predict online outcomes. The cleanest reconciliation is the distillation escape hatch: use the expensive LLM offline to produce a teacher signal (judgments, rankings, synthetic labels), then train a cheap student that serves at DLRM cost. You get the LLM's reasoning at the latency of a forward pass, and you never put the LLM in the 10⁵-QPS hot path at all.

Interview prompts you should be ready for

  1. "Where in the recommender stack would you actually put an LLM, and why not retrieval?" (Lead with the cost arithmetic: an LLM call is ~10²–10⁴× a DLRM forward pass, and per-request LLM cost scales with candidates scored. Retrieval scores 10⁶/request → impossible; re-rank scores 10²/request → one call, affordable; eval/content are offline → cost amortized. The layer falls out of arithmetic, not cleverness.)
  2. "You want to use an LLM-as-judge to label relevance. What could go wrong, and how do you trust it?" (Position bias, verbosity/length bias, self-preference — fatal and circular if judge = generator — and poor calibration of the numeric score. Non-negotiable mitigation: validate against a human-labeled gold set and report agreement (κ / correlation) before gating launches; average over presentation orders; check self-consistency across samples. The judge filters; the A/B test still decides.)
  3. "Contrast generative retrieval with two-tower + ANN." (Two-tower matches via nearest-neighbor over a maintained index; generative retrieval decodes an item's semantic ID autoregressively via RQ-VAE codes, so the 'index' is the model's weights. Pros: no separate index, natural cold-item handling through shared codes. Cons: serial decode latency vs parallel ANN lookup, hallucinated/invalid IDs needing constrained decoding, and poor freshness — adding an item is a near-real-time index insert vs a possible retrain.)
  4. "What is a semantic ID and why does RQ-VAE help?" (Factorize an item's content embedding into a short coarse-to-fine sequence of discrete codes via residual quantization. Items sharing prefixes are semantically related, so a sequence model can generalize across items and emit a cold item's ID from content alone — instead of memorizing an atomic, meaningless raw ID.)
  5. "Your team wants an LLM to re-rank the top 100. What are the risks and the cheaper alternative?" (Risks: position/verbosity bias leaking into the ordering, p99 tail blowing the latency budget, hallucinated/dropped items — constrain output to a permutation of input IDs, randomize order, keep a classical fallback with a circuit breaker. Cheaper alternative: distill the LLM's listwise judgments into a student model that serves at rank-stage cost.)
  6. "What is the danger of training on AIGC content, and how do you mitigate it?" (The autophagy / feedback loop: model trains on its own generations → distribution narrows → population-level mode collapse, catalog homogenization, amplified filter bubble. Mitigate with provenance tagging of synthetic content, a cap on the synthetic fraction of training data, a floor of real human signal, and validating generated items against the real catalog to kill hallucinations.)
  7. "When does an LLM genuinely beat a cheaper model, versus when is it hype?" (Real: reasoning over a small set at re-rank, natural-language/conversational intent, multimodal understanding, generating labels/content offline where humans are scarce. Hype: anything in the high-QPS retrieval/rank hot path where a distilled or two-tower model gets ~the same quality at 10³–10⁴× lower cost. The test is whether the LLM does something a cheaper model provably cannot AND the layer's budget allows it.)
Takeaway
An LLM call costs 10²–10⁴× a DLRM forward pass, and per-request LLM cost scales with candidates scored — so the layer where an LLM can live is decided by arithmetic, not ambition. That sorts the four roles: LLM-as-judge and user simulators run offline (validate against human gold, beware position/verbosity/self-preference bias — the judge filters, the A/B test decides); generative retrieval via semantic IDs is a real research bet that trades the ANN index for autoregressive decode but fights latency, hallucinated IDs, and freshness; LLM re-rankers are affordable at the ~10² shortlist for set-reasoning and explanations, with a classical fallback for the tail; AIGC content is amortized offline but risks feedback-loop homogenization, so tag provenance and cap the synthetic fraction. When the LLM is too expensive to serve, distill it — use it to generate signal, not to answer the request.