Use case · Mixed
AI news filter with Jev: keep, relevance and topic for every headline
Give Jev a reader's interests and a headline, and get back whether to keep it, how relevant it is and what it is about, each with a probability.
Run this example
3 questions · no key neededThe problem
Keyword filters drop the story that says "GPU" when the reader asked for "graphics cards", and keep every story that mentions a blocked word in passing. A feed of hundreds of headlines an hour is too many to send through a chat model one at a time and parse the answers.
How Jev handles it
Put the reader's interests and exclusions in the state above the headline and summary, then ask a Noul to keep it, a Score for relevance and a Choice for topic. The interests are the reader's own words, so changing them changes the filter without retraining anything.
state = (
f"READER INTERESTS: {', '.join(reader.interests)}.\n"
f"NOT INTERESTED IN: {', '.join(reader.blocked)}.\n\n"
f"HEADLINE: {item.title}\nSUMMARY: {item.summary}"
)
response = client.system_one(
model="jev-latest",
state=state,
questions={
"keep": Noul(
instructions="Does this article match one of the reader's interests?",
criteria=NoulCriteria(true="Matches an interest", false="Off-topic for this reader"),
),
"relevance": Score(
instructions="How relevant is this article to this reader?",
criteria=["Not relevant", "Slightly relevant", "Relevant", "Must read"],
),
"topic": Choice(
instructions="What is the article mainly about?",
criteria={
"ai_models": "AI models and research",
"hardware": "Chips, GPUs and data centres",
"regulation": "Laws and policy",
"business": "Companies, markets and deals",
"other": "Anything else",
},
),
},
)
a = response.answers
if a["keep"].noul >= 0.5:
feed.add(item, rank=a["relevance"].score, section=a["topic"].choice)State sent the example loaded in Run this example above, as it first appears.
Answers returned
- Latency (median of 3)
- 594.6ms
- Minus network floor (259.9ms)
- ≈335ms
- Input tokens
- 540
- Cost
- $0.00002268
A headline that matches one interest (GPU prices) without naming it in the same words.
Writing the questions for an AI news filter
Keep and relevance are separate on purpose: keep is the gate, relevance orders what passes it. The measured headline about cloud GPU rental prices matched the reader's "GPU prices" interest without using those words; keep came back at 0.96, and relevance at 2.70, with 0.71 on "Must read" and 0.28 on "Relevant".
Make the topic options the sections your product shows, not a taxonomy of everything. On the measured headline the split was 0.70 hardware and 0.30 business, a fair reading of a price cut by data-centre operators. Show both tags when the second is above about 0.25, or file the item under the higher one.
What to put in the state
Interests first, then the item. Write interests the way the reader would, a few words each, and keep exclusions on their own line: "NOT INTERESTED IN: crypto prices" reads more reliably than a negative buried inside a sentence.
A headline and a one- or two-sentence summary are enough. Full articles cost more tokens, and a filter that runs on every item in a feed should judge what the reader sees before clicking.
What one decision costs
A news filter runs once per reader per item, so volume is the variable that matters. First line: the measured headline with its reader block. Second: one reader, 500 items a day for 30 days. Third: 10,000 readers, 200 items a day each for 30 days.
# the measured headline, three questions 540 tokens × $0.042 / 1M = $0.0000227 # one reader, 500 items a day for 30 days 15,000 × 540 = 8,100,000 tokens × $0.042 / 1M = $0.340 # 10,000 readers, 200 items a day for 30 days 60,000,000 × 540 = 32,400,000,000 tokens × $0.042 / 1M = $1360.80
At product scale the cost is the per-reader multiplication. Filter in two stages: drop what no reader could want with one shared check per item, then ask the per-reader questions about what is left.
When not to use Jev for this
- Readers never state their interests. Ranking from clicks and reading time is a recommender problem; learn it from behaviour.
- The filter is about freshness, source or duplicates. Those are metadata; filter on them in code before asking anything.
- You need a summary or a reason for each item. Jev returns probabilities; explaining why an item was kept is an LLM step.
- The feed is not in English. Jev is English first; test it on your languages before relying on it.
Where it fits in your stack
In a feed pipeline the AI news filter sits after ingestion and de-duplication and before ranking: fetch, drop stale and duplicate items in code, ask Jev per reader, then sort what is kept by relevance.
A reader's hides and saves are labels. When someone hides a kept item, that interest and headline pair is a test case for rewording the interest or the keep question.
Notes from the field
- Exclusions on their own line work better than negatives inside a sentence.
- Relevance is a weighted mean of levels; keep the probabilities to break ties.
- Two topics above about 0.25 usually means the story belongs in both sections.
Common questions
Can AI filter news by my interests?
Yes. Jev reads the stated interests and the headline together; the measured story about GPU rental prices was kept at 0.96 for a reader interested in GPU prices, without a keyword match.
How is this different from a keyword filter?
A keyword filter matches strings; this matches meaning, so "graphics card prices" and "GPU rental cuts" land together. It also returns a probability, so a borderline item can be ranked lower instead of dropped.
Can it filter AI news out of Hacker News?
Yes, with "AI" as an exclusion: send each front-page title, with a summary if you have one, and drop items where keep is low. It needs the text of each item, nothing from the site itself.