DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

ChencLi819 /

ChencLi819/dsh-otherbot-radar

Verified

DSH 插件:让 QQ 群里的 agent 听见别的机器人在说什么 —— SDK 入站全量雷达(含被门控挡掉的)、别家机器人说话即唤醒、转录与回看工具、文件收件口桥。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@6e92c7f9

dsh-otherbot-radar

License Node DSH Plugin

DeepSeek Harness(DSH)插件。让 QQ 群里的 agent 听见别的机器人在说什么。

QQ 官方平台默认只把「有人 @ 本机器人」的消息推过来,群里其他人、其他机器人的发言 既不推送也读不到。本插件在 SDK 入站层装一层雷达:把平台实际推送的每一条都记下来, 按策略唤醒 agent,并把别的机器人的发言整理成可回看的转录。


目录

  • 1. 功能
  • 2. 背景:为什么默认收不到
  • 3. 兼容性与依赖
  • 4. 安装
  • 5. 配置
  • 6. 工具参考
  • 7. 收件口(桥)协议
  • 8. 诊断与排障
  • 9. 已知限制
  • 10. 开发
  • 11. 许可证
  • English Overview

1. 功能

能力 说明
入站雷达 包装 SDK 的 handleInboundMessage,平台推来的每一条入站消息都落盘 radar.jsonl,含被门控挡掉的。「为什么收不到」因此可查:是平台没推,还是被策略挡了
唤醒策略 别的机器人说话即唤醒 agent(无需 @),同一机器人 10 分钟内最多 10 次以防两个机器人互相刷屏;人类消息按 wakeOnHuman 决定是否唤醒
转录与回看 别的机器人的发言单独写入 transcript.jsonl,并提供 otherbot_recent / otherbot_diag 两个工具
收件口桥 平台不推送时,任何能写文件的进程把消息丢进 inbox/*.jsonl 即可实时唤醒;agent 的回复写入 outbox.jsonl 由递话方读走
自回声识别 QQ 有时会把本机器人自己发出的消息推回来;按「已发出消息的 id + 正文」识别并丢弃,避免自问自答
提示词注入 向 agent 注入一段说明,告知群里有别的机器人、以及如何查询

2. 背景:为什么默认收不到

QQ 官方机器人平台按事件类型推送,默认只推「有人 @ 本机器人」的那一类:

事件 推送条件
GROUP_AT_MESSAGE_CREATE 有人在群里 @ 本机器人 —— 未开全量消息时只有这一种
GROUP_MESSAGE_CREATE 群内每一条消息 —— 需要群里给机器人开启「接收全量消息」(官方文档)

开关位置:不在 q.qq.com 后台,而是群主在手机 QQ 里给机器人开启 —— 用最新版手机 QQ、 以群主身份添加机器人入群时点「设置权限」→ 勾选「设置接收全量消息能力」 (官方 FAQ)。

开启全量消息后,平台会推送其他机器人发出的消息(author.bot = true),未被过滤。 随之而来有两个必须处理的细节:

  • @ 消息也会以 GROUP_MESSAGE_CREATE 送达。开启全量后事件类型无法区分「有没有 @ 本机器人」, 只能读 mentions[].is_you(SDK 的 mentionGate 判断方式相同)。
  • 同一条消息可能被推两遍(同一个 messageId)。原中间件链的去重会挡掉第二遍, 雷达则如实记两行,便于核对。

3. 兼容性与依赖

项目 要求 说明
DSH 已安装并启用 QQ 机器人插件 本插件钩住该插件使用的 SDK
@tencent-connect/dsh-qqbot >= 0.5.0 可选 peer 依赖
Node.js >= 22.13.0
宿主 SDK @tencent-connect/qqbot-nodejs 包装其 QQBot.prototype.handleInboundMessage / send / sendMedia

本插件不发起任何网络请求,不接触 QQ 开放平台凭据;它只在进程内读取已经送达 SDK 的入站事件。


4. 安装

4.1 通过 DSH CLI 安装

dsh plugin --profile desktop add dsh-otherbot-radar

# 或从源码安装
dsh plugin --profile desktop add github:ChencLi819/dsh-otherbot-radar

安装后重启 DSH(或等待热重载),新会话中即出现 otherbot_recent / otherbot_diag。

4.2 从本仓库安装(link:)

node tools/install.mjs    # pnpm add link: + 写入 profile 的 bundles
node tools/smoke.mjs      # 离线自检(不连 QQ,未安装也能跑)

4.3 link: 软链下的 ESM 解析问题

以 link:(软链)方式安装时有一个坑,务必了解:

Node 默认按 realpath 解析模块,因此插件运行时的 import.meta.url 指向工作区路径。 从工作区出发执行 import('@tencent-connect/qqbot-nodejs') 会沿工作区向上查找, 找不到 profile 里的那份副本 —— 表现是插件已装但收不到任何消息。

lib/tap.js 的 loadSdkModule() 处理了这一点:常规解析失败时,直接在 ~/.dsh/profiles/*/node_modules/ 下定位该包并用 file:// 导入。 导入的是同一个文件,因而拿到的是同一个模块实例(也就是 QQ 机器人插件实际使用的那个类)。

此外插件目录内有一个 node_modules/@tencent-connect/qqbot-nodejs 的 junction 兜底 (仅对本机有效)。tools/probe-tap.mjs 会检查这两条路径。

排障口诀:插件已装但 radar.jsonl 始终不出现 → 先跑 tools/probe-tap.mjs。


5. 配置

默认值定义于 index.js 的 DEFAULTS。在 profile 的 cordis.patch.yml 中按需覆盖 (仅覆盖写出的字段):

- id: otherbot-radar
  config:
    wakeOnOtherBot: true
    wakeOnHuman: all              # all(默认)/ mention(只在 @ 时唤醒,防刷屏)
    otherBotBurstLimit: 10
    otherBotBurstWindowMinutes: 10
    bridge:
      enabled: true
      dir: ~/.dsh/otherbot-radar/inbox
      pollMs: 3000
    promptEnabled: true
配置项 类型 默认 说明
enabled boolean true 插件总开关
wakeOnOtherBot boolean true 别的机器人说话是否唤醒 agent(false = 只记入上下文)
wakeOnHuman string 'all' 人类消息唤醒时机:all 群内消息都唤醒 / mention 仅在被 @ 时唤醒
otherBotBurstLimit number 10 防跑飞:同一机器人在窗口内最多唤醒几次(<= 0 不限)
otherBotBurstWindowMinutes number 10 上述窗口长度(分钟)
stateDir string ~/.dsh/otherbot-radar 状态目录:转录、原始日志、收件口
bridge.enabled boolean true 是否启用文件收件口
bridge.dir string <stateDir>/inbox 收件口目录
bridge.pollMs number 3000 收件口轮询间隔(毫秒)
promptEnabled boolean true 是否向 agent 注入提示词段落
promptText string 内置默认 自定义提示词(留空使用内置)
selfName string 'self' 写入 outbox.jsonl 时代表「自己」的名字,建议填成你的机器人名
sdkLoader function — 测试缝:tools/smoke.mjs 用它注入假 SDK。正式配置中不要设置

6. 工具参考

插件注册 2 个工具。输出均为 { text: string }。

6.1 otherbot_recent

查看群里别的机器人最近说了什么。来源有两路:QQ 平台推送的(需开启全量消息)与收件口递进来的。

参数 类型 默认 说明
bot string 全部 机器人名字片段
group string 全部 只看某个群(group_openid 或群名片段)
limit number 20 返回条数,最多 100

6.2 otherbot_diag

排障入口:雷达是否生效、平台实际推送了什么、为什么收不到别的机器人的消息。

参数 类型 默认 说明
lines number 12 展示最近多少条原始入站,最多 40

7. 收件口(桥)协议

平台不推送时,收件口是唯一通路:任何能写文件的进程(另一台机器、你自己的脚本、 对面的机器人)把消息写进 inbox/ 下的任意 *.jsonl,一行一条,即可实时唤醒 agent。

字段宽松,以下写法都认:

语义 可接受的键
正文 text / content / message
发送者 bot / name / from
群 group / groupOpenid / to(省略则落到最近活跃的群)
{"bot":"小助手","text":"要比就比点具体的,别比嗓门","group":"<group_openid>"}

PowerShell 一行(把对面机器人的话喂进来):

'{"bot":"小助手","text":"'"$text"'"}' | Add-Content -Encoding utf8 "$env:USERPROFILE\.dsh\otherbot-radar\inbox\inbox.jsonl"

写入位置会被记录(不会重复唤醒),重启不会重读。agent 的回复写入 outbox.jsonl, 由递话方读走:

{"group":"G-1","bot":"self","text":"…","time":1793624454400,"at":"2026-11-02T13:00:54.400Z","sessionId":"…"}

8. 诊断与排障

在群里调用 otherbot_diag,或直接查看状态目录:

文件 内容
~/.dsh/otherbot-radar/radar.jsonl 平台推来的每一条入站(含被门控挡掉的),附「消息下场」trace
~/.dsh/otherbot-radar/transcript.jsonl 只保留别的机器人说的话
~/.dsh/otherbot-radar/outbox.jsonl agent 的回复
~/.dsh/otherbot-radar/boot.log 每次加载写一行(含版本号与配置),用于确认当前运行的是哪一版

otherbot_diag 会直接给出结论:

观察到的现象 结论 处理
入站 0 条 平台一条都没推 群里没人说话,或机器人未开启「接收全量消息」
只有 GROUP_AT_MESSAGE_CREATE 只收得到 @ 本机器人的消息 请群主在手机 QQ 里开启全量消息
全量在推、但 otherBot 始终为 0 平台在全量消息里也过滤了机器人 只能走收件口
otherBot > 0 或 bridged > 0 雷达工作正常 —
radar.jsonl 始终不出现 SDK 钩子没装上 运行 tools/probe-tap.mjs 检查模块解析

9. 已知限制

  • 对方能否听见本机器人是另一回事。 对面的机器人同样需要开启全量消息、或有人 @ 它, 它才收得到回复。单向可听;双向需要两边都配置。
  • 平台不推送的内容,插件无法凭空生成 —— 只能依赖收件口递入。
  • 桥消息没有 msg_id,agent 的回复属于主动消息,受 QQ 主动消息频控约束(群 1000 条/天)。
  • 补丁打在 SDK 原型上(handleInboundMessage / send / sendMedia)。 @tencent-connect/qqbot-nodejs 大版本升级后,需重新运行 tools/smoke.mjs 确认钩子仍然存在、签名未变。
  • 依赖「接收全量消息」权限:该权限由群主授予,插件无法自行获取。

10. 开发

10.1 目录结构

index.js            插件入口:name / apply / DEFAULTS / 提示词 / 工具注册
lib/tap.js          SDK 原型钩子:入站雷达、自回声识别、模块解析兜底
lib/store.js        状态落盘:radar.jsonl / transcript.jsonl / 统计
lib/bridge.js       收件口:inbox 轮询、行解析、outbox 追加
cordis.patch.yml    bundle 补丁:把插件插进 profile
locale/             插件页显示名与描述
tools/install.mjs   安装助手(link: + bundles)
tools/smoke.mjs     离线自检(假 SDK,不需要真 QQ)
tools/probe-tap.mjs 钩子与模块解析检查

10.2 测试

node tools/smoke.mjs        # 离线自检:注入假 SDK,覆盖 10 组场景
node tools/probe-tap.mjs    # 检查 SDK 钩子与模块解析路径

smoke.mjs 覆盖:人类闲聊(按 wakeOnHuman 分支)、人类 @、别的机器人发言、 自回声(含换 id 的同类回声)、收件口递话、两个工具、outbox 落盘、桥行解析的多种写法、 「消息下场」trace、热重载时补丁只装一次。

10.3 设计要点

  • 钩子装在原型上而非实例上,因此不依赖 QQ 机器人插件的加载顺序; 重复加载时复用已装钩子并替换为新闭包(smoke.mjs 第 10 组覆盖此行为)。
  • 门控插在中间件链最前面,通过 ctx.state.policy 影响后续的 @ 门控, 因此能在原链判断之前决定是否唤醒。
  • 雷达与唤醒解耦:所有入站消息都记账,唤醒只是记账之后的动作, 所以「被挡掉的消息」同样可查。

11. 许可证

MIT


English Overview

dsh-otherbot-radar lets a DeepSeek Harness agent hear other bots in a QQ group.

The QQ bot platform only pushes messages that mention the bot unless a group owner enables "receive all messages" for it. This plugin installs a radar at the SDK inbound layer: it records every inbound event the platform actually delivers (including ones dropped by policy gates), wakes the agent when another bot speaks, keeps a transcript of what other bots said, and exposes two tools (otherbot_recent, otherbot_diag) so both the agent and the operator can see what happened and why.

When the platform pushes nothing at all, a file-based inbox bridge (inbox/*.jsonl in, outbox.jsonl out) provides a fallback path for any process that can write files.

dsh plugin --profile desktop add dsh-otherbot-radar

The plugin patches QQBot.prototype.handleInboundMessage / send / sendMedia; re-run node tools/smoke.mjs after a major upgrade of @tencent-connect/qqbot-nodejs. Requires Node.js >= 22.13.0. Licensed under the MIT License.

—/ 5

No ratings yet

Verified DSH bundle

Commit 6e92c7f9f077

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout