Personalized
Memory
A global model tells you who a shopper resembles. It can't tell you what just changed for them in the last five minutes.
Personalization is usually framed as a modelling problem: get a big enough network, feed it enough features, and it will know each customer. But however large the model or wide the feature space, a single trained model is still a global model, an average fit over millions of people. It learns the stable structure of demand well, and quietly smooths away the one thing that's most personal: the moment their taste turns.
This piece is about the layer that sits on top of that global model. A small per-customer memory that never really stops listening: it reads the shopper's behavior as a continuous signal in time, updates itself on every event, and keeps tailoring what the global model proposed. No retraining, no waiting for the next batch. The global model is only where it starts cold; from the first few visits each shopper carries their own baseline, and the memory keeps bending that personal baseline toward the moment. It settles down when a session goes quiet, but it settles onto who this shopper is, not back onto the average.
The clean way to think about it is an old one: a State Space model. The global model is the cold-start prior; the running prior is the shopper's own state. The session is the observation. A Kalman gain, set from behavior rather than hand-tuned, is the shrink factor between them.
Carey Chou ·
So why isn't the global
model just enough?
It's a fair question. If the model is big enough, with enough features, shouldn't it already know everyone? The catch is a quiet one: making it bigger makes the average sharper. It doesn't make the model yours.
A global model learns
the many, over the long run.
A turn happens to
one person, right now.
It isn't the model's fault.
It's just what averaging does.
What if the model didn't
have to relearn you?
The obvious fix is to train a model per customer. It doesn't really work. Millions of tiny models, each starved of data, each needing its own pipeline. It won't scale. Personalized memory gets to the same place a different way.
So the personal layer isn't a model in the training sense at all. It's a state: a running estimate of "where this shopper's intent is right now", carried forward from event to event and recombined with the shopper's own baseline on the fly (the global model only fills that baseline in before we know them). It runs as a continuous loop in time; each new event advances the same state a little, so the memory is always current without ever being retrained. This is the training-free online-inference idea, with one thing made explicit: how hard the memory is allowed to pull.
How much should we trust the moment?
Let the behavior decide.
Any blend of "global prior" and "personal signal" has a dial: how much do you let the fresh signal move the answer? The nice part is that this dial doesn't have to be a constant. It can rise and fall, per customer per moment, driven by features of the behavior itself.
That behavior-set dial is a Kalman gain, with two deliberate changes from the textbook. The prior it leans on is this shopper's own state, not the global average, and the dial has a floor, so even a quiet session still serves something personal. On top of that, the re-rank down-weights what's globally popular, so the personal pick leans into what's distinctive about this shopper instead of echoing the crowd. The rest of this article is one worked example, then the math that makes all three precise.
One shopper, one Saturday,
the dial moving
Meet a regular. For two years the global model has her pegged, correctly: health-conscious, budget-aware, a steady weekly run of produce, chicken, oat milk, kids' snacks. Then a Saturday morning looks nothing like that. Watch what each layer does.
Nothing here is broken; it's just not the right answer for today. The global model is doing exactly what it was trained to do: serve the durable, two-year pattern. It has no place to put "the last four taps look like a party," so it doesn't.
The same signal, two shoppers,
two
different amounts of trust
Notice that the gain is relative. For the two-year regular, the prior is trustworthy, so even a strong signal only tilts the shelf. For a first-time visitor the prior is nearly flat, so the same four taps carry almost the whole decision. A single fixed weight can't really do that. A behavior-set gain handles it on its own: the less you already know, the more the moment gets to count.
And when the signal is just noise,
the dial
closes on its own
A State Space view:
the shopper as the prior
In this section I'll go a level down into the model behind personalized memory: a state-space model, where a recursive Bayesian update treats this shopper's own carried state as the prior, the session as the observation, and the shrink factor as a Kalman gain set from behavior. The global model is still here — but as the cold-start anchor the personal state starts from, not the thing we fall back to. No global-model re-training anywhere.
Read the customer's
current taste as a hidden state x in the global model's embedding space. We never
observe it directly; we see behavior, a noisy readout of it,
and we track it as it drifts.
taste, now
own state
behavior
behavior features
factor
serve
Start from this shopper's own standing state
This is the first change from the textbook filter. The prior
isn't one shared μ; it's μglobal + δ, where δ is the
standing offset this shopper has earned. The global model only sets the baseline before we know
someone — a large P₀ pulls δ toward 0. Once we do know them,
δ stays, so even a silent session resolves to their baseline, not the average. That one
move is most of why the personal answer stops looking like the global one.
Most of the work happens in the variance
This is the small choice that makes it feel like
personalization and not just a filter. In a textbook Kalman filter R is a fixed sensor
spec.
Here the "sensor" is human behavior, and how much to trust it changes moment to moment, so
we estimate R from features of the behavior itself. Small R when
the shopper is speaking clearly; large R when they're not.
Prior variance over total variance
K is the "dial" from §02, but it rides between
Kmin and 1 — not 0 and 1. When behavior is noisy it settles to the floor and
you serve μ₀ = μglobal + δ, the shopper's own standing state; when
behavior is crisp it moves toward 1 and you serve the moment. The floor is the small piece that stops
a quiet session from ever collapsing the personal answer back onto the global average.
Divide out what everyone already buys
A global model is an average, so its top picks are the globally
popular ones — which is exactly why a naive personal re-rank keeps agreeing with it. Dividing by
global popularity (a TF-IDF-style move) makes the personal layer index the long tail the average
smooths away. β tunes how hard you push; a little exploration on top keeps it
from always serving the greedy pick. This is the third change, and it's the one that makes the
difference visible on the shelf.
| Estimation term | In this system | What it controls |
|---|---|---|
| μ₀, P₀ | this shopper's carried state (μ_global + δ); global only seeds it cold | the personal baseline you settle to |
| z | embedded in-session behavior | the fresh signal |
| R | learned from behavior features (consistency, intensity, recency) | how far the dial can open |
| K | the floored shrink factor (Kmin…1) | how much of the moment reaches the shelf, and the floor that keeps it personal |
| μ₁ | re-ranking at serving time, down-weighted by global popularity | what the customer actually sees |
Each event is just a small update
No gradient descent, no per-user weights, no retraining. The
"memory" is a small carried state (μ, P) advanced by two cheap steps per event. That
is what makes it scale to every customer: the expensive, shared thing (the global model) is trained
once; the personal thing is a few vector operations at inference.
Q matters too. It's the admission that taste
moves even when we're not looking, so certainty decays between sessions and the memory
stays willing to be surprised. Set Q too low and you get a stubborn shopper who can
never change; too high and yesterday is forgotten by lunch. It's the memory's forgetting
rate.