A daily digest of what happened in AI, assembled from sources you choose and summarized by Claude. Point it at Hugging Face Daily Papers and a handful of blogs, run it from cron, and read one message instead of twelve feeds.
# AI Digest — 2026-08-17
## HF Daily Papers
- [Scaling Laws for Retrieval-Augmented Generation](https://huggingface.co/papers/2508.01234)
Shows retrieval quality, not model size, sets the ceiling on RAG accuracy past 7B parameters.
## Simon Willison
- [Structured outputs without a schema library](https://simonwillison.net/2026/aug/16/structured-outputs/)
Argues a hand-written JSON Schema beats a Pydantic dependency for one-off extraction scripts.
- The core has no dependencies. Feed parsing, dedup state, rendering, and Telegram delivery are standard library only. The Anthropic SDK is an optional extra, needed only if you want summaries.
- It won't repeat itself. Sent items are recorded, and the record is only written after delivery succeeds — a failed send re-sends next run rather than silently dropping the day.
- One source can't drown the rest.
items_per_sourcecaps each feed, so a blog that published nine times today still contributes one line. - One API call per run, not one per item, with the response constrained to a JSON schema so there is no prose to parse back out.
Python 3.11 or newer.
git clone https://github.com/hyeseonko/ai-digest
cd ai-digest
pip install -e ".[llm]" # drop [llm] to skip summarization
cp digest.example.toml digest.tomlai-digest --dry-run # print the digest, don't record anything as sent
ai-digest # for real
python -m ai_digest --config other.toml--dry-run is the one to use while tuning your source list: it renders the
digest without marking anything as seen, so you can run it repeatedly.
Sources, caps, and delivery live in digest.toml — see
digest.example.toml for a working starting point. Two
source types exist today:
type |
Fields | Notes |
|---|---|---|
feed |
name, url |
Any RSS 2.0 or Atom feed |
hf_papers |
name |
Hugging Face Daily Papers, ranked by upvotes |
Secrets are read from the environment, never from the config file:
| Variable | Needed for |
|---|---|
ANTHROPIC_API_KEY |
Summarization ([summarize] enabled = true) |
TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID |
[delivery] kind = "telegram" |
Each item's title and published blurb go to Claude in a single request, and the
response is schema-constrained to one sentence per item. The default model is
claude-haiku-4-5 — cheap and fast, which is what a stream of one-line
summaries wants; set model in [summarize] to change it.
The prompt asks for what an item claims, not what it "discusses" — the difference between a digest you can skim and a list of titles restated.
If the API key is missing, the package isn't installed, or the call fails, the digest still goes out using each source's own summary text. Summaries are a nice-to-have, not a dependency.
30 5 * * * cd /path/to/ai-digest && /usr/bin/env ai-digest >> digest.log 2>&1ai_digest/sources/ holds one module per source type, each exposing a
collect(...) that returns Items and raises FeedError on failure. Add a
module, add a branch in collect() in __main__.py, and the rest — dedup,
summarization, rendering, delivery — works unchanged.
pip install -e ".[dev]"
pytest -qMIT