DSH 网页角落里的一只罐子,替你挑今天看哪几条 B 站视频:不走平台推荐流,照你自己写的兴趣轴去搜,按点赞、投币、收藏率而不是播放量排序,攒进一个跨天累积的池子,最后让模型挑出五条并写一句讲内容、不讲数据的理由。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-bili-jar
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:Debuger-114514/dsh-bili-jar
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
DSH 插件。右下角一只罐子,点开是今天该看的 B 站视频。
先看三行:
- 需要 dsh ≥ 0.1.7;装完要重启一次(插件在 bundle 层组装)。
- 需要 你自己的 DeepSeek API Key。一轮「换一批」大约
¥0.004–0.01。 - 不用 B 站的推荐流。挑片的规则是你自己写的兴趣轴,最后一步交给模型挑。
罐子平时睡着,装罐时会走两步:
上图是用同一套 CSS 在本地渲染的预览,不是截屏。
它干什么
- 按你填的兴趣轴(
deepseek/时政/历史/ 随便什么)去搜 B 站 - 按互动率(赞、币、藏、弹幕除以播放)排好坏,而不是播放量
- 结果并进一个池子,跨天累积;今天没搜到的好东西,明天被别的词带出来还在
- 最后把前 24 条交给模型,让它挑 5 条,每条写一句理由
- 理由只说内容:讲了什么、怎么讲的、适合什么时候看。数据用来挑,不写进理由
- 点开卡片能小窗播放;不感兴趣的可以 👍/👎(攒够 20 条开始影响打分)
- 点击标题、「打开」或「小窗」即记为已观看,从推荐、关注和待看中移除,小红点同步减少(只统计推荐列表)。「历史」页保留最近 10 条,重复观看移到最前,重启后仍保留;历史超过 10 条时移除最早记录,当前片单仍不会补回已看视频。
模型没配或调用失败时退回纯规则挑片:每根轴先挑一条相似度 ≥0.85 的,同轴最多 2 条、同 UP 最多 1 条。片单不会因为没模型就空着。
一轮都经过什么
搜 每根轴 3 个词(其中 1 个按小时轮换),4 根轴约 9 次搜索,回来 180 条
补货 某根轴凑不够 3 条时,换两条通道再找:按时长带重搜 + 从种子扩散(相关推荐)
并池 和上一轮的池子合并,同一个 BV 只更新数据
筛 时长、播放门槛、充电专属、直播回放、日期窗口、贴不上任何轴 —— 全砍
打分 赞/币/藏/弹幕的率 0.39 + 贴轴 0.30 + 新鲜度 0.10 + 小众 tag 0.06 + 字幕 0.06 + 播放 0.05 + 多轴 0.04
补查 前 12 名回查真实投币数(搜索接口给的是旧的),重新打分
策展 只把前 24 名交给模型,让它挑 5 条、写理由
为什么只给模型 24 条:给整个池子也能挑,但一次调用会贵十倍,挑得还未必更好。
日期:每根轴自己决定
同一个窗口不可能同时适合「时政」和「空洞骑士攻略」—— 前者 14 天就过期,后者 2023 年的攻略今天照样有用。
所以每根轴有一个 freshness:
| 日期窗口 | 时效分权重 | |
|---|---|---|
news |
14 天(全局可改) | 0.10 |
evergreen |
不限 | 0.02 |
怎么定的:不看条数,看合格条目的年龄中位数。超过 90 天就算常青内容。
实测七个冷门词,分得很干净:丝之歌 361 天、空洞骑士 2052 天、vtuber 2385 天(都是 evergreen);时政 13 天、深蓝 26 天、术力口 5 天、kards 5 天(都是 news)。中间几乎没有模糊地带。
条数会跟着搜索结果抖(同一个词两次跑,命中数会变),中位数不会 —— 所以拿它当判据。
新轴默认 news,跑一轮后自动看:如果它凑不够 3 条、而且合格条目普遍很老,就在同一轮里改判成 evergreen,日志记一行原因。设置页每根轴旁边有个两态小开关,点了就是手填,手填之后不再被自动覆盖。
冷门轴为什么搜不到
搜「空洞骑士」时,B 站 的前 3 页被续作「丝之歌」的新内容占满,五年前的好视频排不进来 —— 有一条 33 分钟、108 万播放的攻略要翻到第 4 页才有。
所以凑不够 3 条时会走两条补充通道:
- 按时长带重搜:B 站 搜索支持
duration参数(1=<10 分 / 2=10–30 / 3=30–60 / 4=>60 分),一页 20 条全落在想要的时长里,比混着搜再筛掉强得多 - 种子扩散:
/x/web-interface/archive/related?bvid=是按内容相似度给的,不受新内容淹没。从任意 3 条同主题视频出发(不需要它们合格),去重后能捞回几十条,其中就有搜不到的那条
两条通道都是纯 HTTP,不花模型钱。
小众 tag 分:一条视频的 tag 在池子里越罕见,这一项越高(取最罕见的三个 tag 平均)。目的是别让「必剪创作 / 高能」这种大标签把长尾内容挤下去。
预设
装好就有,不用配:
| 类型 | 自带 |
|---|---|
| 兴趣轴 | 30 根:游戏 / 音乐 / 舞蹈 / 动画 / 知识 / 科技 / 影视 / 娱乐 / 生活 / 美食 / 运动 / 汽车 / 时尚 / 动物 / 鬼畜 / 纪录片 / 搞笑 / 学习 / 手工 / 摄影 / 历史 / 哲学 / 心理学 / 编程 / 数学 / 物理 / 军事 / 财经 / 职场 / 育儿 |
| 子簇 | 68 个,比如「游戏 → 沙盒游戏 / 游戏推荐 / 独立游戏」 |
| 语气 | 三套:鲸鱼女仆 / 正经简报 / 损友吐槽 |
| 头像 | 五张:睡觉 / 看电视 / 探险 / 哦鲸鲸 / 走路(唯一会动的一张) |
清单在 docs/presets.md。设置页点「+ 游戏」就把整根轴连子簇加进来。
轴树会长。 如果预设里没有你要的,或者不够细,点「看建议」:
- 从你池子里的 tag 挖候选(DF + 两两共现 PMI;跟谁都不特别的高频词会被当泛标签丢掉)
- 模型再过一遍:判是不是真细分方向、是不是别的轴的词、起个能当标签用的名字、说一句为什么
- 你点一下才写进自己的树(存在
~/.dsh/bili-jar/axis-tree.json,不碰出厂值)
实跑过的例子:历史 挖出「人文历史档案馆 / 人文 / 美国」,模型全否了,理由是「UP 主品牌不是分类」「太泛」「属于时政轴」;deepseek 留了三个,把 ai编程 改成 AI 编程,把 claude 当作别轴的词丢掉。
记账
三层:单次 / 今天 / 累计。按 DeepSeek 官方规则算钱 —— 北京时间工作日 09:00–12:00、14:00–18:00 是峰时,其余(含周末和法定节假日)半价。
| 元 / 百万 token | 缓存命中 | 未命中 | 输出 |
|---|---|---|---|
| 峰时 | 0.04 | 2 | 8 |
| 谷时 | 0.02 | 1 | 4 |
历史记录按每条自己的时间戳重算,改规则会把旧账一起修正。
装
桌面版的 desktop profile 不让 CLI 装插件,只能手改依赖:
// ~/.dsh/profiles/desktop/package.json
{
"dependencies": { "dsh-bili-jar": "link:D:/你的路径/电子榨菜罐" },
"dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "dsh-bili-jar"] } }
}
cd ~/.dsh/profiles/desktop && pnpm install
其他 profile:
dsh plugin --profile web add dsh-bili-jar
装完重启 dsh,再刷新页面。
第一次用
- 点罐子 → 设置 → 填 API Key(DeepSeek 官方)
- 改兴趣轴。默认那四根是我的口味,换成你的
- 回「推荐」,点换一批
B 站登录是可选的,只用来取 AI 字幕。二维码是插件自己画的(lib/qr.mjs,零依赖),凭证落在自己的目录里。
数据都在哪
~/.dsh/bili-jar/
| 文件 | 内容 |
|---|---|
config.json |
面板里的设置 + 语气预设(含明文 API Key) |
feed.json / pool.json |
当前片单 / 池子 |
reasons.json |
攒下来的推荐理由,关掉再开还能用 |
usage.json |
每次调用的 token 和费用 |
feedback.jsonl / later.json |
赞踩 / 待看 |
history.json |
最近 10 条观看记录,最新在前 |
credential.json |
B 站登录,只有你自己扫码才有 |
STATE.md |
人话摘要:现在什么配置、这一批推了什么、花了多少 |
安全
做过一次检查,结论都写在这:
- 只监听
127.0.0.1(DSH 的 webServer 本来就这么绑),局域网访问不到 - 跨站请求一律拒:带
Sec-Fetch-Site: cross-site,或者Origin不是本机的,直接 403。避免你开着插件逛网页时,被某个页面偷偷改配置或触发付费调用 - API Key 明文存在
config.json,但所有 HTTP 接口只返回sk-••••后四位,/debug也一样 - B 站 cookie 存在
credential.json,只在你自己扫码后写入;POSIX 下用0600 - 不读别的插件的凭证,除非你在设置里显式打开「复用刷B站的登录」(默认关)
- 不收集遥测,不往作者的任何服务器发数据。出站只有两处:
bilibili.com和你配的模型 API - 小窗播放是
player.bilibili.com的 iframe,等于在页面里跑 B 站的播放器
已知的限制
- 时政区很多视频没有 tag,只能靠标题里的实体词判断。「时政」这个词在 B 站被考公内容占着,真·国际时政得用实体词搜(见
docs/tag-tree.md) - 赞踩的学习很粗:只看 UP 和 tag,不看内容本身
- 越往后捞越靠近池子边缘。「更多电子榨菜」按互动率排队,不像首推那样经过模型
- 预设树里有些子簇的词不干净(带 UP 名或活动名),个别大区(科技 / 音乐)只挖出 1–2 个
- 没有端到端测试,只有
tools/里几个自检脚本
结构
| 文件 | 干什么 |
|---|---|
index.js |
host 半端:配置、HTTP 路由、池子落盘、策展接线 |
client.js |
浏览器半端:罐子 + 面板 |
lib/bili.mjs |
B 站客户端:WBI 签名 / 搜索 / 详情 / 粉丝 / 投稿 / 字幕 |
lib/pool.mjs |
候选池:轴匹配、硬过滤、打分、按轴轮转 |
lib/tree.mjs |
轴树:内置 + 用户自己长的枝;子簇挖掘 |
lib/axis-presets.mjs |
30 根预设轴(工具生成,别手改) |
lib/tree-review.mjs |
让模型审子簇建议 |
lib/curator.mjs |
让模型挑片并写理由 |
lib/reasons.mjs |
写理由(API 直连 → 宿主模型兜底),带磁盘缓存 |
lib/usage.mjs |
token 记账 + 峰谷计价 |
lib/qr.mjs |
零依赖 QR 编码器 |
lib/statefile.mjs |
生成 STATE.md |
lib/hostdeps.mjs |
从宿主树里取 @deepseek-ai/* |
工具
node tools/why.mjs BV1xxxxx # 这条为什么没进罐子?逐关诊断
node tools/feed.mjs 10000 0 # 跑一次建池,打印片单
node tools/tree-suggest.mjs 历史 # 从池子里挖子簇建议
node tools/tree-review.mjs deepseek # 规则 + 模型审一遍(--apply 才写盘)
node tools/qr-check.mjs # QR 编码器与 Python qrcode 逐位比对
node tools/affinity-check.mjs # 赞踩加权的单测
node tools/pack-check.mjs # 发版前自检
python tools/cutout.py in.png out.png # 抠掉画在图里的棋盘格
python tools/sprites.py # 从设定表切走路帧
发版
pnpm check # 自检
npm version patch
git push --follow-tags
推 tag 会触发 .github/workflows/publish.yml 发 npm。细节在 docs/publish.md。
更新日志
0.2.5
- 头像多一张「走路」:拿原来那套两帧走路做的,页头 AI 的头像会动
- 装罐时列表底下那个小人也会迈步(同一套两帧),跟廊道里出门找的不是同一个
- README 顶图换成新的「出门找 → 满载而归」
0.2.4
- 每根轴自己决定看不看老内容(
freshness):按合格条目的年龄中位数判定,超过 90 天就算常青,设置里点一下就能改 - 冷门轴补货:按时长带重搜 + 从「相关推荐」做种子扩散。搜不到的老片能捞回来(实测「空洞骑士」从 0 条到 19 条)
- 加载动画改成「出门找 → 满载而归」:12 帧、底部廊道、一步一步走,角度和步幅都调小了
- 刷新时不再清空旧片单:旧卡片留在原位,走路动画表示正在更新
0.2.x
- 预设轴树 30 根 / 68 个子簇;子簇可以从池子里长,模型审过再采纳
- 前端重做:插画面板、装罐时走路、列表底部的小人、四档头像
- 赞踩参与打分;小窗播放;语气预设支持导入
.md - 修:峰谷按本机时区算(成本算成一半)、
/explain的 ReferenceError、/debug泄露 key、explainOn死开关、换头像不刷新页头、走路帧被裁掉背包、设置页打不开(漏声明)、头像上传被 64KB 限制挡住 - 安全:拒跨站请求、响应加
nosniff、凭证文件0600
0.1.0 第一版:按轴搜索、互动率打分、累积池、策展、扫码登录、记账。
许可
代码 MIT。插画(assets/jar-*.png / av-*.png / walk-*.png)由作者用豆包生成,随仓库提供,只用于这个插件的界面。「哦鲸鲸」那档头像取自 dsh-whale-widget(MIT),详见 NOTICE。
链接
同类插件
PC2005-cloud/dsh-pet#dsh-pet★ 3496
DSH Web UI 桌面宠物:25 个透明动画、屏幕漫游、点击反应与拖拽,附可复现的素材生成链。
Nagi-ovo/dsh-ads★ 682
2005 年中文站点风格的整活广告插件:侧栏广告/信息流/角落弹窗 + 假关闭叉,素材全虚构。
vlln/whale-girl★ 375
桌面宠物(QQ 宠物形态):右下角悬浮、可拖拽/投喂/玩耍。
yyh-001/dsh-meme★ 295
聊天表情包:纯文本斗图、情绪主动发图、像 QQ/微信 一样发图、AI 自动学图、自定义表情包。
a86582751/dsh-nexttavern★ 191
NextTavern 是面向 DeepSeek Harness 0.1.7-rc.2 Web 的长篇角色扮演插件,支持角色卡导入与创作、世界线、世界书、分层长期记忆、关键词/语义/混合检索、角色 Agent,以及角色卡或小说导出;支持 SillyTavern 角色卡导入,v0.2.9 修复分发与安装问题。
Sutera-Diffusus/dsh-whale-musume★ 156
鲸鱼娘桌宠:45 项成就、每日任务与周签到、三个小游戏、92 张立绘、620 条台词、成长日记、天气与节日反应、按工具类型切换工作姿态、跨端存档导出/导入(JSON 文件或迁移码)、无障碍模式,以及可选的 MiMo TTS 台词播报。数据只存放在宿主 localStorage,无遥测;已在 DSH 桌面端 0.2.0-rc.2 验收,兼容 0.2.1-rc.1/rc.2 与旧版 0.1.x Web。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。