I'm not an engineer. I've never been one. I have always, however, had an affinity with technology, the kind of person who'll happily spend a Sunday afternoon figuring out why the home network is slow, or setting up smart lights that no one else in the house asked for (or ever uses).

Over the last several weeks, in the little bits of spare time I have outside of work and family, I built a production AI system. Every weekday morning it researches the latest AI news, writes a newsletter, narrates a podcast with two hosts, and publishes both to this website before I've finished my morning tea.

I didn't start out planning to run this entire setup. I actually started because I wanted to see how much I could do with the tooling we have available today. I wanted to tinker, learn and experiment. The system is the by-product of me trying and learning as I went. The experience I am picking up along the way is the actual asset, and it's allowing me to do things I could never have imagined a year ago.

I didn't start by sketching an architecture diagram, as I did not know how to deliver against that. I didn't start on Google Cloud with a fully automated pipeline, as I didn't know how to build one. I started playing around with Claude Cowork, in a Q&A fashion just asking my way through from the start.

Where it started

I was looking for a way to receive a daily newsletter with those stories that would help me stay on top of the latest AI news. Claude has a feature called "scheduled tasks". So I asked it to run a prompt on a schedule. I set one up: every weekday morning, research the latest AI news from a list of newsletters and websites I'd named, and write me a briefing. This sort of worked, but left a lot to be desired.

The writing was decent. The schedule, less so. Some mornings the task fired and the output landed somewhere useful. Other mornings the schedule slipped. Sometimes the response was just a chat reply that lived in my Claude history and went nowhere: no email, no website, no podcast. It was a prompt with a timer. Not a system that I could rely on.

As I got more into it, I wanted reliability and consistency. If I'm going to build a system, I want it to work 100% of the time, otherwise what's the point? No fails on those mornings where I'd want to listen to the podcast or read the newsletter during my commute. I wasn't trying to ship a product. I just wanted the thing to actually run, every weekday, consistently and fully automated, for me to enjoy it.

The pattern

The pattern that would repeat for the next several weeks: quite often the system would throw an error, the task failed, timed out, etc, ask Claude how to get past it, try the smallest thing that might work. If it held, keep it. If it didn't, ask the next question.

A lot of this happened in the terminal, and that itself is part of the journey. I used to log into GitHub through the website, upload a file, watch it overwrite the previous one, and assume there had to be a better way. There was. Claude Cowork (the desktop tool I use as my code assistant) walked me through git, the command line, package managers, the whole works. Installing things along the way. What I would have called plugins are, in this engineering world, usually called CLI tools or packages, installed through a package manager like Homebrew. Today, ninety-nine percent of my work on this system happens in two windows: a terminal, and Claude Cowork on the side, watching what I'm doing and answering my questions in real time.

The terminal isn't where I expected to end up. It's also not where I'd recommend most people start. But the way I got there is the same way the rest of the system got built: one blocker, one question, a small iteration, an improvement, and on to the next experiment; one at a time.

I never sat down and designed the architecture. The architecture slowly came together as my questions and answers led me there. The more accurate way to describe it is that I backed into an architecture, more so than writing out the architecture and then executing against it. I fully realize my current architecture may not be the 'best' for the system that I have built according to professional engineering standards; however it works and efficiently enough so that it costs me virtually nothing to run monthly from an infrastructure perspective.

The graduations

Each piece of the system arrived as the answer to a problem. Six of them, in roughly the order they showed up:

  1. "I need this to run reliably." Claude scheduled tasks couldn't give me that. I asked what would. With Claude's help I landed on Cloud Run and Cloud Scheduler. Cloud Run is a Google service that runs a small piece of code (in my case, a Python web app) when something asks it to, and scales to zero when nothing is happening. Meaning I pay nothing when it's idle. Cloud Scheduler does what the name says: fire an HTTPS request at a specific time, hit my Cloud Run service, and the work happens. That gave me the reliable trigger Claude scheduled tasks couldn't.
  2. "I need it to remember what it did yesterday." When the pipeline retries, I don't want it to send the newsletter twice. I asked how to make the system idempotent (meaning it's safe to run multiple times without doing the same thing twice). I landed on Firestore, Google's serverless document database. Two collections, no migrations, no joins. One small document per day says "did I send today's newsletter yet?" If the answer is yes, the pipeline skips and exits. The whole state model is two documents wide.
  3. "I need to actually call Claude from my code." Worth its own section, see below. I had to move away from 'manual' Claude.
  4. "I need to send the newsletter as a real email." I didn't want to spin up an SMTP server. I asked for the simplest path. I landed on the Gmail API with OAuth. The pipeline drafts the newsletter inside my own Gmail account and then sends it from there. As a side effect, I had a place to review the draft before it went out. That review window became the human-in-the-loop gate, until I trained myself out of it.
  5. "I want to turn the transcript into a podcast." This one had a clear answer: ElevenLabs, a text-to-speech service that's good enough to be mistaken for a real podcast. The transcript gets parsed into speaker segments, each segment gets narrated in one of two voices, the chunks get stitched into a single MP3, and the MP3 lands in Google Cloud Storage with a public URL. I even created a jingle using Suno and added that to the podcast to make it sounds more 'real'. I think that part worked out pretty well, you can check it out by listening to the first seconds of any of the recent podcasts.
  6. "I want a website for all of this." I landed on Cloudflare Pages, a static site host, fed by GitHub repos. The pipeline writes new newsletter HTML and a new podcast feed straight into a GitHub repository through GitHub's Contents API. Cloudflare watches the repo and rebuilds the site within a minute. Three sister sites (briefing, podcast, take) all run this way. This site, the build log, makes four.

For the visuals on those sites (diagrams, banner images, podcast thumbnails, that sort of thing) I lean on Gemini. Right now Gemini's multimodal generation is meaningfully better than Claude's for image work, but that gap is closing, but for now I use Claude Cowork for code and reasoning, Gemini for pixels.

The Claude component, up close

A bit more context on the piece that does the actual work each morning.

In this system, Claude shows up as a series of API calls: straight HTTPS requests from my Cloud Run service to the Anthropic API, authenticated with an API key that lives in Google's Secret Manager (not in the code, not in environment variables, not anywhere it could leak by accident). The pipeline makes four Claude calls back to back, each with a different job.

  1. Research, using Claude Sonnet with the web_search tool turned on. It gets a prompt that says: here are the angles I care about, here are the AI newsletters I subscribe to that you should pull from my Gmail for context, here are the named thought leaders I want to track, and here's the open web. Find me ten to fifteen stories worth covering.
  2. Writing, using Claude Opus 4.6. It takes the research brief, plus a "golden copy" example of a newsletter I think hits the mark, and writes the actual newsletter in markdown.
  3. Self-review, also Claude Opus 4.6. Same model is asked to grade its own output across hook, depth, thought leadership, and resources. If the score dips below a threshold, it rewrites with the specific feedback in mind.
  4. Podcast transcript, also Claude Opus 4.6. It's a full two-host conversation, around two thousand to twenty-five hundred words (usually translates to just under 10 minutes of audio).

A note on the prompts themselves: I didn't write any of them in one sitting. They've evolved over weeks of "the output was off in this way, how do I fix it?" Claude helped me iterate on the prompts that drive Claude.

One more thing I learned the hard way. Claude Cowork has a blind spot: it sometimes forgets how this particular system works and reverts to suggesting setups it's seen elsewhere. For a stretch I kept getting nudged toward Vercel for hosting, even though I'd already picked Cloudflare Pages and was happily working with it. I ended up writing a "skill" in Claude Cowork, which is essentially a piece of persistent memory that allows Claude to avoid forgetting things you have told it many times before (which was getting to be really annoying at times as Claude can be very forgetful). I built one called "ambient advantage architecture" and now I invoke it every time I ask Claude to provide me commands for a terminal session for this project. The drift went away. That moment, building a tool to keep my AI coworker focused and consistent, felt like a milestone of its own.

Where I ended up

This is the picture I couldn't have drawn in week one. It's the end result of all the questions I asked.

Ambient Advantage

Automated Daily AI Briefing Pipeline — Architecture Overview

Phase 1 — Research & Draft
5:30 AM ET
Automated
GCP
Cloud Scheduler
Cron trigger hits
/research-and-draft
Automated
Claude
Claude + Web Search
Pass 1: Researches 10–15 AI stories using web search + Gmail newsletters
Automated
Claude
Claude Writes
Pass 2: Newsletter, podcast transcript (JON/AVA), episode summary
Transcript
Automated
Gmail
Gmail Drafts
Two drafts created for review + auto-approval quality checks
Hybrid — Usually Automated
✅ Default: Auto-Approved
Quality checks score the content automatically. If thresholds are met, drafts are approved and published with zero human touch.
👤 Optional: Chiel Steps In
Chiel can review, edit, or add "Chiel's Take" before approving — shaping the editorial voice when he chooses to.
Phase 2 — Publish
7:00 AM ET (retries every 15 min)
Automated
GCP
Cloud Scheduler
Cron trigger hits
/run
Automated
Beehiiv — Send Newsletter
POST to Beehiiv API → branded email blast to subscriber list
Automated
ElevenLabs
ElevenLabs TTS
Transcript → audio. Two voices (JON/AVA), chunked & concatenated
MP3
Automated
GCS
Cloud Storage
MP3 uploaded to GCS bucket (public URL)
Automated
Cloudflare
Cloudflare — Briefing Site
Newsletter → HTML article committed via GitHub API
Automated
Cloudflare
Cloudflare — Podcast Site
Episode + RSS feed updated via GitHub API
RSS / Apple / Spotify
Automated
Firestore
Firestore
Episode metadata + pipeline state saved. Idempotency guaranteed.

Sites auto-deploy on commit via Cloudflare Pages

Infrastructure
Toronto (northamerica-northeast2)
Auto-scaling
GCP Cloud Run
Runs the pipeline service. Scales to zero — near-zero cost when idle.
Auto-deploy
GCP Cloud Build
CI/CD: push to main → Docker build → deploy. Zero manual steps.
Auto-deploy
Cloudflare Cloudflare Pages
Hosts both static sites. Auto-deploys on every GitHub commit.
Auto-refresh
GCP Secret Manager
API keys, OAuth tokens. Auto-refreshing Gmail credentials.
Auto-commit
GitHub GitHub (6 repos)
cloud-run-podcast, briefing site, podcast site, chiels-take-site, landing site, build log site. Push triggers Cloud Build + Cloudflare deploys.
Auto-alert
GCP Cloud Logging
Monitoring + alert policy on ERROR severity.
Claude
Human + AI Claude Cowork — the builder behind the builder
The entire pipeline was designed, coded, and iterated through Claude Cowork sessions — architecture decisions, Python code, deployment configs, prompt engineering, and custom skills. A dedicated Cowork project holds the full context: an architecture skill teaches Claude how the system fits together, so every conversation picks up where the last one left off.
Fully autonomous end-to-end — with an optional human touch
Every step from research to publishing runs automatically. Quality checks gate approval — most days the pipeline runs completely hands-free. Chiel can step in to shape content when he wants to, not because he has to.
AutomatedNo human action required
HybridAuto-approved unless human opts in
Phase 1: Research & Draft
Phase 2: Publish
Infrastructure

Cloud Scheduler fires a request at my Cloud Run service every weekday morning. Cloud Run talks to Anthropic for the writing, Gmail for the email, ElevenLabs for the audio. State lives in Firestore. The MP3 lands in Cloud Storage. The newsletter and the podcast feed are written to GitHub, and Cloudflare Pages rebuilds the public sites within a minute. Each box on that diagram is its own little story, and the rest of this build log will fill in the boxes one by one.

How I trained myself out of the loop

In the early versions I put myself in the loop. The pipeline would draft the newsletter, draft the transcript, drop them in my Gmail, and wait for me to apply an "approved" label. I'd read, sometimes edit, then click. That was fine for a few weeks. But it meant that I had to do this review in the morning every day, or no content gets created. I also realized that the quality of the content generation is such that I did not need to be in the loop for this system to run.

So I built an improved flow with better AI. The self-review pass came in. A quality-check module came in. It grades each draft on structure, depth, and a few other dimensions. If everything scores above the threshold, the approval label gets applied automatically, and the pipeline keeps moving. If anything fails, I get an email and I'm back in the loop for that one morning only. I got there by asking Claude (using Cowork) all the time how to make these changes, what it requires, how to do it. If the instructions weren't clear, I'd ask Claude to explain again in plain English, break it down in steps, etc.

Today I don't manually label anything. The system runs from end to end on its own, every weekday morning, and running fully automated 100% of the time. When it isn't, I hear about it before subscribers do. That's exactly the relationship I want with it.

The takeaway I'd offer: the question isn't whether AI is good enough to run unsupervised. It's whether you've built the workflow that lets it run unsupervised consistently. Many workflows that leverage AI will need humans in the loop with defined approval gates, in my case here I found the AI system good enough to remove the manual check from the daily pipeline.

What this is teaching me

Here's the 3 takeaways that this experience leaves me with:

  1. You can go very far, very fast, by tinkering. Most of what's in this system came from an evening here, a Saturday morning there. Pick something small that doesn't work, ask the next question, try the smallest possible answer. Repeat. The system you end up with is rarely the one you'd have planned, and that's usually a good thing.
  2. Launch, then iterate. Every component went live before it was ready. The first newsletter was rough. The first podcast had pacing issues. The first website was ugly. None of it would be where it is now if I'd waited until any of those felt finished. Actually launching the pieces into production and seeing how it performs provides real feedback (even just my own daily reading habit) which surfaces issues that no design session ever will.
  3. Treat Claude Cowork as a real coworker. Not a search engine, not a code generator. A coworker. Tell it what you're trying to do and why. Show it your terminal output (I did a lot of copy-pasting from terminal to Claude Cowork, and vice versa). Disagree when its suggestion doesn't sit right. Build it the context it needs to be useful. The skill I mentioned earlier is a small example. The relationship with AI (in my case Claude Cowork) gets better the more you invest in it, the same way it does with any human teammate.

What's next

I'm still tinkering with this. The system isn't finished; none of it is. There's a backlog of things I want to improve, larger things I want to add, and the kind of unexpected questions that only show up once you actually run something every day.

When I learn something worth sharing, I'll post about it here.

If that sounds useful, follow along. If you're somewhere in the middle of your own version of this, I'd love to hear how it's going. Find me on LinkedIn.

I hope my experience will encourage you to become a tinkerer too. It's never been easier to bring your ideas to life.