DailyAI: summarise once,
serve everyone.
AI news moves fast and is full of repeated headlines. DailyAI gathers the day's stories, drops the duplicates, and uses an LLM to pick what matters and explain why it matters. It scores each source's trustworthiness and groups related stories into threads, all ahead of time, so readers get instant pages that cost nothing in model calls.
rss, openai, fullToo many headlines, too little signal, and an LLM bill that grows with every reader.
A single model launch can generate forty near-identical headlines. Readers want a short, trustworthy digest with the "so what?" spelled out.
The obvious build, calling an LLM whenever someone opens the page, gets expensive quickly and makes every page load slow. DailyAI moves all of the intelligence into a scheduled batch job, and the reader-facing app only reads from a database.
News cards with a 60–80-word summary, a one-line why it matters, a topic, a sentiment tag (bullish, bearish or neutral), a source trust tier and a story-thread label. Tapping a card opens a longer brief, which is generated once and then cached.
A batch job on one side, a fast reader on the other
The diagram splits into two halves. The top half runs on a schedule: news sources feed into a LangGraph pipeline that writes finished cards to storage. The bottom half runs when a reader visits: FastAPI reads those cards and serves them to the web app, email and push. No arrow connects a reader's request to the LLM.
← swipe to see the whole diagram →
✦ marks the only node that calls a model in the default openai mode. Everything below the dotted line is database reads only.
Follow one refresh cycle, node by node
Each LangGraph node reads one key from the shared state and writes the next one (raw_articles → deduplicated → curated → trust_scored → …). Use the summary mode toggle to see how the same graph behaves at different budgets.
Model calls per day, per-view vs summarise-once
Move the sliders. A per-view design pays for a model call on every page open. DailyAI pays once per feed per refresh, however many people read it.
Simplified model: one curation run per feed per refresh. In practice curation runs in bounded parallel chunks (CURATOR_CHUNK_SIZE), so the real number is a small multiple of this, and it still doesn't grow with readers.
Built as a product, not a demo
Morning Edition
A shared daily magazine issue built at 08:00 UTC with a transparent list of sources. It is emailed through Mailgun and can be previewed at /edition/YYYY-MM-DD.
Accounts without sign-up
Anonymous profiles identified by a sync code. Preferences, saved stories and reading signals move between devices without an email address or password.
Learning loop
Streaks, a quiz, a knowledge page and a leaderboard turn passive scrolling into a habit of actually understanding the AI news.
Public developer API
Read-only endpoints for the feed, categories and trending story threads, documented at /api-docs, so other apps can build on the curated data.
Quality guardrail
Every LLM run gets a deterministic output_quality score (non-empty, sensible length, complete sentences, no prompt leakage) without an extra model call.
Ready for Germany
Impressum, Datenschutz and terms pages, plus English and German UI strings served from the backend. It is also an installable PWA with a service worker and push notifications.
Glossary for the curious
RSS graph/nodes/collector.py
LangGraph StateGraph graph/pipeline.py
node_timings. That lets you swap, reorder or test nodes on their own and see exactly where time goes.Near-duplicate detection graph/nodes/deduplicator.py
Provider fallback chain llm/provider.py
Source trust tiers graph/nodes/trust.py
Ranking formula graph/nodes/personalizer.py
importance × 10 + trust × 3 + recency, where recency is +2 if the story is under 8 h old and +1 if under 24 h. When a profile has reading signals, preferred topics and categories raise that reader's score for matching stories.