Case study / a pipeline that watches videos so I don't have to

video-curator

Shipped 2026 · runs as AgentTube inside Agentic OS 97

My social media feeds consist of a high amount of AI coding content. From philosophy to architecture, to the latest and greatest in AI technology, I'm always feeling a bit left behind. Every week, there's always a new repo to download, Karpathy tweet to digest, or a new model to try. If I looked into every new video I came across that sounded interesting, I'd never actually get any real work done.

That's fine, but I'm on the hundred-dollar Max plan, and having Claude do a hundred percent of the work eats through usage limits fast. There's also a wider read across the AI engineering community that Claude is the stronger big-picture thinker, the one who comes up with original ideas, while Codex is the more rule-based, precise engineer, one who arguably writes better code and stays safer doing it. This led me to the idea of a self-digesting AI pipeline that could watch the videos for me, analyze the important parts, and rank whether it's a worthy addition to my workflow.

The catch was checking that usefulness against my actual workflow, not just whether a video was a cool idea worth an hour of messing around. I work in a massive code base with hundreds of skills, multiple agents, multiple models, and an entire second brain system that keeps all of the logic sane. Generic usefulness derived from a video was never going to be useful to me. I needed specific usefulness that applied to my current workflow. If a video is titled "Ten New GitHub Repos to Try Out with Claude" but only two of them would actually help me, I needed the AI to know that. These ideas combined led me to the pipeline I now use for video curation and digestion.

agenttube · what to watch
AgentTube inside Agentic OS 97, styled like early-2000s YouTube: a What to Watch grid of curated video cards, each tagged with its source (YouTube or Instagram) and a match percentage, with a paste-a-URL box and an Update Feed button.
The flow, start to finish

Save it, hit one button, read the verdict.

The process is simple. I find a video on YouTube in my feed that looks interesting. Instead of stopping what I'm doing to watch it, I save it to a specific folder on my YouTube account. That's the whole act of capture. No notes, no tabs left open, no "I'll get to it later" that I never get to. The video just sits in the folder waiting.

Then, whenever I'm ready, I open my Agentic OS 97 application, go to AgentTube, and hit Curate. Or I can call a skill directly inside of my agent of choice, and the pipeline takes over from there. It watches every video in that folder it hasn't already scraped, skips the ones it already knows, and runs each new one through four stages.

First it scrapes. yt-dlp pulls the video down, ffmpeg grabs a screenshot every couple of seconds and weights the ones where the creator is pointing at or acknowledging something on screen, and the transcript gets parsed straight from YouTube's captions. It reads the video's description too, for any extra context on specific repos mentioned or files worth grabbing. If a video has no captions, Whisper transcribes the audio as a fallback. The pipeline always has something to read. And if even Whisper comes back empty, it writes a clean title-only note scored zero so the dead weight sinks to the bottom of the deck instead of failing the run.

Then the reader model does the ingest. Routed through Codex, with my local FreeLLMAPI router as a fallback, a fast, cheap model reads the transcript alongside those frames and turns it into one flat, objective account of what the video contains. No opinions. No scoring. Just a plain description of the subject, the tools and commands named, and the steps shown, built from what's actually on screen and said.

Then Claude does the thinking. Claude Sonnet or Codex Terra takes that objective writeup and reads it against my standing curation rules and a snapshot of the skills I already have installed. From that it produces a short description of the video, a relevance score from 0 to 1 for whether the technique belongs in my workflow, and a gameplan for how I'd actually integrate it. The score is graded against my real stack, not against generic usefulness, which is the entire point.

Finally it writes the card. The whole thing lands as a structured markdown note: frontmatter on top, then the objective account, the transcript, the actionable extract, a routing label, and the relevance score. That card is what I read.

The flow ends with me making a call. The pipeline does the watching and the triage. I keep the judgment.

notes/ig-DVbvL8FivDm.md · a curator card
An example curator card: frontmatter with source, title, and thumbnail path up top, then Understand the video with the objective account and transcript excerpt, an actionable extract, a no-op routing decision, and a relevance score of 0.15.
video-curator / curate.py · stages 1-4 · under the hood
Terminal running curate.py: stage 1 scrape (yt-dlp + ffmpeg), stage 2 transcript ingest via the reader model, stage 3 Claude analysis, stage 4 write note, then an idempotency skip on re-run.
The part I'm proudest of

Two models, one job each.

I split the judgment across two models on purpose, and to me that split is the best decision in the whole build. One model describes, Claude decides, and the two never trade places.

A fast, cheap model, routed through Codex with my local FreeLLMAPI router as a fallback, produces a flat, objective account of what's in the transcript and the sampled frames, with no scoring and no opinions. I run it at low temperature and give it one instruction: describe the video, nothing else. It never sees my stack, my rules, or the question Claude is about to answer. Claude Sonnet or Codex Terra then reads that fixed account as context and makes the calls I actually care about. The describer can't flatter the thing the decider is about to recommend, because the describer never sees the recommendation. It's like making a witness write down what they saw before anyone tells them the verdict.

That separation buys replayability too. Because the transcript is saved in the note, I can re-run the ingest and Claude passes straight off the stored text without re-downloading or re-scraping the video. So I can iterate on the scoring prompt and watch the verdict change without ever paying to pull the video down again.

One thing I want to be precise about. The routing label is a recommendation, not an automation. The card tells me a video belongs in improvements_jsonl, or is an operational_fix, a stack_edit, an edit_existing_skill, an obsidian_vault note, or a flat no-op. I make the actual call. The pipeline triages. I decide.

01 Scrape yt-dlp + ffmpeg frames · transcript 02 Describe Codex · FreeLLMAPI frames + transcript · no opinions 03 Decide Claude / Codex Terra title · score · route 04 Card markdown note cached by video id The curation pipeline Describe and decide, split across two models. The describer never sees the recommendation. The transcript is saved, so both passes replay with no re-scrape.
briefing/curator/ · notes + frames on disk
The curator notes directory: eleven markdown cards next to their per-video scraped frame thumbnails, one representative frame per curated card, all cached and scored by video id.
AgentTube, and the four buttons

Where the verdict and the action live in one place.

A markdown card on its own is just a file in a folder. The place I actually read the verdicts is AgentTube, the front end for this pipeline inside Agentic OS 97, styled to look like early-2000s YouTube. It watches the same folder I save videos to, and every curated video shows up as a card in a What to Watch feed I can flip through like a deck, tagged with its source and a match percentage. Open one and I get the summary, the proposed change, the routing decision, and the full relevance score, so I can sort through a whole playlist's worth of curations in a couple minutes.

The cards are nice, but the buttons are the point. I built four actions so that acting on a verdict is one click, not a context switch.

agenttube · card view
An opened AgentTube card with its source, match percentage, and video preview, and the four action buttons underneath: Accept + build, Teach, Skip, and Archive.

Accept, open as session

The one I reach for when a video actually has something I want to build. Accept is wired to open the idea as a fresh session in whichever AI I pick, in the right project path, with the video's gameplan already loaded, so there's no copy-pasting and no re-explaining what the video was about. The verdict becomes the start of the work.

Skip

Not useful, nothing to add. One tap and it's gone from the feed. No session, no terminal, no ceremony.

Archive

For the ones that are fine but not worth acting on today, maybe worth another look someday. Archive files it into its own list instead of throwing it away, so a maybe stays sorted separately from a flat no.

Teach

Teach is where the pipeline gets smarter. It writes a briefing on the video it just curated, grabs the description and the model's own recorded thought process, and opens a session primed for me to correct it. I tell it what it got wrong, and the correction gets appended to my standing rules, so the next judgment inherits it.

AgentTube is the difference between a pipeline that produces a folder of notes and a tool I actually use. The verdict and the action live in the same place.

It gets sharper every time I correct it

I gave it a memory.

Scoring relevance is subjective, and a fixed prompt will keep making the same misjudgments about what fits my stack. So I gave it a memory.

A plain markdown file, learnings.md, gets injected verbatim into Claude's prompt as cached context before every analysis. It holds seven standing rules: extract the technique not the summary, rewrite clickbait titles into the actual method, score against my real stack and not generic usefulness, check which skills I already have installed, and so on. Underneath those rules sits a dated, append-only log of every correction I've made.

When the pipeline reads a video wrong, the Teach button is how I fix it. I correct it once, the correction lands in that file, and every future judgment inherits it. The scores get better because I taught them, not because the model nailed it cold. Teaching the pipeline is editing a text file, not retraining anything.

video-curator / learnings.md · standing rules
learnings.md: the seven standing curation rules injected into every analysis, followed by the start of the dated, append-only correction log.
How it's built

The stack, and the decisions in it.

It's a Python CLI under the hood, no web framework, wired into AgentTube inside Agentic OS 97 on top. A few decisions are worth defending. The two-model split trades one extra API call for honest output. The frugality boils down to model selection: a fast, cheap model for the bulk ingest, Claude Sonnet or Codex Terra for the judgment that has to be good. And the whole pipeline is idempotent. A note already on disk means a video is already curated, so hitting Curate never re-runs the scrape-and-score on something I already have, which is what makes it cheap to point at a backlog.

Language
Python
AI
Codex + FreeLLMAPI fallback (objective ingest)Claude Sonnet or Codex Terra (judgment)
Media
yt-dlpffmpegWhisper (Groq or OpenAI)
Scraping
Playwright (headless chromium)browser_cookie3Chrome cookies
Sources
YouTube (via yt-dlp)Instagram web
Dashboard
AgentTube (Agentic OS 97)what-to-watch card feed
State
state.json seen-listmarkdown noteslearnings.mdgit

The pipeline also pulls from Instagram saved collections, which have no public API. A Playwright headless chromium session rides my existing Chrome cookies, scrolls a saved collection, and yields the post shortcodes, all inside a session I already trust so there's nothing new to store. A YouTube failure doesn't take the Instagram half down, and one bad video doesn't abort the batch. A failed curation just retries on the next import. I point it at my queue and walk away.

video-curator / import_saved.py · batch run
import_saved.py run: enumerated 12 videos, 9 already seen, 3 new after deduping against state.json and notes on disk; batch curating with a graceful failure that retries next import, and an idempotency skip on a second pass.