dsh-napcat:给 DeepSeek Harness 加一个 QQ 通道

前言

DeepSeek Harness 的理念是「一切皆插件」。如果你正在用 NapCat 或 OneBot 11 协议跑 QQ 机器人,想直接把消息接入 DSH 的 agent,而不是自己写转发逻辑,dsh-napcat 是一个现成的实现。

这个插件通过 NapCat(OneBot 11 协议)把群聊/私聊消息送进 DSH 的 agent,再把回复发回 QQ。每个群或私聊对应一个独立的 dsh 会话,同时提供了会话记忆、主动发言、性格设定、文件/图片收发等实用能力。

是什么

  • 插件名:dsh-napcat
  • 维护者:wzwei1990
  • 分类:客户端
  • 解决的问题:把 NapCat / OneBot 11 事件转换成 DSH 的会话,让同一个 agent 同时服务多个 QQ 聊天
  • 当前版本:v0.3.20(参考 dsh-onebot / dsh-im / dsh-qqbot 的形态)

核心功能

连接与触发

  • 连接方式:支持 forward(插件主动连 NapCat 的 WebSocket)和 reverse(NapCat 拨进插件)
  • token 校验:两边需配置相同的 accessToken
  • 断线重连:指数退避
  • 触发方式:@机器人 / 回复机器人 / 关键字(triggerKeywords,如「小灯」);群聊可要求必须 @

会话与分组

  • 一个群 / 一个私聊 = 一个 dsh 会话,id 格式为 napcat-group-<群号> 或 napcat-private-<QQ>
  • 会话 id 里编入 cwd 哈希,重启后不换会话
  • 每个聊天自动建一个工作区(侧边栏显示「群 1103089802」/「私聊 1000001」)并挂载会话
  • 首条消息时把会话标题写成 MM-DD HH:mm

准入策略

  • 私聊 / 群聊各自有策略:open(开放)、allowlist(白名单)、disabled(禁用)
  • 可配置白名单,只允许特定用户进入

群记忆

每群(或私聊)一份长期记忆,与其它群互不干扰,包含两层结构:

层 内容 用途
热上下文 最近 N 条消息(默认 200 条) 每次触发自动注入最近 20 条
长期记忆 群设定 / 黑话 / 人物关系 / 事实结论(mnemon 记忆空间) 显式召回(固定层 + 按需层两次)

模型自动维护分层标签:

  • 【设定】→ tags 加 setting
  • 【黑话】→ tags 加 glossary
  • 【人物】→ tags 加 person
  • 【事实】→ 无额外标签

自动捕获:只要对话中出现上述新信息,模型自己写入(memoryAutoCapture,默认开启)。信息变化时先 mnemon_forget 旧条目再写新版本(带「更新于 MM-DD」)。

手动入口(可选):

  • @机器人 记住:周五发周报:写一条事实
  • @机器人 记住设定:群里管老张叫张哥:写设定(也支持 记住黑话: / 记住人物:)
  • @机器人 记忆:检索本群长期记忆并回答
  • @机器人 忘掉 XXX:召回后软删对应条目

历史预热:缓冲不足或最新一条已过期时,用 NapCat 的历史接口补齐(群用 get_group_msg_history,私聊用 get_friend_msg_history)。预热是合并(按时间+昵称+内容去重),不会覆盖已攒下的历史。

图片与表情包

默认只存叫到机器人时的图片。开启缓存后,群里的图片/表情包也会落盘:

imageCache: all                 # off=只存叫到机器人时的图;all=群里的图也存
imageCacheMaxBytes: 2097152     # 单张 ≤ 2MB
imageCacheDailyCap: 100         # 每个聊天每天最多 100 张
imageCacheRetentionDays: 7      # 超期目录自动清理
  • 落盘位置:<会话cwd>/napcat-inbox/imgs/<YYYYMMDD>/<hash>-<原名>
  • 聊天记录里写成 [图片:<文件名>],之后可用 read_image 回看
  • 去重:按图片 URL 的 hash
  • 历史图片也会缓存:预热时逐张尝试用 get_image 解析,成功则落盘并写成 [图片:<文件名>],解析失败标 [图片(已过期)]
  • 记录里带可读路径:[图片:napcat-inbox/imgs/<日期>/<文件>](相对会话工作目录)
  • 注意:@ 它那一轮图片会随消息直接送进模型;历史/主动发言轮默认只给记录,按需读图

主动发言(伪人模式)

默认关闭。开启后,群里有人聊天时,会按泊松概率决定要不要自然插一句。

判定链(全部通过才考虑插话):

  • 总开关:proactiveEnabled
  • 静默时段:proactiveQuietHours(如 00:00-08:00,12:00-13:00)
  • 冷却:proactiveCooldownMinutes(默认 30)
  • 每小时上限:proactiveMaxPerHour(默认 3)
  • 有人聊:近窗口内至少 K 条他人消息(proactiveMinMessages / proactiveWindowMinutes,默认 3 条 / 5 分钟)
  • 概率:泊松过程,proactiveRatePerHour(λ,默认 1.5 次/小时;设 0 用 proactiveChance 固定概率)

主动发言的提示里会拎出最后 2 条消息作为锚点,要求模型:

  • ≤ 2 句口语化
  • 不重复别人刚说的话
  • 不总结、不列点、不点人名
  • 没话说只回 __SKIP__

模型决定有话可说 → 正常回复(≤ 2 句、口语化、不总结不列点)→ 发出并记一次发言;没话说 → 回 __SKIP__ → 插件丢弃这条,并累计 skipStreak(连续跳过会按 1/2、1/4…退避降低下次概率)。

被禁言时自动停发:探测 get_group_member_info.shut_up_timestamp 和 get_group_info.group_all_shut,禁言期间不再发消息、也跳过主动发言。

主动发言也会写记忆:第一次主动发言时若还没有记忆空间,会先建空间,再从近期群聊里提炼 1~3 条写进去;已有空间时只在听到值得长期记的新信息时顺手记 1 条。

推荐起步值:

proactiveEnabled: true
proactiveRatePerHour: 3
proactiveCooldownMinutes: 15
proactiveMaxPerHour: 3
proactiveQuietHours: "00:00-08:00"
proactiveMinMessages: 2
proactiveWindowMinutes: 5

性格设定

通过 personaOverrides 配置:

group:<群号>=<人设>
private:<QQ>=<人设>
  • 按会话精确匹配注入到 systemPrompt.context
  • 只影响语气 / 称呼 / 风格,不会把设定原文念给用户,也不会拿它当自我介绍
  • 留空 = 不注入任何性格,纯工具人

文件与图片收发

  • 图片(收):原生送达。下载到 <会话cwd>/napcat-inbox/ → attachments.admitPromptContent → ImageBlock 进模型请求;同时保留 [图片: <路径>] 文本兜底
  • 文件(收):私聊三级兜底(get_private_file_url → base64 → http url);远端 NapCat 只给本机路径时会给出明确原因
  • 群文件(收):按需拉取,支持模糊文件名
  • 引用消息:引用一条带图/文件的消息 @机器人,会通过 get_msg 取回被引用消息里的媒体
  • 图片 / 文件(发):napcat_send_image(本地路径或 URL,自动 base64,NapCat 在远端也能发)、napcat_send_file(file 段,失败退回 upload_*_file)

稳定性与其他

  • 复用宿主已存在的 agent;同一会话装配串行化
  • 会话文件丢失(ENOENT)自愈并重投;归档过的会话改用 -rN 新会话(不擅自解除归档)
  • QQ 侧无人可点「同意」,自动把该 agent 审批策略设为 never(GUI 里显示 Custom 属预期)
  • 诊断:<会话cwd>/napcat-inbox/_image-debug.log 逐步记录收图

安装与启用

NapCat 侧

选择一种连接方式:

  • forward(推荐):插件主动连 NapCat 的 WebSocket
  • NapCat 开 WebSocket 服务器,记下 ws://<host>:<port> + token
  • reverse:NapCat 连插件的 WebSocket 服务
  • NapCat 填 ws://<插件所在机器>:<port>;插件这边填 host / port / accessToken
  • accessToken 两边必须一致

安装插件

# 从 GitHub
dsh plugin --profile web add github:wzwei1990/dsh-napcat

# 或本地目录
dsh plugin --profile web add /path/to/dsh-napcat

典型用法

  1. 在 NapCat 中配置 WebSocket 连接,确保 token 一致
  2. 使用上述命令安装插件
  3. 在 DSH 的设置页里,为每个群/私聊配置准入策略、白名单、关键词等
  4. 开启群记忆(默认开),模型会自动捕获设定、黑话、人物、事实
  5. 如需主动发言,启用 proactiveEnabled 并调整相关参数
  6. 需要时配置 personaOverrides,为不同群或私聊注入性格
  7. 开启图片缓存(imageCache: all)后,群里的图片会按日期和 hash 落盘,聊天记录里会显示 [图片:<文件名>]

适用场景与注意

  • 适合:已经在用 NapCat / OneBot 11,希望把 DSH agent 直接接入 QQ 聊天,并需要会话记忆、性格设定、主动发言等能力的开发者
  • 注意:插件以当前 DSH 进程的权限运行;安装前应检查源码与许可证

结尾

dsh-napcat 把 NapCat 的 OneBot 11 事件转换成 DSH 的会话,让同一个 agent 同时服务多个 QQ 聊天。它提供了会话记忆、主动发言、性格设定、文件/图片收发等能力,适合想在 DSH 生态中快速接入 QQ 通道的开发者。

  • 目录页:https://www.skillhub.cn/plugins/wzwei1990/dsh-napcat
  • GitHub:https://github.com/wzwei1990/dsh-napcat
羽毛球分组比赛记分
小程序二维码

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

Xiaoye