Use when the user wants to collect research material for an article or topic by gathering YouTube videos and web articles into a NotebookLM notebook, then running analysis queries and saving results as markdown. Best for "收集素材"、"给我找这个话题的相关视频和文章"、"整理成 NotebookLM 分析" type requests. Combines yt-dlp YouTube search, NotebookLM `nlm` CLI research, and markdown report output.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-writing-skills:research-collectorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
这个 skill 只做一件事:
这个 skill 只做一件事:
./research/<topic>/,可配置)不负责:
yt-dlp-direct skill)publisher-wechatsync skill)一句话原则:用户说"帮我收集 X 话题的素材"或"拉一批 YouTube + 文章到 NotebookLM",就走这条固定流水线,不要每次重新设计。
适用场景:
不适用场景:
nlm notebook queryyt-dlp-direct开始前必须确认:
nlm CLI 已安装且登录:nlm login --checkyt-dlp 在 PATH 中:which yt-dlp./research/<topic>/,可以通过 RESEARCH_OUTPUT_DIR 环境变量或对话里直接指定其他路径)前置不满足时:
nlm login --check 失败 → 让用户跑 nlm login,session 有效期 ~20 分钟yt-dlp 没装 → 停止并告诉用户./research/<topic>/ 下(或用户指定的目录)在动手前必须和用户明确:
<主题> 素材)nlm notebook create "<话题> 素材"
# 从输出提取 ID,然后:
nlm alias set <short-name> <notebook-id>
alias 取短名,比如 skills-research、vps-2026,后续所有命令都用 alias。
并行跑 2-3 个不同角度的搜索,每个 15 条:
yt-dlp --simulate --print "%(title)s|%(webpage_url)s|%(view_count)s|%(uploader)s" \
"ytsearch15:<关键词 A>"
yt-dlp --simulate --print "%(title)s|%(webpage_url)s|%(view_count)s|%(uploader)s" \
"ytsearch15:<关键词 B>"
输出里的 JS runtime warning 可以忽略。
从结果里按以下规则筛 top 15:
用 bash 循环逐条加,每次 sleep 2 秒:
cat > /tmp/yt_urls.txt <<'EOF'
https://www.youtube.com/watch?v=XXX1
https://www.youtube.com/watch?v=XXX2
...
EOF
while IFS= read -r url; do
echo "=== Adding: $url ==="
nlm source add <alias> --url "$url" 2>&1 | tail -5
sleep 2
done < /tmp/yt_urls.txt
偶尔会遇到单条失败(视频不公开、区域限制),忽略继续,最后报告成功率。
nlm research start "<英文查询,适合 web 研究>" \
--notebook-id <alias> --mode deep
deep 模式 ~5 分钟,返回 ~40 条网页源。
关键:一个 notebook 同一时间只能有一个 research 任务在跑。如果要跑第二轮,必须等第一轮 import 完或 --force。
等待完成:
nlm research status <alias> --max-wait 360
Bash 工具默认 timeout 120 秒,必须加 timeout: 400000(即 400 秒)。
研究完成后从输出里拿 task-id,然后:
nlm research import <alias> <task-id> --timeout 600
Bash 工具加 timeout: 700000。
注意:用户有时会说"素材够了,不用再导入",要停下来直接进 Phase 6。
默认跑 3 个角度,命令直接重定向到文件避免输出过大:
mkdir -p "./research/<topic>"
nlm notebook query <alias> "<问题 1 的中文提示>" \
> "./research/<topic>/query1-<slug>-raw.json" 2>&1
nlm notebook query <alias> "<问题 2 的中文提示>" \
> "./research/<topic>/query2-<slug>-raw.json" 2>&1
nlm notebook query <alias> "<问题 3 的中文提示>" \
> "./research/<topic>/query3-<slug>-raw.json" 2>&1
每个 query 的 Bash 调用要加 timeout: 240000。
默认 3 个查询模板(按需改关键词):
原始输出是 JSON 包含 answer + citations,用 Python 抽 value.answer 字段:
python3 <<'PY'
import json, pathlib
base = pathlib.Path("./research/<topic>")
files = [
("query1-<slug>-raw.json", "## Query 1:<标题>"),
("query2-<slug>-raw.json", "## Query 2:<标题>"),
("query3-<slug>-raw.json", "## Query 3:<标题>"),
]
out = ["# <话题> 素材研究", "",
"> 基于 NotebookLM 笔记本 `<notebook-name>` 的分析结果", "",
"---", ""]
for fname, heading in files:
out.append(heading)
out.append("")
raw = (base/fname).read_text()
try:
data = json.loads(raw)
out.append(data.get("value",{}).get("answer",""))
except Exception as e:
out.append(f"(解析失败: {e})")
out.append("")
out.append("---")
out.append("")
(base/"素材研究汇总.md").write_text("\n".join(out))
print("Written:", (base/"素材研究汇总.md").stat().st_size, "bytes")
PY
执行完要给用户报告:
素材研究汇总.md,如果存在先追加 -v2nlm login --check # 会告诉你是否有效
nlm login # 重新登录
session 有效期约 20 分钟。
先看版本:
yt-dlp --version
如果太旧提示用户更新。JS runtime / ffmpeg 的警告可以忽略,不影响 --simulate 模式。
单独查状态(不阻塞):
nlm research status <alias> --max-wait 0
如果 status 一直是 in_progress 超过 10 分钟,用 --force 重开:
nlm research start "..." --notebook-id <alias> --mode deep --force
所有 query 都重定向到文件,再用 Python 抽 answer,不要尝试在终端直接打印大 JSON。
watch?v= 标准格式,不用 shorts/live)nlm login --checknotebooklm-mcp-cli(pip 包,作者 jacob-bd)随附的 nlm-skill,或上游 README https://github.com/jacob-bd/notebooklm-mcp-cli../yt-dlp-direct/SKILL.mdCLAUDE.md / AGENTS.md,本 skill 不强依赖,可选阅读npx claudepluginhub xiaomoboy/claude-writing-skills --plugin claude-writing-skillsCreates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.