Skip to content
Mohammed Tahir
Writing5 min read

Feed for you

Ranked feeds pick winners from what already exists. The next version generates the item at request time, for one person, and never shows it again. That changes what you have to build.

  • AI
  • Product

The feed as we've had it for fifteen years is a ranking problem. There's a pool of items somebody else made, a model that scores them against you, and a slot machine that hands back the top k. Every improvement has been an improvement to the scorer.

The interesting shift is that the pool no longer has to exist before you ask. Generation is now cheap and fast enough that the item can be produced at request time, for one person, and then thrown away. On-demand generation is the new feed, and it breaks most of the assumptions the ranked feed was built on.

What actually changes

The candidate set becomes unbounded. Retrieval used to be about finding the best hundred things from a corpus. Now the corpus is a starting point and the candidate is something you synthesise: a summary stitched from four sources, a walkthrough of a repo you just opened, a comparison nobody has written because nobody else needed it.

There is no cold start on the item side. Classic recommenders can't rank an item with no engagement history. A generated item has no history by definition, so the whole apparatus of item embeddings learned from interaction data stops applying. What you rank is not items, it's intents.

Popularity stops being a signal. Half of feed ranking is a proxy for "other people liked this". When the item is made for one person and shown once, there is no other person. You lose your strongest prior and have to replace it with something built out of the user's own context.

The unit economics invert. Ranking is cheap per impression and the cost of a bad recommendation is roughly zero. Generation costs real money per impression, so an item nobody reads is a direct loss. That single fact drives most of the engineering below.

The parts you end up building

Context, not a profile

A recommender profile is a vector learned from clicks. A generated feed needs something closer to a working brief: what this person is doing right now, what they already know, what they've already been shown, what they said they cared about. Recency dominates. What someone opened twenty minutes ago is worth more than a year of aggregate behaviour.

I keep this as an explicit, inspectable object rather than an embedding, for two reasons. You can debug it, and you can show it to the user. A feed that can explain why it made something is a feed people trust enough to correct.

Grounding, or it's worthless

A generated feed with no source is a hallucination machine with a scroll bar. Every item should be traceable to something real: a document, a repo, a message, a page. Generation is the presentation layer over retrieval, never the source of the facts.

This is also the honest answer to "is this just slop". Slop is generation without grounding. Retrieval quality is the whole product, and the model is the part that makes the retrieved thing readable for this particular person.

A budget, enforced

You cannot generate a hundred candidates and rank them. Pick the intent first with something cheap, then generate a handful. In practice that means a fast, small model or a plain heuristic proposing what's worth making, and the expensive model only running on what survives.

Cache aggressively at the level below the item. The retrieval results, the summaries of sources, the intermediate structure: all reusable across people. The final composition is what's personal, and it's the cheapest part.

Something to do with the miss

When the generation is wrong, the recovery has to be immediate and in the item itself. Not a thumbs down that trains a model next Tuesday. Something that changes the next item on this scroll: less of this, go deeper, wrong project. The feedback loop being visible within one session is what makes the thing feel like it's yours rather than something being done to you.

Freshness by construction

The old feed goes stale when the pool goes stale. This one goes stale when your context stops changing, which is a much better failure mode: it means the feed is quiet when you're quiet, and it moves when your work moves.

What I'd be careful about

Three things worry me, and I don't think any of them is solved.

Sameness. A model with a house style produces a feed with a house voice. Ranked feeds are chaotic because humans made the items, and that chaos is doing more work than we credit. Generation trades variety for fit, and too much fit is boring.

No shared object. You can't send someone a link to a thing that was made for you and never existed anywhere else. Feeds are partly social infrastructure. If nothing is shareable, you've built a very good private reader and lost the network.

Optimising the wrong loop. Ranked feeds learned to maximise time spent, and we know how that ended. A generated feed can do the same thing faster, because it can manufacture exactly the item that keeps you there. The measure has to be whether the person got what they came for and left, not whether they stayed.

Where this actually lands first

Not on a general-purpose social feed. It lands where the corpus is private, the intent is narrow, and the cost of a miss is high enough to pay for generation: your inbox, your codebase, your customers, your network. That's the shape of what I'm building with Connectin, and it's the same argument. The relevant thing already exists somewhere in your own data. It has just never been assembled for the question you're holding today.

Building something where this is relevant? Write to me.