dsh-onebot-companion:为 dsh-onebot-qq 补回 QQ 通道「聊天礼仪」的一体化 DSH 插件

前言

在 DeepSeek Harness(DSH)里接 QQ,常见做法是装 dsh-onebot-qq 做通道。通道插件负责 OneBot 协议与收发,但「像真人一样聊」的细节——沉默怎么表达、旁白要不要发出去、连发三条算不算一轮、长回复要不要分条、消息间隔怎么告诉模型、群聊里喊名字算不算 @——往往要额外约定。

有人会把这些逻辑写进 node_modules 里的上游包;dsh-onebot-qq 一旦升级(例如 pnpm 换目录),改动会被整包冲掉。维护者 xfgil 的 dsh-onebot-companion 走另一条路:不改 node_modules,在运行时给上游原型挂包装(Runtime prototype patching),把出站守卫、每轮行为规则、对话节奏、人设、语音等能力收进一个工作流向插件。它取代早期的 dsh-onebot-guard、dsh-onebot-prompt、dsh-onebot-rhythm 等独立包;旧插件需先卸载再装本插件,不要与旧包同时启用,否则同一条原型链会被包两次,出现重复分条、重复计数。

下面介绍插件定位、模块能力、安装配置与使用注意。DSH 社区插件目录在 SkillHub,与 DeepSeek / 幻方无官方从属关系;本文事实以 GitHub 仓库 README 为准(当前 package 版本 0.4.1,MIT 许可证,GitHub 星标 0)。

这是什么

dsh-onebot-companion 是 DSH 的 QQ 通道 companion 插件:为已启用的 dsh-onebot-qq 补回被 0.9.x 升级冲掉或上游未覆盖的能力。一句话概括 README 的定位:出站沉默守卫 + 每轮行为规则 + 对话节奏 + 人设 + 语音 + 会话换代防护 + 时间戳,并附带群 mention、卡片还原、表情、睡意闸、社交动作、日记/约定、关系阶段等模块。

内部按职责拆成 十七个模块,各自可开关;十一个模块挂在 dsh-onebot-qq 的原型方法上,其余通过宿主钩子或工具注册接入。

核心功能

出站与节奏

  • guard:拦截 [[silent]]、剥离整行括号旁白、吞排队提示与管理员专用回执,以及自述/报幕类回合进度;清理后为空则不发。
  • rhythm:入站合并(连打多行在一个安静窗口内合成一轮)、出站分段(长回复按字数预算分多条发出,带打字延迟)。
  • stamp:在 <user_message> 开标签上注入 time=(发送时刻)与 gap=(距上一条已算好的间隔,如 3m47s),减轻模型自己算时间差出错。

会话与人设

  • adopt:裸 session id 在磁盘仍有历史日志时,优先 resume 接管,避免上游 retireSession 导致「每条消息开新会话、上下文全丢」。
  • prompt:每轮向 agent 注入 14 条行为规则,并可附带情绪行、风格行(默认仅第一步注入,避免撑大上下文)。
  • persona:情绪四变量、随机主动发言、风格学习;状态落在 profile 的 mediaDir,与插件总状态文件分离以便换插件不丢画像。
  • tier:把 affinity 投影成关系阶段台阶,接入提示词。

群聊与入站增强

  • mention:群聊正文出现配置的名字(默认含「云玥」「玥玥」「Yara」)即视为被叫到;可选潜水续话、兴趣话题插话(topics 默认关)。
  • linkcard:将 [卡片] 还原为带标题与链接的 [卡片:标题 https://…]。
  • emoji:修正上游 emoji 表述、补商城表情路径;认不出的原生表情可整条不回(装死)。
  • sleep:说了睡意词之后,群聊仅 @ 或喊名字才接,私聊照旧。
  • isolation:群聊非管理员回合通过 ctx.tools.guard() 硬隔离工具,仅保留发声与白名单工具(如 qq_say、read_image 等,以配置为准)。

工具与扩展

  • voice:注册 qq_say,文字经 edge-tts(云端)或本机 IndexTTS 合成后作为 QQ 语音发出。
  • hands:qq_poke、qq_react、qq_like、qq_requests 等;qq_approve 不直接通过,生成审批单由管理员私聊 /同意 编号。
  • diary / promise:qq_diary、qq_promise 工具与小本子、到点提醒约定。
  • lastword:记录「她最后一次真正开口」的时间与片段,可通过 HTTP /physical 等观测。

共享挂载点(如 dispatchFollowup 上的 stamp + rhythm)由 core/patch.js 的模块标记与优先级决定链顺序,与挂载时序无关。

环境要求

  • DSH 宿主 0.2.0-rc.2 及以上、0.3.0 以下(README 注明开发与验证版本含 0.2.1-rc.2 / Electron 44)。
  • 已安装并启用 dsh-onebot-qq(默认按 0.9.x 内部结构挂载)。
  • Node.js ≥ 22。
  • 插件本身不额外依赖第三方 npm 包;使用默认 voice.backend: edge 时需自行 pip install edge-tts;backend: local 需 IndexTTS 服务与足够显存(README 写 8G 起 NVIDIA)。

安装与启用

本插件未发布到 npm,没有 npm i 或 dsh plugin add 渠道;需用 link: 挂进 profile,bundle 通过自带的 cordis.patch.yml 自注册。

1. 取得源码

任选 README 列出的一种方式:Release 源码包、GitHub 网页 Download ZIP,或:

git clone https://github.com/xfgil/dsh-onebot-companion.git D:\path\to\plugins\dsh-onebot-companion

解压或 clone 后的目录下称 <插件目录>。

2. 在 profile 的 package.json 注册

编辑 <DSH_HOME>\profiles\<profile>\package.json,增加依赖与 bundles:

{
  "dependencies": {
    "dsh-onebot-companion": "link:D:/path/to/plugins/dsh-onebot-companion"
  },
  "dsh": {
    "profile": {
      "bundles": [
        "dsh-onebot-companion"
      ]
    }
  }
}

不要在 profile 的 cordis.patch.yml 里再手写重复 insert,否则会起两个实例。

3. 建链接并加载

顺序很重要:先 pnpm install 建 node_modules 链接,再改 profile 清单。 若先改清单后建链接,宿主热更新可能短路跳过重试,表现为管理页 enabled: true 但无 entryId、功能不生效;补救方式是在插件管理页关掉再打开一次。

cd <DSH_HOME>\profiles\<profile>
pnpm install

改完一般无需重启宿主;若安装了同作者的 dsh-hot-reloader,可自动跟进。

4. 确认运行

curl.exe http://127.0.0.1:<端口>/onebot-companion

或查看 $DSH_HOME/onebot-companion/state.json 是否落盘。

配置要点

配置写在 profile 的 bundle 配置段(宿主透传给 apply(ctx, config))。插件不导出 Config schema,避免 profile 侧 loader 投影报错。最小示例:

dsh-onebot-companion:
  enabled: true
  packageName: dsh-onebot-qq
  profileDir: ''
  pollMs: 3000
  stateFile: ''

  guard:
    enabled: true
  adopt:
    enabled: true
  rhythm:
    enabled: true
  persona:
    enabled: true
  voice:
    enabled: true
    backend: edge
    program: python

packageName / profileDir 会自动下发到各模块段,无需在每个模块重复。完整字段见 README「配置」一节(含 mention.names、rhythm.inbound/burst、isolation.allowedTools、sleep、diary、promise 等)。

若曾安装 dsh-onebot-guard / dsh-onebot-prompt / dsh-onebot-rhythm,请先卸载,仅保留 dsh-onebot-companion。

典型用法

沉默与出站清理

模型输出 [[silent]] 或整行括号旁白时,guard 在 sendToChat / sendMsg 层拦下或剥离,用户侧看不到无效气泡。可通过 HTTP 观测最近命中:

curl.exe "http://127.0.0.1:<端口>/onebot-companion/hits?limit=20"

语音消息

在 agent 可用工具中调用 qq_say(需 voice 模块启用且 edge-tts 或 IndexTTS 就绪)。试合成不落盘发送:

curl.exe -X POST http://127.0.0.1:<端口>/onebot-companion/say -H "Content-Type: application/json" -d "{\"text\":\"你好\"}"

分段预览

调试 rhythm 出站分段:

curl.exe -X POST http://127.0.0.1:<端口>/onebot-companion/burst -H "Content-Type: application/json" -d "{\"text\":\"一段较长的测试文本\",\"maxChars\":20}"

模块热开关

仅 loopback(非 127.0.0.1 返回 403):

curl.exe -X POST http://127.0.0.1:<端口>/onebot-companion/module -H "Content-Type: application/json" -d "{\"module\":\"guard\",\"enabled\":true}"

总状态与各模块挂载情况:GET /onebot-companion;情绪、风格、日记、约定、lastword 等有对应 GET 端点,详见 README「HTTP 观测面」。

适用场景与注意

适合谁:已在 DSH 上用 dsh-onebot-qq 做 QQ 机器人或群助手,需要沉默协议、分条节奏、时间间隔、群名 @、人设与语音等「工作流层」能力,且希望 升级通道插件时不丢补丁 的开发者。

务必知晓:

  1. 插件以 当前 DSH 进程权限 运行,会 patch 运行时加载的 dsh-onebot-qq 原型并读写 $DSH_HOME 与 profile mediaDir 下的状态文件;安装前请阅读源码与 MIT 许可证,确认配置中的管理员 QQ、路径、工具白名单符合你的安全边界。
  2. DSH / dsh-onebot-qq 版本需落在 README 声明的范围内;上游大版本变更可能导致补挂失败(插件靠 pollMs 扫描自愈,但拿不到上游导出函数时会放弃挂载而非瞎猜)。
  3. voice 的 edge 模式依赖外部 Python 与网络;isolation 的 read_image 默认严格依赖 mediaDir 白名单。
  4. 群消息前缀 [HH:MM 昵称(QQ)] 仍用处理时刻,与 stamp 的 time= 属性可能差几秒,README 标明为已知边界。

结尾

dsh-onebot-companion 把 QQ 通道聊天所需的守卫、节奏、人设、语音和会话修复收进一个 bundle:一份配置、一个 HTTP 观测面、十七个可关模块,用原型外挂替代改 node_modules,面向 dsh-onebot-qq 0.9.x 生态。目录与分类(工作流)见 SkillHub 插件页;源码、安装细节与自测接口见 GitHub:xfgil/dsh-onebot-companion。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜