Use case · Search · ML

Tune ranking weights without a deploy

Your relevance weights are magic numbers buried in a scoring function. Every tweak is a pull request, a review, and a release — and still nobody measures what it did to conversion.

ranking surface = high risklatency guarded on every phase

The problem

Your relevance weights are magic numbers buried in a scoring function.

Ranking is the highest-leverage code in a lot of products and the least experimented on, because the loop is so slow. A weight change takes a day to ship and a week to argue about, so the team tunes it twice a year instead of twice a sprint.

It is also the easiest place to fool yourself. Relevance improvements often trade against latency or result diversity, and if you only watch click-through you will happily ship something that makes search feel worse.

What the team needs is not a machine-learning platform. It is the ability to move four numbers in production, on a slice of traffic, with latency and zero-result rate watched automatically.

ranking/score.py
# before — a deploy per experiment
def
  score = (
    0.55 * relevance
  + 0.20 * recency
  - 0.10 * same_seller_penalty
  )

# after — the same numbers, resolved
# per request from one parameter set

What you put under control

Declared once, then governed centrally. This is the only code step.

Parameters
ParameterTypeDefaultRange
ranking.relevance_weightnumber0.550–1
ranking.recency_boostnumber0.200–1
ranking.diversity_penaltynumber0.100–1
ranking.candidate_depthnumber20050–1000
Surfaces that consume them
SurfaceKindRole
Search resultsrankingdecision
Category pagesrankingdecision
Recommendationsrankingdecision

Those bindings are what compute the risk class — high: ranking surface · decision binding.

Variants are parameter value sets
Variantrelevance_weightrecency_boost
control0.550.20
relevance-led0.680.12
freshness-led0.480.34

Risk class: high

ranking surface · decision binding. A human approves the measurement plan before any traffic, and again before the value becomes the product default.

How it runs

The mechanism is configuration. The application code is already done.

Experiment, then contextual bandit
Chosen for a high-risk change.

A high-risk surface never starts traffic without a human approving the plan. The experiment establishes causality across the three arms; latency and zero-result rate are blocking guardrails throughout.

Because relevance preferences differ by user, a linear contextual bandit can then personalize the weights using the context you already pass in — no model to deploy.

Phases running
Setup
Canary
Experiment
Rollout
Complete
Guardrails on every phase
latency_p95
must not increase > 40ms
blocking
zero_result_rate
must not increase > 0.5%
blocking
result_diversity
must not decrease > 5%
warning

What you get back

A verdict you can defend, and the reasoning kept for next time.

ranking-relevance / measurement day 4 of ~7
Evidence still accumulating — hold
Leading variant is ahead on the primary metric, but the interval has not cleared zero. All guardrails passing.
primary metric
+1.9%
search_to_purchase · conversion rate · per search session
measurement progress
64%
of the sample needed for a verdict
guardrails
3 / 3
passing, none near threshold
search_to_purchase primary
relevance-led +1.9% · anytime-valid interval still crosses zero
+1.9%
latency_p95 guardrail
inside the acceptable band on all arms
passing
zero_result_rate guardrail
inside the acceptable band on all arms
passing

Four numbers you can finally move, with the two things that usually get traded away — latency and zero-result rate — watched on every phase rather than checked afterwards.

When it completes, the winning values become the parameter defaults and the whole thing — question, variants, evidence, verdict — is retained. The next person to propose moving this number starts from the answer instead of the argument.

Retained after this change

The question asked, the values tried, the interval at the moment of the call, which thresholds were in force, and who approved the promotion.

Searchable by parameter, surface, or metric

Keep reading

The mechanics behind this page.

Start with this one number

Parameterize it this week. The first measured change usually pays for the integration.