派子代理替你刷B站,挑好内容再回来汇报
30.7/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Azurehzh/dsh-biliforwake-subagent该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · tool
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 127 处,展示前 92 条)
- 读取本地文件index.js:277
try { myVer = String(JSON.parse(readFileSync(join(pluginDir, 'package.json'), 'utf8')).version || '') } catch { myVer = '' } - 读取本地文件index.js:286
if (existsSync(win)) return win - 读取本地文件index.js:289
for (const d of readdirSync(lib)) { - 读取本地文件index.js:292
if (existsSync(p)) return p - 读取本地文件index.js:298
try { return readdirSync(sitePkgs(venvRoot)).some((n) => n.startsWith(prefix)) } catch { return false } - 读取本地文件index.js:300
const venvReadyNow = () => existsSync(venvPython()) && hasPkg(join(stateDir, '.venv'), 'bilibili_api') - 写入本地文件index.js:304
mkdirSync(outDir, { recursive: true }) - 写入本地文件index.js:308
try { appendFileSync(logFile, line + '\n', 'utf8') } catch { } - 写入本地文件index.js:722
if (level !== 'off') { try { appendFileSync(reportFileOf(), '\n\n---\n\n' + output + '\n', 'utf8') } catch {} } - 写入本地文件index.js:740
try { mkdirSync(笔记夹, { recursive: true }) } catch (e) {} - 请求外部主机api.bilibili.comindex.js:752
const vr = await fetch('https://api.bilibili.com/x/web-interface/view?bvid=' + m[1]) - 发起网络请求index.js:752
const vr = await fetch('https://api.bilibili.com/x/web-interface/view?bvid=' + m[1]) - 写入本地文件index.js:758
writeFileSync(路径, '# ' + m[1] + String.fromCharCode(10, 10) - 删除本地文件index.js:1977
if (!文本) { unlinkSync(路径); continue } - 删除本地文件index.js:1981
unlinkSync(路径) - 删除本地文件index.js:1987
unlinkSync(路径) - 删除本地文件index.js:1992
unlinkSync(路径) - 写入本地文件index.js:2038
const appendInstall = (s) => { try { appendFileSync(installLogFile, s, 'utf8') } catch { } } - 执行外部命令固定命令index.js:2045
const c = spawn('uv', ['--version'], { windowsHide: true, stdio: 'ignore' }) - 执行外部命令来自配置/变量index.js:2059
const c = spawn(cmd, ['--version'], { windowsHide: true, stdio: 'ignore' }) - 执行外部命令来自配置/变量index.js:2068
try { c = spawn(cmd, args, { cwd: stateDir, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'], env: pyEnv() }) } - 执行外部命令来自配置/变量index.js:2114
c = spawn(cmd, args, { cwd: stateDir, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'], - 请求外部主机www.bilibili.comindex.js:2248
const r = await fetch(目标, { headers: { referer: 'https://www.bilibili.com/' } }) - 发起网络请求index.js:2248
const r = await fetch(目标, { headers: { referer: 'https://www.bilibili.com/' } }) - 执行外部命令来自配置/变量index.js:2475
try { child = spawn(cmd, args, { detached: true, stdio: 'ignore' }) } catch (e) { resolve(String(e?.message ?? e)); return } - 发起网络请求client.js:45
const jget = async (p) => asJson(await fetch(API + p, { credentials: 'same-origin' })) - 发起网络请求client.js:46
const jpost = async (p, body) => asJson(await fetch(API + p, { - 写入剪贴板client.js:374
await navigator.clipboard.writeText(v) - 写入剪贴板client.js:546
onClick: () => navigator.clipboard.writeText(更新命令).then(() => setMsg('命令已复制')).catch(() => setMsg('复制不了,手动选中吧')), - 发起网络请求client.js:1100
fetch(API + '/cards', { credentials: 'same-origin' }) - 读取本地文件lib/hostdeps.mjs:40
for (const n of readdirSync(join(npm, '@deepseek-ai'))) { - 读取本地文件lib/hostdeps.mjs:53
for (const p of readdirSync(join(dshHome, 'profiles'))) { - 读取本地文件lib/hostdeps.mjs:68
if (!existsSync(pkgFile)) return null - 读取本地文件lib/hostdeps.mjs:69
const pkg = JSON.parse(readFileSync(pkgFile, 'utf8')) - 读取本地文件lib/hostdeps.mjs:76
return existsSync(file) ? pathToFileURL(file).href : null - 读取本地文件lib/mcp.mjs:16
const PKG = (() => { try { return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) } catch { return {} } })() - 执行外部命令来自配置/变量lib/mcp.mjs:36
this.proc = spawn(command, args, { - 读取本地文件lib/verify.mjs:44
if (!existsSync(f)) return null - 读取本地文件lib/verify.mjs:46
const c = JSON.parse(readFileSync(f, 'utf8')) - 发起网络请求lib/verify.mjs:62
const r = await fetch(url, { headers }) - 读取本地文件lib/verify.mjs:120
if (!existsSync(seenFile)) return { checked: [], skipped: 0, text: '⚠️ 判重表还没生成,没什么可复核的' } - 读取本地文件lib/verify.mjs:124
const rows = parseSeen(readFileSync(seenFile, 'utf8')) - 读取本地文件lib/verify.mjs:130
try { state = JSON.parse(readFileSync(stateFile, 'utf8')) } catch { } - 写入本地文件lib/verify.mjs:152
try { writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8') } catch { } - 读取本地文件lib/verify.mjs:168
if (!existsSync(f)) return null - 写入本地文件lib/verify.mjs:169
writeFileSync(f, readFileSync(f, 'utf8').replace(/ *$/, '') + '\n' + text + '\n', 'utf8') - 写入本地文件lib/state.mjs:47
mkdirSync(dir, { recursive: true }) - 读取本地文件lib/state.mjs:52
try { return JSON.parse(readFileSync(file, 'utf8')) } catch { return fallback } - 写入本地文件lib/state.mjs:56
writeFileSync(file, JSON.stringify(value, null, 2), 'utf8') - 读取本地文件lib/state.mjs:67
if (!existsSync(from)) { log(`缺文件:${from}`); continue } - 读取本地文件lib/state.mjs:68
if (!overwrite && existsSync(to)) continue - 读取本地文件lib/state.mjs:69
if (overwrite && existsSync(to) && readFileSync(from, 'utf8') === readFileSync(to, 'utf8')) continue - 读取本地文件lib/state.mjs:69
if (overwrite && existsSync(to) && readFileSync(from, 'utf8') === readFileSync(to, 'utf8')) continue - 写入本地文件lib/state.mjs:70
copyFileSync(from, to) - 读取本地文件lib/state.mjs:82
try { if (existsSync(home)) return home } catch { } - 写入本地文件lib/state.mjs:110
writeFileSync(home, newText, 'utf8'); writeFileSync(ledger, hShip, 'utf8') - 写入本地文件lib/state.mjs:116
if (hLast !== hShip) writeFileSync(ledger, hShip, 'utf8') - 写入本地文件lib/state.mjs:121
writeFileSync(fresh, newText, 'utf8') - 发起网络请求lib/login.mjs:45
const r = await fetch(SPI, { headers: { 'User-Agent': UA } }) - 发起网络请求lib/login.mjs:54
const r = await fetch(GEN, { headers: { 'User-Agent': UA } }) - 发起网络请求lib/login.mjs:63
const res = await fetch(pollUrl(key), { headers: { 'User-Agent': UA }, redirect: 'manual' }) - 写入本地文件lib/login.mjs:79
mkdirSync(stateDir, { recursive: true }) - 写入本地文件lib/login.mjs:81
writeFileSync(file, JSON.stringify({ - 写入本地文件lib/login.mjs:93
try { chmodSync(file, 0o600) } catch { } - 写入本地文件lib/login.mjs:103
const w = (s) => { try { writeFileSync(diag, s) } catch {} } - 执行外部命令来自配置/变量lib/login.mjs:106
child = spawn(pythonPath || 'python', ['-c', code, url, png], { cwd: stateDir, windowsHide: true }) - 读取本地文件lib/login.mjs:114
w(`exit=${c}\npythonPath=${pythonPath}\npng=${png}\npngExists=${existsSync(png)}\nstderr=${err || '(空)'}`) - 读取本地文件lib/login.mjs:115
if (c === 0 && existsSync(png)) resolve(png); else resolve(null) - 读取本地文件lib/uvfetch.mjs:33
return createHash('sha256').update(readFileSync(file)).digest('hex') - 发起网络请求lib/uvfetch.mjs:45
const r = await fetch(source.url + '.sha256') - 读取本地文件lib/uvfetch.mjs:55
try { entries = readdirSync(dir, { withFileTypes: true }) } catch { return null } - 执行外部命令来自配置/变量lib/uvfetch.mjs:69
const r = spawnSync(cmd, args, { stdio: 'ignore' }) - 读取本地文件lib/uvfetch.mjs:83
if (existsSync(target)) return target - 写入本地文件lib/uvfetch.mjs:85
mkdirSync(dir, { recursive: true }) - 删除本地文件递归lib/uvfetch.mjs:87
rmSync(tmp, { recursive: true, force: true }) - 写入本地文件lib/uvfetch.mjs:88
mkdirSync(tmp, { recursive: true }) - 请求外部主机pypi.tuna.tsinghua.edu.cnlib/uvfetch.mjs:100
const r = await fetch('https://pypi.tuna.tsinghua.edu.cn/pypi/uv/json') - 发起网络请求lib/uvfetch.mjs:100
const r = await fetch('https://pypi.tuna.tsinghua.edu.cn/pypi/uv/json') - 发起网络请求lib/uvfetch.mjs:124
const res = await fetch(s.url) - 写入本地文件lib/uvfetch.mjs:126
await pipeline(Readable.fromWeb(res.body), createWriteStream(s.file)) - 读取本地文件lib/uvfetch.mjs:127
const mb = (statSync(s.file).size / 1048576).toFixed(1) - 写入本地文件lib/uvfetch.mjs:144
copyFileSync(hit, target) - 写入本地文件lib/uvfetch.mjs:145
try { chmodSync(target, 0o755) } catch { } - 执行外部命令来自配置/变量lib/uvfetch.mjs:147
const r = spawnSync(target, ['--version'], { stdio: 'ignore' }) - 删除本地文件递归lib/uvfetch.mjs:150
rmSync(tmp, { recursive: true, force: true }) - 删除本地文件递归lib/uvfetch.mjs:158
rmSync(tmp, { recursive: true, force: true }) - 读取本地文件lib/selfupdate.mjs:61
meta = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8')) - 发起网络请求lib/selfupdate.mjs:84
const res = await fetch(url, { - 删除本地文件递归selfcheck.mjs:45
try { rmSync(SANDBOX_HOME, { recursive: true, force: true }) } catch { } - 写入本地文件selfcheck.mjs:46
mkdirSync(SANDBOX_HOME, { recursive: true }) - 读取本地文件selfcheck.mjs:58
const pkg = JSON.parse(readFileSync('./package.json', 'utf8')) - 删除本地文件递归selfcheck.mjs:118
try { rmSync(SANDBOX_HOME, { recursive: true, force: true }) } catch { }
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:api.bilibili.com、www.bilibili.com、pypi.tuna.tsinghua.edu.cn
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/dsh-tools给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成dsh-bili-subagent | 刷 B站(子代理版)
让你的 AI 伙伴自己去刷 B站,然后回来跟你说话。
插件不再自己「跑一轮然后写一份日报给你看」——它只负责派一个子代理去看,子代理读字幕、翻评论、挑出值得的,写一份给伙伴看的内部报告;再由你的伙伴(你自己的 AI)用自己的口吻决定怎么告诉你:公开评论只写一两句勾人,私信可以详细。
本仓库是 c1overzz/dsh-bili-scroll 的改版(fork),基于它的 0.1.10,沿用 MIT 许可并保留原作者署名与 LICENSE。感谢原作者把底子打好。
它现在怎么干活
到点(或你点「现在跑一轮」) ↓ 插件往「你指定的那个会话」里塞一句(文案可在设置页改):到谷时啦,去 B 站刷一轮吧~ ↓ 你的伙伴看到这句 → 调 bili_scan → 插件派出一个子代理 ↓ 子代理只负责「看」:搜视频 → 扫标题 → 看简介 → 读整段字幕 → 翻评论区 ↓ 交回一份内部报告(标题 / BV号 / 讲了什么 / 为什么值得 / 评论区反响) ↓ 伙伴按设置决定怎么告诉你:评论 @ 你 / 私信你 / 两个都发
报告同时追加写入 <DSH_HOME>/bili-duty/out/<日期>.md,想回看随时能翻。
展开完整文档(README 剩余 1 节)
dsh-bili-subagent | 刷 B站(子代理版)
让你的 AI 伙伴自己去刷 B站,然后回来跟你说话。
插件不再自己「跑一轮然后写一份日报给你看」——它只负责派一个子代理去看,子代理读字幕、翻评论、挑出值得的,写一份给伙伴看的内部报告;再由你的伙伴(你自己的 AI)用自己的口吻决定怎么告诉你:公开评论只写一两句勾人,私信可以详细。
本仓库是 c1overzz/dsh-bili-scroll 的改版(fork),基于它的 0.1.10,沿用 MIT 许可并保留原作者署名与 LICENSE。感谢原作者把底子打好。
它现在怎么干活
到点(或你点「现在跑一轮」) ↓ 插件往「你指定的那个会话」里塞一句(文案可在设置页改):到谷时啦,去 B 站刷一轮吧~ ↓ 你的伙伴看到这句 → 调 bili_scan → 插件派出一个子代理 ↓ 子代理只负责「看」:搜视频 → 扫标题 → 看简介 → 读整段字幕 → 翻评论区 ↓ 交回一份内部报告(标题 / BV号 / 讲了什么 / 为什么值得 / 评论区反响) ↓ 伙伴按设置决定怎么告诉你:评论 @ 你 / 私信你 / 两个都发
报告同时追加写入 <DSH_HOME>/bili-duty/out/<日期>.md,想回看随时能翻。
和上游(dsh-bili-scroll)的区别
| | 上游 | 本版 |
| 谁去刷 | 插件自己起一个 headless dsh 会话 | 你的伙伴派一个子代理 |
| 花谁的钱 | 那一轮用的模型(默认官方) | 可指到便宜/免费的中转,不占官方额度 |
| 结果给谁 | 写日报文件,插件自己发评论 | 写内部报告给伙伴,伙伴自己决定怎么说 |
| 说给谁听 | 只有公开评论 | 评论 @ / 私信 / 两个都发 |
| 在哪儿发生 | 固定的 headless profile | 你指定哪个会话,就在哪个会话里聊 |
| 改提示词 | 改 prompts/duty.md 文件 | 设置页里直接编辑 |
| 本地转写 | 有(要装 Whisper,约 1 GB) | 已移除 |
| 回楼中楼 | 插件自动替你回(人机味) | 把 @ 和回复递给你的伙伴,让伙伴自己回 |
| 检查更新 | 有 | 有(设置页点一下,查自己的仓库) |
| 子代理记录 | 会清理 | 全留着,以后能回看当时刷了什么 |
本版加了什么(相对上游)
- ⭐ 派子代理去刷:刷站的不再是插件,而是你的伙伴派出去的一个子代理 —— 看和说彻底分开
- ⭐ 挑什么样的(两道硬门槛):最低播放量、至少发布几天。不达标的视频在搜索那一步就被滤掉,子代理根本看不到;有门槛时会自动多抓几倍再筛,免得筛完一条不剩
- ⭐ 投递方式自己选:评论 @ / 私信 / 两个都发;两者都开时,这一轮没发评论就发不出私信
- ⭐ 自动刷在哪个会话:到点只往你选的那个会话说一句,能看着它干活、也能接着追问
- 子代理的模型可换:provider + 模型联动下拉,指到免费中转就不花官方额度
- 提示词全在面板里改:称呼 + 子代理流程,支持 {owner} {direction} {n} 占位符,改完不用重启
- 额度口径明确:每天最多自动刷几轮,面板显示「今天已自动刷 X / N 轮」—— 手动跑不占额度
- 12 个工具:bili_scan(主入口)bili_search bili_subtitle bili_comments bili_reply bili_send_message bili_status bili_config bili_whoami bili_login_start bili_login_poll bili_setup
- 删掉的:本地转写(约 1 GB)、headless/overlay、工作区、关注关键词、上游的群答疑与 tools/ 开发脚本
- 修掉的:DSH 原生设置下「改了又弹回去」、/config 白名单丢字段、pythonPath 落成 python 导致二维码画不出
自动刷是怎么触发的
编排器每 60 秒看一次表,几件事同时成立才跑:
1. 自动刷时段不是「只手动」(三档:只手动 / 只在谷时 / 全天都跑)
2. 今天自动刷的轮数 < 每天最多自动刷几轮
3. 「只在谷时」时,现在得落在某个窗口里:中午 12:00–14:00 或 夜间 18:00–09:00;整个周末整天都算谷时(「全天都跑」不看这条)
4. 离上一轮已经隔够 两轮之间至少隔几分钟(默认 180 分钟 = 3 小时)
举例:设「每天 5 轮」「间隔 180 分钟」,晚上那一轮会这样走 ——
18:00 → 21:00 → 00:00 → 03:00 → 06:00 (5 轮用完就停)
想跑得密(比如周末狂刷):把间隔调到 5 分钟、每天轮数调到 50 —— 一分钟一跳的表照样能一轮接一轮地来。
⚠️ 没投出去不算数:目标会话没醒着、或者派子代理失败,这一轮的额度会退回去,下一个周期还能重试。
装之前(一条前提,30 秒)
机器上要有 Python 3.10+ 或 uv —— 有一个就够:
- 有 uv 最好:单文件、解压就能用、不用管理员、不用进 PATH;
- 都没有也没关系:点「装主依赖」时插件会自己下一份 uv 到自己的家目录(免管理员),先直连 GitHub,不通走国内加速,下载完核对官方 sha256;
- ⚠️ 杀软报这个下载:把 %USERPROFILE%\.dsh\bili-duty\bin\ 加白;不想加白就自己装一份 uv 或 Python 3.10+。
需要 DSH ≥ 0.1.7-rc.1。版本不满足时内核会静默跳过这个插件(装了跟没装一样,不报错)。
装
在 DSH 里:设置 → 插件 → 安装,填这一行;或者命令行:
github:Yuuyuko-uu/dsh-bili-subagent
dsh plugin --profile desktop add github:Yuuyuko-uu/dsh-bili-subagent
本版暂未发布到 npm(账号还在等),所以先用 GitHub 地址装。
上架之后就能简写成 dsh plugin add dsh-bili-subagent。
⭐ 最省事的一条:把仓库链接贴给你自己的 dsh,说「帮我装这个插件」。
⚠️ 装完必须重启一次 dsh(插件在 bundle 层组装,不重启不生效)。然后进 设置 → 刷B站。
装完起不来?先看这个
如果 DSH 弹「The application could not start」,错误里有 Unexpected token ''、is not valid JSON、 readProfileManifest —— 那是 profile 的 package.json 被存成了 UTF-8 带 BOM。
跟插件无关:内容都是对的,只是开头多了三个看不见的字节,DSH 读它就崩。
先找出来(不同装法位置不一样,别猜 —— 真正的 profile 目录里同时有 cordis.yml、cordis.patch.yml、package.json;机器上别处那些同名的都不算):
Get-ChildItem C:\,D:\,E:\ -Directory -Filter profiles -Recurse -Depth 4 -ErrorAction SilentlyContinue |
ForEach-Object {
Get-ChildItem $_.FullName -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$p = Join-Path $_.FullName 'package.json'
if ((Test-Path (Join-Path $_.FullName 'cordis.patch.yml')) -and (Test-Path $p)) {
$b = [System.IO.File]::ReadAllBytes($p)
$bom = ($b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF)
"{0} BOM={1}" -f $p, $bom
}
}
}
输出里 BOM=True 的那一行,就是要修的文件(标准安装在 C:\Users\<你>\.dsh\profiles\<档名>\package.json)。
去掉 BOM(路径换成上面那一行):
$p = "把上面 BOM=True 那一行的路径粘到这里"
[System.IO.File]::WriteAllText($p, [System.IO.File]::ReadAllText($p), (New-Object System.Text.UTF8Encoding($false)))
然后重启 DSH 就好,数据一点没丢。实在进不去时,那个错误框里的 「Disable third-party plugins, back up profile patch, and restart」 能先起来,再一个个开回去定位。
⚠️ 手动改 profile 里的文件,一律存 UTF-8 无 BOM。让 AI 帮你改时,别让它用 Set-Content -Encoding UTF8 或 Out-File -Encoding utf8(Windows 自带的这两个默认带 BOM)。
更新到最新版
最省事:把这个仓库的地址丢给你自己的 DSH,说「帮我更新这个插件」。装完重启一次 DSH。
也可以点 设置 → 刷B站 最上面的「检查更新」 —— 有新版会提示,还能一键复制更新命令。
命令行(--profile 照你平时那个写,桌面端一般 desktop、网页端 web):
dsh plugin --profile desktop remove dsh-bili-subagent
dsh plugin --profile desktop add github:Yuuyuko-uu/dsh-bili-subagent
⚠️ 必须先卸再装:直接装可能拿到缓存里的旧副本,装完还是老的。
⚠️ 装完重启一次 DSH才会用新代码。
我的设置会不会丢?
不会。 设置存在 DSH 家目录(%USERPROFILE%\.dsh\)里,不在插件代码里;卸载只删代码:
.dsh\bili-duty\config.json (还有 state.json、B站登录凭证)
所以卸载 → 重装,刷视频的设置、每天刷了几轮、B站登录状态 都还在。
三件小事提醒:
- 别用「重装 DSH」来更新插件 —— 那是两件事,重装可能动到 profile。
- 新版本新加的设置项会用默认值(以前没这一项),想要自己的值就再填一次。
- 设置项改名/换单位时(比如「隔几小时」→「隔几分钟」)会自动换算,不用你管。
首次使用(两步)
1. 装主依赖 —— 设置页点「装主依赖」:在插件自己的家目录建独立 venv,装 bilibili-api-python / aiohttp / mcp<2 / qrcode。走国内镜像,通常几十秒(进度写 install.log)。
2. 扫码登录 —— 点「扫码登录」,用手机 B站 扫。
⚠️ 确认时选「记住我 / 长期」,选 24 小时的话明天就得重扫。
凭证只落在本机:<DSH_HOME>/bili-duty/bili_credential.json,不上传任何地方。
设置页里有什么
| 区块 | 说明 |
| 什么时候自己跑 | 三档:只手动 / 只在谷时 / 全天都跑。「只在谷时」时会展开「中午谷时 12:00–14:00」「晚上/夜间谷时 18:00–09:00」两个勾选框;只要是自动(不是只手动),下面还有一个两轮之间至少隔几分钟(默认 180,最少 5、最多 720)。按这个节奏一轮一轮轮转,跑到「每天最多自动刷几轮」用完为止;手动跑不受间隔限制。谷时口径依据 DeepSeek 定价:工作日 9:00–12:00、14:00–18:00 是高峰,其余(含整个周末)都是谷时 |
| 派子代理刷的模型 | 选服务商 + 模型(联动下拉,选中即存)。默认「跟当前会话一样」;也可以指到免费或便宜的中转,那样就不花官方额度的钱 |
| 自动刷在哪个会话 | 到点时往哪个会话里递话。不选 = 自动挑最近聊过的那个;连一个都没有才临时新建(用完自动释放) |
| 提示词(可改) | 四段都能自己写,留空都 = 用内置默认:① 子代理提示词(派出去的子代理看;{owner} {direction} {n});② 投递提示(报告交回时附给伙伴看,告诉它怎么发评论/私信;{owner} {mention} {commentQuota} {uid} {commentBlock} {dmBlock});③ 自动刷触发语(到点塞进目标会话的那一句;{owner});④ 评论怎么写(发公开评论时照它写;{owner} {mention} {quota} {style} —— {style} 每次从几种口吻里随机挑一种,省得每条都一个调门)。「称呼」改了,四段里的名字一起变 |
| 一轮挑几条 | 每次最多挑几条(1–10)。和「每天最多自动刷几轮」是两件事 |
| 挑什么样的 | 两道硬门槛:最低播放量、至少发布几天。不达标的视频在搜索那一步就被滤掉,子代理根本看不到(0 = 不过滤);有门槛时会自动多抓几倍再筛,免得筛完一条不剩 |
| 它会不会替你说话 | 「自动评论并 @ 你」开关 + 每轮几条(0–20)+「要 @ 谁」(留空 = 不发评论);再往下是投递方式:只发评论 / 只私信 / 评论+私信 |
| 日报写多细 | 完整 / 薄 / 不写。薄只留「值不值得 + 链接」 |
| 有人找我就马上告诉你 | 默认关。开着之后隔一会儿问一句 B站:有人私信你、@ 你、回了你的评论,就立刻把内容递到伙伴手上,不用等下一轮刷。两个子开关(私信 / @ 和回复)、间隔 60–1800 秒、只在谷时 / 全天 |
| 环境与账号 | 装主依赖、测一下、扫码登录 |
| 它的地盘 | 插件家目录、今天的报告、打开文件夹 |
设置同时落在两处:插件自己的 config.json 和 DSH 原生「插件设置」。
以设置页(DSH 原生那层)为准——那才是真正生效的值。
12 个工具
| 工具 | 干什么 |
| bili_scan | 主入口:派一个子代理去刷,拿回内部报告 + 投递提示 |
| bili_search | 搜视频(可排序) |
| bili_subtitle | 取 AI 字幕全文(判断内容就靠它) |
| bili_comments | 取热门评论 |
| bili_reply | 在视频下发评论(@ 就是写在正文里的纯文本) |
| bili_send_message | 发私信 |
| bili_status | 今天跑了没、挑了几条、额度剩多少、下次什么时候开 |
| bili_config | 读 / 改设置(不用开设置页) |
| bili_whoami | 看登录的是谁 |
| bili_login_start / bili_login_poll | 扫码登录 |
| bili_setup | 建 venv、装依赖 |
投递方式:评论 / 私信 / 都要
- 只发评论(默认):在挑中的视频下面留一条很短的评论,@ 你填的那个人 —— 别人也看得到,所以只说一个点、不带私事。
- 只私信:一条公开评论都不发,最不打扰别人。私信内容可以详细(实测 500 字符就顶,别太长)。
- 评论 + 私信:两边都发。
⭐ 两者都开时,有一道硬闸:这一轮还没发评论就发不出私信(会被顶回去让你先评论)。
因为实测模型会习惯性跳过评论、只顾着发私信。评论"调过就算"(失败也解锁),不会把伙伴卡死。
⚠️ B站 对「陌生人私信」会限流、可能不弹提醒 —— 建议先让两边互关。
有人找我就马上告诉你
平时要等到谷时刷那一轮,才知道有没有人 @ 你、私信你 —— 中间那几个小时就干等着。
开了这个(默认关),它会隔一会儿问一句 B站:有新消息就立刻把「谁、说了什么、哪条视频」递到伙伴手上。
- B站 没有推送接口(没有 webhook、也没有回调地址),所以「马上」只能是定时去问。
默认 120 秒问一次,最短 60 秒 —— 再勤就有被 B站 限流的风险(那边会返回 -412 或者让你验证)。
- 问得省:先问一个「未读数」(一个请求、几百字节),数字变了才去读具体是谁说了什么。
没消息的时候就是一句数字,不会把私信列表全拉一遍。
- 只在谷时 / 全天:默认只在谷时问(高峰时段把会话叫醒比较贵)。
- 同一条只递一次:私信记在插件家目录的 watch.json,@ 和回复跟「每轮顺手看一眼」共用 inbox.json 的账,两条路不会把同一件事提两遍。
- 这是通知,不是代回:回不回、怎么回、要不要看那条视频,仍然由伙伴自己决定。
- 关着的时候一个请求都不发;出错会退避(隔三倍间隔再试),不会一直撞。
费用
- 子代理走你选的那个模型:指到免费/便宜的中转,这一轮就不花官方额度的钱。
- 自动刷默认只在谷时触发(也能选「全天都跑」,那就是高峰时段也花);「每天最多自动刷几轮」填 0 = 不自动跑,只手动跑。
- 手动「现在跑一轮」不占额度。
- ⚠️ 已知小缺陷:自动刷的额度在触发那一刻就 +1,那一轮失败也占额度。
- 改设置不影响 DSH 的前缀缓存,不额外花钱。
红线(写死在提示词里)
- 不透露你的隐私:账号、机器路径、聊过的内容 —— 一个字都不进评论
- 公开评论极短、只说一个点;不带私事、不刷屏、不吵架
- 不确定的事不编(报告里如实写「没查到」)
- 没字幕的视频直接跳过,不硬编内容
装不上 / 用不顺时
1. 设置页里根本不出现「刷B站」 —— 多半是 DSH 版本不满足(静默跳过),或插件没重启。先确认版本,再重启一次。
2. 扫码时一直不出二维码 —— 家目录里 pythonPath 落成了 python。
设置页点一次「装主依赖」,它会自动指回插件自己的 venv。
3. 「自动刷」没动静 —— 看 duty.log:如果写着「目标会话现在没醒着」,先去那个会话里说句话,让它醒着。
4. uv 下载不动 —— 自己放一份 uv.exe 到 <家目录>\bin\,插件会用那一份,跳过下载。
5. 想更新到新版 —— 设置页最上面的「检查更新」会给一条现成的命令,照着跑,完了重启一次 dsh。
如果你是 AI 助手,正在帮用户装这个插件
1. 先确认机器上有 Python 3.10+ 或 uv(python --version / uv --version);都没有就先装 uv。
2. 装插件:dsh plugin --profile desktop add github:Yuuyuko-uu/dsh-bili-subagent。
3. ⚠️ 提醒用户重启一次 dsh,不重启插件不生效。
4. 重启后进 设置 → 刷B站:先「装主依赖」,再「扫码登录」(确认时选「记住我 / 长期」)。
5. 不要替用户开「自动评论并 @ 你」——那是拿用户的号公开说话。要用也得用户自己填「要 @ 谁」。
依赖与致谢
- 内置 bilibili-mcp(MIT,Copyright (c) 2026 AGI_Ananas)——搜索 / 字幕 / 评论 / 发评论这些能力来自它;本插件只做「挑什么、什么时候挑、要不要说话」这一层。
- 本仓库的底子是 c1overzz/dsh-bili-scroll(MIT)。
- 需要本机 Python 3.10+(用 uv 或 python -m venv 建独立环境);mcp 必须锁 <2。
许可证
MIT(内置的 vendor/bilibili-mcp/ 另见该目录下的 LICENSE)。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Azurehzh/dsh-biliforwake-subagent
派子代理替你刷B站,挑好内容再回来汇报
相关插件 · 工具 / 效率
破甲管控台kingcharleslzy-ai/dsh-purge
dsh-purge Community · DeepSeek Harness 社区维护版:宿主兼容、状态诊断、提示词管理、更新与本机备份回滚。基于小杨 / YuJunZhiXue 的 dsh-purge。
★ 4,330已汉化DeepSeek 客户端
74.5
网文长卷lingfengQAQ/webnovel-writer
基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200…
★ 7,636已汉化DSH
72.2
多智能体协作HKUDS/AutoSwarm
AutoSwarm: Unify Your Agents. Unify Your Context (Codex · Claude Code · DeepSeek Harness · Muse · Grok · WorkBuddy· nanobot · and more)
★ 2,349已汉化DSH
71.6
Vox 拼贴视频生成Alisa0808/vox-director
🎬 Vox Director拼贴动效导演
★ 2,129已汉化DSH
71.4
Agent 演化引擎Q00/ouroboros
智能体 OS:智能体自己变聪明,我们只守住底线:面试准入、分阶段评估、带预算的进化循环。MCP 服务器,14 种运行时:Claude Code、Codex CLI、Gemini CLI、OpenCode、Copilot、Kiro 等。
★ 6,311已汉化DSH
71.4
智能体运行框架路由HarnessRouter/harnessrouter
智能体 harness 的统一接口。
★ 3,984已汉化DSH
71.3
这是你的仓库?认领条目