惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
博客园 - 司徒正美
美团技术团队
Last Week in AI
Last Week in AI
月光博客
月光博客
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
U
Unit 42
T
Tailwind CSS Blog
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
Google DeepMind News
Google DeepMind News
H
Help Net Security
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
A
About on SuperTechFans
Y
Y Combinator Blog
罗磊的独立博客
D
DataBreaches.Net
有赞技术团队
有赞技术团队
MyScale Blog
MyScale Blog
博客园_首页
博客园 - 三生石上(FineUI控件)
G
Google Developers Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
博客园 - Franky
M
MIT News - Artificial intelligence
B
Blog
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
I
InfoQ
S
SegmentFault 最新的问题
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
I Built a Personal Intelligence System That Curates GitHub and News for Me — Here's How It Works
MediBlackSand · 2026-06-22 · via DEV Community

I Built a Personal Intelligence System That Curates GitHub and News for Me — Here's How It Works

A personal intelligence system that reads the news and scrapes GitHub for you, curates it with an LLM, and delivers it to your phone before you've finished your coffee. No dashboard. No login. Just three briefings, on a schedule you set.

The Problem

I'd already built TeachSim, a multi-agent system running on an LLM via OpenRouter, delivered entirely through Telegram, hosted on a budget VPS. Once that stack existed, the obvious question was what else it could power. The quickest win turned out to be information consumption itself.

The actual itch was how I was consuming news. Google had been pushing me daily feeds for years: algorithmically chosen, entirely passive. I never decided what showed up, I just scrolled what arrived. I wanted to try the opposite, same infrastructure, a completely different job. An LLM doing the choosing instead of an engagement optimized feed, for both the news I read and the open-source ecosystem I found increasingly interested to keep a tab on day to day.

That second half turned out to matter as much as the first. I don't have time to manually browse GitHub Trending every day, and Trending rewards absolute popularity over genuine novelty. The bet was that an LLM scanning broadly and judging by relevance rather than star count would surface things I'd never have found otherwise.

It has. Real tools the pipeline has actually surfaced for me, not things I went looking for: RTK, sst/opencode, and AI Engineering From Scratch, among others. That alone justified building it: the self-directed version surfaces tools I'd never have found through a popularity-ranked feed.

What GitHub Digest Is

GitHub Digest is a personal automation system that delivers three scheduled briefings straight to Telegram:

  • A morning news briefing: dozens of RSS feeds across world events, technology, AI research, and a few specialist categories, curated down to a handful of stories that fed into Deepseek V4 Flash and judged actually worth my attention that day.
  • A GitHub Discovery digest: a wide net of GitHub Search API queries surfacing repos I haven't seen before, tiered into "gem" (brand new, low stars, high velocity), "exploding" (star count accelerating fast), and "hot" (established but trending this week).
  • A weekly Momentum briefing: tracks a personal watchlist of tools over time and reports what changed, in plain language rather than a star-count delta.

Plus an on-demand command layer, so I can pull any of the three manually from my phone, check system health, or manage my watchlist without touching a terminal.

The Architecture

Sources (RSS feeds / GitHub Search API / personal watchlist)
            │
            ▼
       Scrapers (per-source rate limiting, per-feed age windows)
            │
            ▼
       Analyzers (LLM curation — picks what's actually worth surfacing)
            │
            ▼
       Delivery (Telegram bot, chunked for plain-text limits)
            │
            ▼
   Always-on command listener (on-demand pulls, watchlist management)

Three independent scrape-to-analyze-to-deliver pipelines, each on its own schedule, sharing a single delivery layer and a single listener process. All running on a single-core, 1GB budget VPS, which turns out to be the single biggest constraint shaping every other decision in this build.

The curation step runs through an OpenRouter-routed LLM call: currently a fast, cheap model chosen specifically because curation needs consistency and low cost at high frequency (three runs a day, every day) rather than frontier-level reasoning.

Under the Hood

The model's real output isn't always where you'd expect it, and this one fails silently. The LLM doing curation sometimes returns its actual content in a reasoning field instead of the standard content field, depending on how it worked through the ranking task internally. The first time this happened, nothing crashed and no error appeared anywhere in the logs. The pipeline ran to completion, the cron job reported success, and the briefing that arrived on Telegram was just empty. That's a worse failure mode than a clean exception: an empty message looks like "nothing happened to be newsworthy today," not "something broke," so it took a few quiet mornings before the pattern was obvious enough to investigate. The fix is a fallback chain every analyzer checks in order, content → reasoning_content → reasoning → text, rather than assuming the model will always populate the field the API docs imply it should. It's a one-line change once you know to make it, and an invisible one until you've been burned by it.

Cron doesn't speak the same language as your terminal. Every scheduled job activates the Python virtual environment with . venv/bin/activate rather than source venv/bin/activate, and the reason is more fundamental than a style preference. source is a bash builtin; cron runs jobs through sh, not bash, and sh doesn't recognize it. The job had been tested manually dozens of times in an interactive terminal, where source works fine because the terminal is bash, so the activation line looked correct right up until it ran unattended for the first time, failed to activate the environment, and silently used whatever Python and packages happened to be on the system path instead of the ones the project actually depends on. No error, no crash, just a job quietly running against the wrong environment until something it depended on wasn't there. . is the POSIX-portable equivalent and works in both shells. The fix is one character, but only once you understand why an interactive test can pass while the unattended version of the exact same command fails.

How Repos Actually Get Chosen

"Show me what's new on GitHub" is a bad prompt on its own. You get either noise or the same dozen famous repos everyone already knows about. Getting to a daily handful that's actually worth reading took a few layers of filtering before an LLM ever sees a candidate.

Casting a wide net first. The scraper runs a large batch of targeted search queries across several broad technical categories, each phrased to surface different kinds of repos: some queries hunt for brand-new activity, others for established projects with recent momentum, others for specific technical niches. No single query style finds everything; the combination is the point. The constraint shaping all of it: GitHub's search-specific endpoint caps out at 30 requests per minute, tighter than the general API limit and easy to blow through with this many categories firing in a loop. The scraper sleeps 2.1 seconds between calls, landing at roughly 28 requests a minute: close enough to the ceiling to finish a full run in a few minutes, far enough under it to never trip the limiter. A 403 anyway triggers a full 60-second backoff before retrying, rather than hammering an endpoint that just said slow down.

Code search hides the one number that matters. GitHub's code-search endpoint is useful for finding repos by what's actually in them, not just their name or description, but the nested repository object it returns is missing the star count entirely. Every code-search hit needs a second, separate API call to fetch the full repo record before any tiering logic can run. Skip that step and half your candidates silently sort as zero-star nobodies.

Tiering compares each repo against itself, not a fixed bar. Three tiers, and none of them use a flat "must have N stars" threshold:

  • Gem: very new (under two weeks old), low absolute stars, but high velocity relative to its own short life.
  • Exploding: older, but its star count over the last comparison window is accelerating sharply versus its own recent trend.
  • Hot: established, but trending this week compared to its own historical baseline. A popular repo having an ordinary week doesn't qualify; one having an unusually active week does.

That last distinction matters: a repo with ten thousand stars and no LLM-relevant recent activity is no more interesting on a given day than one with two hundred. What's being measured is change against the repo's own pattern, not absolute popularity.

The LLM is told explicitly not to just rank by stars. The curation prompt frames the task as picking what's meaningful: genuine novelty, technical relevance, and whether it's something I'd plausibly have missed without this pipeline. A repo near the top of the star-velocity list can still get passed over if it's a fork, a tutorial repo, or something with no real substance behind the trending number.

The weekly tracker measures change, not snapshots. For repos on a personal watchlist, every run stores that day's stats and compares them against the last stored snapshot, so the weekly report is a genuine delta (stars gained, momentum direction) rather than a restated current state. The explanation style is deliberately written for someone encountering each tool for the first time, since a watchlist can easily span tools outside what you use day to day.

This watchlist isn't auto-populated the way the daily Discovery digest is. It's a small, deliberately curated set I add to by hand through a chat command whenever something earns a permanent spot. Right now it's three repos: langchain-ai/langgraph (the orchestration framework underneath the multi-agent architecture I run in Teachsim, so a breaking change there has direct downstream consequences for things I've already shipped), pydantic/pydantic-ai (a newer agent framework from a team whose validation library I already trust, worth watching to see whether it earns the same trust in the agent space), and sst/opencode (a coding agent I started to use when Claude is in rate limits or blocked etc, so velocity here is a signal about where that category of tool is heading). None of these were discovered by the pipeline. They're things I already knew mattered and wanted tracked automatically instead of checking manually. The weekly report tells me, in plain language, whether each one had a quiet week or a meaningful one.

How the News Actually Gets Judged

"Is this worth reading" sounds like a single judgment call, but treating it that way is exactly how you get an inconsistent briefing: solid one day, padded with filler the next. The news analyzer runs off a fairly opinionated rubric instead, applied the same way across a few hundred headlines a day.

It's told what not to include, explicitly. No celebrity news, no sports results, no weather unless it's catastrophic, no stock prices, no opinion pieces that don't contain any new information. That exclusion list does more work than any positive instruction: it's far easier to define "not worth your time" precisely than "worth your time" precisely.

It's allowed to skip a category entirely. If a section has nothing worth including that day, the model is told to drop it rather than pad it with a weak story just to fill the slot, and it has to report which categories it skipped and why in a short line at the end. Silence has to be justified, not just defaulted into.

Every kept item earns its place with two sentences, not one: what happened, and separately, why it matters. A story can be true and notable and still get cut if the model can't articulate the "so what" in one clean sentence. That forces an actual relevance judgment instead of a "this happened" summary.

One section is deliberately anti-safe. There's a slot reserved for something unexpected: outside the normal categories, the kind of thing a curious person would find interesting precisely because nobody assigned it there. Without that forcing function, an LLM left to its own judgment tends to pick safe, obviously-important stories and nothing delightful or odd.

The model runs at a low temperature for this task. It's tuned for consistent judgment calls, not creative variation. I want the same story judged the same way today and next week, not a slightly different read each run.

So it's not magic curation. It's a rubric, and the LLM's job is applying it consistently across a volume of headlines that doesn't scale if you're doing it by hand.

Honest State of It

This is a single-user, single-region tool, not a product. It runs on a deliberately cheap VPS with real RAM constraints, which has already ruled out some approaches I considered (self-hosted text-to-speech, for one: the model and codec overhead alone would compete with the always-on listener process for memory). The codebase isn't open source right now while I keep iterating on it.

It's also entirely text-based today. Voice and richer formatting are designed but not yet built, more on that below.

Deepseek V4 Flash via Openrouter seems to be doing a good enough job, it allows me to read the gist of interesting news sometimes behind paywall and there was only once that I read the LLM thinking process rather than the actual news. Re-generating the news fixed it straightaway. Is it providing me a wholesome view of news and the world? Maybe not but it sure beats Google providing me with generic news everyday.

What's Coming Next

Voice layer. The morning news briefing gets a parallel spoken version: a handful of top stories, rewritten for speech (no URLs, no markdown, abbreviations spelled out) and sent as a Telegram voice note via an API-based text-to-speech call. Self-hosting TTS isn't viable on this hardware, so this stays API-based and stays cheap. The cost estimate for daily voice generation lands at a few cents a month.

Email as the primary reading surface. Telegram's plain-text formatting and message-length chunking work fine at the current volume, but there's no rich formatting and no searchable archive: real problems once content volume grows. The plan is to make HTML email the main place I actually read the full briefing, while Telegram steps back to a notification ping plus the voice note plus on-demand commands. Same underlying pipeline, a second delivery path added alongside the existing one, gated behind a feature flag so the live system never breaks while the new path gets built.

GitHub Discovery, scaled up, and the math that constrains it. The plan adds several more topic categories to the search net, which sounds like it just means "more queries," but the 30-requests-per-minute search ceiling doesn't move just because the scope does. Roughly tripling the query count means the per-call sleep interval has to widen too, from the current 2.1 seconds to something closer to 3.2, or the scraper starts tripping the same limiter it was built to respect. The tradeoff is a longer run time in exchange for broader coverage: still comfortably a single-digit number of minutes, just no longer the fastest pipeline of the three. Repo counts per category will also stop being uniform. The categories I care about most get more picks per day, the narrower ones get fewer, and that's a deliberate choice rather than an oversight.(It took me a long time to talk with Claude to decide what fields and topics to track, there are just way too many fields and repos in Github!)

Broader news scope, same constraint-driven approach. The news pipeline scales similarly, more feeds, more output sections, with the per-feed age-window logic (different freshness lookback for daily-cadence sources versus slower-publishing ones) carrying over unchanged, since that part of the design already solved the problem correctly the first time.

None of this changes the core shape of the system. It's still three pipelines, an LLM doing the judgment calls, and a phone that doesn't need an app to receive any of it.

Closing Thought

The bet here is that the bottleneck in personal information consumption usually isn't access, it's triage. There's no shortage of news, and no shortage of interesting open-source work. What's scarce is time spent deciding what's worth reading. Handing that decision to a cheap, fast model running on a five-dollar VPS, three times a day, has been a more useful experiment than I expected going in.


GitHub Digest is a personal project, currently text-only with voice and email delivery in active development. Built with Python, scheduled via cron and systemd, curated with an LLM via OpenRouter.

Find me on GitHub: github.com/mediblacksand