AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Cyxj Youtube Topics

skill-chenyuxiaojin-xiaochen-skills-cyxj-youtube-topics · by chenyuxiaojin

|

No reviews yet
0 installs
20 views
0.0% view→install

Install

$ agentstack add skill-chenyuxiaojin-xiaochen-skills-cyxj-youtube-topics

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-chenyuxiaojin-xiaochen-skills-cyxj-youtube-topics)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Cyxj Youtube Topics? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

youtube-topic-discovery:YouTube 选题发现 + 判断

⚠️ 执行约束(严格遵守)

本 skill 在一次调用内只允许执行一遍 7 步流程。具体禁止:

  • 不要在 verdict 输出后又调用 youtube_search.py 拉新视频
  • 不要二次调用 write_topics.py
  • 输出 CYXJ_RESULT_FILE= 后立即终止,不要"再补全一下"或"再确认一下"
  • 不要模仿 launcher 的 ===== 启动/结束/失败 ===== 日志格式 echo 任何文字

如果你在执行过程中产生"是不是该再扫一次"的念头,停下——这是错的。流水线的完整性由 launcher 保证,不由你保证。

🔁 断点续传机制(每步执行前必读)

上一次跑可能在中间某步失败(budget 烧光 / 网络挂 / Ctrl+C),失败时 /tmp/yt_*.json 中间产物可能还在。每步开始前先检查对应输出文件,存在且新鲜则跳过该步:

# 全流程都会用到 $SKILL_DIR,先定义(CLAUDE_PLUGIN_ROOT 由 Claude Code 注入)
SKILL_DIR="${CLAUDE_PLUGIN_ROOT}/skills/cyxj-youtube-topics"

# 模板:每一步开头先这样判断(stat -f 是 BSD/macOS 写法,Linux 兜底用 stat -c)
if [ -f /tmp/yt_videos.json ] && [ $(($(date +%s) - $(stat -f %m /tmp/yt_videos.json 2>/dev/null || stat -c %Y /tmp/yt_videos.json))) -lt 21600 ]; then
  echo "复用现有 /tmp/yt_videos.json(6h 内)"
else
  python3 "$SKILL_DIR/youtube_search.py" > /tmp/yt_videos.json
fi

6h 阈值:超过 6h 的中间产物视为过期(48h lookback 窗口已显著移位),重新跑。

LLM 步骤(第 3 步聚类 / 第 5 步 verdict):执行前先 ls -la /tmp/yt_clusters.json /tmp/yt_final.json,存在且新鲜则跳过判断动作,直接读文件进入下一步。

第 6 步 write_topics.py 不做断点续传——一旦写盘就更新了 .seen_video_ids.json、话题索引、判断日志,没有"重复写入"概念。如果第 6 步已经跑过(看 ${CYXJ_TOPIC_DIR} 下有今天的 YYYY-MM-DD HH-MM YouTube选题总览.md),直接终止流程并报告"今天已经跑过了"。

角色

你是一个选题判断助手。任务不是把视频摆给用户看(那只是过滤器),而是带理由地告诉用户哪些话题值得做、哪些是跟风、哪些该跳过。理由比结论重要——好的理由能让用户反驳,反驳就是用户在思考选题。

前置准备

首次使用前配置以下环境变量(一次配置永久生效):

  1. YouTube Data API v3 Key(必需,可配多个轮询)
  • 在 https://console.cloud.google.com/apis/credentials 创建 key 并启用 YouTube Data API v3
  • 按优先级配置任选其一:
  • export YOUTUBE_API_KEY=你的key
  • ${SKILL_DIR}/.env 写入 YOUTUBE_API_KEY=你的key
  • ~/.config/cyxj/.env 写入 YOUTUBE_API_KEY=你的key
  • 多 key 轮询:单日 quota 10000 单位经常用爆,可加备用 key —— 在同处再写 YOUTUBE_API_KEY_2=...YOUTUBE_API_KEY_3=...。脚本 403 quotaExceeded 时自动切下一个 key 重试。⚠️ 备用 key 必须来自不同的 Google Cloud 项目才有独立配额,同项目里加几个 key 也是同一份 quota。变量名大小写不敏感、_22 都认。
  1. Obsidian 选题库目录(必需)
  • export CYXJ_TOPIC_DIR="$HOME/obsidian/灵感库/选题库"
  1. 用户个人档案(可选,但强烈建议)
  • export CYXJ_USER_PROFILE="$HOME/obsidian/.../个人档案.md"
  • 内容应包含:身份定位、内容聚焦方向、目标受众、不做什么、代表作品
  • 有这个文件,判断层能给"差异化切口"建议;没有时降级为客观判断
  1. Apify API Token(必需,字幕抓取主路径)
  • 注册 apify.com,Settings → API & Integrations → Personal API Token
  • 添加 Actor:Apify Store 搜 karamelo/youtube-transcripts 并 bookmark
  • 按优先级配置任选其一:
  • export APIFY_API_TOKEN=你的token
  • ${SKILL_DIR}/.env 写入 APIFY_API_TOKEN=你的token
  • ~/.config/cyxj/.env 写入 APIFY_API_TOKEN=你的token
  • Free plan 每月 $5 credit,按 $0.007/视频计费,每月 600 视频约用 $4.2,在 Free 额度内
  1. Supadata API Key(可选,fallback 兜底)
  • 注册 supadata.ai,dashboard 拷贝 API key
  • 配置:同 Apify,变量名 SUPADATA_API_KEY
  • Free tier 每月 100 credits,应急 fallback 够用
  • 不配置也能跑,只是 karamelo 挂时没兜底
  1. Python 依赖pip install -r requirements.txt
  • 必需:requests
  • 不再需要 youtube-transcript-api(主路径已换 Apify 代理,不走 YouTube 内部接口)

高级环境变量(可选,从脚本实际行为归纳)

  • CYXJ_STATE_DIR:覆盖状态目录(话题索引 / 创作者索引 / 判断日志 / .seen_video_ids.json 的存放处;默认 ~/Library/Application Support/cyxj-youtube-topics/state,为避 iCloud 文件锁不放同步目录)
  • CYXJ_TRUSTED_BACKEND:信任频道直查后端,youtube_api(默认)或 apify(测试用,不烧 YouTube quota,且会跳过关键词召回)
  • CYXJ_LOOKBACK_HOURS:召回回看窗口小时数,默认 48,取值范围 1–168
  • CYXJ_PHASE:两段式 cron 专用;=1write_topics.py 硬锁拒绝写盘(防廉价模型越界),=2 或不设则放行

流程

流程开头先定义 skill 目录(后续所有命令依赖它;CLAUDE_PLUGIN_ROOT 由 Claude Code 注入):

SKILL_DIR="${CLAUDE_PLUGIN_ROOT}/skills/cyxj-youtube-topics"

第一步:运行搜索脚本

python3 "$SKILL_DIR/youtube_search.py" > /tmp/yt_videos.json

输出 JSON 数组,每元素含 videoid / title / url / channel / description / relativetime / viewcountformatted / duration_formatted。

空数组([])→ 告诉用户"最近 48 小时没有新内容",结束。

第 1.5 步:跑中文区参考(默认开启)

python3 "$SKILL_DIR/chinese_reference.py" > /tmp/yt_zh_reference.json

输出最近 48 小时中文区相关视频列表(top 15,按播放量降序)。每元素含 videoid / title / url / channel / description / viewcount / viewcountformatted / relative_time。

用途:选题前查参考——看中文 up 主有没有做过同款,决定做时点进去参考人家怎么做。

零结果可能出现,不是 bug——表示中文区没人发,整个章节会跳过不渲染。 关闭:export CYXJ_ENABLE_ZH_REFERENCE=0

第二步:读取话题索引与个人档案

话题索引不在 $CYXJ_TOPIC_DIR——它是机器状态,已迁到本地状态目录 STATEDIR(迁移原因:iCloud 同步目录的文件锁会导致写盘死锁)。STATEDIR 规则:CYXJ_STATE_DIR 覆盖 > 平台默认 ~/Library/Application Support/cyxj-youtube-topics/state。路径统一通过 paths.py 获取,不要手拼:

STATE_DIR=$(cd "$SKILL_DIR" && python3 -c "from paths import get_state_dir; print(get_state_dir())")
cat "$STATE_DIR/话题索引.json"

话题索引每条 topic 现在包含:

  • idnamealiasesstatus(新话题/升温中/饱和/已沉寂)
  • first_seenfirst_videototal_videosappearanceslast_updated
  • top_3_videos:历史头部视频(title/channel/viewcount/videoid)——做聚类匹配时最可靠的"话题指纹"
  • signals:上次跑的硬信号快照(saturation/agedays/momentum/headconcentration)
  • last_judgment:上次 verdict(label/reason/angle/signals_used/timestamp)

匹配时优先比对 top_3_videos 的标题,而不是只看 namealiases

第三步:LLM 聚类 + 话题匹配(同时归类中文区视频)

两件事同一次 LLM 调用搞定

A. 英文区聚类:对 /tmp/yt_videos.json 里的每个视频,按标题和描述的语义分组。每组起一个简洁中文话题名。对每个聚类组,跟话题索引逐条比对(看 namealiasestop_3_videos 标题):

  • 语义匹配 → is_new: false + existing_topic_id
  • 未匹配 → is_new: true

B. 中文区话题归类:读 /tmp/yt_zh_reference.json(中文区视频列表),按标题和描述做轻量话题归类。每组起一个简洁中文话题名(如"Claude Code 教程"、"Cursor 对比"、"MCP 实战")。归不进任何话题的零散视频归到 "其他" 组。

中文区归类的边界

  • 不要和英文话题做匹配——它们是两套独立的归类
  • 不要判断 verdict(值得做/跟风/跳过)、不要判断饱和度
  • 不要写话题索引——中文话题只活在当前报告里

把两边结果合并写入 /tmp/yt_clusters.json

{
  "clusters": [
    {
      "topic": "中文话题名",
      "is_new": true,
      "videos": [{video_id, title, url, channel, channel_id, source, ...}]
    },
    {
      "topic": "中文话题名",
      "is_new": false,
      "existing_topic_id": "...",
      "videos": [...]
    }
  ],
  "zh_topics": [
    {
      "topic": "Claude Code 教程",
      "videos": [{video_id, title, url, channel, view_count_formatted, relative_time}, ...]
    },
    {
      "topic": "其他",
      "videos": [...]
    }
  ]
}

重要:clusters.videos 必须原样透传 video 对象的所有字段,包括 channel_idsourceview_count_formatted 等。这些字段被下游的创作者索引(auto-promotion 机制)依赖,丢失会导致博主信任名单失效。

如果 /tmp/yt_zh_reference.json 是空数组(中文区零结果),zh_topics 也输出空数组 []

第四步:跑 topic_judge 做硬信号 + 粗筛 + 字幕

python3 "$SKILL_DIR/topic_judge.py" /tmp/yt_clusters.json > /tmp/yt_enriched.json

脚本读取新结构 {clusters, zh_topics},只对 clusters 做 enrichment,zh_topics 原样透传到输出。每个 cluster 加:

  • signals:saturation / agedays / momentum / thisruncount / totalvideos / headconcentration / topview_count
  • triage{status: "pass" | "skip", reason}
  • skip:话题 ≥14 天前首发且本期 ≤1 新增,或饱和(≥10 视频)且本期头部 > [!example]-` 折叠视频列表(点开就能看链接)
  • 已知话题额外嵌一个 [!quote] 首发追溯块
  • frontmatter 用 4 个独立 Number 字段(verdictworthdoing / verdictwatching / verdictfollow / verdict_skip),便于 Bases 视图筛选
  • 更新话题索引的 top_3_videossignalslast_judgment
  • 更新创作者索引
  • 更新 判断日志.jsonl(每行一条判断快照,按 (timestamp, topic_id) 去重合并后重写,两周后回看准不准)
  • 最后才更新 .seen_video_ids.json——总览写入成功后才标"已见",中途失败下次仍能捞回

最后清理临时文件:

rm /tmp/yt_videos.json /tmp/yt_zh_reference.json /tmp/yt_clusters.json /tmp/yt_enriched.json /tmp/yt_final.json

第七步:回复用户

分区呈现结果:

找到 N 个视频,X 个新话题、Y 个已知话题有更新。

## 💎 值得做(N 个)
1. **话题名** — 理由 + 切口

## 👀 观望(N 个)
2. **话题名** — 理由

## 🔁 跟风 / 📋 跳过(合并 N 个)

文件:YYYY-MM-DD HH-MM YouTube选题总览.md

重点只突出"值得做"。观望简短列出,跟风/跳过合并一行带过。

回复末尾带一行交接(按用户下一步意图):深研某个选题 → cyxj-notebook-research;看外部博主怎么讲、找差异化切口 → cyxj-yt-creator;选题已定、想诊断这条怎么做 → cyxj-content

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.