Diversity is the objective; the LLM writes the policy, never serves the feed.
Three loops. A nightly offline brain does all the thinking (pools, priors, per-user probes, NL profiles). A precompute step pushes a versioned slate per user into KV. The online path is filter + one deterministic rank() — the same function that runs in the Feed Lab, in the serving Worker, and on the phone.
The three loops.
The offline brain
Global pools (context floor, behavioural kNN, fresh-unproven, rare), festival ramp → takeover → cut, neighbour-seeded Beta exploration priors, and — per active user — an LLM slow brain: a natural-language profile (auditable in the console), affirmative text probes, a curated buffer. All LLM work lives here.
Per-user slates in KV
Pure push: a versioned 50–100-id slate per user (no follow graph ⇒ no fan-out problem; cost O(DAU)). User = ≤5 interest-cluster medoids over frozen Cohere embeddings (decay on importance, never on vectors) + negative centroids as a re-rank penalty (never query subtraction).
filter + rank()
Deterministic, isomorphic, additive terms (quality · share propensity · novelty-to-user · event priority · declared prefs · taste affinity) + MMR diversity + quality floor + exploration slots. Vectorize never on the hot path. The client keeps a 20–30-item buffer and re-orders in-session with the same rank().
The objective, stated plainly.
Share-intent, not watch-time
The north star is forwards — a light, safe share-intent signal — not minutes. Appointment mechanics (the morning batch, a designed stop point), no compulsion loops.
Amplify the recipe, not the dish
Novelty and rarity rank; over-circulation costs score. What spreads is the pattern (a deity × language × mood that works), not a single viral card.
One embedding, LLMs offline
Server-side personalisation on one multimodal index (Cohere embed-v4); the LLM writes probes, profiles and policy offline and is never in the request path.
Policy as an artifact
FeedPolicy is a versioned document (draft → staging → production) edited in the Lab; serving reads the production label. The Lab's simulator, the serving Worker and the phone run the identical function.
Go deeper
In the repo
- packages/feed (rank · mmr · coldstart · metrics · policy — pure TS, FL-1)
- services/consumer-api/src/feed.ts
- services/console-api/src/lab/*
- apps/showcase/scripts/export-vectors.mjs