The Agentic Daily
An autonomous newsroom running on my own hardware: a roster of editorial personas that research, draft, judge and publish a daily edition without a human in the loop.
Python · TypeScript · Astro · vLLM · llama.cpp · NVIDIA DGX Spark · cron
The writing pipeline on this site drafts a post and waits for me. The Agentic Daily does not wait. It reads the day's sources, decides what matters, assigns stories to a roster of editorial personas, drafts them, judges the drafts against each other, composes an edition, and publishes — on a schedule, on hardware I own, with nobody holding the merge button.
It is the larger, stranger sibling of the pipeline described in the AI writing pipeline, and most of what I have learned about building AI systems in the last year came from it breaking.
The shape of it
Sources come in from Hacker News, arXiv, Hugging Face papers, Reddit and Bluesky. A classifier scores them for novelty and relevance. Surviving stories are assigned to editorial personas — each with its own remit, register and standing obligations — which draft the copy. A judge compares drafts, an editor composes the edition, and the result ships as a static site with a feed.
Roughly:
- 155,000 lines of Python for the agent pipeline, evaluation harnesses and orchestration
- 119,000 lines of TypeScript and 82,000 of Astro for everything that renders
- 23,256 Python and 4,518 TypeScript test functions across 2,329 files
- 18 editorial personas, each a separate voice with its own failure modes
Nothing in the publishing path calls an external API. Every model runs locally.
The part that actually taught me something
I built the newsroom first and the measurement second, which was the wrong order.
The system had an LLM judge picking the better of two drafts. It felt authoritative. Then I ran the obvious control — I gave it two drafts generated from an identical configuration and asked it to pick a winner. It picked one, confidently, a third of the time.
Every A/B result I had was sitting on top of that noise. Not wrong, exactly, but unmeasured: I had no idea which of my improvements were real and which were the judge flipping a coin. The fix was not a better prompt. It was replicates, a measured noise floor, and a rule that no change ships on a margin smaller than the instrument's own error.
That has become the through-line of the project. A few of the others:
- A grammar can stop a model from thinking. Constraining output with a GBNF grammar forces the first token, which means the model never enters its reasoning phase. Same input, same schema-valid shape: 121.9 seconds of reasoning without it, 1.4 seconds with. Both pass validation. Only one of them thought. A schema guard constrains shape, never content.
- Tune the dial that's connected to something. Before rebuilding the persona system for a new engine, I measured what explained the variance in output: persona accounted for 8.7%, temperature for 0.3%. The engine swap needed no persona recalibration at all. Two days of planned work, deleted by one measurement.
- Measure at the unit where the decision is written. The same fix read as a 12% improvement per pair and a 70% improvement per bet. Both numbers were honest; they answered different questions. A denominator that varies per subject is a dimension of the experiment, not a footnote in the write-up.
Why it isn't public
The repository is private for now. The system publishes daily and I would rather it be judged on what it publishes than on a snapshot of its internals, and there is editorial machinery in there I am not finished being embarrassed by.
I am happy to walk through the architecture with anyone who finds this interesting — the evaluation harness in particular, which is the part I think generalises beyond newsrooms.
This project is active. The write-up grows as the system does.