Jake Rosow
AI-Pipeline Case Study
case-study · shipit-news

Shipit News

An AI and coding news feed that groups the last 72 hours into stories and records what every run cost.

Role
Architect + integrator
Status
Live
Started
2026-03
URL
shipit.news ↗
Source
Private · live URL + screenshots + run instrumentation
live screens

Feed, topic, and digest.

Topic detail: generated summary, key points, source count, and raw evidence trail.
Daily digest: archived snapshot generated from the same pipeline.

hiring signal
What this proves

I can build a small AI product where the interesting work is the plumbing: getting data in cleanly, watching what it costs, and swapping models without a rewrite.

Risk handled

A pipeline on a cron will happily re-post the same story every half hour, and the bill for it turns up a month later.

Evidence

It runs every 30 minutes without repeating a story, asks RSS feeds only for what changed, routes every model call through one swappable function, and writes a cost row per run.

pipeline

What runs every thirty minutes.

sources → fetch → dedupe → cluster → summarize → score — idempotent on re-run.
  1. 01 fetch parallel · per-source
  2. 02 dedupe by url · idempotent
  3. 03 cluster 72h → topics haiku 4.5 cached
  4. 04 summarize topic → 2-3 graf haiku 4.5 cached
  5. 05 score engagement × recency

A personal AI/coding news feed across Hacker News, Reddit, RSS, Bluesky, and YouTube. Claude clusters the last 72 hours into stories, writes a short summary, and logs the cost of every run. The useful part is the plumbing: it runs every 30 minutes without duplicating items or hiding spend.

Why it exists

There are plenty of AI/coding news feeds. None of them surface the long tail I actually read: researchers on Bluesky, niche YouTube channels, and the subreddits where threads start before they hit Hacker News.

It also shows the production habits I care about: routing between models, caching prompts, ingestion that never counts a story twice, and a cost figure attached to every run. Small enough to inspect. Big enough that the instrumentation matters.

What made it hard

Summarizing the day's headlines in one model call works exactly once. Put it on a 30-minute cron and the same stories start arriving twice while the bill climbs somewhere nobody is looking.

Most of the work went into the unglamorous parts: throwing out URLs it has already seen, asking RSS feeds only for what changed, caching the system prompts, and writing a cost row for every run. One code path covers both local SQLite and Turso. The Claude calls are the small part.

runs
Last three runs. Token usage and cost written to a stats_json column on every run.
id · when in tok out tok cache read cost
run_47b1 13:00 UTC 82,140 3,920 76,300 $0.018
run_47ac 12:30 UTC 81,902 3,815 76,150 $0.017
run_47a8 12:00 UTC 82,224 4,201 76,300 $0.019
cache hit ratio over last 3 runs 93% $0.054
decisions

What the plumbing has to guarantee.

One callLLM() over Anthropic, Gemini, and Cerebras

Chose

One call shape covers Anthropic, Gemini, and Cerebras: system prompt, user message, optional JSON tool. Anthropic gets tool_use and cache_control; Gemini and Cerebras use OpenAI-compatible chat/completions.

Why

I can swap models or A/B runs without rewriting the pipeline. The LLM surface stays small enough to reason about.

Cost

Only Anthropic gets prompt caching today. Switching providers still works, but the bill can stop getting cheaper. New models also need prices added by hand.

Every system prompt is cached, and every run writes what it cost

Chose

Anthropic system prompts use ephemeral cache_control. Each run writes input, output, cache_creation, cache_read, and estimated USD to the database.

Why

A 30-minute cron needs unglamorous economics. Cache hit rate should be a SQL query.

Cost

The OpenAI-compatible path returns zero cache fields. Cost estimates also depend on a static price table.

Re-running the pipeline never duplicates a story

Chose

Items dedupe by URL. RSS sources store ETag and Last-Modified, then send If-None-Match / If-Modified-Since on the next pull. No new items means the run only refreshes scores.

Why

The schedule only works if a rerun is cheap in compute and dollars.

Cost

URL dedupe misses late momentum. A story that jumps from 12 comments to 400 after first ingest is undercounted.

the stack

The stack.

Want the walkthrough, or the parts that aren’t written up yet?

jakerosow@gmail.com
Up next
Cost Specialist A Claude project that audits Claude API spend