关于 youtube-topic-research
youtube-topic-research 用于按主题搜索并总结 YouTube 视频,适合视频调研与内容筛选。它结合字幕和时效性信号排序,也可将选定视频导出为 notebooklm-mode 来源。
主要功能
- 01搜索并筛选 YouTube 视频
- 02获取字幕并生成摘要
- 03按相关性和时效性排序
- 04导出视频供 notebooklm-mode 使用
适用场景
- 01查找某编程主题的教程
- 02筛选快速变化领域的新视频
- 03创建用于深入调研的视频来源库
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ moonlight-lupin/ agent-skills --skill youtube-topic-research安装后在 Claude Code 中输入/youtube-topic-research确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
requirements.txtreferences/debugging-patterns.mdfast_moving_domains.yamlip-blocking-workaround.mdqualify_prompt.mdreview_prompt.mdscripts/search_and_summarize.pytemplates/output.md.j2tests/__init__.pytest_search_and_summarize.py详细介绍
YouTube 主题研究技能
适用场景
当用户想要查找并总结特定主题的 YouTube 视频时使用——如果用户已经提供了 URL,则不适用(请使用转录提取技能)。此技能会搜索、筛选视频,获取转录文本,并返回最相关视频及其摘要。
示例:
- “查找关于 Python 异步编程的 YouTube 视频”
- “给我看看近期关于大模型微调的视频”
- “React Server Components 有哪些优秀教程?”
- “通过 YouTube 研究这个主题,然后构建一个知识库” → 供给模式
两种模式
独立模式(默认)
搜索 YouTube,获取转录文本,为视频排序,并返回热门推荐,包括摘要、新近度指标以及观看/跳过建议。
NotebookLM 供给模式
用户批准视频后,将每个选中的视频保存为与 notebooklm-mode 兼容的源文件,其中包含元数据、URL、转录摘录、视觉内容/演示说明、摘要和新近度状态。
供给模式触发语:
- “把这些添加到 notebooklm”
- “用这些视频创建一个源知识库”
- “先通过 YouTube 研究这个主题,然后构建一个知识库”
- “将视频用作来源”
# Feeder mode — export selected videos as notebooklm-mode source files
python scripts/search_and_summarize.py "docker networking" --export-vault /path/to/vault
此操作会在知识库中的 sources/ 目录内生成源文件,格式适用于 notebooklm-mode 导入。随后,Agent 可以运行 notebooklm-mode,基于视频来源开展有据可依的问答、做笔记、撰写报告或制作幻灯片。
架构
youtube-topic-research
│
├── standalone recommendation output (default)
│
└── --export-vault: selected videos as source files
│
▼
notebooklm-mode vault
│
▼
grounded Q&A / notes / reports / slides
与 notebooklm-mode 的关系
此技能可独立使用,也可作为供给端接入 notebooklm-mode:
| 用例 | 模式 |
|---|---|
| “帮我找一些优质的 Docker 网络教程” | 独立模式 |
| “查找 Godot 4 Agent 工作流的近期视觉演示” | 独立模式 |
| “使用 YouTube 研究这个主题并保存来源” | 供给模式 → notebooklm-mode |
| “根据视频和文章为我撰写一份有据可依的简报” | youtube-topic-research + notebooklm-mode |
| “总结这个 YouTube URL” | 单独的转录提取技能 |
大多数用户想要的视频只是推荐内容。供给模式用于真正的研究——让视频来源为后续问答和交付成果提供依据。
前提条件
pip install ddgs "youtube-transcript-api<1.0" jinja2 pyyaml
ddgs CLI(DuckDuckGo 搜索)是主要的搜索后端。youtube-transcript-api 用于获取转录文本。**请固定版本为 <1.0:**脚本使用 get_transcript() / list_transcripts() 静态方法 API,该 API 已在 youtube-transcript-api 1.0 中移除(更名为实例方法 .fetch() / .list())。如果不固定版本,安装时会拉取 1.x,导致转录文本获取失败且不显示任何提示。
快速开始
# Standalone — returns top 2 videos with summaries
python scripts/search_and_summarize.py "python async tutorial"
# Custom top-k
python scripts/search_and_summarize.py "LLM fine-tuning 2024" --top 3
# Disable freshness flags (for evergreen topics)
python scripts/search_and_summarize.py "linux basics" --no-freshness
# JSON output for programmatic use
python scripts/search_and_summarize.py "rust ownership" --format json
# Feeder mode — export to a notebooklm-mode vault
python scripts/search_and_summarize.py "docker networking" --export-vault /path/to/vault
流程
User Query
│
▼
┌─────────────────────────────────────┐
│ 1. SEARCH (ddgs videos) │
│ -q "query" -m 8 -o json │
│ Filter: publisher == "YouTube" │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 2. QUALIFY (heuristic or LLM) │
│ Score 0-100 per candidate │
│ Criteria: topic_match, authority,│
│ duration_signal, freshness │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 3. FETCH TRANSCRIPTS (top 3-4) │
│ youtube_transcript_api direct │
│ OR external fetch_transcript.py │
│ Health check: len > 500 chars │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 4. REVIEW (heuristic or LLM) │
│ Relevance score + summary bullets│
│ Chunk if > 40K chars │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 5. FORMAT & OUTPUT │
│ Standalone: output.md.j2 │
│ Feeder: notebooklm source files │
└─────────────────────────────────────┘
大模型集成
步骤 2 和 4 使用大模型提示词模板(references/qualify_prompt.md 和 references/review_prompt.md)。默认情况下,脚本使用启发式评分。要启用大模型筛选/审阅,Agent 运行时需重载 call_llm():
import search_and_summarize
def my_llm_call(prompt: str) -> dict | None:
# Call your LLM API (OpenAI, Ollama, Hermes, etc.)
# Must return a parsed JSON dict matching the prompt's output schema
response = my_llm_api.chat(prompt)
return json.loads(response)
search_and_summarize.LLM_CALL = my_llm_call
当 call_llm() 返回有效的 JSON 字典时,脚本会使用大模型评分。当其返回 None 时,脚本会回退到启发式评分。启发式评分会综合关键词重合度(移除停用词后)、观看次数、时长和发布时间。
对于较长的转录文本(>40K 字符),脚本会将其分块,通过大模型逐块审阅,然后合并结果。
视觉分析注意事项
此技能可以根据元数据、标题、说明和转录文本,识别可能包含丰富视觉内容/演示的视频,但除非运行时支持检查视频帧/图像,否则它并不会真正检查视频画面。基于转录文本生成的摘要不等同于视觉分析。此技能会根据标题/说明中的关键词标记可能包含演示、操作演练或视觉讲解的视频,但无法确认观众实际上会在屏幕上看到什么。
供给模式源文件格式
使用 --export-vault 时,每个视频都会保存为与 notebooklm-mode 兼容的源文件:
# YouTube Source: [Video Title]
| Field | Value |
|------|-------|
| URL | https://youtube.com/watch?v=... |
| Uploader | Channel Name |
| Published | YYYY-MM-DD |
| Duration | 18:42 |
| Views | 1.2M |
| Retrieved | YYYY-MM-DD |
| Type | youtube |
| Transcript Quality | good |
| Freshness | fresh |
## Why Selected
[Short reason based on query fit, authority, freshness, and transcript relevance.]
## Visual / Demo Value
- Shows live coding / dashboard / product walkthrough / diagrams / UI demo.
- Useful because this topic benefits from visual explanation.
## Transcript Extracts
> "Relevant transcript quote..."
> — approx. timestamp: 04:12
> "Another relevant quote..."
> — approx. timestamp: 09:45
## Summary
- Key point 1
- Key point 2
- Key point 3
## Gaps
- Does not cover X
- Assumes Y
配置
快速变化领域(references/fast_moving_domains.yaml)
定义近期内容更重要的主题的新鲜度阈值:
domains:
- name: ai_ml
keywords: ["ai", "llm", "fine-tuning", "gpt", "claude", ...]
stale_months: 12
aging_months: 6
# ... web_frameworks, cloud_devops, programming_languages, databases
未匹配的主题使用默认值(过时 > 36 个月,陈旧 > 24 个月)。
默认值
| 参数 | 默认值 | 覆盖方式 |
|---|---|---|
max_candidates | 8 | --max-candidates |
qualify_top_k | 4 | --qualify-top |
transcript_top_k | 3 | --transcript-top |
final_top_k | 2 | --top |
min_transcript_chars | 500 | --min-transcript |
chunk_size | 40000 | --chunk-size |
enable_freshness | true | --no-freshness |
错误处理
| 失败点 | 行为 |
|---|---|
未安装 ddgs | 退出并提示安装方法 |
ddgs videos 返回空结果 | 使用更宽泛的查询重试一次;若仍为空则报告 |
| DDG 中没有 YouTube 结果 | 报告“查询未找到 YouTube 视频” |
| 所有字幕获取失败/已禁用 | 返回原始 DDG 列表,并提示“无法获取字幕” |
| LLM 资格筛选失败 | 回退到启发式评分 |
| 字幕长度 > chunk_size | 自动分块,重叠 2K;逐块审查后合并 |
| 输出格式化失败 | 回退为纯文本摘要 |
| IP 被封锁(云虚拟机) | 请参阅 references/ip-blocking-workaround.md |
限制
- 不使用 YouTube API — 依赖 DuckDuckGo 视频索引(可能遗漏非常新或尚未编入索引的视频)
- 字幕可用率约为视频的 50-70%;自动生成的字幕可能有误
- 速率限制 — DDG 可能会限制频繁请求;此技能会在调用之间延迟 1-2 秒
- Token 成本 — 通过 LLM 审查完整字幕,每个视频约使用 5-15K 个 Token
- 语言 — 优先使用英语;若不可用则回退到任何可用的字幕
- IP 封锁 — YouTube 可能会封锁云服务提供商的 IP;请参阅解决方法
- 不进行视觉检查 — 根据元数据识别可能包含视觉内容或演示的视频,而非分析视频帧
扩展
- 在
references/fast_moving_domains.yaml中添加领域 - 自定义
references/qualify_prompt.md/references/review_prompt.md - 修改
templates/output.md.j2以使用不同的输出格式(Discord、Slack) - 设置
TRANSCRIPT_SCRIPT环境变量以指向其他字幕获取器 - 覆盖
call_llm(),以使用 LLM 驱动资格筛选和审查
文件
youtube-topic-research/
├── SKILL.md # This file
├── scripts/
│ └── search_and_summarize.py # Main entry point
├── references/
│ ├── qualify_prompt.md # LLM prompt for metadata qualification
│ ├── review_prompt.md # LLM prompt for transcript review
│ ├── fast_moving_domains.yaml # Freshness thresholds by domain
│ ├── debugging-patterns.md # DDG CLI quirks, date parsing, transcript cleaning
│ └── ip-blocking-workaround.md # YouTube IP blocking workarounds (cloud VMs)
└── templates/
└── output.md.j2 # Jinja2 template for standalone output