最新资讯
stackoverflow.blog 欢迎来到芯片时代:半导体制造、AI 数据中心与芯片设计的未来 www.youtube.com AI Agent 总犯同样的错:CentralAgent AI 将记忆重构为经验系统 pub.towardsai.net Netflix 科学家建议重采样 LLM 评判:5 次仅将误差棒缩小 13% pub.towardsai.net Jev 作为 LLM 前的静默层:构建提示感知的模型路由器 reddit.com OpenAI 称 Astra 仅满足 10% 安全任务标准 dev.to FreeToken:在自有 GPU 上运行前沿 MoE 模型及其内存需求 dev.to 当 AI Agent 说“完成”时,究竟完成了什么? dev.to 部署 Underdog Bark 3.0 Pro:逐字转写、自定义后端与分块设置 dev.to 为艰难对话构建 AI:五个 Agent、一条安全正则与一位盲评监督者 techcrunch.com Palo Alto Networks 洽谈以 5 亿美元收购 AI Agent 安全初创公司 Clutch theinformation.com 黄仁勋被要求就涉华间谍指控向国会作简报 www.infoq.com Edera 推出 Object Capability Bounded Authority,试图将凭证与 AI Agent 工作负载隔离
多元动态
登录 注册
智能体 dev.to · @Eric Z. Casaucao

为 RAG 大规模抓取 YouTube 字幕(以及会搞垮管道的 3 个问题)

原文 我的收藏

文章讨论在 RAG 或 Agent 管线中把视频字幕作为语料的价值:字幕与媒体对齐、带分段时戳,重要视频常有人工字幕,比自行 ASR 更省成本且避免第二重误差。作者梳理了批量抓取非自有视频字幕时的来源可信度问题、官方 API 的局限、可用的 Python 入库路径,以及需要提前设计的失败模式。

AI推荐理由 面向 RAG/Agent 视频管线的工程实践文,具体讨论批量抓取 YouTube 字幕的来源可信度、官方 API 限制与失败模式,并给出 Python 入库路径;对构建视频语料检索的开发者有直接参考价值,但属个人经验分享,未提供可复现的完整基准数据。

72

正文

If you are building a RAG or agent pipeline over video, the transcript is the payload. Titles and descriptions are thin; a 40-minute talk is thousands of tokens of dense, quotable prose. The good news is that YouTube already exposes that prose as captions. The bad news is that pulling captions for videos you do not own, at batch scale, is where most naive pipelines fall over. This post walks through the source-of-truth question, the official-API dead end, a working Python path into a vector store, and the failure modes worth designing around. Why captions and not ASR You can run speech-to-text on the audio. For a single video it is fine. For hundreds it is expensive, slow, and introduces a second source of error: your ASR output will disagree with the captions every viewer already sees. YouTube captions are aligned to the media, carry per-segment timestamps, and are often human-authored for the videos that matter most. When a human track is missing, auto-generated captions are still a far better starting point than re-transcribing the audio yourself. One caveat to state plainly: caption extraction is not transcription. If a video has no captions at all, there is nothing to extract — you would need a real ASR step, and you should handle that case explicitly rather than silently returning an empty document. The official API can't fetch third-party captions The obvious first move is the YouTube Data API v3. Its captions.download endpoint looks promising, but it only returns caption tracks for videos owned by the authenticated channel, or where you have permission. For arbitrary third-party videos — the ones your RAG corpus actually needs — it returns an error. The Data API is a channel-management API, not a transcript API. So the practical route is the public player surface: the watch page's player response carries the caption track metadata, which points at timedtext resources you can fetch. That is the approach YouTube's own web player uses, and it needs no OAuth and no Google Cloud key. A Python snippet: Actor run to embeddable chunks Rather than maintain your own signed HTTP calls, you can call an Actor that already handles the player payload, retries, and proxy rotation. Here is the whole loop: submit a batch, read the dataset, and turn each transcript into chunk records ready for embedding. from apify_client import ApifyClient client = ApifyClient("") run = client.actor("casaucao/youtube-transcript-scraper").call(run_input={ "videoUrls": [ "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "https://youtu.be/9bZkp7q19f0", ], "languages": ["en", "es"], "outputFormat": "segments", "includeMetadata": True, "maxRetries": 3, "concurrency": 5, }) chunks = [] for item in client.dataset(run["defaultDatasetId"]).iterate_items(): if item.get("status") != "ok" or not item.get("fullText"): continue segments = item["segments"] window = [] size = 0 start = segments[0]["start"] if segments else None for seg in segments: window.append(seg["text"]) size += len(seg["text"]) if size >= 1200: chunks.append({ "videoId": item["videoId"], "title": item["title"], "language": item["language"], "start": start, "text": " ".join(window), }) window, size = [], 0 start = seg["end"] if window: chunks.append({ "videoId": item["videoId"], "title": item["title"], "language": item["language"], "start": start, "text": " ".join(window), }) print(len(chunks), "chunks ready to embed") Enter fullscreen mode Exit fullscreen mode The fields that matter here: fullText for the whole document, segments for timestamp-preserving chunking, language and translatedFrom for provenance, and isGenerated to know whether a human or the machine wrote it. Once you have chunks, hand each text to your embedding model and store the videoId and title as metadata so citations can link back to the source second. The three things that actually break it 1. IP blocking at volume. Caption endpoints start rejecting or throttling requests once you push real batch sizes from a single address. Retries help, but only if you rotate the exit IP. Run behind a proxy pool and switch to residential if you are consistently getting block pages. Exponential backoff with jitter keeps a single bad window from cascading into a failed run. 2. The player payload changes underneath you. This is the fragile part of the approach, and it is worth knowing the specific scars. Using the watch-page payload rather than the InnerTube /player endpoint avoids a class of auth problems, but client versions go stale — an outdated InnerTube client version can make playlist browse calls return HTTP 500, and resolving a channel @handle needs a consent cookie in the request before it will resolve. These are not documented behaviors; they are found in production and fixed in production. 3. Per-item failure must not kill the run. With a batch of hundreds of URLs, some will be age-restricted, region-locked, private, or simply caption-less. A pipeline that raises on the first bad item is useless. Each row should carry its own status and error so the caller can log the failures and keep the good transcripts. Translation fallback belongs in the same bucket: if your preferred language is unavailable, fall back to another track and translate when possible, recording translatedFrom so you know the text is not in the original tongue. Practical notes on cost and testing Batch extraction is metered per event rather than per compute minute. As of writing the Actor bills $3 per 1,000 transcripts plus $0.50 per 1,000 metadata-enriched videos, and failed videos or videos without captions are not charged. On the free plan, runs are capped to the first few videos so you can validate shape and quality before scaling up. Do that: run three videos, check that segments align with what you hear, confirm the language fields, and only then point it at your whole channel. If you want to skip the plumbing, I built the Actor used above — the YouTube Transcript Scraper on Apify. It handles single videos, batches, Shorts, playlists and channel expansion, with segments, text, markdown, srt and vtt output. It is my own tool, so treat this as disclosure rather than an impartial review — but the failure modes above are the real ones I hit building it, and they apply to any caption pipeline you write yourself.

来源报道 · 1 篇 · 以下链接均前往原始媒体

← 返回精选动态 原文

更多内容