3 · Use the structure you have¶
The podcast feed already contains plenty of useful information as it is: where every chapter starts, what each one is about, and when the episode aired. The pitch "just throw it into the AI" throws all of that away, then pays a model to reconstruct it, less accurately. The cheapest, most reliable work is often the work you don't hand to the model.
What the feed already gives you¶
The RSS feed ships Podlove chapter markers (a title and a start time per segment) and a publish date, human-authored structure already sitting in the file:
<podcast:chapters>
<chapter startTime="0" title="Intro" />
<chapter startTime="184" title="Wirecard – der Insolvenzverwalter…" />
<chapter startTime="1102" title="Govcoins" />
</podcast:chapters>
<pubDate>Mon, 20 Jan 2022 06:00:00 +0100</pubDate>
Read straight from the feed, those become three things the rest of the system leans on:
- Chunk boundaries. Chapter starts anchor the 90-second, chapter-aligned chunks the relation extractor works over, so a fact's location in the audio is inherited, not guessed.
- A table of contents. Every chapter title is a human-written summary of a segment.
- A calendar axis.
pubDate, parsed from RFC-822 into a typed Neo4jDateTimeacross all 463 episodes (2016 → 2026), so questions like "how has coverage of X moved over time" can be answered in a meaningful way.
When a feed carries no chapters, there's a graceful fallback - one [default] chapter
spanning the whole episode - and nothing downstream breaks. The lesson generalises well
past podcasts: most "unstructured" data isn't, once you look for the filenames, ticket
fields, email headers and timestamps wrapped around it.
Metadata as a consistency check¶
What's great about this metadata is that it can also be used to check our extraction results for consistency. A recurring move in this project is to validate a model's output against a signal drawn straight from the feed, and the recording date is the cleanest example.
Publish date isn't the same as recording date, and for a topical show the gap matters: a
claim can be stale before the episode even airs. The host often announces when they're
recording ("so, es ist der 18. Januar…"), so a local model extracts that date - but only
when the transcript genuinely states it (evidence-gated, no guessing) - and then anchors
it to the pubDate from the feed: a recording date has to fall on or before the publish
date, and within a few weeks of it, or it's rejected. The surviving gap, pubDate −
recordingDate, becomes a staleness window the timeline can flag.
The cross-check earns its keep by catching a real error: on one episode the host announced the wrong year, and the weekday named in the audio plus the publish date together proved the true one, so the extracted date was auto-corrected rather than trusted. A structured signal from the feed turned a model's plausible-but-wrong output into a corrected, defensible one.
The same move shows up one stage over, at speaker attribution: the feed's prose cast list validates who the pipeline thinks is talking, before and after the expensive LLM refinement, which is where the next chapter goes. The real lesson here is not so much cheap versus expensive, but building up independent sources of truth and using their agreement (or disagreement) to either lift a fact's credibility or flag it for a closer look.