Operator guide · built on Horizon, an open-source project by Thysrael · Case study

Horizon AI Daily

Every morning at 6:30, your PC collects the last 24 hours of AI news from 16 feeds, has Claude score each story against your own rules, writes up the best ones with background and context, and emails you the briefing. This page explains what each part does and how they connect.

6:30 AMdaily, Windows Task Scheduler
16 feedslabs, press, Reddit, HN, GitHub
Claude Sonnet 5.5scores and writes every item
~6–7 minper run, start to email
≤ 20 itemsper briefing, by quota
What it is

An open-source news radar, set up for AI

Horizon is a free, MIT-licensed Python project by Thysrael (about 12,800 stars on GitHub). It's a general tool for turning lots of feeds into one short daily briefing. Out of the box it's set up for general tech and finance news, with a Chinese/English focus.

Your copy has been set up for one job: a daily "what's new in AI" email in English. That meant choosing AI-specific sources, writing a custom scoring profile that drops non-AI stories, setting quotas so no one kind of source crowds out the rest, and fixing two problems that stopped it working on your machine.

Nothing runs in the cloud except the two services it calls. Collection, filtering and scheduling all happen on your PC. Claude is reached through Anthropic's API using your key, and the email goes out through your own Gmail account.

Architecture

What talks to what

Everything inside the dashed box runs on your PC. Arrows show which way data flows.

INTERNET · SOURCES YOUR PC INTERNET · SERVICES AI lab blogs Anthropic, OpenAI, DeepMind, Google AI News & analysis Verge, TechCrunch, Latent Space +5 Reddit (RSS) 5 subreddits in 2 combined feeds Hacker News top 30 stories + comments (API) OSS Insight GitHub repos gaining stars today Task Scheduler daily 06:30 run-horizon.ps1 starts it, writes a log Horizon pipeline .venv\Scripts\horizon.exe 1 Fetch 2 Merge 3 Score 4 Filter 5 De-dupe 6 Balance 7 Enrich 8 Deliver Steps 3, 5 and 7 call Claude. Step 7 can also search the web and look up earlier briefings. Full details further down. config.json settings .env 2 secret keys ai-news scoring rules summaries each briefing Read at start (dashed lines). Briefings are saved as Markdown. Logs: C:\dev\AI News\logs (last 30 runs) Anthropic API claude-sonnet-5-5 · your key Web search DuckDuckGo and others, no key Gmail SMTP smtp.gmail.com:465 (SSL) Your inbox "Horizon AI Daily" email
Two arrows point both ways because Horizon sends a request and gets an answer back. Only the orange path carries your briefing out of the PC.
A typical run

What happens between 6:30 and your inbox

Approximate times, based on the full run on Saturday 7 November, which took 6 minutes 26 seconds. Busier weekdays take a little longer.

  1. Task Scheduler starts the job

    It runs run-horizon.ps1 in a hidden window. If the PC was off or you weren't logged in, it runs as soon as you next log in. It only starts if there's a network connection, and it's stopped if it ever runs longer than 45 minutes.

  2. Horizon loads its settings

    It reads data/config.json, the two secrets in .env, and the scoring profiles. It then sets the time window to the last 24 hours.

  3. Collect

    It downloads every feed and keeps only items published in the window. On a quiet day that's about 75 items, on a busy one about 100. The Reddit feeds may be refused a few times and retried after 15, 30 and 45 seconds.

  4. Score

    One Claude request per item, two at a time. Each item comes back with a score from 0 to 10, a one-line summary, and tags. This is the slowest step and uses most of the tokens.

  5. Choose

    Items below the score threshold are dropped. Claude merges stories that cover the same event, and quotas cap each kind of source. This takes a few seconds.

  6. Write up

    For each chosen item, one at a time, Claude writes the summary, background, impact and community-discussion sections. It searches the web and looks at earlier briefings when it needs more context.

  7. Deliver

    The briefing is saved as Markdown in data/summaries/, converted to an HTML email, and sent to every address in data/subscribers.json. Right now that's only you.

How items are whittled down

From about a hundred stories to about ten

Real counts from the test run on 5 November, the first run with the AI-only profile. Bars are drawn to scale.

Collected 16 feeds, last 24 h 102 Scored by Claude every item, 0–10 102 Passed threshold AI news ≥ 6 · deep dives ≥ 5 17 Same-story merge 5 duplicates folded in 12 Quotas applied per-category caps, max 20 10 In your email written up in full 10
The big drop is the score threshold. About five in six items are routine updates, opinion threads or non-AI stories. On Saturday 7 November it went 74 → 5 → 4 → 4, because weekends are quieter.
The pipeline in detail

Eight steps, three of them AI

The steps run in this order every time. They're defined in src/orchestrator.py.

1

Fetch

Each source type has its own collector in src/scrapers/. RSS and Atom feeds are parsed with feedparser. For lab blogs and long-form feeds, the full article is also downloaded and cleaned with trafilatura, so Claude reads the whole post, not just a teaser. Hacker News comes from its official API and includes the top comments.

No AI
2

Merge

If the same link turns up from two sources, for example an OpenAI post that is also on Hacker News, the copies are merged into one item that keeps the discussion from both.

No AI
3

Score

Each item goes to Claude with its profile's rules (profiles/ai-news/analysis.md), the article text, and engagement figures such as upvotes and comment counts. Claude returns JSON with a score from 0 to 10, a reason, a one-line summary, and 3–5 tags. If the JSON is malformed it gets one retry.

Claude · ~100 calls
4

Filter

Items scoring below their profile's threshold are dropped. That's 6 for AI news and 5 for the deep-dive blogs.

No AI
5

De-dupe

Different links about the same event, such as five articles on one model launch, are grouped by Claude. Only the highest-scoring version is kept, with the others' text folded in.

Claude · 1 call
6

Balance

Items are sorted by score, then each source category may only fill its quota (see the quota chart). The briefing is capped at 20 items. Write-ups are only done after this, so no tokens are spent on items that wouldn't make it in.

No AI
7

Enrich

Claude writes the final sections for each item. It has two tools: web_search for facts the article doesn't include, and history_search, which looks through your earlier briefings so it can say what has changed since a previous report.

Claude · ~10 calls + tools
8

Deliver

The items are grouped under "AI News" and "Technology Blog" and rendered as Markdown. The Markdown is saved and converted to HTML. Then it's sent with a plain-text copy through Gmail, using an encrypted SMTP connection on port 465 and your App Password.

No AI
Inputs

The 16 feeds

Defined under sources in data/config.json. The category decides which quota an item counts against. The profile decides which scoring rules are used.

SourceHow it's readCategoryProfileNotes
Anthropic NewsRSS + full textlabsai-newsAnthropic has no official feed, so this uses a community-maintained one (Olshansk/rss-feeds) that mirrors anthropic.com/news
OpenAI NewsRSS + full textlabsai-newsopenai.com/news/rss.xml
Google DeepMindRSS + full textlabsai-news
Google AI BlogRSSlabsai-newsblog.google/technology/ai
The Verge AIRSSpressai-news
TechCrunch AIRSSpressai-newsThe busiest feed, about 18 items a day
Simon WillisonRSSanalysisai-newsHands-on notes on new models and tools
Latent SpaceRSS + full textanalysistech-blogEngineering newsletter and podcast
InterconnectsRSS + full textanalysistech-blogNathan Lambert on open models and RL
Import AIRSSanalysistech-blogJack Clark's weekly research roundup
Hugging Face BlogRSS + full textopen-modelstech-blogCounts towards the analysis quota
smol AINewsRSScommunityai-newsDaily recap of AI Discord servers, Reddit and X
Reddit: r/LocalLLaMA + r/MachineLearningRSS, top of the day, 25 postscommunityai-newsRetried if Reddit says "too many requests"
Reddit: r/ClaudeAI + r/OpenAI + r/singularityRSS, top of the day, 25 postscommunityai-newsSame retry
Hacker NewsOfficial APIcommunityai-newsTop 30 stories with ≥ 100 points, plus comments. General tech, so non-AI stories are scored out
OSS InsightPublic APIoss-trendingai-newsRepos gaining ≥ 50 stars in 24 h whose name or description matches llm, agent, gpt, claude, mcp, rag and similar. Up to 10

Why Reddit is read through RSS. Reddit now blocks most automated requests to its normal pages and its JSON listings. Horizon's built-in Reddit reader tries both and only then falls back to RSS, waiting about 20 seconds for each blocked attempt. Reading the RSS feeds directly skips those blocked attempts. Combining the subreddits into two feeds means only two requests a day. The trade-off is that comment threads aren't fetched, though they were being blocked anyway.

Judgement

How Claude decides what's important

Each item is scored using its profile's rules. Lab announcements, news, Reddit and Hacker News use the custom ai-news profile written for this setup. Long-form blogs use Horizon's built-in tech-blog profile, which rewards engineering depth and practical lessons.

The ai-news profile has one extra rule the general one lacked: an item must be mainly about AI. Non-AI items score at most 3, however important they are, and items that only mention AI in passing score at most 4. That rule is what removed the SSH security bug and the Discord desktop app story from the first test run.

0–2 noise
3–4 low / non-AI
5–6 worth a look
7–8 high value
9–10 must know
0357910
deep dives ≥ 5
AI news ≥ 6

Scoring bands come from profiles/ai-news/analysis.md. Thresholds are set under processing.profile_settings in config.json. Raise the AI news threshold to 7 for a shorter briefing, or lower it to 5 for a longer one.

Balance

Quotas keep one kind of source from taking over

Without quotas, a busy Reddit day could fill the whole briefing. Each source category gets a fixed number of slots, filled highest score first. Unused slots aren't passed on, and the overall cap is 20.

Lab announcementslabs · 6
CommunityReddit, HN, AINews · 6
Industry newspress · 4
Analysis & deep divesanalysis + open-models · 4
Trending repososs-trending · 3
Anything elsedefault group · 2

Slots add up to 25, so the 20-item cap only matters on unusually busy days. Quotas are set under digest.category_groups in config.json.

Output

What one item looks like

A real item from the 5 November test briefing, shortened. Each part on the left of the card is produced by a different piece of the profile.

The Ultimate MoE Training Handbook: training Mixture-of-Experts models with Megatron-LM

★ 6.0/10 · rss · Reddit: LocalLLaMA + MachineLearning · Nov 5, 19:01
Summary

A new handbook for engineers who have trained dense models explains how to train Mixture-of-Experts models with Megatron-LM, from a hardware test and dense baseline through to a first single-node MoE run. The authors say it draws on about 800k GH200 GPU-hours on the Alps cluster at CSCS.

Background

An MoE model replaces each dense feed-forward layer with many smaller "expert" networks and a router that sends each token to only a few of them. That cuts compute per token but adds problems such as balancing load across experts.

Impact

Teams moving from dense to MoE training get a consolidated starting point: a baseline comparison, recommended flags and scripts. Teams on other hardware should validate the settings themselves.

#Mixture-of-Experts#Megatron-LM#LLM training#handbook

AI News items get

  • Summary: what changed and for whom, with the concrete names, versions and numbers
  • Background: the concept or earlier development you need to understand it
  • Impact: one concrete consequence, left out if there isn't a real one
  • Community discussion: the most useful argument from comments, when there are comments

Technology Blog items get

  • Background: the problem the post addresses
  • Solution: what the author did or proposes
  • Takeaway: what you can use from it

These are set in each profile's profile.json and enrichment.md.

On disk

Where everything lives

C:\dev\AI News\
├─ horizon-explained.html        this page
├─ run-horizon.ps1               what Task Scheduler runs; writes a log, keeps the last 30
├─ logs\horizon-YYYY-MM-DD_HHMM.log  one per run; check here first if an email doesn't arrive
└─ Horizon\                      clone of github.com/Thysrael/Horizon
   ├─ .env                       ANTHROPIC_API_KEY, EMAIL_PASSWORD (git-ignored, never shared)
   ├─ .venv\                      Python 3.12 environment with Horizon installed
   ├─ data\
   │  ├─ config.json             sources, model, thresholds, quotas, email settings
   │  ├─ subscribers.json        who gets the email (just you)
   │  └─ summaries\              horizon-YYYY-MM-DD-en.md, one per day
   ├─ profiles\
   │  ├─ ai-news\                custom: AI-only scoring and write-up rules
   │  ├─ tech-blog\              built-in, used for long-form blogs
   │  └─ tech-news\ …            built-in, unused
   ├─ docs\_posts\                copy of each briefing, formatted for a GitHub Pages site (unused)
   └─ src\                        Horizon's code (two small local fixes)

Files in orange are the ones you're most likely to open or edit.

Local changes

What was changed from stock Horizon

ChangeFileWhy
Recognise Anthropic's new "temperature" errorsrc/ai/client.pyClaude's API now rejects the temperature setting with the message "Extra inputs are not permitted". Horizon is meant to retry without it but didn't recognise that wording, so every Claude call failed. Adding the phrase lets the retry work.
Wait and retry on "too many requests"src/scrapers/rss.pyReddit's RSS often answers with error 429. Horizon now retries up to three times, waiting 15, 30 and 45 seconds, instead of skipping the feed.
AI-only scoring profileprofiles/ai-news/The built-in profile is for all of tech, so half of the first briefing wasn't about AI.
AI sources, quotas, Gmail deliverydata/config.jsonReplaces the example sources, which include Linux and finance feeds and a Chinese Telegram channel.
Slower pacing (2 scoring calls at a time, 1 write-up at a time)data/config.jsonOne run lost all its write-ups after a burst of about 100 requests. The likely cause is the request-rate limits on new Anthropic API accounts.
Daily schedule and log wrapperTask Scheduler, run-horizon.ps1Horizon has no scheduler of its own.

Before updating Horizon from GitHub: the two code fixes are local edits. Updating with git pull may conflict with them or overwrite them, unless the maintainer has fixed the same problems. Your config, profile and keys are separate files and won't be touched.

Running it

Day-to-day operation

Costs

  • A run uses about 160,000–200,000 Claude tokens, roughly 85% input and 15% output.
  • Scoring all the items accounts for most of it. Write-ups are fewer but longer.
  • See what that costs on the Anthropic Console's Usage page. Switching ai.model to claude-haiku-5-5 makes it noticeably cheaper.
  • Web search, the feeds and Gmail are free.

If an email doesn't arrive

  • Open the newest file in C:\dev\AI News\logs. The last line shows the exit code, where 0 means success.
  • No log for today? The PC was off, or you hadn't logged in yet. The run starts when you do.
  • "authentication failed" means the Gmail App Password was revoked. Make a new one and update .env.
  • Claude errors usually mean the API credit has run out. Check Billing in the Console.

Common changes

  • Add a source: copy one line in the rss list and change the name and URL.
  • Longer or shorter briefing: change the AI news threshold or digest.max_items.
  • Change the time: Task Scheduler → "Horizon AI Daily" → Triggers.
  • Add a recipient: add their address to subscribers.json.

Run it by hand

In PowerShell, from C:\dev\AI News\Horizon:

.\.venv\Scripts\horizon.exe

Add --hours 4 for a quick, cheap test over the last 4 hours. Each run sends an email, so you'll get one for every test.