snowmac/castrag

Python

0

1 commits

updated Sep 23, 2026

See the code

See what people are saying

README

castrag

A small, resumable pipeline for turning a large podcast (or any large audio) archive into something you can actually search and ask questions of — transcription, structured summaries, semantic search, and grounded Q&A, all scripted around the OpenAI API.

Built to process 230 episodes (~145 hours of audio) for about $33 total. Full write-up of how it works and what broke along the way: see technical-blog.html (open it directly in a browser, or publish it wherever you like).

Why this exists

Feeding a large transcript archive into an LLM's context window doesn't scale, and reading it yourself doesn't either. This pipeline gives you three ways to actually use a large audio archive:

  1. Structured summaries — a fast, cheap overview per episode (topics, quotes, takeaways, tone)
  2. Semantic search — embed everything once, then find the exact passage relevant to any question in milliseconds
  3. RAG-based Q&A — ask a natural-language question and get an answer grounded in, and cited to, the actual source material — no hallucinated advice

Pipeline

transcribe.py   mp3s        → transcripts/*.txt
build_index.py  transcripts → index/ (embeddings + metadata)
summarize.py    transcripts → summaries/*.json
ask.py          question    → cited answer (stdout)
analyze_themes.py  summaries → themes.json (cross-corpus synthesis)

Every script only reads from the previous stage's output directory and only writes to its own — nothing is ever mutated in place, and every script skips work that's already done. That means you can kill any stage mid-run, add more source files later, or swap models between batches, and just rerun.

Setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
brew install ffmpeg   # or your platform's equivalent

Create a .env file in the project root:

OPENAI_API_KEY=sk-...

Usage

# 1. Drop your audio files into audio-files/, then:
python transcribe.py

# 2. Generate per-episode structured summaries:
python summarize.py

# 3. Build the semantic search index:
python build_index.py

# 4. Ask questions grounded in the transcripts:
python ask.py "what did they say about X?"

# 5. (Optional) synthesize themes across the whole corpus:
python analyze_themes.py

summarize.py and analyze_themes.py both have a short constant near the top (SHOW_DESCRIPTION, FOCUS_THEMES) you should edit to match your own show and what you actually want extracted — they ship with generic placeholders, not any specific podcast's content.

Notes on cost and models

  • Transcription defaults to gpt-4o-mini-transcribe; whisper-1 also works and may transcribe slightly better for noisy audio, at roughly double the per-minute cost.
  • Source files get chunked to ~15-minute, 64kbps mono segments before upload — this keeps you well under API file-size limits and works for any audio length.
  • Concurrency is capped at two levels (files × chunks-per-file) to stay under provider rate limits without going fully sequential. Tune FILE_WORKERS / CHUNK_WORKERS_PER_FILE in transcribe.py for your own rate limit tier.
  • The search index is a single numpy array + JSON metadata file — no vector database needed until you're well past tens of thousands of chunks.

What isn't in this repo

The actual transcripts, summaries, and embeddings produced by running this against a real show aren't included — that's someone else's copyrighted audio content, even in text form. This repo is the workflow, not any particular show's content. Point it at your own audio.

License

MIT — see LICENSE.

Contributors

snowmac

1 commits

snowmac/castrag

Python

0

1 commits

updated Sep 23, 2026

See the code

See what people are saying

README

castrag

A small, resumable pipeline for turning a large podcast (or any large audio) archive into something you can actually search and ask questions of — transcription, structured summaries, semantic search, and grounded Q&A, all scripted around the OpenAI API.

Built to process 230 episodes (~145 hours of audio) for about $33 total. Full write-up of how it works and what broke along the way: see technical-blog.html (open it directly in a browser, or publish it wherever you like).

Why this exists

Feeding a large transcript archive into an LLM's context window doesn't scale, and reading it yourself doesn't either. This pipeline gives you three ways to actually use a large audio archive:

  1. Structured summaries — a fast, cheap overview per episode (topics, quotes, takeaways, tone)
  2. Semantic search — embed everything once, then find the exact passage relevant to any question in milliseconds
  3. RAG-based Q&A — ask a natural-language question and get an answer grounded in, and cited to, the actual source material — no hallucinated advice

Pipeline

transcribe.py   mp3s        → transcripts/*.txt
build_index.py  transcripts → index/ (embeddings + metadata)
summarize.py    transcripts → summaries/*.json
ask.py          question    → cited answer (stdout)
analyze_themes.py  summaries → themes.json (cross-corpus synthesis)

Every script only reads from the previous stage's output directory and only writes to its own — nothing is ever mutated in place, and every script skips work that's already done. That means you can kill any stage mid-run, add more source files later, or swap models between batches, and just rerun.

Setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
brew install ffmpeg   # or your platform's equivalent

Create a .env file in the project root:

OPENAI_API_KEY=sk-...

Usage

# 1. Drop your audio files into audio-files/, then:
python transcribe.py

# 2. Generate per-episode structured summaries:
python summarize.py

# 3. Build the semantic search index:
python build_index.py

# 4. Ask questions grounded in the transcripts:
python ask.py "what did they say about X?"

# 5. (Optional) synthesize themes across the whole corpus:
python analyze_themes.py

summarize.py and analyze_themes.py both have a short constant near the top (SHOW_DESCRIPTION, FOCUS_THEMES) you should edit to match your own show and what you actually want extracted — they ship with generic placeholders, not any specific podcast's content.

Notes on cost and models

  • Transcription defaults to gpt-4o-mini-transcribe; whisper-1 also works and may transcribe slightly better for noisy audio, at roughly double the per-minute cost.
  • Source files get chunked to ~15-minute, 64kbps mono segments before upload — this keeps you well under API file-size limits and works for any audio length.
  • Concurrency is capped at two levels (files × chunks-per-file) to stay under provider rate limits without going fully sequential. Tune FILE_WORKERS / CHUNK_WORKERS_PER_FILE in transcribe.py for your own rate limit tier.
  • The search index is a single numpy array + JSON metadata file — no vector database needed until you're well past tens of thousands of chunks.

What isn't in this repo

The actual transcripts, summaries, and embeddings produced by running this against a real show aren't included — that's someone else's copyrighted audio content, even in text form. This repo is the workflow, not any particular show's content. Point it at your own audio.

License

MIT — see LICENSE.

Contributors

snowmac

1 commits

Languages

Python

52.3%

HTML

47.7%