DeepSeek Harness Hub
← 全部攻略

余额鲸鱼挂件技术拆解:bundle 挂载、mtime 热读取与定点记账内核

UI / 主题类文章2026/9/21 发布0 次阅读

余额鲸鱼挂件技术拆解:bundle 挂载、mtime 热读取与定点记账内核

DSH 插件里多数挂件只做一件事:往界面塞一个面板。MeteorNOX/DeepSeek-Balance-Whale-Widget(包名 dsh-whale-widget,作者 MeteorNOX,首页 2,689 star)同时管住三样生命周期完全不同的东西:一个悬浮角色、一套持续写入的账本、21 条由宿主提供的 HTTP 路由。它们不在同一层,实现方式值得拆开看。

一、它是一个标准 DSH bundle 插件

关键在 package.json 的一行声明:dsh.bundle.patch 指向 cordis.patch.yml。这决定了它的身份——不是独立进程,也不是要你自己挂脚本的扩展。bundle 插件的含义是:宿主按声明加载它,路由由宿主托管,前端资源由宿主分发;挂件本身不监听端口、不起服务,只往宿主里补一组能力与一组路由。运行环境也随之确定:Web UI 需 Node.js 22.19 及以上,并需 pnpm 可用。


dsh plugin --profile web add dsh-whale-widget      # 方式 D,npm 已发布版,推荐

dsh plugin --profile web add github:MeteorNOX/DeepSeek-Balance-Whale-Widget

dsh plugin --profile web remove dsh-whale-widget

装完必须重启 dsh web,再 F5 刷新浏览器。很多人第一次看不到鲸鱼,就是只刷了浏览器、没重启宿主。

二、目录结构就是架构图


dsh-whale-widget/

├── package.json              # bundle 元数据(dsh.bundle.patch → cordis.patch.yml)

├── cordis.patch.yml          # 插件挂载声明

├── lib/index.js              # 宿主侧本体(路由 + 记账 + 音效/图片/角色服务)

├── lib/accounting.mjs        # 记账内核(定点金额运算 + 余额观测/校正账本)

├── assets/whale-widget.js    # 前端挂件本体(宿主按 mtime 热读取)

└── whale-widget-prompt.md    # 完整规格/维护提示词

宿主侧与前端被切成两半:lib/ 归宿主,assets/ 归浏览器。这不是随手分的目录,而是两套不同的生效规则。

三、cordis.patch.yml:挂载声明也决定改动面

cordis.patch.yml 是插件的入口声明,宿主启动时按它把能力接进来。所以「装没装上」的标准答案不是看页面有没有鲸鱼,而是看宿主配置里有没有这条记录:


dsh --profile web --dump-config | Select-String -Pattern "whale"

匹配到 dsh-whale-widget,说明挂载已进宿主配置;匹配不到,前端怎么刷都不会有东西出来。这份声明也是升级时的改动面:旧的手动安装会留下自己的补丁段,与新声明并存时,冲突出现在最不直观的地方。

四、前端按 mtime 热读取

assets/whale-widget.js 由宿主按 mtime 热读取——不把这份 JS 缓存死,而是看修改时间决定要不要重读。结果很干脆:只改前端,硬刷新(Ctrl+F5)即生效;改了宿主 lib/index.js,必须重启 dsh web。

这条分界线把「我改了怎么没反应」拆成两种处理方式。同源现象是:手机上拖不动鲸鱼时,正确动作不是研究触摸逻辑,而是先硬刷新拿到最新 whale-widget.js

五、为什么记账内核必须用定点金额运算

lib/accounting.mjs 做两件事:定点金额运算,以及余额观测/校正账本。金额为什么不能用普通浮点数?因为这是一个只做加法、且永不停止的场景。

余额下降被观测为消费,观测每 60 秒一次,一天 1440 次,一个月四万多次。浮点误差在这个量级上会以肉眼可见的方式漂出来:你看到的「今日已用」可能和手算对不上,而且偏移方向还不固定。对账本来说,这比「精度不够」更糟——它意味着数据不可复核。

所以金额按 8 位小数记账,显示保留两位。计量口径也在这一层定死:额度已用按 DSH 会话 token 累计,口径为 input + cacheRead + output,推理 token 已含在 output 内,跨天保留。

六、账本模型:观测、累计与校正

记账思路朴素,但边界清楚:余额下降按观测差额累计为消费;余额上升单独记录为充值/赠金,不冲掉已有消费;余额增加时提示「待核对余额调整」,可在「小鲸鱼记账 → DeepSeek(内置)→ 设置 → 余额校正」按实际到账金额校正。

第三条是关键。余额接口只返回快照、不提供充值流水;当充值与消费落在同一次刷新间隔内,两个快照解不出中间发生了什么,必须由人给出实际到账金额。所以它不猜,而是明确标注「这里需要核对」。这也解释了高频疑问:充值后消费数字没变是预期行为,充值不增加消费,只会在数字上方出现「待核对余额调整」。

数据保留同样写在账本层:逐轮明细 90 天或最多 2 万条,逐日归档 365 天,超期归档到 .dshw-usage-archive.json;写入是原子的,且 0.3.1 首次写入旧账本前会自动创建迁移备份(已存在则不覆盖)。

还有一条容易混淆的边界:账本里「已观测消费」与「余额校正」都是 DeepSeek 账户口径、不含其它厂商,「本机模型费用」才是所有模型的本地估算。这解释了「今日已用显示 --」为什么正确:统计从第一次成功的余额观测开始,起点之前的消费不在区间内。

七、21 条路由与信任栅栏

挂件暴露 21 条 /dsh-whale/ 路由,全部接入 DSH 浏览器信任栅栏(connection.requestRejection):不带会话凭据的裸 curl 返回 401,伪造 Host 头返回 403,浏览器内带会话访问才是 200。

这个设计容易被误读。在浏览器外 curl /dsh-whale/balance.json 拿到 401,第一反应往往是「接口坏了」。恰恰相反:401/403 说明路由已注册、栅栏在工作;真坏了的表现是这条路由不存在。这一个前缀下装的东西并不轻——余额、外观配置、前端 JS、音效分组都在其中,读写的又是本地账本与角色/音频目录,属于本机敏感范畴。

八、取舍:三条边界各归其位

宿主负责边界,内核负责正确,前端负责体验。边界交给 DSH(挂载声明、路由托管、信任栅栏);正确性收在 lib/accounting.mjs(定点、校正、归档、原子写);可玩性留在 assets/whale-widget.js,改它不碰账本。代价是生效规则变成两条:改前端硬刷新,改宿主重启。对一个既要长期记账、又要频繁调样式的挂件来说,这个代价划算。

想看它落到真实工作流里的样子,https://dpharness.com/top 的插件库里有完整入口,MeteorNOX/DeepSeek-Balance-Whale-Widget 的详情页也在其中。

多厂商余额统一看板实践:把 DeepSeek、OpenRouter、Kimi、智谱装进一只鲸鱼

我的 AI 支出原本是散的:DeepSeek 在官网看,OpenRouter 在后台看,Kimi 分大陆站与国际站两套账号,智谱的 Coding Plan 又是另一个页面。月底想回答「这个月花了多少」,得开四个标签页、换三种货币、手工加两遍。后来我用 MeteorNOX/DeepSeek-Balance-Whale-Widget(包名 dsh-whale-widget,首页 2,689 star)把这件事收进了一个悬浮看板。

一、先确认它活着,再谈配置

前提是 pnpm 可用,Web UI 需要 Node.js 22.19 及以上。然后:


dsh plugin --profile web add dsh-whale-widget

dsh --profile web --dump-config | Select-String -Pattern "whale"

第二条命令是分水岭:匹配得到 dsh-whale-widget,说明挂载已进宿主配置;匹配不到,前端怎么刷都不会有东西出来。确认后重启 dsh web,再 F5。

二、DeepSeek 只需要一个凭据

必需凭据只有一个 DEEPSEEK_API_KEY(用来拉余额),在 DSH 凭据服务里配。容易被旧教程带偏的是 DEEPSEEK_PLATFORM_TOKEN——不需要,早期「实时·令牌」模式已下线,今日已用统一由小鲸鱼记账计算。另有一条设计值得注意:密钥不落配置文件,配置文件里只存凭据名(如 OPENROUTER_API_KEY)。

三、加厂商像点菜:34 个模板

点开自定义 API,有 34 个厂商模板。选完会自动带好凭据名、币种、接口、字段路径、事件匹配与探活地址,多数厂商就是「选一下、填个 key」。

能直接查到余额或额度的这一组我全接了:DeepSeek(内置)、OpenRouter、Kimi/Moonshot(大陆与国际站)、阶跃星辰、Novita、智谱 GLM Coding Plan、Kimi Coding、MiniMax Coding、OpenCode Go,以及 OpenAI 兼容中转站(OneAPI / New API)。

有一条规矩必须记住:凭据名要跟着模板变。换厂商时沿用上一家的凭据名,新 key 会写进那家的凭据里、把原来的覆盖掉。v679 起新增模型会自动跟随模板,但手工改时仍要留意。

余额按模板的接口与 JSON 字段路径读取,路径支持 a.b[0].c,也支持 scale 乘数——有的厂商返回「分」而不是「元」,一说就解决。填完可以先点「测试连通性」验证 key。

还有一类厂商——硅基流动、火山方舟、OpenAI、Anthropic、Gemini、xAI、Groq、Mistral、Together、Fireworks、阿里云百炼、百度千帆、腾讯混元、讯飞星火、魔搭、本地模型(Ollama / LM Studio)——官方没有「用 API key 查余额」接口,下拉里标注「(无余额接口)」:选完用 probeUrl 探活验证 key,余额显示「—」,今日已用按会话事件估算。硅基流动的 /user/info 自 2026-08-14 起停止服务,其余多属于云端 AK/SK 签名的 OpenAPI。

四、订阅额度和资源包要分开管

这是我踩得最深的一个坑。智谱、Kimi Coding、MiniMax Coding、OpenCode Go 提供订阅额度接口kind:'quota' 模板),直接读官方接口的「窗口已用% + 重置时间」,一个接口还能返回多窗口——OpenCode Go 就是 5h / 周 / 月三窗口。

但这类接口只对订阅套餐账号有效。我拿 Token 资源包账号去调智谱接口,返回「当前用户不存在 coding plan」。这种情况要改用「额度(订阅/资源包)」:填总量,已用按 DSH 会话 token 自动累计,口径 input + cacheRead + output(推理 token 已含在 output 内,跨天保留),也可切手动,重置策略支持「不重置 / 每日 / 每月」。

单价(可选)藏在「密钥/接口」面板里,要展开「接口与字段(高级)」才看得到:缓存命中、未命中输入、输出三项,单位「币种/百万 token」,选美元必须填汇率,记账统一按人民币结算。

五、让数字主动来找我

看板只是集中信息,真正省事的是提醒。我开了三个:余额预警、今日预算(今日已用达额弹提醒)、每轮消耗提示(每轮结束弹消耗泡泡)。三者都支持自动关闭秒数,0 表示不自动关闭;气泡模式不可用时提醒会自动退化为居中卡片,卡片里也会渲染图片模块。

每个模型还会自动获得「余额·」与「额度·」两个泡泡模块,占位符有 {balance}{today}{quota}{quota_used}{quota_left}{quota_total}{quota_reset}。我把余额和今日已用拼成两行常驻显示,点一下鲸鱼手动刷新,平时 60 秒自动刷一次;网络抖动时它会沿用最近余额,不报错。

六、峰谷价格表改变了我几点跑批

价格是 [空闲, 高峰] 两档,高峰为工作日 9:00–12:00 与 14:00–18:00(北京时间),其余空闲,空闲价是高峰的一半;2026-08-23 起周末全天按谷价

以 Flash 为例:缓存命中 0.02 / 0.04,未命中输入 1 / 2,输出 4 / 8(CNY / 百万 tokens);V4 Pro 是 0.15 / 0.30、4.5 / 9.0、13.5 / 27.0。看完这张表我改了两件事:批量文档处理从下午挪到晚上,重复性任务尽量走缓存命中那一档;周末全天谷价更直接,我把周末当成跑长任务的主场。旧模型名 deepseek-v4-flashdeepseek-v4-flash-vision-exp 仍可调用,按 Flash 价计费。

七、Codex 统计补上最后一块

我不只用 API,也用 Codex 桌面端。这部分余额查不到,但消费能统计:数据来源是本机 $CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl(含 archived_sessions/),明文 JSONL。

只读本机文件、不联网、不需要密钥,也不会写入 ~/.codex。口径上优先用日志累计量(total_token_usage)的差值累加,天然避免同一轮多条记录被重复计数;模型归属由 turn_context.payload.model 判定;按天 + 模型聚合,带增量缓存。若账号有 ChatGPT 订阅,rate_limits 的窗口快照会让子菜单自动追加窗口已用%与重置倒计时。

看板稳定之后

用量记录窗口可以切「今日模型消费 / 近 7 天 / 全部记录」,看模型占比条,按日期展开明细、支持搜索;deepseek-flash 会显示为 DeepSeek-V4.1-Flash。

有个数字需要单独理解:「已观测消费」「余额校正」是 DeepSeek 账户口径,由那把 API key 的余额观测得出,不含其它厂商;「本机模型费用」才是所有模型的本地估算。

插件详情与完整清单在 https://dpharness.com/top 。

订阅周报,不错过新攻略
每周一封 · 插件 + 福利

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群