article-optimizer
Use when the user wants to improve a specific article under a fixed viral-scoring rubric, iterate on one article to raise its score, or run single-article…
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
$ npx -y skills add xiaomoBoy/claude-writing-skills --skill research-collector --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/research-collectorContext preview
The summary Claude sees to decide when to auto-load this skill.
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
name: research-collector description: 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.
这个 skill 只做一件事:
不负责:
一句话原则:用户说"帮我收集 X 话题的素材"或"拉一批 YouTube + 文章到 NotebookLM",就走这条固定流水线,不要每次重新设计。
适用场景:
不适用场景:
开始前必须确认:
1. `nlm` CLI 已安装且登录:`nlm login --check` 2. `yt-dlp` 在 PATH 中:`which yt-dlp` 3. 用户明确说明了主题和角度 4. 输出目录可写(默认 `./research/<topic>/`,可以通过 `RESEARCH_OUTPUT_DIR` 环境变量或对话里直接指定其他路径)
前置不满足时:
在动手前必须和用户明确:
1. **主题是什么**(要一句话能喂给 ytsearch 的关键词) 2. **角度**(比如"最常用 + 个人创作" vs "最新发布 + 技术细节") 3. **笔记本命名**(默认 `<主题> 素材`) 4. **量级**(默认:15 油管 + deep research 自动 ~40 网页)
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 个查询模板(按需改关键词):
1. **Top 清单**:"基于所有 source,请列出被最多来源推荐的 Top 10 X。对每个 X 说明:(1) 名称 (2) 具体做什么 (3) 主要使用场景 (4) 推荐它的来源数量 (5) 类型分类。按推荐频率从高到低,用中文输出。" 2. **目标读者向**:"我要写一篇面向 <读者画像> 的文章。请筛选出对 <读者> 最有帮助的 Top 8 X,每个说明:(1) 名称 (2) 具体痛点 (3) 典型用法一句话 (4) 类型 (5) 最具体的来源编号。去掉不相关的,聚焦 <场景>,用中文。" 3. **入门 + 坑**:"针对 <读者> 使用 X 时,请总结:(1) 最快入门方式 (2) 去哪里获取 (3) 最容易踩的 5 个坑 (4) 什么时候其实不需要 (5) 最新的重要更新。每点配来源编号,用中文。"
原始输出是 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执行完要给用户报告:
1. Notebook 名字 + alias + 实际 source 数量 2. 3 份 raw JSON 和 1 份汇总 markdown 的落盘路径 3. 失败/跳过的 source(如果有) 4. 汇总文件的头部预览(前 20 行左右) 5. 建议的下一步(交给用户决定下游怎么用,本 skill 到此结束)
nlm 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,不要
A toolkit of Claude Code skills for long-form content creators — research, score, rewrite, and publish, end to end. 中文版: README.zh-CN.md 5 skills extracted from a real working writing setup. They are opinionated, narrow in scope, and meant to compose.
Use when the user wants to improve a specific article under a fixed viral-scoring rubric, iterate on one article to raise its score, or run single-article…
Use when the user has a finished blog master draft and wants to publish it to multiple content platforms (知乎/掘金/CSDN/公众号 等) via the @wechatsync/cli tool.…
Use when the user wants to iterate on a viral-article scoring system itself, calibrate or improve a scoring prompt against labeled samples, or run batch…
Use when the user wants to download or inspect online audio/video directly with the installed `yt-dlp` CLI. Best for single videos, playlists, audio…