Skip to content

Releases: ZelotsNullzwei/whale-pod

WhalePod v0.3.0

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 26 Oct 04:18

v0.3.0 正式版

从 0.2.5 到 0.3.0 的核心变化是「她开始记得住人了」。图片下载的实际修复、按 QQ 号认人、记忆蒸馏、主动行为,都围绕这一条。

主要变化

图片真的能看见了

fetchImage 里 Buffer.from(res.body) 接不住 Web/Node stream,所有图片下载都失败,表情包全部降级成「(对方发了一个表情包)」文字。模型看不到图,于是「她不知道我在说什么」。

现在按类型分派读取,实测日志从「一张都没入库」变成「已附图 1 张」。

按 QQ 号认人

昵称会换、会撞,用它当 key 会把同一个人拆成好几个。现在档案主键一律是 QQ 号,昵称只作为别名累积。

记忆从「拼接」改成「按人覆盖」

原来同一件事被反复写进摘要,越拼越长,最后撞上 3000 字上限硬截断。现在按 QQ 号覆盖同名行,二十次 merge 后仍在一屏内。

主动行为(两个独立开关,可在设置页开关)

  • beg.enabled 默认开:定期查搜索余额,低了主动讨
  • proactive.enabled 默认关:群安静够久就自己冒泡

五道闸门:时段限制、静默时长、全局冷却、每日上限、白名单会话。

记忆目录可自定义

memory.dir 可以把长期记忆放到别的盘/同步盘,不必搬整个数据目录。

正式版补充的修复

设置页的「主动行为」区加了两个开关,修了三个叠在一起的 bug:

  1. 前端少读一层 .config —— 复选框读不到值,看起来「勾选不上」
  2. 配置块被插进了 qq 内部 —— 程序读顶层 cfg.proactive 读不到
  3. 改缩进没改层级 —— 视觉上像顶层,实际仍嵌在 qq 里

测试

12 个 check 脚本,419 项全部通过。

升级

替换插件即可,配置都在数据目录(~/.dsh/whale-pod/config.json)。

WhalePod v0.2.5(已过时)

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 23 Oct 08:12

本版为重新发布。 首个 v0.2.5 包里带了一个设置页滚动的毛病
(内容区中间滚不动,只有边上能滚),已修复并重新打包。
在此之前下载过 v0.2.5 的话,请重新下载。

主题:分得清在跟谁说话

前几版解决的是「该不该搜」「花了多少钱」。这一版解决更根本的一件事:
它分不分得清这句话是在跟我说的。

原来的判据很粗:句子里出现「你」就算在追问我,概率直接抬到 0.97。
但「你」是中文群聊里最高频的人称代词,绝大多数时候指的是别的群友。
实测这一句也被判成追问:

机器人:我觉得 V4 快一些
小红:你今天怎么了?          ← 在问别人,却被判成追问我 → p=0.97

结果就是它会抢着回答不是问它的话。

现在先判断「在跟谁说话」

证据 结论
引用了谁的消息 引用我的 → 是;引用别人的 → 不是
句中叫了别的群友名字 不是
同一个人连发两条 是(在补充刚才那句)
有承接词(那 / 所以 / 为什么…) 是
紧接在我发言之后并提到我 是
证据不足 不确定 —— 不硬猜

「不确定」是独立的第三种结果:既不当作在问我(不抢话),也不当作在问别人
(该接的时候不装死)。

追问分了强弱

紧接在我后面的 → 0.97;隔了几句的 → 0.85。原来一律 0.97,弱信号会抢话。
另外超过 5 分钟就不算「接着我的话」了。

顺手修掉的几个真问题

都是实机跑出来的,不是推演:

  • 同一句话回两次 —— 协议端重连会重推消息。原来只在写记忆时判重,
    决策和发送照跑第二遍。现在在决策之前就拦掉。
  • 回复过时 —— 延迟 + 生成几十秒,发出去时话题已经翻篇。现在延迟后和
    生成后各检查一次;有人 @ 我或引用我就照常发。
  • 冷却补回一直是坏的 —— defer 字段在注册表那层被吃掉,
    「冷却中,稍后补回」的消息其实被永久丢弃。这个 bug 从引入 defer 那天就在。
  • 长期记忆从没生效 —— 默认关着;而且就算打开,阈值 200 也大于窗口 30,
    永远触发不了,摘要只可能发生一次。现在默认开启、阈值降到 20,
    并在启动时校验配置(配错会打 warn,不再静默失效)。
  • 私聊每句要等 15 秒 —— 沿用群聊的防刷屏冷却。实测日志里「冷却中」出现
    193 次。私聊改为 1.5 秒,群聊不变。
  • 叫它名字反而不应 —— 群聊冷却会把「肥鱼还活着吗」这类明确召唤拦下来。
    179 次冷却里有 21 次是这种误伤(另 70 条是图片表情、51 条是短句,
    这些该拦,所以只做豁免、不缩短全局冷却)。

设置页滚动修好了

设置里 WhalePod 那一页,滚轮只有落在边上才有用,放内容区中间滚没反应。

原因:.gd_root 设了 overflow-y:auto 却没有高度约束,高度撑到内容高,
自己永远滚不动 —— 于是成了「滚不动的滚动容器」;它又设了
overscroll-behavior:contain,阻止滚动传给外层那个真正的滚动容器。
两头都不滚,只有落在它外面的边距或滚动条上才滚得到。

去掉 overscroll-behavior:contain 即可(保留 overflow-y:auto,
那是侧栏面板下的兜底滚动)。

用真实滚轮事件验证(落点取内容区正中):

父容器 scrollTop 结果
修复前 0 → 0 ❌ 完全没滚
修复后 0 → 360 ✅ 滚动了 360px

这个毛病 0.2.4 也有,不是 0.2.5 引入的。

测试

新增 4 个套件、共 135 项:

套件 项数 覆盖
check-social 44 对话对象识别、追问分级、概率边界
check-concurrency 32 走真实 onEvent 路径验过时检测、去重、多群隔离
check-memory-cooldown 36 连续多轮摘要、私聊冷却、配置校验
check-cooldown-exempt 23 豁免的正例与反例

现有套件全绿:check-decision 64/64、check-qq 60/60 等。
概率边界一律用注入随机源验证,不靠人工读码。

已知问题

  • 同一毫秒触发两次决策(历史日志 14 处),疑似空 messageId 绕过判重,未确认
  • check-multimodal / check-router / check-launcher-args / check-poke 有既有失败,
    与本次改动无关(已在 main 上逐项对比确认)

安装

解压后把 plugin/ 用 link: 挂到 profile,重启 DSH。

WhalePod v0.2.4(已过时)

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 20 Oct 08:17

⚠️ 此版本已过时,请使用 v0.2.5。

这个版本里群聊的追问判据只看「有没有出现『你』」,会把别的群友之间的
对话误判成在问它;另外消费级 bug 有几个:同一句话可能回两次、冷却补回
的消息被永久丢弃、长期记忆默认关闭且阈值配成了永远触发不了。
保留仅供追溯,不要用于新安装。


主题:把搜索链路理顺

0.2.3 让搜索能触发、能配图。这一版解决三件更实际的事:该搜的不搜、
搜索花了多少钱看不见、接口用错了贵一倍,另外补上了搜索开关
和 README 的定位问题。

短问句 / 裸名词也能触发了

实际群聊里最常见的两种说法都没命中判断:

消息 0.2.3 现在
「祀强吗」 ❌ 不搜 ✅ 短问句
「终末地新干员」 ❌ 不搜 ✅ 新事物信号

顺带修了两个 bug:detectProperNoun 有一条分支返回了对象(拼成
[object Object]);今天中午吃什么 被误判成需要搜索。

搜索接口换成原生 REST API

原来走 Anthropic 兼容层的 server tool,模型要先把网页全文读进上下文再
总结 —— 输入 2~3 万 token,费用按 token 算,耗时 3~8 秒。

读官方文档后发现给的是独立 REST API:

POST /v1/tools/search   →  结构化结果,按次 ¥0.005,不按 token
POST /v1/tools/fetch    →  抓单页正文(本次不用)

改成两步:先 /v1/tools/search 拿 5 条结果(need_content=false,
只要 summary 不要整页正文),再把标题+摘要交给 /v1/chat/completions
写成回答。

问题 耗时 搜索费 总结费 合计
葬送的芙莉莲作者 1.0s ¥0.005 ¥0.0005 ¥0.0055
进击的巨人 1.2s ¥0.005 ¥0.0012 ¥0.0062
2026年10月新番 3.8s ¥0.005 ¥0.0046 ¥0.0096

平均 ¥0.0071/次(原来 ¥0.0157,降 55%),耗时降到 1~4 秒。答案质量
还更好 —— 会指出资料矛盾。

侧栏加了「联网搜索」设置块

这是唯一真花钱的部分,所以给了显眼的开关:启用搜索 / 配封面图 /
最多搜几次 / 余额提醒阈值。

顺带修了一个热更新 bug:/api/whale-pod/config 原来只推 qq.*,
search.* 写进配置但不推给运行中的 bridge —— 开关拨了、配置存了、
行为没变,得重启才生效。

搜索按次计费也算进估价

Search  每 1,000 次成功请求  5 元  →  ¥0.005 / 次
Fetch   每 1,000 次成功请求  5 元  →  ¥0.005 / 次

目前未计费,2026-11-01 00:00 起开始收。我们按会收来算。

余额低了会让大肥鱼念叨

搜索失败最常见的原因除了网络不通,就是余额见底 —— 以前完全静默。
新增余额检查,低于 ¥2 时挂一句提示。但不写「请充值」这种客服腔:
大肥鱼人格里本来就有「Token 是脑力口粮」「白米饭」这一串设定,
让她按性格抱怨就行。只提一次,不变复读机。

README:先说清楚这是 DSH 插件

原来的开头把「DSH 插件」写成轻描淡写的定语,然后立刻讲架构卖点。
读者(尤其从视频来的)不知道没有 DSH 就用不了。

现在开头就是「给 DSH 装一个 QQ 聊天机器人 —— 它是 DSH Desktop 的插件,
不是独立程序」,紧跟一张表说明它提供什么、分别依赖 DSH 的什么,
然后才是 ✅/❌ 适配判断。

成本说明也重写了:按模型官网价折算,支持官方 API 和任何自备渠道,
不绑定特定环境。

安装

解压后把 plugin/ 用 link: 挂到 profile,重启 DSH。

WhalePod v0.2.3(已过时)

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 20 Oct 07:03

⚠️ 此版本已过时,请使用 v0.2.4。

这个版本的搜索对短问句(「祀强吗」)和裸名词(「终末地新干员」)不触发,
而且搜索费用没有计入侧栏估价。
保留仅供追溯,不要用于新安装。


主题:让它知道自己不知道

不认识的、知识截止之后的,承认不确定或者去查 —— 而不是硬编一个答案。

把终末地的抽象青蛙认成自己

群里发《明日方舟:终末地》那只青蛙梗图时,它会接「这不就是我吗」。
人格里对外貌只有一行「蓝长发、鲸鱼耳鳍和尾巴、女仆围裙」,没有任何边界,
看到动物/抽象生物梗图就容易被模糊的「蓝」「水」「卡通」特征带跑。

新增「你长什么样(别认错自己)」:固定形象逐条列清楚,明确青蛙/狗/猫/
鱼形梗图/抽象生物都不要代入,并点名终末地那只青蛙与鲸鱼娘无关。

看图能力被自己压制

原来的提示词整段在说「别人发来的表情/图片,别去解读它」,连
「对方问图里是什么」也不给例外 —— 收到带信息的截图也只回语气词。

现在按「对方想不想让你看图里的内容」分三类:

图的性质 该做的
表情包 / 梗图 回情绪,别描述
截图 / 照片 / 有信息 认真看,挑重点说
被问「图里是什么」 必须答,看不清就说看不清

收集窗口 6 → 10 条,maxImages 2 → 4。

新番 / 番剧跟不上,靠旧记忆瞎说

搜索功能一直是好的(实测 846 字 / 17 个来源),问题是根本不触发:
关键词表里没有「新番」「番剧」「这季」「开播」;疑问判定只认「吗/呢/问号」,
而口语「这季新番有啥好看的」完全没有这些标记。

补上番剧/影视/赛事类关键词,疑问判定加「啥/哪些/哪个/推荐」。

具体人名、作品名优先查

模型对具体名字最容易翻车 —— 把作者记成别人、把导演说错、把真实
存在的人说成虚构角色,而且说得非常肯定。这类错误比「不知道」伤害大得多。

出现专有名词就查:书名号内容、外文词、「XX的作者/导演/主演」、
「XX是谁/怎么样」、「XX什么时候/多少集/第几季」、「XX第二季/剧场版」。

搜索又快又便宜了

原来用 deepseek-chat。实测三个方案:

模型 耗时 单次费用 每月100次
deepseek-chat(原) 6.8s ¥0.060 ¥6.00
deepseek-flash + 开推理 12.3s ¥0.030 ¥3.00
deepseek-flash + 禁推理 3.2s ¥0.011 ¥1.14

两个关键点:

  • 省钱在输入不在输出 —— 搜索场景输入是大头(搜索结果正文全塞进
    上下文,2~3 万 token),而 flash 的输入价只有 chat 的一半。
  • 必须禁用推理 —— flash 默认先吐 thinking,会把 max_tokens 吃光
    (正文 0 字)、输出翻三倍、慢一倍。搜索是「查完照实转述」,不需要推理。

必要时补一张封面图

搜到具体作品/产品时,从来源页面的 og:image 抓一张封面,接在回复最后。
只试前 3 个来源、单个 3 秒超时、排除 logo/icon,失败就跳过。

实测「葬送的芙莉莲」:661ms 抓到封面。

人格里加「知识有截止日期」

⚠️ 真正的丢人是:不知道却硬编一个答案。

· 话题明显在截止点之后 → 直说不太确定,而不是猜
· 具体事实(日期、名字、销量、排名)→ 宁可给范围也别给准确数字
· 闲聊不用小心,只有具体事实才需要

注意

人格改动走自动升级:没手动改过 persona/roles/default.md 的
(指纹表里 written === builtin),重启后端就会更新;改过的会保留。

安装

解压后把 plugin/ 用 link: 挂到 profile,重启 DSH。

WhalePod v0.2.2(已过时)

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 20 Oct 04:22

⚠️ 此版本已过时,请使用 v0.2.3。

这个版本的提示词过度压制看图能力,且人格里没有自我形象的边界说明。
保留仅供追溯,不要用于新安装。


这一版修了什么

费用一直是 ¥0

两个独立原因:

  • _trackUsage 读的是 opened.provider / opened.model,但
    openFirstAvailable 返回的是 { stream, picked, attempts } —— 这两个字段
    永远是 undefined,拿不到价格就返回 0。(同一文件另一处日志早就写明
    「路由信息在 opened.picked 里」,这里一直没改。)

  • 价格表只有 11 条,实际在用的 53 个模型大半匹配不到:glm-5.3 / kimi-k3 /
    gpt-6 / gemini-3.5 / grok-4.7 全都没有价格。

现在价格表按各厂商官网挂牌价重写,覆盖 DeepSeek、智谱、Kimi、MiniMax、
MiMo、阶跃、OpenAI、Anthropic、Gemini、xAI;priceOf 会剥掉渠道前缀
(workbuddy/)和后缀(-free/-sg/-1017),同一个模型换渠道不会走丢价格。

计费口径与渠道无关 —— 同一模型走 6 个不同渠道,费用完全一致。

用量重启归零

计数器原本只在内存里。现在落到 <home>/usage.json,构造时自动恢复,
每次调用后原子写。重启后 token 数、费用、按渠道/模型/来源的分布都接着累计。

费用显示「(免费)」

走免费渠道时 usd 恒为 0,界面上永远显示「¥0(免费)」。去掉这个后缀,
改成按官网价折算并按量级选小数位(≥1 两位、≥0.01 三位、否则四位),
小额不再被 toFixed(2) 抹成 0.00。

安装

解压后把 plugin/ 用 link: 挂到 profile,重启 DSH。
NapCat 会在首次启动时自动下载。

WhalePod v0.2.1(已过时)

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 20 Oct 03:13

⚠️ 此版本已过时,请使用 v0.2.2。

这个版本的「折算费用」恒显示 ¥0,用量统计重启归零。
保留仅供追溯,不要用于新安装。


这一版修了什么

0.2.0 发布后发现的加载通路问题,装上后界面会直接空白或每 4 秒闪一次。

插件 UI 完全不出现

  • 改用 dsh.client 官方通路加载浏览器半身 —— 之前走手动注入
    (webserver/index-inject 推一行 script),这条路对 apply 执行时机、
    webServer 就绪顺序、桌面壳收集注入表的时机都敏感,任何一环变动
    都让 UI 静默消失,日志里还看不出原因。

  • 删注入块时误删了三个变量声明(target / readWhalePodToken /
    clientPathResolved),导致所有透传请求抛 ReferenceError。

接口 403

  • 透传被宿主会话认证拦成 403 —— 插件原来只注入 webServer,自己判
    回环就放行;桌面端每个请求还要过宿主的会话认证。现在注入 connection
    并委托它的 requestRejection。

界面闪烁

  • 每 4 秒轮询都会让面板闪一次 —— useAsync 重载时把 status 打回
    loading,面板判定依赖 status,于是每轮询一次就在「在线」和
    「后端未运行」之间跳。现在重载保留上一次状态,判定改成看 data 有没有。

  • 关闭后端时甩红字 —— 502/ECONNREFUSED 是"后端没起"的正常信号,
    不该当故障显示。现在只显示真正的 HTTP 4xx/5xx。

其他

  • 转发回调引用 TDZ 里的 timer,导致请求偶发失败
  • 面板上能看到接口错误(桌面版没 F12)

安装

解压后把 plugin/ 用 link: 挂到 profile,重启 DSH。
NapCat 会在首次启动时自动下载。

WhalePod v0.2.0(已过时)

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 20 Oct 01:34

⚠️ 此版本已过时,请使用 v0.2.1。

这个版本的插件装上后界面会空白或每 4 秒闪一次(加载通路 + 状态判定的问题)。
保留仅供追溯,不要用于新安装。


安装

  1. 解压,把 plugin/ 目录用 link: 方式挂到 profile
  2. 重启 DSH,侧栏出现「鲸舱」

无需单独装 Python 或协议端 —— NapCat 会在首次启动时自动下载。

这一版修了什么

崩溃类

  • client.js 被加载两次导致 DSH 桌面端崩溃 —— package.json 声明的
    dsh.client 与 index.js 里的手动注入同时生效,浏览器里 factory 重复注册,
    前端崩溃后主进程连带报 Cannot find package '@deepseek-ai/cordis'。

  • 后端启动几秒后自己退出 —— DSH 重启时插件宿主进程被替换,旧 ppid 消失,
    守护进程误判「宿主已退出」而自杀。现在由插件传入 --hosted,跳过该监控。

  • 设置页白屏 —— 一个 state 变量跨组件作用域引用,渲染期抛
    ReferenceError,整棵子树被卸载。

功能类

  • 配置被静默重置 —— config.json 带 UTF-8 BOM 时 JSON.parse 失败,
    整份配置回落到默认值(表现为「明明开了 QQ,重启又变回关闭」)。

  • 消息按空行分段 —— 想分两条说时中间空一行即可,会发成两条消息。

  • 不再复述媒体注解 —— 模型有时把「(对方发了个QQ表情,id=20)」当正文发出来,
    那是喂给它的系统说明,现在输出侧一律剥掉。

  • 设置页保存后侧栏立刻同步 —— 原来要等 20 秒轮询。

其他

  • 设置页右上角加了「★ 点个 Star」
  • 决策层:追问时不再沉默

已知限制

  • 需要 DSH 2.x
  • QQ 登录走 NapCat,首次启动需要扫码

WhalePod v0.1.0(已过时)

Pre-release

Choose a tag to compare

@ZelotsNullzwei ZelotsNullzwei released this 18 Oct 12:17

⚠️ 此版本已过时,请使用 v0.2.1。

这个版本的插件装上后界面会空白或每 4 秒闪一次(加载通路 + 状态判定的问题)。
保留仅供追溯,不要用于新安装。


⚠️ 此版本已过时,请使用 v0.2.0。

这个 zip 里的代码存在会导致 DSH 桌面端崩溃的缺陷(client.js 被加载两次)。
保留仅供追溯,不要用于新安装。


WhalePod v0.1.0

DSH 的 QQ 聊天机器人插件。 一个托盘进程管全部 —— 网关、桥接、决策、人格、协议端。

这个版本有什么

  • LLM 网关:OpenAI 兼容,内置 DeepSeek 账户凭证,也支持任意自建供应商
  • QQ 桥接:OneBot v11 收发,决策层先判断该不该说话,再决定说什么
  • 协议端托管:自动下载并托管 NapCat,含免扫码快速登录
  • 人格系统:内置大肥鱼 / 潜水版 / 普通群友三种,可自由编辑与切换
  • Web 管理界面:10 个页面,可折叠侧栏

运行模式

模式 状态
whale-pod ✅ 可用
astrbot ⚠️ 有框架,未完善

只想要一个能跑的 QQ 机器人,用 whale-pod 模式就够了。

安装

下载 dsh-whale-pod-v0.1.0.zip,解压后把目录放进 DSH 的 profile:

<你的 profile>/node_modules/dsh-whale-pod

再把它加进 profile 的 package.json(dsh.profile.bundles),重启 DSH。

数据目录在 ~/.whale-pod,删掉这个目录即完全卸载。

要求

  • DSH Desktop
  • Node 22.19+
  • QQ 协议端(NapCat 可在界面里一键安装)

已知限制

  • reverse WS 未实现(只支持主动连协议端)
  • 长期记忆用滚动摘要,不用向量检索
  • AstrBot 模式尚未在真机验证