Voice-to-podcast pipeline: from smartphone recording through AI processing to finished podcast

My Weird Prompts

A Voice-to-Podcast Pipeline

Technical Architecture White Paper

Daniel Rosehill — October 2026 — Version 4.0

Pipeline V5.22 · Prompts 4.29 · GPT-6.1 Sol (script), DeepSeek V4.1 Flash and Gemini Flash (other stages) · Chatterbox Regular on 3× Modal L4 (CUDA-graph fp16) · Meorav v2.1 for Daniel

Previous edition (February 2026, v1.0)

Abstract

My Weird Prompts is a fully automated podcast. Daniel sends in a prompt — a voice memo, a few typed lines, a link, sometimes a photo — and about a quarter of an hour later a finished episode is live: a researched, scripted conversation between AI characters, voiced with cloned voices, mastered, given cover art and show notes, and published to the website and every podcast platform. Nobody edits anything in between.

The pipeline runs on Modal (serverless CPU and GPU), with Cloudflare R2 for files and for the website's content catalogue, Neon PostgreSQL for metadata, Pinecone for the hosts' memory, and Vercel for the website. Every script is written by GPT-6.1 Sol, and the other text stages run on DeepSeek V4.1 Flash and Gemini Flash, all through OpenRouter; the hosts are voiced by Chatterbox, and Daniel by Meorav, a model fine-tuned on his own recordings, both running on the show's own GPUs.

This document describes production as of October 2026 (pipeline V5.9, prompts 4.21): the stages an episode passes through, the safeguards around them, what it costs, and what I learned getting here. The headline numbers below are computed from the episode archive every time the site deploys. For the history of how the pipeline changed, and which episode each change first appeared in, see the pipeline changelog.

1. By the Numbers

Every episode is stamped with the model that wrote its script, the pipeline and prompt versions that made it, and its running time. These figures and charts are rebuilt from that record on every deploy, so they are never more than a deploy behind.

6,399 episodes published
2,853 hours of generated audio
27 min average episode length
18.2 episodes a day, on average, since November 2025
Episodes by script model The model that wrote each episode's script, oldest first. Hours are of finished audio.
Gemini 2.5 Flash 66 · 29 h Gemini 3 Flash 1,968 · 815 h Claude Sonnet 4.6 202 · 95 h DeepSeek V3.2 57 · 23 h DeepSeek V4 Pro 2,957 · 1,419 h DeepSeek V4.1 Flash 652 · 269 h Ling 3.1 Flash 2 · 1 h GLM-5.3 Flash 1 · 0 h Claude Haiku 5.5 10 · 4 h GPT-6 Luna 1 · 0 h Solar Pro 4 1 · 1 h GLM-5.3 106 · 44 h GLM-5.2 3 · 1 h Xiaomi MiMo V2.6 Pro 1 · 0 h Gemini 3.8 Flash 1 · 0 h GPT-6.1 Sol 151 · 64 h Other 220 · 87 h

"Other" is one-off guest models on experiment episodes (MiMo, MiniMax, GLM, Grok, Mercury and others), hand-written scripts, and unrecorded.

Show as table
Script modelEpisodesHours of audioShare
Gemini 2.5 Flash66291.0%
Gemini 3 Flash1,96881530.8%
Claude Sonnet 4.6202953.2%
DeepSeek V3.257230.9%
DeepSeek V4 Pro2,9571,41946.2%
DeepSeek V4.1 Flash65226910.2%
Ling 3.1 Flash210.0%
GLM-5.3 Flash100.0%
Claude Haiku 5.51040.2%
GPT-6 Luna100.0%
Solar Pro 4110.0%
GLM-5.3106441.7%
GLM-5.2310.0%
Xiaomi MiMo V2.6 Pro100.0%
Gemini 3.8 Flash100.0%
GPT-6.1 Sol151642.4%
Other220873.4%
Episodes per month, by script model Each colour is a model era. The current month is still in progress.
  • Gemini 2.5 Flash
  • Gemini 3 Flash
  • Claude Sonnet 4.6
  • DeepSeek V3.2
  • DeepSeek V4 Pro
  • DeepSeek V4.1 Flash
  • Ling 3.1 Flash
  • GLM-5.3 Flash
  • Claude Haiku 5.5
  • GPT-6 Luna
  • Solar Pro 4
  • GLM-5.3
  • GLM-5.2
  • Xiaomi MiMo V2.6 Pro
  • Gemini 3.8 Flash
  • GPT-6.1 Sol
  • Other
0 250 500 750 1,000 Nov 2025 Dec Jan 2026 Feb Mar Apr May Jun Jul Aug Sept Oct Nov
Show as table
MonthGemini 2.5 FlashGemini 3 FlashClaude Sonnet 4.6DeepSeek V3.2DeepSeek V4 ProDeepSeek V4.1 FlashLing 3.1 FlashGLM-5.3 FlashClaude Haiku 5.5GPT-6 LunaSolar Pro 4GLM-5.3GLM-5.2Xiaomi MiMo V2.6 ProGemini 3.8 FlashGPT-6.1 SolOtherTotal
Nov 202514––––––––––––––––14
Dec 20255158–––––––––––––––109
Jan 2026–271–––––––––––––––271
Feb 2026–481––––––––––––––1482
Mar 2026188453––––––––––––18911
Apr 2026–27419754147–––––––––––13685
May 2026––––620––––––––––––620
Jun 2026––––836–––––––––––1837
Jul 2026––––525––––––––––––525
Aug 2026––––404––––––––––––404
Sept 2026––––425254–––––––––––679
Oct 2026–––––3982110111311151166736
Nov 2026 (to date)–––––––––––105––––21126

Computed from the episode archive each time the site deploys. Last episode counted: 10 November 2026. The same data is published as the My-Weird-Prompts/episodes dataset.

The show has had six main script writers. Most of the switches came in a two-week stretch in April 2026, as the pipeline moved from Gemini to Claude to DeepSeek looking for a model that would write a full-length episode at a sustainable price. The changelog has the story behind each switch.

2. Introduction

2.1 The Concept

My Weird Prompts (MWP) is an experiment in full-stack AI automation: a podcast where every episode starts as a question from one person and ends as a published, multi-voice show, with no manual editing in between. It covers whatever Daniel happens to be curious about — AI tooling one hour, Jerusalem's underground burial economy the next.

Prompts reach the pipeline through the Send App (send.myweirdprompts.com) or the MCP admin server used from Claude Code. Listeners can send a prompt too, through the form on the site or by email to prompts@myweirdprompts.com; those come to Daniel rather than straight into the pipeline. The pipeline transcribes the prompt, researches the topic, plans and writes a dialogue script, cleans it up in code, voices it, assembles and masters the audio, and publishes it to the website and podcast platforms.

2.2 Design Goals

  1. Zero human editing — every stage is automated, from transcription to publication.
  2. Grounded, not improvised — a research agent gathers current, dated sources, going to primary sources where it can, before a word of script is written.
  3. Funny by default — a serious question gets a straight answer, but the episode around it should be entertaining wherever the material allows.
  4. Broadcast-quality audio — mastered and loudness-normalised to −16 LUFS with a −2 dBTP true-peak ceiling.
  5. Fail open where it's safe, fail closed where it isn't — a missing cover image shouldn't kill an episode; a truncated script should.
  6. Honest attribution — every episode ends by naming the model that wrote it, and that credit has to be true.
  7. Cheap enough to run daily — well under a dollar per episode, all in.

2.3 The Cast

Character Role
Corn (Host) A laid-back sloth who opens the episode and steers the conversation — with dry, short quips, and without playing moderator.
Herman (Co-host) An enthusiastic donkey who goes deep on the details and asks the follow-ups.
Hilbert Flumingtop (Producer) The show's producer, and the ridiculous one. Gets an on-air turn in every episode: he arrives about four-fifths of the way through with a deadpan, escalating and deliberately absurd story from his own life (around 650 words) that uses the topic as a way in, never as an analogy. After the discussion he reads the fixed “send a prompt” clip, and he reads the model credit.
Larry (Advertiser) Reads an advert nobody booked, for a made-up product, at a natural pause in the first half of every standard episode. The ad's format and the hosts' reaction are drawn at random each episode.
Daniel (The human) Sends the prompts and maintains the pipeline. A clone of his voice reads the AI disclaimer at the top of each episode, and when the prompt was a voice memo, his original recording plays before the hosts start.
3. System Architecture
Isometric view of the serverless cloud architecture: compute, storage, and hosting components

3.1 High-Level Flow

Two ways in, one generator, and a fan-out to storage and distribution:

Send App MCP (Claude Code) Modal Webhooks duplicate guards · 60s cancel window Episode Generator LangGraph + generic dispatcher Modal CPU · DeepSeek V4.1 Flash TTS 3× L4 Cloudflare R2 Audio, images, content catalogue Neon PostgreSQL Episodes, jobs, tags Pinecone Host memory, past episodes Wasabi + B2 Off-site backups CDN Episode Files Website + RSS (Vercel) Podcast Platforms Hugging Face, Telegram

3.2 Deployment Topology

Component Platform Where
Send AppVercel (Clerk auth)send.myweirdprompts.com
Pipeline webhooks + generatorModal (serverless CPU)Internal
TTS workersModal (L4 GPUs)Internal — 3 dialogue workers per episode
Admin MCP serverClaude Code integrationPrivate
Public MCP serverVercelmyweirdprompts.com/mcp (read-only)
WebsiteVercel (Astro, SSR behind an edge cache)myweirdprompts.com
Content catalogueCloudflare R2 (private bucket)Episode data for the episode pages, homepage, episode list and RSS feed, written at publish time
MWP FM radioVercel (PWA)stream.myweirdprompts.com
Object storageCloudflare R2episodes.myweirdprompts.com
DatabaseNeon PostgreSQLServerless Postgres
Vector memoryPineconeHost memories, past-episode search
BackupsWasabi + Backblaze B2Off-site copies of every episode

3.3 Infrastructure Stack

Everything is serverless or managed — there is no server to keep running:

  • Compute: Modal — CPU containers for orchestration, L4 GPUs for speech
  • LLM: through OpenRouter, with DeepSeek's own API as the standby route. GPT-6.1 Sol writes the script; Gemini Flash writes the title, description and blog post; DeepSeek V4.1 Flash runs every other text stage. Utility stages use OpenRouter's “latest” aliases, so they move to a new generation of the same family without a code change
  • Speech: Chatterbox Regular (open weights, self-hosted, pinned to an exact release); prompts are transcribed by Gemini Flash (latest), with Whisper large-v3 as the fallback, both through OpenRouter
  • Orchestration: LangGraph for script generation; a generic dispatcher that routes 14+ episode formats through one code path; an LLM supervisor that decides whether a crashed run is worth retrying
  • Storage: Cloudflare R2 (zero egress fees), Wasabi and Backblaze B2 for backups
  • Data: Neon PostgreSQL for metadata and jobs; Pinecone for vector memory
  • Hosting: Vercel (Astro). A new episode goes live through the R2 content catalogue as soon as it publishes, with no site build; the rest of the site still rebuilds on a half-hourly schedule
  • CI/CD: GitHub Actions — merging a pipeline change to main deploys it to Modal
4. Pipeline Stages

Each episode passes through twelve stages. The text half runs as a LangGraph state graph in one Modal container; the audio half fans out to GPU workers and back. Across 164 episodes made on pipeline V5.4–V5.6 (12–17 October 2026), a run took 11–17 minutes (10th to 90th percentile; median 13), of which voicing took about four and a half.

1 Intake 2 Transcription 3 Prompt Analysis 4 Research Agent 5 Episode Planning 6 Script Writer 7 Deterministic Polish 8 Memory Extraction 9 Metadata + Cover Art 10 Speech (3× L4) 11 Assembly + Mastering 12 Publication LLM stage (DeepSeek V4.1 Flash) Deterministic code / other models GPU
1

Stage 1: Intake

A prompt can be a voice memo recorded in the Send App (Opus, 48 kHz mono, with the browser's echo cancellation and noise suppression), typed text, links, documents, or images. Before anything is spent:

  • Exact-duplicate guard: each prompt is normalised (Unicode, quotes, whitespace, case) and fingerprinted. A prompt that is already queued, running or recently finished is refused with HTTP 409 before a job is created — this catches the double-tapped send button.
  • Near-duplicate guard: a prompt rewritten and resent a few minutes later gets past a fingerprint, and twice that made two full episodes from one question. So the new prompt is embedded (Gemini Embedding, 768 dimensions) and compared with up to 40 prompts from the last six hours. Anything scoring 0.86 or higher on cosine similarity — at most two candidates — goes to DeepSeek, which reads both prompts and judges whether they ask the same thing. Only a “duplicate” verdict blocks, with the same 409 and a “send anyway” override. Any error lets the prompt through: a duplicate episode is cheaper than a lost prompt. See 8.9 for why the embedding alone can't decide.
  • 60-second cancellation window: a new job waits a minute before its first paid API call, checking every five seconds whether it has been cancelled. Changing your mind costs nothing.
  • Attachments: text, PDF and CSV files are extracted and passed to the pipeline as text; linked pages are fetched in full and treated as primary sources.
  • Images: up to five per prompt, downscaled to 1568 px (HEIC converted). They go straight to the script writer, which can see them; unreadable images are skipped rather than failing the episode.
  • Length: the Send App offers short (15 minutes), standard (25) or extended (30); left unset, the planner chooses (Stage 5).
2

Stage 2: Transcription

Voice memos are transcribed by Gemini Flash (OpenRouter's latest-Flash alias), in a single pass that also strips filler words (um, uh, you know). If that call fails or comes back empty, Whisper large-v3, also through OpenRouter, transcribes it instead. Either way a deterministic correction pass then fixes words that are reliably misheard. Whisper used to run on OpenAI's own API, until in October 2026 that account ran out of credit and took every voice-memo episode down with it; moving it to OpenRouter left one fewer provider balance to keep funded. The original recording is kept: it plays in the episode, just before the hosts begin.

3

Stage 3: Prompt Analysis

A low-temperature model call reads the prompt and pulls out the questions it asks, in order, plus any notes about how the hosts should approach it. Crucially, it does not rewrite the prompt. Earlier versions handed the hosts a tidied-up summary; now the script writer receives Daniel's words exactly as sent, and is told to recap them in its own words and read them for intent rather than recite them.

4

Stage 4: Research Agent

Before a word of script is written, a tool-calling research agent spends up to five rounds investigating the topic. It doesn't see every tool on every topic. A set of core tools is always available, and specialist toolkits are loaded by topic: a keyword match on the research brief preloads the ones that fit (free and deterministic), and the agent can load any other itself if the match missed it.

ToolkitTools (source)Used for
Core (always on)Web search (Exa, hour-level freshness), breaking news, open news (GDELT), fetch page, full-text reader (arXiv, PDFs and web pages, fetched directly), WikipediaGeneral research, current events, and reading a source in full
TechnologyarXiv, Hugging Face (model and dataset cards, papers), GitHub (repositories and releases), fetch repository (gitingest), practitioner discussionAI, software and hardware topics, from the primary source
MedicalPubMed (NCBI)Health topics
SciencearXivPhysics, maths, statistics and the like
JudaismSefariaTorah, Talmud, halacha and Jewish practice

Each tool that could run away with the budget has a per-run cap (six calls each for GitHub, Hugging Face, arXiv and Sefaria; five full-text reads; three Wikipedia lookups; four Exa searches and six Exa page fetches). An over-cap call gets a “budget spent” reply rather than an error, so the agent moves on. For a model the prompt names, it is told to read the model card; for a paper, the paper itself; and for technical topics generally, the official docs, repository, spec or paper before any forum thread.

Its output is a structured brief: an overview, a dated timeline of recent developments, key findings, numbers, notable positions, open questions and negative findings (what it looked for and couldn't find), and dated sources marked when they are primary. The hosts treat that brief as material, not as the agenda: perspectives lead and findings support, and the weight of evidence follows the topic — an opinion or culture question doesn't need studies. When Daniel describes something he has lived through, that is testimony, not a claim to fact-check.

The research is wrapped in fallbacks: if the agent fails, a simpler search loop runs; if that fails, a single search; if even that fails, the episode proceeds on the model's own knowledge. A brief under 2,000 characters counts as a failed gather, and the agent is sent back once for more.

5

Stage 5: Episode Planning

A planning call outlines the episode's segments with the research in view and sets its length. Left to itself it picks between 20 and 30 minutes by how much the topic will bear; a length chosen at send time is honoured. Each tier has a word range calibrated against the speech engine's real pace:

TierTargetWords
Short15 min2,000–2,600
Standard25 min3,700–4,300
Extended30 min4,600–5,300

Alongside the plan, the grounding step gathers the other context the writer will need:

  • Past episodes on similar topics, from a vector search over the archive, so the hosts can refer back instead of repeating themselves
  • Host memories — facts the hosts have picked up in earlier episodes
  • Lorebook entries — the few pieces of each character's backstory most relevant to this topic (only entries that clear a similarity threshold make it in)
  • The world today: the date, and Jerusalem's weather (conditions, high, low, chance of rain, from Open-Meteo), which the hosts mention only when it's relevant. It replaced a digest of news headlines that cost three searches and rarely mattered.
6

Stage 6: Script Writer

The core creative step: GPT-6.1 Sol, called through OpenRouter, writes the whole episode in a single call (since 19 October 2026; before that DeepSeek V4.1 Flash) — across 164 DeepSeek-written episodes, 3,500–5,700 words (median about 4,400) and 120–230 lines (median about 160). It sees the raw prompt, any images, the research brief, the plan, the character cards for Corn and Herman and the card for how they know each other, Hilbert's character notes, lorebook entries and memories.

SettingValueWhy
Modeldeepseek-flash (V4.1 Flash)The model DeepSeek actually serves; see 8.7
GenerationSingle passSection-by-section writing restarted and repeated itself; see 8.6
TemperatureNot sent (provider default, 1.0)Raising it produced gibberish; see 8.5
Thinking modeOff, explicitlyLeft on, it silently disables sampling controls
Max output10,000 tokens up to 40 minutes (18,000 at 45, 28,000 at 60+), under a 32,768 ceilingRoom for the longest tier without truncation

The script prompt (version 4.21) sets the shape of every standard episode. A few of its standing rules:

  • Funny by default: a genuine question is framed straight but played for laughs wherever the material allows, and an ambiguous one leans ridiculous. Grief, illness and other people's hardship are exempt.
  • The hosts think first: they reason about the question themselves before reaching for sources, and when nothing has been studied they say what they think rather than announcing the gap.
  • One recurring beat, rotated over three episodes: Larry’s unbooked advert, then Dorothy’s Grim Fact (Corn’s mother with one true, depressing fact from the episode’s research), then a wildcard that steps through the other guests — an angry caller, a useless expert, a voicemail, a correspondent somewhere irrelevant, Standards and Practices. Each beat is written by its own small-model call in that character’s voice, checked by code, and inserted into the script word for word.
  • Hilbert's turn at about the 80% mark, around 650 words, in which the topic is the door, not the story.
  • One callback at most to a real past episode, and only to one the research actually found.
  • No prompt address in the script: how to send a prompt is said by a fixed clip after the discussion (Stage 11), not improvised by the writer.
Why DeepSeek? Over the show's life the script writer has been Gemini 2.5 Flash, Gemini 3 Flash, Claude Sonnet 4.6, DeepSeek V3.2, DeepSeek V4 Pro DeepSeek V4.1 Flash, and since 19 October 2026 GPT-6.1 Sol. DeepSeek won on the combination that matters for a daily long-form show: it writes a full-length episode on request, follows a long system prompt, and costs a few cents per script. Self-hosting DeepSeek or a smaller open model on Modal was costed and came out more expensive at every configuration at the show's volume. The charts above show how many episodes each model wrote.
7

Stage 7: Deterministic Polish

There is no second LLM pass over the script. Instead, a set of plain-code rules (regular expressions and counters, no model) removes the verbal habits that language models fall into over thousands of episodes. Every rule is idempotent — running it twice changes nothing — and every one was added because the tic was measured across the archive, not guessed at:

  • Sycophantic openers (“Exactly,” “Absolutely!”, “That's a great point”) and filler praise
  • Self-referential lines about the episode being AI-written, and on-air references to the research pass
  • Overused words and phrases: capped, or rotated through synonyms chosen by a hash of the script, so each episode is consistent with itself and different from the last
  • Runs of turns opening with “And”, “So” or “Right”, and clipped “Not X. Y.” fragments
  • Echo handoffs, where a speaker opens by repeating the previous speaker's last line. Since pipeline V5.5 this includes the repeat-then-extend kind: the repeated head is cut and the addition kept, but only when the addition starts a new clause, so the cut never leaves a fragment. A second sweep runs at the end, after other passes have removed turns.
  • Wave-on turns, a host line that is nothing but “go on”
  • Any host cue introducing Hilbert — he is never summoned, he just arrives

Two more passes run in code at the end of the script. A callback to a past episode survives only if it names one of the related episodes the research supplied, and only the first. And the sign-off gains a line naming up to three related episodes (similarity of at least 0.6), with numbers and titles read fresh from the database and spoken in pairs, like years. An episode that turns up in more than a quarter of the last twenty runs' candidates is dropped as a “hub” that is vaguely related to everything. A rule that must always hold goes here or in the script prompt; see 8.3 for why.

8

Stage 8: Memory Extraction

After the script is final, a model call pulls out durable facts the hosts have now “learned” and writes them to a Pinecone index, with a namespace per character. A new memory replaces any older one that says nearly the same thing (similarity above 0.75), so the store stays current rather than piling up near-duplicates. This stage fails open: a missed memory never holds up an episode.

9

Stage 9: Metadata & Cover Art

Gemini Flash writes the title, description, URL slug and an image prompt from the finished script, as structured output with length limits that are checked and regenerated on a miss. A second, separate call writes a short blog post of about 100 words. New slugs end in a random five-digit suffix, so two episodes on the same subject can never collide. The image prompt goes to Krea 2 Turbo Style on fal.ai, given three earlier covers as style references, for a square cover (Flux Schnell is the fallback). Categorisation, tagging and the episode's search embedding (Gemini Embedding, 768 dimensions) are computed in parallel at publication. A failed cover falls back to a default image.

10

Stage 10: Speech (Parallel GPU Workers)

Parallel GPU workers processing text-to-speech segments simultaneously

Every host line is voiced by Chatterbox Regular, an open-weights voice-cloning model, running on the show's own Modal GPUs. Each character, guests included, has a voice of its own; a speaker the pipeline doesn't recognise falls back to Herman's voice. Daniel's own voice, in the prompt introduction, the AI disclaimer and any lines he has in an episode, comes from a separate model, Meorav, described below.

Architecture

Orchestrator (CPU) Normalises the text, cuts long lines into chunks of at most 250 characters, and splits them into three contiguous blocks
↓
Worker 1 (L4) ~⅓ of dialogue
Worker 2 (L4) ~⅓ of dialogue
Worker 3 (L4) ~⅓ of dialogue
↓
Results merged in order and concatenated with ffmpeg

Text Normalisation

Chatterbox does no number or symbol expansion of its own, and the script prompt's “spell numbers out” rule didn't hold: the last 60 scripts before the fix carried about 1,000 digit tokens. Since October 2026, every line containing a digit, a symbol or a domain passes through a layer of tech-specific rules (so an RTX 4090 is “forty ninety” and GPT-4o is “GPT four-oh”) and then NVIDIA's rule-based NeMo text normaliser, before it is chunked. Every other sentence passes through untouched. Run over those 60 scripts, it left no unspeakable tokens behind. See 8.10.

Key Optimisations

  • CUDA-graph fp16 decode: stock Chatterbox launches each layer's work separately for every speech token, so the GPU spends more time being told what to do than doing it. The pipeline records one token's worth of work as a single CUDA graph, replays it once per token, and runs the language-model backbone in half precision. On the L4 that took the real-time factor from 0.96 to 0.35; see 6.2.
  • No attention weights: stock Chatterbox asked for attention weights on every decode step, which forces the slow attention path; only a multilingual alignment component reads them. The image build patches both requests off, and checks there are exactly two, so a new release can't quietly dodge the patch.
  • Cached voice conditionals: each character's voice embedding is computed once and stored in R2, instead of being recomputed for every line.
  • Weights in the image, pinned: the model files ship inside the container image at an exact release, so a cold start doesn't download ~3 GB first, and every episode records which Chatterbox build voiced it.
  • Immediate scale-down: workers shut down two seconds after finishing their batch instead of idling for a minute on the meter.
  • Encoding off the GPU loop: each line is encoded to AAC on a CPU thread while the GPU moves on to the next.

Failure Handling

  • Each line gets one retry; individual failures are tracked but don't abort the episode. Lines already rendered are skipped on a re-run, so a retry resumes rather than starting over.
  • If more than 20% of lines fail, the episode is aborted rather than published with gaps.

Daniel's Voice: Meorav

Quick voice clones, which take a few seconds of reference audio, keep a speaker's timbre and lose their accent: Daniel's came out American. So his voice is a model of its own. Meorav (Hebrew for “mixed”) is a full fine-tune of Qwen3-TTS 1.7B on 1,103 takes of Daniel reading, about 88 minutes after trimming: phonetic sentences covering every English sound, conversational lines in his own register, English sentences with Hebrew words in them, and names of places. Every weight is trained (learning rate 7×10-6, three epochs), which is what moves the accent. Because the training sentences mix English and Hebrew, it says Hebrew words inside English lines the way he does, with none of the code-switching machinery below.

  • Where it runs: its own GPU worker in a separate container image (its dependencies conflict with Chatterbox's), alongside the Chatterbox workers. It reads the introduction to every prompt and the AI disclaimer, and any of Daniel's lines in an episode that asks for it. A failed prompt introduction falls back to a Chatterbox clone of Daniel rather than failing the episode.
  • Versions: v2.1 since 22 October 2026, the v2.0 recipe on the same takes after DeepFilterNet 3 noise removal. Each container asks Hugging Face for the newest published version, so a new release goes live without a deploy; the version baked into the image is the fallback, and every line records which version spoke it.
  • Speed and checks: about 2.4 seconds of L4 time per second of speech, several times slower than Chatterbox, so Daniel's lines are split across two workers. On long lines v2.0 sometimes dropped words, so each new version is checked by transcribing test lines against their text before it is adopted.

The model is published as Hebrish/Meorav (access on request, CC BY-NC 4.0). For a whole episode of Daniel talking to it, and how that was stitched together, see The Bake-Off: My Real Voice vs My Voice Clone.

Other Languages

Selected episodes are also published as translated editions, each language with its own feed. The script is translated, and the same hosts re-voice it on Chatterbox Multilingual. Hebrew text first gets full vowel marks from Dicta's niqqud model, because unvowelled Hebrew is ambiguous to read aloud. A translated edition links back to its English original and the original links to it.

Experimental: Hebrew Code-Switching

Daniel often drops Hebrew words, written in English letters, into English prompts. An opt-in route, off by default and separate from the normal workers, finds those words with a small token classifier, has a language model write each in Hebrew script with full vowel marks, and renders each line in English and Hebrew pieces on Chatterbox Multilingual before stitching them together. If a script turns out to contain no Hebrew at all, the job fails before it touches a GPU.

11

Stage 11: Assembly & Mastering

The finished episode runs in a fixed order:

  1. Intro jingle
  2. AI disclaimer, read by Daniel's voice model, Meorav
  3. Daniel's original prompt recording (voice-memo prompts only)
  4. The dialogue, with Larry's ad in the first half and a short pre-recorded spoof advert spliced in near the halfway point
  5. “Send a Prompt”: a fixed clip of Hilbert giving the address for sending prompts, about 12.5 seconds
  6. Model credit (naming the script model) and voice credit, read by Hilbert
  7. Outro

Mastering: the prompt recording has long silences trimmed and a voice EQ applied; the dialogue bus gets a faint room-tone bed underneath (so the gaps between lines don't drop to digital silence), per-character tonal adjustments, EQ, compression and de-essing, and, since 17 October 2026, a pitch-preserving slow-down to 0.97× speed. The final mix is loudness-normalised to −16 LUFS with a −2 dBTP true-peak ceiling and encoded as 128 kbps mono AAC at 48 kHz, with chapter markers and waveform peaks for the website player.

12

Stage 12: Publication & Distribution

  • Storage: audio, cover art, transcript, chapters and peaks uploaded to Cloudflare R2
  • Database: episode row written to Neon with its full production record — models, versions, timings and costs. If that insert fails, the job fails and the episode goes to recovery storage; it used to report success anyway
  • Website + RSS: the pipeline asks the website to write the episode into its content catalogue, JSON files in a private R2 bucket that the episode page, homepage, episode list and RSS feed read from, and to purge their cached copies. The episode is live within moments, with no site build; before, it waited up to half an hour for the next scheduled build. Spotify, Apple Podcasts and the rest pick it up from RSS, with WebSub and Podcast Index pings
  • Backups: copies to Wasabi and Backblaze B2
  • Announcements: Telegram, once the episode page is actually live
  • Open data: daily syncs to the Hugging Face episodes and transcripts datasets. Prompt text is never published, there or anywhere else; the prompt audio inside an episode is part of the episode
5. Reliability & Safeguards

The rule of thumb: anything that would make a worse episode fails open; anything that would make a broken one fails closed.

5.1 Fail-Open Stages

StageOn failureImpact
Near-duplicate guardLet the prompt throughA possible duplicate episode
Transcription (Gemini)Whisper large-v3Fillers removed by a later cleanup pass instead
Research agentSimpler search loop → single search → noneLess grounded script
WeatherEmpty blockThe hosts don't know the weather
Episode planningContinue without a plan, on a fallback 3,400–3,900-word targetLess structured script
Image inputsSkip the unreadable imageWriter sees fewer images
Memory extractionSkipHosts don't remember this one
Cover artDefault coverGeneric artwork
Content catalogue writeThree retries, then skipEpisode appears at the next site build
BackupsSkipNo off-site copy until re-run

5.2 Quality Gates

Before voicing, a script that misses its length range is sent back once: expanded if it is more than 10% short, trimmed if it is more than 5% long (and the result is rejected if it overshoots). These then abort the episode before any GPU time is spent or anything is published:

  • Script too short: below a floor set by the planned length — 1,800 words for 15 minutes, 3,000 for 25, 3,800 for 30 (a truncated or refused generation)
  • Too few lines: under 10 dialogue segments (the script didn't come back in the expected format)
  • Speech failure rate: more than 20% of lines failed to voice

5.3 A Supervisor for Crashes

A crashed run used to be retried a fixed number of times with a fixed wait. That is fine for a network blip and wasteful for anything that won't fix itself — bad input, an expired key, an empty credit balance — which then burned two more complete runs before giving up. Now a small LLM call (temperature 0, 300 tokens) reads the error and says one of two things: retry, with a wait it chooses, or abort. The guard rails are in code, not in the model: the retry cap (two automatic retries) is enforced by code, the wait is clamped to between 15 seconds and five minutes, and if the supervisor itself fails the run falls back to the old fixed rule.

5.4 Recovery Storage

If an episode passes every gate but publication itself fails (an upload or database error), everything that was generated — audio, cover, script, metadata — is saved to a recovery area so it can be republished without regenerating it.

5.5 No Zombie Jobs

A top-level guard around the whole pipeline marks any crash as a failed job in the database. Before it existed, a crash before publication could leave a job showing “running” forever.

5.6 Credit Alerts

Twice a day a housekeeping job checks the prepaid balances the pipeline depends on and emails Daniel when DeepSeek or OpenRouter is under $5, or when DeepSeek reports the account as unavailable, which happens before the balance reads zero. It keeps emailing on every run until somebody tops up. This exists because a DeepSeek balance hitting zero in August 2026 stopped every episode.

5.7 Test Mode

A test run executes the entire pipeline including the database writes, verifies the stored row field by field, then deletes it. Public pages filter test rows out regardless. Its first run caught a real bug: one of two database insert paths had its own hard-coded column list and was silently dropping a field.

5.8 Observability

Every run records a trace of its stages, including the research agent's full tool log, and every published episode stores its own production record: script model, pipeline and prompt versions, research engine, GPU type, worker count, the exact Chatterbox build, generation and speech times, and LLM and GPU cost. That record is what this page's charts are built from, and it is published in the episodes dataset.

6. Cost Analysis

Costs below are the per-episode figures the pipeline records on every episode (LLM cost from token usage; GPU cost as worker time at Modal's list price), as medians across the 164 episodes made on pipeline V5.4–V5.6 between 12 and 17 October 2026: all written by DeepSeek V4.1 Flash and voiced on three L4 workers with the CUDA-graph fp16 decode. The median episode in that set ran about 27 minutes.

6.1 Per-Episode Cost

ItemMedianTypical range (10th–90th percentile)
LLM (every text stage, DeepSeek V4.1 Flash)$0.07$0.05–0.09
Speech GPUs (3× L4)$0.18$0.14–0.27
Orchestrator CPU~$0.01—
Cover art (Krea 2 Turbo Style)~$0.01—
Storage, database, hosting~$0Within free tiers or negligible per episode
Total per episode~$0.26$0.21–0.35; scales mostly with episode length

Speech is about 70% of the cost of an episode and the LLM about a quarter. That is the reverse of the show's early days, when a hosted voice API and a premium script model made an episode cost around $2. It is also down from about $0.43 an episode in late September, before the per-episode slate was retired (9 October) and the speech decode was rebuilt (10 October). The recorded speech cost works out to about $0.39 per hour of finished audio, above the $0.28 benchmark in 6.2, because it bills all three workers for the whole parallel stage, start-up and waiting for the slowest block included.

6.2 Why L4 (again)

GPUPer hour (Modal list price)RTF, stock decodeRTF, CUDA-graph fp16 decodeGPU cost per audio-hour (graph fp16)
L4 (current, since 10 Oct 2026)~$0.800.960.35~$0.28
T4 (briefly, 10 Oct 2026)~$0.590.840.52~$0.31
A10G (until May 2026)~$1.100.610.31—

RTF is seconds of rendering per second of audio, measured on the production build with 16 real script lines (decisions 103 and 105, October 2026). The GPU choice flipped twice in one day. Stock Chatterbox generates speech one token at a time and is limited by kernel-launch overhead rather than raw GPU power, so on the stock decode a T4 rendered about as fast as an L4 for less per second, and the workers moved to T4 (about $0.50 per audio-hour against $0.77). The same day the decode was rebuilt: each one-token step is captured as a CUDA graph and the language-model backbone runs in fp16. With the launch overhead gone, the L4's extra compute finally shows: it now renders nearly three times faster than before (RTF 0.957 to 0.346) and costs less per audio-hour than a graphed T4, so the workers went back to L4. The fp16 decode picks slightly different speech tokens late in a few lines, so it shipped as a listening test; a token-identical fp32 graph mode and the stock decode remain one setting away. A prototype that decodes several turns at once is built and benchmarked but not yet wired in.

6.3 At Scale

At September 2026's pace of about 23 episodes a day, nearly all of the running cost is GPU time, which is why the speech stage gets most of the optimisation work. Running the LLM on the show's own GPUs instead was costed too: to fit V4.1 Flash takes eight H200s, and it would only break even at about 4,500 a month, against the roughly 640 episodes actually made, so the script stays on DeepSeek's API.

7. Technology Stack
CategoryServiceRole
LLMGPT-6.1 Sol; DeepSeek V4.1 Flash; Gemini Flash (all via OpenRouter)Script (Sol); title, description and blog post (Gemini); every other text stage: prompt analysis, research, planning, memory, tagging, duplicate verdicts, crash supervisor (DeepSeek)
LLM standbyOpenRouterFallback route if DeepSeek's API is unavailable
TranscriptionGemini Flash (latest); Whisper large-v3 fallback (both via OpenRouter)Voice-memo prompts
SpeechChatterbox RegularVoice-cloned dialogue, self-hosted on L4 GPUs
Text normalisationNeMo text processing + custom rulesNumbers and symbols to spoken form before speech
ResearchExa, GDELT, Wikipedia, arXiv, Hugging Face, GitHub, gitingest, PubMed, SefariaTools for the research agent, loaded by topic
WeatherOpen-MeteoToday's Jerusalem weather for the script
OrchestrationLangGraphScript-generation state graph
Vector memoryPinecone + Gemini EmbeddingHost memories, lorebooks, similar-episode search, near-duplicate shortlist
Image generationfal.ai (Krea 2 Turbo Style; Flux Schnell fallback)Cover art
ComputeModalServerless CPU and GPU containers, job queue, cron
Object storageCloudflare R2Audio, images, transcripts, voice conditionals, show elements, the website's content catalogue
BackupsWasabi, Backblaze B2Off-site episode and prompt archive
DatabaseNeon PostgreSQLEpisodes, jobs, tags, production records
WebsiteAstro on Vercelmyweirdprompts.com, RSS, public API and MCP server
Prompt intakeStatic web app + Clerk on VercelSend App
Open dataHugging FacePublic dataset
AdminMCP server + Claude CodeDispatching episodes, operations, analytics
8. Lessons Learned

8.1 Chatterbox Regular vs Turbo

The pipeline first ran Chatterbox's faster Turbo variant. It hallucinated: injected words, repeated phrases, audio artefacts. Switching to Regular eliminated about 95% of them; the occasional slip that remains is rare enough to pass unnoticed in a 25-minute episode.

Takeaway: For long-form audio, quality per line matters more than speed. One artefact every few minutes ruins an episode; a few extra minutes of GPU time doesn't.

8.2 Find the Real Bottleneck Before Buying a Faster GPU

Caching each voice's conditioning and splitting lines across three GPU workers took speech from over 36 minutes to about 10. Baking the weights into the image and shutting workers down two seconds after their batch trimmed the bill further. The biggest gain came last, and it wasn't a bigger GPU: stock Chatterbox spent most of its time launching work, not doing it, which is why a cheap T4 kept up with an L4. Capturing the decode step as a CUDA graph removed that overhead and made the same L4s nearly three times faster.

Takeaway: On serverless GPUs you pay for idle, for setup and for overhead. Profile what the GPU is actually waiting on before paying for more of it.

8.3 The Review Pass That Never Ran

The pipeline has an LLM “review” pass designed to fact-check and tighten each script — an earlier edition of this white paper described it as running on every episode. An audit found it was off by default in production, so every instruction written into its prompt had never run. It stays off. Its predecessor, an external fact-checking agent, had once returned a 169-word “corrected” script and wiped out an episode. The rule that Hilbert is never summoned shows the cost: it lived in the review prompt, so hosts kept cueing him in, until a deterministic polish pass started removing the cue.

Takeaway: A rule that must hold goes in the prompt that is definitely executed, or in deterministic code. Optional LLM passes are where instructions go to die.

8.4 Tics Are Measured, Not Guessed

Across thousands of episodes, every model develops verbal habits. Asking the model to stop rarely works — worse, quoting an example of the bad phrase in the prompt made it more common, as the model copied the example. What works is counting each habit across the archive, then removing it in deterministic code with a clear cap. Echoes are the clearest case: 138 still reached the audio across 45 of 60 recent episodes after the first echo rule shipped; the repeat-then-extend pass, run over the same transcripts, removes 124 of them.

Takeaway: Never show a model the phrase you don't want. Measure, cap in code, and re-measure.

8.5 Temperature Is Not a Creativity Dial

Raising the script temperature to 1.2 to make episodes livelier produced gibberish within a day and was reverted. The script stage now sends no temperature at all and uses the provider's default. A related trap: DeepSeek's thinking mode, left on, silently ignores temperature and other sampling settings, so the pipeline turns it off explicitly on every call.

Takeaway: Check what the provider actually honours before tuning a parameter, and assume defaults are defaults for a reason.

8.6 One Pass Beats Many

Writing scripts section by section looked like a way to get longer, more controlled episodes. In practice, sections restarted the conversation and repeated material the previous section had covered. A single call with a large output budget gives a more coherent episode.

Takeaway: Modern long-context models hold a 4,000-word conversation together better than any stitching you can do around them.

8.7 Name the Model That Actually Serves You

In September 2026 DeepSeek began answering requests for V4 Pro with V4.1 Flash, until V4.1 Pro ships. Every episode ends by crediting the model that wrote it, so asking for one model and receiving another would have made that credit false. The pipeline now requests V4.1 Flash by name, and the on-air credit says so.

Takeaway: The model name in your config is a claim about what's running. If the provider changes what that name means, update the claim.

8.8 Memory Needs Two Layers

Hosts with no memory repeat themselves; hosts with too much recite their backstory every episode. The answer was two layers: authored character cards and lorebooks (who the characters are, pulled in only when relevant to the topic) and an extracted memory store (what they've learned, deduplicated as it grows).

Takeaway: Retrieve character, don't inject it wholesale. Relevance thresholds do more for consistency than longer character sheets.

8.9 A Threshold Can't Tell a Rewrite From a Sequel

The obvious near-duplicate check is an embedding similarity with a cut-off. The measurements ruled it out: part two of a listener's series scored 0.952 against part one — two different episodes that should both exist — which was higher than two of the three genuine rewrites. So the embedding only builds a shortlist, and a language model, reading both prompts, makes the call. The first version of its prompt blocked a listener's explicit follow-up question; once that was fixed it matched all 14 labelled test pairs, on two consecutive runs.

Takeaway: Similarity is not sameness. Use the cheap score to narrow the field and a reader to decide, and fail open when the reader is unavailable.

8.10 Small Models Make Bad Normalisers

Turning “A10G” or “80/20” into speakable words looked like a job for a small local language model. On 80 hard test sentences, a 1.5-billion-parameter model left digits in 55 and dropped words in 17; a 0.5-billion one left digits in 72 and turned “an A10G is a dollar” into “A ten thousand dollars is A one hundred dollars”. A rule-based normaliser with a thin layer of tech rules left nothing unspeakable, in about a third of a second per episode.

Takeaway: Where the right answer is fixed and checkable, deterministic code beats a model that might be creative about it.
Appendix: Stage Reference
No.StageModel / ToolOn failure
1IntakeExact + near-duplicate guards (Gemini Embedding, DeepSeek V4.1 Flash); 60s cancel window409 / cancel; near-duplicate guard fails open
2TranscriptionGemini Flash (latest), Whisper large-v3 fallback (OpenRouter)Fallback, then hard fail
3Prompt analysisDeepSeek V4.1 FlashHard fail
4Research agentDeepSeek V4.1 Flash + topic toolkitsFail-open (fallback chain)
5Episode planningDeepSeek V4.1 Flash, Pinecone, Open-MeteoFail-open
6Script writerGPT-6.1 SolHard fail (quality gates)
7Deterministic polishCode (no model)—
8Memory extractionDeepSeek V4.1 Flash, PineconeFail-open
9Metadata + cover artGemini Flash, Krea 2 Turbo StyleCover fail-open
10SpeechNeMo normaliser; Chatterbox Regular, 3× L4, CUDA-graph fp16Abort above 20% line failures
11Assembly + masteringffmpegHard fail
12PublicationR2 (files + content catalogue), Neon, RSSRecovery storage
—Crash handlingLLM supervisor (DeepSeek V4.1 Flash)Retry or abort; two automatic retries at most