scan_topic
Run multi-keyword Bilibili topic scans in one call: deduplicate and rank candidates, pull top-candidate comments with basic image checks, and return coverage and cost signals for evidence gathering.
Instructions
阶段 1 广扫的唯一入口:多关键词搜索 → 去重 → 排序 → 对头部候选拉评论(含低成本判图)。
一次调用替代原来的「N 次搜索 + M 次元数据 + M 次评论」。返回: · candidates:全部候选的完整元数据 + 命中词族数 + 每千播放互动率 · digest:只有排序靠前的 comment_budget 条带评论摘要与评论区结构指标 · digest[].images:热评带图时的 160px 微表(判"这图是什么类型",读不出数字) · coverage:每个关键词命中数、去重后总数、跨词族命中数、样本偏差声明 · degraded / ok / cost:本次的降级信号、是否完整、以及实际开销
参数取舍:
keywords 建议 4–6 个,覆盖 同义词/上位词/下位词/黑话/英文 五类
per_query 每个词取多少条(≤50;取 30 通常已进入长尾)
comment_budget 花评论预算的条数。默认 12:再多也读不动,再少会漏掉侧面
comment_n 每条候选读多少条热门评论。默认 15——8 条看不到"高赞反方"这一层
image_policy "hot"(默认)热评里有图就判;"off" 最快;"all" 不论有没有都尝试
image_top 每条候选最多拼几张热评图,默认 6
families 强烈建议传:{"上位词": [...], "产品名": [...], "黑话": [...]}。
排序键会改成「命中的不同语义族数 → 族内命中数 → 播放量」。
不传时 kw_families 返回 null——代码无法凭空知道哪些词属于同一族。
pages_per_keyword 每个词翻几页。长尾在第 2 页——实测每词 page_size=30
时各命中 26–30 条,恰好卡在上限,长尾根本没取到。
min_play 排除播放量低于此值的候选(收窄候选池,不是扩大)
published_after "YYYY-MM-DD",排除更早的内容(算法偏好新内容,"老"≠"好")
offset(批次 D2)
跳过排序后的前 N 条,取下一批。用来解决「召回 835 条、只返回 50 条」的断层:
候选池没变,只是分页看。coverage.next_offset 给了下一页的起点;
coverage.rest_preview 是未展示候选的一行摘要(不含评论,成本≈0),
可以先扫一眼再决定要不要翻页。
exclude_topic(批次 D3 · 增量模式)
传议题名,自动把 .registry/videos.json 里该议题已登记过的 BV 排除。
同议题第二轮用它,避免把上次已分析的条目再扫一遍。
与 exclude_bvids 可叠加使用。
排序规则(传了 families 时,批次 D2):标题/简介强命中的不同族数 → 命中的不同族数 → 命中关键词数 → 字段权重 → 播放量(log)。 强命中族数是为了压掉「靠标签蹭进来」的候选——B 站搜索是模糊匹配, 标签沾边就能命中很多关键词。
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | ||
| families | No | ||
| keywords | Yes | ||
| min_play | No | ||
| comment_n | No | ||
| image_top | No | ||
| per_query | No | ||
| image_policy | No | hot | |
| exclude_bvids | No | ||
| exclude_topic | No | ||
| comment_budget | No | ||
| max_candidates | No | ||
| published_after | No | ||
| pages_per_keyword | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |