When putting together an issue of the Data Elixir newsletter, there are hundreds of relevant posts, tools, and resources to consider. Most of it gets to me through ~200 RSS feeds, 806 social media accounts, Hacker News, and Reddit.
I’ve written Python scripts to fetch and rank posts from the social media accounts, and those scripts have become essential for catching what’s resonating around the web. But resonating isn’t the same as good, and it’s not the same as being right for Data Elixir either. That judgment still comes from me, reading. And even with the scripts helping to filter everything, I still end up with 100-200 posts to consider each week.
It would be great to automate some of that last-mile curation, but that kind of reading and judgment isn’t something traditional code can do.
LLMs make it possible.
I still make the final calls, but some of the links in the Data Elixir issue you read this week were surfaced by an LLM I taught to think like me.
This post walks through how I built it, including the judge at its center, and the part I care about most: how I taught it my taste, and how I checked whether it actually learned. Along the way are the dead ends that taught me the most, and a prompt you can drop into a coding agent to start building something like this yourself.
How It Works
The judge that decides what’s worth reading is the heart of all this, but before getting into that, here’s the big picture.
Every morning, a Python script pulls new links from a collection of RSS feeds, an email inbox, and Hacker News. Then each one is simplified to a common form: a title, a link, where it came from, and a short snippet.
The script drops anything that’s stale or has already been seen, and then does the one expensive step: it hands what’s left to an LLM judge that scores each link against my taste, one at a time. Whatever clears the bar gets ranked and lands in my inbox.
That’s the whole architecture, and nearly all of it is plumbing.
The judge is the part that matters. More sources without a good judge would just mean drowning faster. And the judge is only as good as the rubric it judges against. For this project, the rubric is defined in a plain markdown file I call taste.md.
Teaching It My Taste
taste.md is 111 lines of short descriptions of what I’m looking for. It’s organized into categories that cover who the audience is, positive signals that raise the score, and things that disqualify a post.
Those three categories cover everything I need, including specific traits like:
- “Substantive and about working with data (or directly useful to people who do)”
- “Teaches, demonstrates, or argues something”
- “Reasonably fresh (roughly within the last month) and durable”
and on and on.
Writing taste.md is easy. Figuring out whether I actually got it right is not. And it didn’t start out as 111 lines, either.
Vibes
My first attempt at a taste.md file was just me, describing what I look for and what I skip. “Teach me something. Posts should target a smart, data-savvy audience. No hype.”
I ran it against a week of candidates and read the results. They looked fine. Good stuff near the top, junk near the bottom. Great.
But that’s the trap. The results were plausible, but plausible isn’t the same as right. It’s the same trap as ranking by engagement. It’s a useful first filter, but a high number didn’t prove something was good. I needed a test that an LLM couldn’t talk its way through.
Labels
So I built a test using a spreadsheet of my own curation decisions. I started with 20 links that I had featured in Data Elixir and another 15 that I had passed on, each with a one-line reason.
The rejects, and especially the near misses, turned out to matter more than the picks. That boundary, between “good” and “good but not for me,” is where taste actually lives. A slam-dunk “yes” doesn’t teach the judge anything it didn’t already know.
I did two things with that spreadsheet. The first was to write a script that reads each labeled article and works out the traits that separate the yeses from the nos, so I could fold them back into taste.md. The first time I ran it, I used only the featured examples and it confidently concluded that my audience was professional software engineers. For Data Elixir, that’s not true. Without the rejects there was no contrast, and everything that makes my taste specific rather than generic lives in what I say no to. Negatives carry the signal.
The second thing I did with that spreadsheet was the one that hurt: a backtest. Score all 35 links blind. No labels, no notes, just the judge, and then measure how often it agreed with me. The first number was 51%. A coin flip. And when I looked closer it was worse than that: the median score of the things I had featured was 62, and the median of the things I’d rejected was also 62. The judge didn’t disagree with me so much as it had no opinion. Everything landed in the same undifferentiated pile.
But now I had a number to move instead of a feeling to satisfy. I tightened the traits, re-ran the backtest, and watched the results climb. First, 51%, then 57%, then 71%, and the medians finally pulled apart: 72 for featured, 48 for rejected. The judge had learned to discriminate.
Of course, it’s more complicated than that sounds because the traits interact. At one point I softened a rule about engineering depth, because it was sinking a post that had been a popular pick in Data Elixir. The softening fixed that post but then quietly floated a dense, math-heavy theory piece I probably wouldn’t feature, because a different rule had been catching it and no longer could. It was whack-a-mole. Without the backtest I would have had a taste.md that fixed one case, broke another, and felt like progress anyway.
Outcomes
The reality is, my labels are taste too, and my taste isn’t ground truth. What I think is a great link and what my readers are actually interested in are not always the same. So I added one more judge: real engagement.
I use a platform called beehiiv to publish Data Elixir, and it logs every time an actual person clicks a link in the newsletter. “Actual person” is important here because there are a LOT of bots that click links in the newsletter as they try to determine if something is spam. For me, that’s noise, but beehiiv uses a variety of mechanisms to identify and filter out bot clicks.
For the 35 links I had selected to help define the taste.md file, I pulled the engagement numbers from beehiiv and lined them up against the judge’s scores for the same posts. Two stories came out of that, and they pointed in opposite directions.
The first story was a “build attention from scratch” post that I had featured. The judge scored it as a 38, which was well below my bar. I would have been tempted to modify the taste.md file to push it up, but based on reader engagement, it was one of the weakest links in that issue. The judge wasn’t missing something. It was seeing something my own enthusiasm had talked me past.
The second story was a post from a well-known AI writer about what it feels like to work with a new model. The judge scored it 38 and buried it. It was the single most-clicked link in that issue. The judge was being systematically hard on reflective first-person posts with no code in them, and readers love those posts.
I kept iterating the taste.md file and running backtests until it consistently scored like me. Or scored like my readers, actually.
The individual verdicts aren’t the point. The ladder is: vibes → my labels → real outcomes, each step correcting the one before it. I started by trusting my gut, caught my gut being unmeasurable, replaced it with my documented decisions, then caught those losing to what people actually clicked. Every step made the judge’s taste a little less mine-in-theory and a little more mine-in-practice. And sometimes the judge’s scores were better than mine.
What It Sends Me
Every morning before I’m awake, the whole thing runs and drops a ranked shortlist in my inbox:
The reason is the part that matters. The score tells me where something landed. The reason tells me why, and that’s what lets me accept or overrule it in about two seconds. “Clear, hands-on Bayesian workflow in Python”: yes. “Package release announcement dressed up as an article”: no. I’m not reading 200 posts anymore. I’m reading 15 one-line arguments and clicking through to read the 2 or 3 posts that are worth my time.
Extending It
Nothing about this is specific to Data Elixir. The judge doesn’t know or care where a candidate came from. It could be from an RSS feed, a newsletter in an inbox, or a Hacker News search. Every source gets normalized into the same shape before it reaches the taste test. Which means the whole system can be aimed at something completely different by changing just two things: the sources it reads, and the taste.md it judges against.
To verify that, I stood up a second instance. It’s the same code, untouched and pointed at a list of the most popular blogs among Hacker News readers. After developing a new taste.md file, I had a completely different curator. This one reads a couple hundred of the web’s most-loved technical blogs and then hands me the posts that I’m most likely to be interested in.
If you’re interested in building this, Michael Lynch maintains a ranked list of popular Hacker News writers at HN Popularity Contest.
It’s a bit of work to pull out the URLs and then track down the RSS feeds. Here’s an OPML file that I created recently. Just drop this into your own system:
Top Hacker News Writers
<?xml version="1.0" ?>
<opml version="2.0">
<head>
<title>Top HN Writers: RSS Feeds</title>
<dateCreated>Fri, 26 Jun 2026 16:22:56 +0000</dateCreated>
</head>
<body>
<outline type="rss" text="Paul Graham: Essays" title="Paul Graham: Essays" xmlUrl="http://www.aaronsw.com/2002/feeds/pgessays.rss" htmlUrl="https://paulgraham.com"/>
<outline type="rss" text="Krebs on Security" title="Krebs on Security" xmlUrl="https://krebsonsecurity.com/feed/" htmlUrl="https://krebsonsecurity.com"/>
<outline type="rss" text="Simon Willison's Weblog" title="Simon Willison's Weblog" xmlUrl="https://simonwillison.net/atom/everything/" htmlUrl="https://simonwillison.net"/>
<outline type="rss" text="Daring Fireball" title="Daring Fireball" xmlUrl="https://daringfireball.net/feeds/main" htmlUrl="https://daringfireball.net"/>
<outline type="rss" text="Julia Evans" title="Julia Evans" xmlUrl="https://jvns.ca/atom.xml" htmlUrl="https://jvns.ca"/>
<outline type="rss" text="danluu.com" title="danluu.com" xmlUrl="https://danluu.com/atom.xml" htmlUrl="https://danluu.com"/>
<outline type="rss" text="Ken Shirriff's blog" title="Ken Shirriff's blog" xmlUrl="https://www.righto.com/feeds/posts/default" htmlUrl="https://righto.com"/>
<outline type="rss" text="Stratechery by Ben Thompson" title="Stratechery by Ben Thompson" xmlUrl="https://stratechery.com/feed" htmlUrl="https://stratechery.com"/>
<outline type="rss" text="Troy Hunt" title="Troy Hunt" xmlUrl="https://www.troyhunt.com/rss/" htmlUrl="https://troyhunt.com"/>
<outline type="rss" text="Kalzumeus Software" title="Kalzumeus Software" xmlUrl="https://kalzumeus.com/feed/articles/" htmlUrl="https://kalzumeus.com"/>
<outline type="rss" text="Schneier on Security" title="Schneier on Security" xmlUrl="https://www.schneier.com/feed/" htmlUrl="https://schneier.com"/>
<outline type="rss" text="Terence Eden’s Blog" title="Terence Eden’s Blog" xmlUrl="https://shkspr.mobi/blog/feed/atom" htmlUrl="https://shkspr.mobi"/>
<outline type="rss" text="<antirez>" title="<antirez>" xmlUrl="https://antirez.com/rss" htmlUrl="https://antirez.com"/>
<outline type="rss" text="Jeff Geerling" title="Jeff Geerling" xmlUrl="https://www.jeffgeerling.com/blog.xml" htmlUrl="https://jeffgeerling.com"/>
<outline type="rss" text="Coding Horror" title="Coding Horror" xmlUrl="https://blog.codinghorror.com/rss/" htmlUrl="https://blog.codinghorror.com"/>
<outline type="rss" text="Drew DeVault's blog" title="Drew DeVault's blog" xmlUrl="https://drewdevault.com/blog/index.xml" htmlUrl="https://drewdevault.com"/>
<outline type="rss" text="Derek Sivers" title="Derek Sivers" xmlUrl="https://sive.rs/feed" htmlUrl="https://sive.rs"/>
<outline type="rss" text="The Old New Thing" title="The Old New Thing" xmlUrl="https://devblogs.microsoft.com/oldnewthing/feed/" htmlUrl="https://devblogs.microsoft.com/oldnewthing"/>
<outline type="rss" text="Fabien Sanglard" title="Fabien Sanglard" xmlUrl="https://fabiensanglard.net/rss.xml" htmlUrl="https://fabiensanglard.net"/>
<outline type="rss" text="daniel.haxx.se" title="daniel.haxx.se" xmlUrl="https://daniel.haxx.se/blog/feed" htmlUrl="https://daniel.haxx.se"/>
<outline type="rss" text="Gwern.net Newsletter" title="Gwern.net Newsletter" xmlUrl="https://gwern.substack.com/feed" htmlUrl="https://gwern.net"/>
<outline type="rss" text="Steve Blank" title="Steve Blank" xmlUrl="https://steveblank.com/feed/" htmlUrl="https://steveblank.com"/>
<outline type="rss" text="Martin Fowler" title="Martin Fowler" xmlUrl="https://martinfowler.com/feed.atom" htmlUrl="https://martinfowler.com"/>
<outline type="rss" text="John D. Cook" title="John D. Cook" xmlUrl="https://www.johndcook.com/blog/feed/" htmlUrl="https://johndcook.com"/>
<outline type="rss" text="Daniel Lemire's blog" title="Daniel Lemire's blog" xmlUrl="https://lemire.me/blog/feed/" htmlUrl="https://lemire.me"/>
<outline type="rss" text="Scott Hanselman's Blog" title="Scott Hanselman's Blog" xmlUrl="http://feeds.hanselman.com/ScottHanselman" htmlUrl="https://hanselman.com"/>
<outline type="rss" text="Pluralistic: Daily links from Cory Doctorow" title="Pluralistic: Daily links from Cory Doctorow" xmlUrl="https://pluralistic.net/feed/" htmlUrl="https://pluralistic.net"/>
<outline type="rss" text="DYNOMIGHT" title="DYNOMIGHT" xmlUrl="https://dynomight.net/feed.xml" htmlUrl="https://dynomight.net"/>
<outline type="rss" text="The Digital Antiquarian" title="The Digital Antiquarian" xmlUrl="https://www.filfre.net/feed/" htmlUrl="https://filfre.net"/>
<outline type="rss" text="tonsky.me" title="tonsky.me" xmlUrl="https://tonsky.me/atom.xml" htmlUrl="https://tonsky.me"/>
<outline type="rss" text="null program" title="null program" xmlUrl="https://nullprogram.com/feed/" htmlUrl="https://nullprogram.com"/>
<outline type="rss" text="The Universe of Discourse" title="The Universe of Discourse" xmlUrl="https://blog.plover.com/index.rss" htmlUrl="https://blog.plover.com"/>
<outline type="rss" text="the morning paper" title="the morning paper" xmlUrl="https://blog.acolyer.org/feed/" htmlUrl="https://blog.acolyer.org"/>
<outline type="rss" text="Idle Words" title="Idle Words" xmlUrl="https://idlewords.com/index.xml" htmlUrl="https://idlewords.com"/>
<outline type="rss" text="Matthew Garrett" title="Matthew Garrett" xmlUrl="https://mjg59.dreamwidth.org/data/rss" htmlUrl="https://mjg59.dreamwidth.org"/>
<outline type="rss" text="Slate Star Codex" title="Slate Star Codex" xmlUrl="https://slatestarcodex.com/feed/" htmlUrl="https://slatestarcodex.com"/>
<outline type="rss" text="Brendan Gregg's Blog" title="Brendan Gregg's Blog" xmlUrl="https://brendangregg.com/blog/rss.xml" htmlUrl="https://brendangregg.com"/>
<outline type="rss" text="mtlynch.io" title="mtlynch.io" xmlUrl="https://mtlynch.io/index.xml" htmlUrl="https://mtlynch.io"/>
<outline type="rss" text="Armin Ronacher's Thoughts and Writings" title="Armin Ronacher's Thoughts and Writings" xmlUrl="https://lucumr.pocoo.org/feed.atom" htmlUrl="https://lucumr.pocoo.org"/>
<outline type="rss" text="A Few Thoughts on Cryptographic Engineering" title="A Few Thoughts on Cryptographic Engineering" xmlUrl="https://blog.cryptographyengineering.com/feed/" htmlUrl="https://blog.cryptographyengineering.com"/>
<outline type="rss" text="Joel on Software" title="Joel on Software" xmlUrl="https://www.joelonsoftware.com/feed/" htmlUrl="https://joelonsoftware.com"/>
<outline type="rss" text="Programming in the 21st Century" title="Programming in the 21st Century" xmlUrl="https://prog21.dadgum.com/atom.xml" htmlUrl="https://prog21.dadgum.com"/>
<outline type="rss" text="Zach Holman" title="Zach Holman" xmlUrl="https://zachholman.com/atom.xml" htmlUrl="https://zachholman.com"/>
<outline type="rss" text="Random ASCII – tech blog of Bruce Dawson" title="Random ASCII – tech blog of Bruce Dawson" xmlUrl="https://randomascii.wordpress.com/feed/" htmlUrl="https://randomascii.wordpress.com"/>
<outline type="rss" text="Bret Victor's website" title="Bret Victor's website" xmlUrl="https://worrydream.com/feed.xml" htmlUrl="https://worrydream.com"/>
<outline type="rss" text="catonmat.net" title="catonmat.net" xmlUrl="https://catonmat.net/feed" htmlUrl="https://catonmat.net"/>
<outline type="rss" text="bunnie's blog" title="bunnie's blog" xmlUrl="https://www.bunniestudios.com/blog/feed/" htmlUrl="https://bunniestudios.com"/>
<outline type="rss" text="Hillel Wayne" title="Hillel Wayne" xmlUrl="https://www.hillelwayne.com/index.xml" htmlUrl="https://hillelwayne.com"/>
<outline type="rss" text="A Collection of Unmitigated Pedantry" title="A Collection of Unmitigated Pedantry" xmlUrl="https://acoup.blog/feed/" htmlUrl="https://acoup.blog"/>
<outline type="rss" text="Computer Things" title="Computer Things" xmlUrl="https://buttondown.com/hillelwayne/rss" htmlUrl="https://buttondown.com/hillelwayne"/>
<outline type="rss" text="Eli Bendersky's website" title="Eli Bendersky's website" xmlUrl="https://eli.thegreenplace.net/feeds/all.atom.xml" htmlUrl="https://eli.thegreenplace.net"/>
<outline type="rss" text="Gabriel Weinberg" title="Gabriel Weinberg" xmlUrl="https://gabrielweinberg.com/feed" htmlUrl="https://gabrielweinberg.com"/>
<outline type="rss" text="xkcd.com" title="xkcd.com" xmlUrl="https://xkcd.com/atom.xml" htmlUrl="https://xkcd.com"/>
<outline type="rss" text="A Smart Bear" title="A Smart Bear" xmlUrl="https://longform.asmartbear.com/index.xml" htmlUrl="https://asmartbear.com"/>
<outline type="rss" text="Austin Z. Henley's Blog" title="Austin Z. Henley's Blog" xmlUrl="https://austinhenley.com/blog/feed.rss" htmlUrl="https://austinhenley.com"/>
<outline type="rss" text="matklad" title="matklad" xmlUrl="https://matklad.github.io/feed.xml" htmlUrl="https://matklad.github.io"/>
<outline type="rss" text="Embedded in Academia" title="Embedded in Academia" xmlUrl="https://blog.regehr.org/feed" htmlUrl="https://blog.regehr.org"/>
<outline type="rss" text="Robert Heaton | Blog" title="Robert Heaton | Blog" xmlUrl="https://robertheaton.com/feed.xml" htmlUrl="https://robertheaton.com"/>
<outline type="rss" text="Filippo Valsorda" title="Filippo Valsorda" xmlUrl="https://filippo.io/atom.xml" htmlUrl="https://filippo.io"/>
<outline type="rss" text="The Desolation of Blog" title="The Desolation of Blog" xmlUrl="https://lapcatsoftware.com/blog/feed" htmlUrl="https://lapcatsoftware.com"/>
<outline type="rss" text="Aphyr: Posts" title="Aphyr: Posts" xmlUrl="https://aphyr.com/posts.atom" htmlUrl="https://aphyr.com"/>
<outline type="rss" text="benjojo blog" title="benjojo blog" xmlUrl="https://blog.benjojo.co.uk/rss.xml" htmlUrl="https://blog.benjojo.co.uk"/>
<outline type="rss" text="Eyes Above The Waves" title="Eyes Above The Waves" xmlUrl="https://robert.ocallahan.org/feed.xml" htmlUrl="https://robert.ocallahan.org"/>
<outline type="rss" text="Tedium" title="Tedium" xmlUrl="https://tedium.co/feed" htmlUrl="https://tedium.co"/>
<outline type="rss" text="Josh Comeau's blog" title="Josh Comeau's blog" xmlUrl="https://www.joshwcomeau.com/rss.xml" htmlUrl="https://joshwcomeau.com"/>
<outline type="rss" text="Dustin Curtis" title="Dustin Curtis" xmlUrl="https://dcurt.is/feed" htmlUrl="https://dcurt.is"/>
<outline type="rss" text="fasterthanli.me" title="fasterthanli.me" xmlUrl="https://fasterthanli.me/index.xml" htmlUrl="https://fasterthanli.me"/>
<outline type="rss" text="Sabine Hossenfelder: Backreaction" title="Sabine Hossenfelder: Backreaction" xmlUrl="https://backreaction.blogspot.com/feeds/posts/default" htmlUrl="https://backreaction.blogspot.com"/>
<outline type="rss" text="Articles — brandur.org" title="Articles — brandur.org" xmlUrl="https://brandur.org/articles.atom" htmlUrl="https://brandur.org"/>
<outline type="rss" text="Send More Paramedics" title="Send More Paramedics" xmlUrl="https://blog.fogus.me/feed/" htmlUrl="https://blog.fogus.me"/>
<outline type="rss" text="Ctrl blog" title="Ctrl blog" xmlUrl="https://feed.ctrl.blog/latest.atom" htmlUrl="https://ctrl.blog"/>
<outline type="rss" text="Cal Newport" title="Cal Newport" xmlUrl="https://calnewport.com/feed" htmlUrl="https://calnewport.com"/>
<outline type="rss" text="BIG by Matt Stoller" title="BIG by Matt Stoller" xmlUrl="https://mattstoller.substack.com/feed" htmlUrl="https://mattstoller.substack.com"/>
<outline type="rss" text="lcamtuf’s thing" title="lcamtuf’s thing" xmlUrl="https://lcamtuf.substack.com/feed" htmlUrl="https://lcamtuf.substack.com"/>
<outline type="rss" text="Max Woolf's Blog" title="Max Woolf's Blog" xmlUrl="https://minimaxir.com/index.xml" htmlUrl="https://minimaxir.com"/>
<outline type="rss" text="Jeff Kaufman's Writing" title="Jeff Kaufman's Writing" xmlUrl="https://jefftk.com/news.rss" htmlUrl="https://jefftk.com"/>
<outline type="rss" text="the jsomers.net blog" title="the jsomers.net blog" xmlUrl="https://jsomers.net/blog/feed" htmlUrl="https://jsomers.net"/>
<outline type="rss" text="Stephen Wolfram Writings" title="Stephen Wolfram Writings" xmlUrl="https://writings.stephenwolfram.com/feed/" htmlUrl="https://writings.stephenwolfram.com"/>
<outline type="rss" text="cdixon" title="cdixon" xmlUrl="https://cdixon.org/rss.xml" htmlUrl="https://cdixon.org"/>
<outline type="rss" text="seangoedecke.com RSS feed" title="seangoedecke.com RSS feed" xmlUrl="https://seangoedecke.com/rss.xml" htmlUrl="https://seangoedecke.com"/>
<outline type="rss" text="chris-granger.com" title="chris-granger.com" xmlUrl="http://feeds.feedburner.com/ChrisGranger" htmlUrl="https://chris-granger.com"/>
<outline type="rss" text="Jim Nielsen’s Blog" title="Jim Nielsen’s Blog" xmlUrl="https://blog.jim-nielsen.com/feed.xml" htmlUrl="https://blog.jim-nielsen.com"/>
<outline type="rss" text="BetterExplained" title="BetterExplained" xmlUrl="https://betterexplained.com/feed/" htmlUrl="https://betterexplained.com"/>
<outline type="rss" text="computers are bad" title="computers are bad" xmlUrl="https://computer.rip/rss.xml" htmlUrl="https://computer.rip"/>
<outline type="rss" text="Dave Cheney" title="Dave Cheney" xmlUrl="https://dave.cheney.net/feed" htmlUrl="https://dave.cheney.net"/>
<outline type="rss" text="James Long's sketchbook" title="James Long's sketchbook" xmlUrl="https://jlongster.com/feed.xml" htmlUrl="https://jlongster.com"/>
<outline type="rss" text="Kevin Kelly" title="Kevin Kelly" xmlUrl="https://kk.org/feed" htmlUrl="https://kk.org"/>
<outline type="rss" text="Richard Stallman's Political Notes" title="Richard Stallman's Political Notes" xmlUrl="https://stallman.org/rss/rss.xml" htmlUrl="https://stallman.org"/>
<outline type="rss" text="ejohn.org" title="ejohn.org" xmlUrl="https://ejohn.org/feed" htmlUrl="https://ejohn.org"/>
<outline type="rss" text="ASCII by Jason Scott" title="ASCII by Jason Scott" xmlUrl="https://ascii.textfiles.com/feed" htmlUrl="https://ascii.textfiles.com"/>
<outline type="rss" text="jacob toots" title="jacob toots" xmlUrl="https://jacobian.org/index.xml" htmlUrl="https://jacobian.org"/>
<outline type="rss" text="CRAIG KERSTIENS" title="CRAIG KERSTIENS" xmlUrl="https://craigkerstiens.com/index.xml" htmlUrl="https://craigkerstiens.com"/>
<outline type="rss" text="benkuhn.net" title="benkuhn.net" xmlUrl="https://www.benkuhn.net/index.xml" htmlUrl="https://benkuhn.net"/>
<outline type="rss" text="overreacted — A blog by Dan Abramov" title="overreacted — A blog by Dan Abramov" xmlUrl="https://overreacted.io/atom.xml" htmlUrl="https://overreacted.io"/>
<outline type="rss" text="Alyssa Rosenzweig" title="Alyssa Rosenzweig" xmlUrl="https://rosenzweig.io/feed.xml" htmlUrl="https://rosenzweig.io"/>
<outline type="rss" text="Things Of Interest" title="Things Of Interest" xmlUrl="https://qntm.org/rss.php" htmlUrl="https://qntm.org"/>
<outline type="rss" text="Paul Buchheit" title="Paul Buchheit" xmlUrl="https://paulbuchheit.blogspot.com/feeds/posts/default" htmlUrl="https://paulbuchheit.blogspot.com"/>
<outline type="rss" text="Acko.net" title="Acko.net" xmlUrl="https://acko.net/atom.xml" htmlUrl="https://acko.net"/>
<outline type="rss" text="What's new" title="What's new" xmlUrl="https://terrytao.wordpress.com/feed/" htmlUrl="https://terrytao.wordpress.com"/>
<outline type="rss" text="Raph Levien’s blog" title="Raph Levien’s blog" xmlUrl="https://raphlinus.github.io/feed.xml" htmlUrl="https://raphlinus.github.io"/>
<outline type="rss" text="Shtetl-Optimized" title="Shtetl-Optimized" xmlUrl="https://scottaaronson.blog/?feed=rss2" htmlUrl="https://scottaaronson.blog"/>
<outline type="rss" text="おいもログ" title="おいもログ" xmlUrl="https://oimo.io/blog/feed" htmlUrl="https://oimo.io"/>
<outline type="rss" text="Software and Tech stories from an Insider - iDiallo.com" title="Software and Tech stories from an Insider - iDiallo.com" xmlUrl="https://idiallo.com/feed.rss" htmlUrl="https://idiallo.com"/>
<outline type="rss" text="fuzzy notepad" title="fuzzy notepad" xmlUrl="https://eev.ee/feeds/atom.xml" htmlUrl="https://eev.ee"/>
<outline type="rss" text="Ferd.ca" title="Ferd.ca" xmlUrl="https://ferd.ca/feed.rss" htmlUrl="https://ferd.ca"/>
<outline type="rss" text="journal.stuffwithstuff.com" title="journal.stuffwithstuff.com" xmlUrl="https://journal.stuffwithstuff.com/rss.xml" htmlUrl="https://journal.stuffwithstuff.com"/>
<outline type="rss" text="Old Vintage Computing Research" title="Old Vintage Computing Research" xmlUrl="https://oldvcr.blogspot.com/feeds/posts/default" htmlUrl="https://oldvcr.blogspot.com"/>
<outline type="rss" text="wingolog" title="wingolog" xmlUrl="https://wingolog.org/feed/atom" htmlUrl="https://wingolog.org"/>
<outline type="rss" text="Beej 💾" title="Beej 💾" xmlUrl="https://mastodon.sdf.org/@beejjorgensen.rss" htmlUrl="https://beej.us"/>
<outline type="rss" text="Errata Security" title="Errata Security" xmlUrl="https://blog.erratasec.com/feeds/posts/default" htmlUrl="https://blog.erratasec.com"/>
<outline type="rss" text="Seth's Blog" title="Seth's Blog" xmlUrl="https://seths.blog/feed" htmlUrl="https://seths.blog"/>
<outline type="rss" text="Math ∩ Programming" title="Math ∩ Programming" xmlUrl="https://www.jeremykun.com/index.xml" htmlUrl="https://jeremykun.com"/>
<outline type="rss" text="Nicky's New Shtuff" title="Nicky's New Shtuff" xmlUrl="https://ncase.me/feed.xml" htmlUrl="https://ncase.me"/>
<outline type="rss" text="Laurence Tratt: Blog" title="Laurence Tratt: Blog" xmlUrl="https://tratt.net/blog/rss" htmlUrl="https://tratt.net"/>
<outline type="rss" text="Waxy.org" title="Waxy.org" xmlUrl="https://waxy.org/feed/" htmlUrl="https://waxy.org"/>
<outline type="rss" text="I, Cringely" title="I, Cringely" xmlUrl="https://www.cringely.com/feed/" htmlUrl="https://cringely.com"/>
<outline type="rss" text="Random Ramblings on Math, Juggling, Programming, Business, and stuff ..." title="Random Ramblings on Math, Juggling, Programming, Business, and stuff ..." xmlUrl="https://solipsys.co.uk/rss.xml" htmlUrl="https://solipsys.co.uk"/>
<outline type="rss" text="Andrej Karpathy blog" title="Andrej Karpathy blog" xmlUrl="https://karpathy.github.io/feed.xml" htmlUrl="https://karpathy.github.io"/>
<outline type="rss" text="defmacro" title="defmacro" xmlUrl="https://defmacro.org/feed.xml" htmlUrl="https://defmacro.org"/>
<outline type="rss" text="Ramblings from Jessie" title="Ramblings from Jessie" xmlUrl="https://blog.jessfraz.com/index.xml" htmlUrl="https://jessfraz.com"/>
<outline type="rss" text="Rands in Repose" title="Rands in Repose" xmlUrl="http://randsinrepose.com/feed/" htmlUrl="https://randsinrepose.com"/>
<outline type="rss" text="Scattered Thoughts" title="Scattered Thoughts" xmlUrl="https://scattered-thoughts.net/atom.xml" htmlUrl="https://scattered-thoughts.net"/>
<outline type="rss" text="Metadata" title="Metadata" xmlUrl="https://muratbuffalo.blogspot.com/feeds/posts/default" htmlUrl="https://muratbuffalo.blogspot.com"/>
<outline type="rss" text="Both Sides of the Table - Medium" title="Both Sides of the Table - Medium" xmlUrl="https://medium.com/feed/both-sides-of-the-table" htmlUrl="https://bothsidesofthetable.com"/>
<outline type="rss" text="Downtown Doug Brown" title="Downtown Doug Brown" xmlUrl="https://www.downtowndougbrown.com/feed/" htmlUrl="https://downtowndougbrown.com"/>
<outline type="rss" text="Robert Elder Software's Blog" title="Robert Elder Software's Blog" xmlUrl="https://blog.robertelder.org/rss" htmlUrl="https://blog.robertelder.org"/>
<outline type="rss" text="Phoboslab" title="Phoboslab" xmlUrl="https://phoboslab.org/log/feed" htmlUrl="https://phoboslab.org"/>
<outline type="rss" text="Azimuth" title="Azimuth" xmlUrl="https://johncarlosbaez.wordpress.com/feed/" htmlUrl="https://johncarlosbaez.wordpress.com"/>
<outline type="rss" text="devever.net" title="devever.net" xmlUrl="https://devever.net/~hl" htmlUrl="https://devever.net/~hl"/>
<outline type="rss" text="Stavros' Stuff" title="Stavros' Stuff" xmlUrl="https://stavros.io/feed/short/" htmlUrl="https://stavros.io"/>
<outline type="rss" text="Stack Diary" title="Stack Diary" xmlUrl="https://stackdiary.com/feed/" htmlUrl="https://stackdiary.com"/>
<outline type="rss" text="latest projects - mitxela.com" title="latest projects - mitxela.com" xmlUrl="https://mitxela.com/feed" htmlUrl="https://mitxela.com"/>
<outline type="rss" text="Bits about Money" title="Bits about Money" xmlUrl="https://www.bitsaboutmoney.com/archive/rss/" htmlUrl="https://bitsaboutmoney.com"/>
<outline type="rss" text="zwischenzugs.com" title="zwischenzugs.com" xmlUrl="https://zwischenzugs.com/feed/" htmlUrl="https://zwischenzugs.com"/>
<outline type="rss" text="ianVisits" title="ianVisits" xmlUrl="https://www.ianvisits.co.uk/feed/" htmlUrl="https://ianvisits.co.uk"/>
<outline type="rss" text="Raptitude.com" title="Raptitude.com" xmlUrl="https://www.raptitude.com/feed/" htmlUrl="https://raptitude.com"/>
<outline type="rss" text="Marcus on AI" title="Marcus on AI" xmlUrl="https://garymarcus.substack.com/feed" htmlUrl="https://garymarcus.substack.com"/>
<outline type="rss" text="Cal Paterson" title="Cal Paterson" xmlUrl="https://calpaterson.com/calpaterson.rss" htmlUrl="https://calpaterson.com"/>
<outline type="rss" text="Dmitry.GR" title="Dmitry.GR" xmlUrl="https://dmitry.gr/rss.php" htmlUrl="https://dmitry.gr"/>
<outline type="rss" text="eatonphil.com" title="eatonphil.com" xmlUrl="https://eatonphil.com/rss.xml" htmlUrl="https://eatonphil.com"/>
<outline type="rss" text="Arthur O’Dwyer" title="Arthur O’Dwyer" xmlUrl="https://quuxplusone.github.io/blog/feed" htmlUrl="https://quuxplusone.github.io"/>
<outline type="rss" text="Steve Losh" title="Steve Losh" xmlUrl="https://stevelosh.com/rss.xml" htmlUrl="https://stevelosh.com"/>
<outline type="rss" text="destroyallsoftware.com" title="destroyallsoftware.com" xmlUrl="https://destroyallsoftware.com/atom.xml" htmlUrl="https://destroyallsoftware.com"/>
<outline type="rss" text="Rondam Ramblings" title="Rondam Ramblings" xmlUrl="https://blog.rongarret.info/feeds/posts/default" htmlUrl="https://blog.rongarret.info"/>
<outline type="rss" text="datagubbe" title="datagubbe" xmlUrl="https://datagubbe.se/atom.xml" htmlUrl="https://datagubbe.se"/>
<outline type="rss" text="Red Blob Games: latest blog posts" title="Red Blob Games: latest blog posts" xmlUrl="https://www.redblobgames.com/blog/posts.xml" htmlUrl="https://redblobgames.com"/>
<outline type="rss" text="Tristan Hume" title="Tristan Hume" xmlUrl="https://thume.ca/atom.xml" htmlUrl="https://thume.ca"/>
<outline type="rss" text="Jeff Huang's Articles" title="Jeff Huang's Articles" xmlUrl="https://jeffhuang.com/feed.xml" htmlUrl="https://jeffhuang.com"/>
<outline type="rss" text="Seph" title="Seph" xmlUrl="https://josephg.com/blog/rss/" htmlUrl="https://josephg.com"/>
<outline type="rss" text="ImperialViolet" title="ImperialViolet" xmlUrl="https://imperialviolet.org/iv-rss.xml" htmlUrl="https://imperialviolet.org"/>
<outline type="rss" text="Stevey's Blog Rants" title="Stevey's Blog Rants" xmlUrl="https://steve-yegge.blogspot.com/feeds/posts/default" htmlUrl="https://steve-yegge.blogspot.com"/>
<outline type="rss" text="Index on www.complete.org" title="Index on www.complete.org" xmlUrl="https://complete.org/index.xml" htmlUrl="https://complete.org"/>
<outline type="rss" text="Nibble Stew" title="Nibble Stew" xmlUrl="https://nibblestew.blogspot.com/feeds/posts/default" htmlUrl="https://nibblestew.blogspot.com"/>
<outline type="rss" text="Tim Harford" title="Tim Harford" xmlUrl="https://timharford.com/feed/" htmlUrl="https://timharford.com"/>
<outline type="rss" text="Home on Erik Bernhardsson" title="Home on Erik Bernhardsson" xmlUrl="https://erikbern.com/index.xml" htmlUrl="https://erikbern.com"/>
<outline type="rss" text="Tech Blog" title="Tech Blog" xmlUrl="https://tech.marksblogg.com/feeds/all.atom.xml" htmlUrl="https://tech.marksblogg.com"/>
<outline type="rss" text="Irrational Exuberance" title="Irrational Exuberance" xmlUrl="https://lethain.com/feeds.xml" htmlUrl="https://lethain.com"/>
<outline type="rss" text="www.linusakesson.net" title="www.linusakesson.net" xmlUrl="http://www.linusakesson.net/rssfeed.php" htmlUrl="https://linusakesson.net"/>
<outline type="rss" text="Unix Digest - Articles" title="Unix Digest - Articles" xmlUrl="https://unixdigest.com/articles.xml" htmlUrl="https://unixdigest.com"/>
<outline type="rss" text="The Popehat Report" title="The Popehat Report" xmlUrl="https://rss.beehiiv.com/feeds/6QXMLvJf2y.xml" htmlUrl="https://popehat.com"/>
<outline type="rss" text="Susam Pal" title="Susam Pal" xmlUrl="https://susam.net/feed.xml" htmlUrl="https://susam.net"/>
<outline type="rss" text="Probably Dance" title="Probably Dance" xmlUrl="https://probablydance.com/feed/" htmlUrl="https://probablydance.com"/>
<outline type="rss" text="Andreas Kling" title="Andreas Kling" xmlUrl="https://awesomekling.github.io/feed.xml" htmlUrl="https://awesomekling.github.io"/>
<outline type="rss" text="250bpm" title="250bpm" xmlUrl="https://250bpm.substack.com/feed" htmlUrl="https://250bpm.substack.com"/>
<outline type="rss" text="matduggan.com" title="matduggan.com" xmlUrl="https://matduggan.com/rss/" htmlUrl="https://matduggan.com"/>
<outline type="rss" text="Ludicity" title="Ludicity" xmlUrl="https://ludic.mataroa.blog/rss/" htmlUrl="https://ludic.mataroa.blog"/>
<outline type="rss" text="Christian Hascheks blog" title="Christian Hascheks blog" xmlUrl="https://blog.haschek.at/rss.xml" htmlUrl="https://blog.haschek.at"/>
<outline type="rss" text="HTTP Toolkit" title="HTTP Toolkit" xmlUrl="https://httptoolkit.com/rss.xml" htmlUrl="https://httptoolkit.com"/>
<outline type="rss" text="All Things Distributed" title="All Things Distributed" xmlUrl="https://www.allthingsdistributed.com/atom.xml" htmlUrl="https://allthingsdistributed.com"/>
<outline type="rss" text="Two-Bit History" title="Two-Bit History" xmlUrl="https://twobithistory.org/feed.xml" htmlUrl="https://twobithistory.org"/>
<outline type="rss" text="Matt Keeter" title="Matt Keeter" xmlUrl="https://mattkeeter.com/atom.xml" htmlUrl="https://mattkeeter.com"/>
<outline type="rss" text="The Mad Ned Memo" title="The Mad Ned Memo" xmlUrl="https://madned.substack.com/feed" htmlUrl="https://madned.substack.com"/>
<outline type="rss" text="frog hop" title="frog hop" xmlUrl="https://graydon2.dreamwidth.org/data/rss" htmlUrl="https://graydon2.dreamwidth.org"/>
<outline type="rss" text="Rubenerd" title="Rubenerd" xmlUrl="https://www.rubenerd.au/feed/" htmlUrl="https://rubenerd.com"/>
<outline type="rss" text="brr" title="brr" xmlUrl="https://brr.fyi/feed.xml" htmlUrl="https://brr.fyi"/>
<outline type="rss" text="The Copetti site" title="The Copetti site" xmlUrl="https://www.copetti.org/index.xml" htmlUrl="https://copetti.org"/>
<outline type="rss" text="Eugene Yan" title="Eugene Yan" xmlUrl="https://eugeneyan.com/rss/" htmlUrl="https://eugeneyan.com"/>
<outline type="rss" text="Ed Zitron's Where's Your Ed At" title="Ed Zitron's Where's Your Ed At" xmlUrl="https://www.wheresyoured.at/rss/" htmlUrl="https://wheresyoured.at"/>
<outline type="rss" text="Daniel Miessler" title="Daniel Miessler" xmlUrl="https://danielmiessler.com/feed.rss" htmlUrl="https://danielmiessler.com"/>
<outline type="rss" text="Locklin on science" title="Locklin on science" xmlUrl="https://scottlocklin.wordpress.com/feed/" htmlUrl="https://scottlocklin.wordpress.com"/>
<outline type="rss" text="Martin Kleppmann's blog" title="Martin Kleppmann's blog" xmlUrl="https://feeds.feedburner.com/martinkl?format=xml" htmlUrl="https://martin.kleppmann.com"/>
<outline type="rss" text="Elad Blog" title="Elad Blog" xmlUrl="https://blog.eladgil.com/feed" htmlUrl="https://blog.eladgil.com"/>
<outline type="rss" text="Patrick Breyer" title="Patrick Breyer" xmlUrl="https://www.patrick-breyer.de/feed/" htmlUrl="https://patrick-breyer.de"/>
<outline type="rss" text="arp242.net" title="arp242.net" xmlUrl="https://arp242.net/feed.xml" htmlUrl="https://arp242.net"/>
<outline type="rss" text="Underjord.io" title="Underjord.io" xmlUrl="https://underjord.io/feed.xml" htmlUrl="https://underjord.io"/>
</body>
</opml>Pair it with the prompt below and you’ve got everything you need to start.
Try It Yourself
I’m not releasing the code because it’s wired to my specific setup, but the code is the easy part anyway. A coding agent can build the whole scaffold in a couple hours. The two things that actually make it work are a taste.md that captures your judgment and the discipline to test it. I’ll come back to both, but the build comes first, and two habits keep it cheap and sane.
First, start with just a single source and the judge. Let that be the whole product; add more sources, delivery, and scheduling later, once you trust the judge. Second, do the mechanical filtering before the judging. It’s easy to drop old posts, but asking an LLM about each one costs a call.
The judge itself is one LLM call per candidate: in goes the title, source, and snippet; out comes a score (0–100), a verdict (in / maybe / out), and a one-sentence reason. That reason isn’t decoration. It’s what lets you accept or overrule each pick in seconds.
Writing a taste.md
Your taste.md is the whole ballgame, and it’s just a plain markdown file, written in your voice. Organize it in three parts:
- Who you’re curating for (even if that’s only you)
- Positive signals that raise the score
- Disqualifiers that sink a post even when it’s good
Don’t write it from theory. Write it from examples instead. Collect posts you recently loved and others that you’re not interested in, and then write down what actually separates them. The ones you’re not interested in matter most, especially the near-misses. Look for the posts that are good but not good for you. That boundary is where your taste lives, and it’s the part a generic rubric will never guess.
Don’t trust it until you’ve tested it
Your first taste.md will produce a plausible-looking ranking, but that’s a trap. Plausible isn’t right, and you can’t eyeball the difference. Before you trust it, score your labeled examples blind and measure how often the judge agreed with you, and whether your yeses and nos actually pull apart. Then edit the file and re-run. That loop, not the code, is what turns “an LLM that ranks things” into “an LLM that ranks things the way you would.”
A prompt to get you started
The prompt below does the real work. It front-loads an interview, forces the labeled examples (with a line that won’t let you skip the hard input), and bakes the whole vibes→labels→outcomes discipline into the build itself. Paste it into your favorite coding agent:
Show the prompt
Help me build a personal content-curation assistant: it pulls candidate links from sources I choose, scores each against my taste, and returns a ranked shortlist.
Before writing any code, interview me. Ask these one at a time and wait for my answer before the next:
1. What am I curating, and for whom? (Links for a newsletter, papers for my own reading, jobs, deals… and who the audience is, even if it's just me.)
2. What sources should it pull from? (RSS, a newsletter inbox, Hacker News, Reddit, an API.) We'll start with exactly one.
3. What makes something a *yes* for me — and, more importantly, what makes something a near-miss *no*? Push me for specifics, not generalities.
4. Can I hand you ~15 things I recently chose and ~15 I passed on, each with a one-line reason? If I can't yet, tell me to go collect them first — this is the single most important input, so don't let me skip it.
5. How should the shortlist reach me? (An email, a file, a web page.)
6. How often should it run, and roughly how many candidates per run?
Once you understand my answers, propose a minimal architecture and wait for my approval before building. Hold to these principles:
- The judge is the keystone. Build the smallest end-to-end version first: one source → normalize each item to {title, url, source, snippet, date} → a judge that scores each 0–100 with a verdict (in/maybe/out) and a one-sentence reason → a ranked list. Everything else comes later.
- My taste lives in a plain-text `taste.md` file I can read and edit — that file *is* the judge's system prompt. Do not bury my taste in code.
- Cheap filters before expensive ones: dedupe and drop stale items *before* any LLM call.
- The one-sentence reason is required, not optional.
Then — the part that matters most — help me test it before I trust it:
- Build a backtest: score the ~30 labeled examples I gave you *blind* (strip the labels and notes), then report how often the judge agreed with me and the median score of my yeses vs. my nos.
- If they don't clearly separate, help me revise `taste.md` and re-run — and watch for one fix quietly breaking another. Iterate until the judge discriminates.
Start by asking me question 1.
It still catches me off guard some mornings when those emails closely match what I would have picked myself. That was the whole point, but it didn’t come from a smarter model. The first version was a coin flip. It got here because I wrote my taste down and kept testing it until the machine and I agreed. The judgment is still mine. Teaching it to a machine was just the first time I’d had to figure out exactly what that judgment was.
