Filtering a YouTube Feed with a Decision Model
Published 6 October 2026
A use case worth writing down: Slashly, a Chrome extension that filters the YouTube home feed down to topics you chose, using Jev — a decision model — to judge each video. 961 videos were classified for about 1.2 US cents (≈ ₹1.16) in estimated model input cost.
The problem¶
You open YouTube to learn something specific. The home feed offers plenty you might watch, but not much that matches what you came for. The recommender optimises for watch time; you want it to optimise for intent.
What it does¶
- You pick the topics you want in your feed.
- For each video, Jev checks the title and channel against those topics and returns a score.
- Slashly uses that score to decide what stays visible.
- A strictness slider lets more through or makes the filter more selective.
The slider works on saved scores, so moving it doesn't trigger another model call. The model is called once per video; the threshold is a pure client-side decision.
flowchart LR
feed[YouTube home feed] --> extract[Extract title + channel]
extract --> cache{Score cached?}
cache -- yes --> decide
cache -- no --> jev[Jev: score vs chosen topics]
jev --> store[(Saved scores)]
store --> decide{score ≥ strictness?}
slider[Strictness slider] --> decide
decide -- yes --> show[Keep visible]
decide -- no --> hide[Hide]
Why the design is cheap¶
-
Small inputs. Title and channel are a few dozen tokens. No thumbnails, descriptions or transcripts. That's what makes the numbers work:
Total Per video Per 1,000 videos USD ~$0.012 ~$0.0000125 ~$0.0125 INR ~₹1.16 ~₹0.0012 ~₹1.2 -
Score once, threshold many times. Separating scoring (expensive, model) from deciding (free, a comparison) is the key move. Any knob a user might fiddle with should sit on the cheap side of that line.
- A narrow question. "Does this video match one of these topics?" is a classification, not an open-ended task. A decision model fits that shape better than a chat agent: one input, one judgement, no tool loop.
How I'd build the pieces¶
Details beyond the above aren't public yet (the project is due to be open-sourced), so this is a sketch of how the parts would plausibly fit, not a description of the actual code.
- Content script watches the feed with a
MutationObserver, because the home page loads cards as you scroll. Each new card yields a video ID, title and channel. - Cache keyed by video ID + topic set. The same video shows up across sessions; changing the topic list invalidates the scores, changing the slider doesn't.
- Batch requests from the background service worker, so a screen of 20 cards is one round trip rather than 20.
- Hide, don't delete. Set
display: noneon the card so un-hiding when the slider moves is instant and the page layout recovers cleanly. - Fail open. If the model call fails or times out, leave the card visible. A filter that blanks your feed on an outage is worse than no filter.
What's still open¶
- Accuracy isn't measured yet. The obvious next step: hand-label a few hundred videos, then plot precision and recall across slider positions. That also tells you where the default threshold should sit.
- Titles lie. Clickbait titles and broad channels ("a podcast about everything") are where title + channel runs out. Adding the description is the cheap next signal before reaching for transcripts.
- Cost is input-only and estimated. Output tokens and request overhead aren't in the 1.2 cents, though for a short score they should be small.
Takeaway¶
The interesting part isn't YouTube. It's the pattern: a cheap model call that turns fuzzy content into a number, and a deterministic rule on top that the user controls. It fits a lot of everyday filtering — inboxes, RSS, notifications, job boards — anywhere the judgement is fuzzy but the action is binary.