youtube-topic-research について
youtube-topic-research は、テーマに沿って YouTube 動画を検索・要約するスキルです。字幕と鮮度の指標で候補を並べ、選んだ動画を notebooklm-mode 用のソースとして出力できます。
主な機能
- 01YouTube 動画の検索と絞り込み
- 02字幕の取得と要約
- 03関連性と鮮度による順位付け
- 04notebooklm-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 動画を探して」
- 「LLM のファインチューニングに関する最近の動画を見せて」
- 「React Server Components の優れたチュートリアルは?」
- 「YouTube でこのトピックを調査してから、保管庫を作成して」→ フィーダーモード
2 つのモード
スタンドアロンモード(デフォルト)
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 への取り込み用にフォーマットされたソースファイルが生成されます。その後、エージェントは 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 ネットワーキングに関する良い YouTube チュートリアルを探して」 | スタンドアロン |
| 「Godot 4 のエージェントワークフローを視覚的に紹介する最近のデモを探して」 | スタンドアロン |
| 「YouTube でこのトピックを調査して、ソースを保存して」 | フィーダー → notebooklm-mode |
| 「動画や記事を根拠にした概要を作成して」 | youtube-topic-research + notebooklm-mode |
| 「この YouTube URL 1 件を要約して」 | 別のトランスクリプト抽出スキル |
動画を求めるユーザーの多くは、単におすすめを知りたいだけです。フィーダーモードは、動画ソースを以降の質疑応答や成果物の根拠にする必要がある、本格的な調査向けです。
前提条件
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 │
└─────────────────────────────────────┘
LLM の統合
ステップ 2 と 4 には、LLM プロンプトテンプレート(references/qualify_prompt.md と references/review_prompt.md)があります。デフォルトでは、スクリプトはヒューリスティックによるスコアリングを使用します。LLM による選別・レビューを有効にするには、エージェントのランタイムで 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 辞書を返すと、スクリプトは LLM によるスコアリングを使用します。None を返した場合は、ヒューリスティックによるスコアリングにフォールバックします。ヒューリスティックでは、キーワードの重複(ストップワードを除去)、再生回数、動画の長さ、公開からの経過時間を使用します。
長いトランスクリプト(40K 文字超)の場合、スクリプトはトランスクリプトを分割し、各チャンクを個別に LLM でレビューしてから、結果を統合します。
視覚分析に関する注意点
このスキルは、メタデータ、タイトル、説明、トランスクリプトから、映像やデモが豊富と思われる動画を特定できます。ただし、ランタイムがフレーム/画像の検査に対応していない限り、動画の映像そのものを実際に検査することはできません。トランスクリプトに基づく要約は、視覚分析とは異なります。このスキルは、タイトルや説明に含まれるキーワードから、デモ、チュートリアル、視覚的な解説が含まれる可能性の高い動画にフラグを付けますが、視聴者が実際に画面上で何を見るかを確認することはできません。
フィーダーモードのソースファイル形式
--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 が空を返す | より広いクエリで 1 回再試行します。それでも空の場合はその旨を報告します |
| DDG に YouTube の検索結果がない | 「クエリに一致する YouTube 動画が見つかりませんでした」と報告します |
| すべてのトランスクリプトの取得に失敗、または無効化されている | DDG の生のリストと「トランスクリプトを取得できませんでした」を返します |
| LLM による適格性判定に失敗 | ヒューリスティックによるスコアリングにフォールバックします |
トランスクリプトが chunk_size を超える | 2K のオーバーラップを設けて自動的にチャンク分割し、各チャンクを確認して統合します |
| 出力のフォーマットに失敗 | プレーンテキストの要約にフォールバックします |
| IP がブロックされている(クラウド VM) | references/ip-blocking-workaround.md を参照してください |
制限事項
- YouTube API は使用しません — DuckDuckGo の動画インデックスに依存しているため、非常に新しい動画や未インデックスの動画が見つからない場合があります
- トランスクリプトの利用可能率 — 動画の約 50~70%です。自動生成字幕には誤りが含まれる場合があります
- レート制限 — DDG は短時間に連続したリクエストを制限する場合があります。このスキルは呼び出しの間に 1~2 秒の遅延を設けます
- トークンコスト — LLM でトランスクリプト全体を確認する場合、動画 1 本あたり約 5~15K トークンを使用します
- 言語 — 英語を優先し、利用可能なトランスクリプトがない場合は他の言語にフォールバックします
- IP ブロック — クラウドプロバイダーの IP は YouTube にブロックされる場合があります。回避策のリファレンスを参照してください
- 映像の目視確認なし — フレーム分析ではなくメタデータから、映像やデモが含まれていそうな動画を特定します
拡張
references/fast_moving_domains.yamlにドメインを追加しますreferences/qualify_prompt.md/references/review_prompt.mdをカスタマイズします- 出力形式を変更する場合は
templates/output.md.j2を編集します(Discord、Slack) TRANSCRIPT_SCRIPT環境変数に代替のトランスクリプト取得ツールを指定します- LLM を使った適格性判定や確認を行うには、
call_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