dsh-qq-bot
非官方移植:本项目是 QQ-bot 的 DeepSeek Harness 插件版。 原项目作者 ezoiLZH —— 人设协议、表情包机制、消息聚合、SKIP/LEAVE 冷却、群内指令等设计全部来自原项目,特此致谢。 本项目经原作者许可发布;按原作者要求,任何转载或二次分发请保留本段署名与上方原项目链接。 如果原作者希望调整署名或撤下本项目,开个 issue 即可,我会立刻处理。
仓库:https://github.com/wufa-cat/dsh-qq-bot · 下载:https://github.com/wufa-cat/dsh-qq-bot/releases
把 QQ 变成 DeepSeek Harness 的聊天入口:OneBot v11(NapCat)收消息,Harness 的模型回消息。 macOS 与 Windows 都能开箱即用——装好插件,在界面里点几下就能跑起来,不需要命令行、不需要 clone 任何仓库。
- 每个 (机器人, 群/私聊) 一个持久 agent 会话,人设走系统提示词
- 消息聚合、冷却限频、
[SKIP]/[LEAVE]行为 - 人格(
persona/*.md)在插件界面里直接编辑 - 表情包按「机器人/分类」管理,界面里上传、删除、直接测试发送
- NapCat(Docker)服务的启动/停止/重启、扫码登录、环境自检、目录打开全在界面里
- 工具白名单:聊天会话默认一个工具都不给;要联网才开
web_search(P0,防止群友间接拿到命令能力) - 对话巡检:状态灯 + 最近事件 + 跳过原因 + 聊天记录尾巴,排障不用翻日志
- 关键词规则:命中直接回,不进模型
- 定时消息:每天/指定星期往群里发固定内容
- 长期记忆:直接在界面里编辑
data/memory-<chat>.json - 语音合成 / 生图:TTS 与图片生成,全部用你自己填的 API Key(不做 ASR,用 QQ 自带的语音转文字)
- 图片多模态、B 站/分享链接解析、群内指令(
/ping、/表情、/reload…)
一、准备:装 Docker
机器人通过 NapCat 连接 QQ,NapCat 跑在 Docker 里。
Windows
- 安装 Docker Desktop for Windows(自带
docker compose)。 - 启动 Docker Desktop,等托盘图标变成绿色(引擎就绪)。
- 不需要在 WSL 里手动装任何东西。
macOS
任选一种:
Docker Desktop:装好并启动即可;
colima(更轻):
brew install colima docker docker-compose colima start --arch aarch64 --vm-type vz --cpu 2 --memory 4插件会在点「启动服务」时自动
colima start(已装但没运行时)。
Linux 也能跑(用系统 Docker),只是没做专门适配。
二、安装插件
需要已安装 DeepSeek Harness(桌面版或 Web 版)。
# 直接从 GitHub Release 装(推荐)
dsh plugin --profile desktop add https://github.com/wufa-cat/dsh-qq-bot/releases/download/v1.3.0/dsh-qq-bot-1.3.0.tgz
# 或者用本地下发的 tarball / 目录
dsh plugin --profile desktop add ./dsh-qq-bot-1.3.0.tgz
# 或者直接用目录
dsh plugin --profile desktop add /path/to/dsh-plugin
# 发布到 npm 之后也可以
dsh plugin --profile desktop add dsh-qq-bot
--profile desktop是桌面版专用 profile;Web 版改成--profile web。 目录软链安装(add /path/to/dsh-plugin)不会安装插件的依赖,v1.2.2 起已自动回退到 Node 内置 WebSocket,不需要额外处理。
安装完完全退出并重启 Harness(Cmd+Q / 托盘退出),让 Host 侧代码生效。
三、界面里配置(三步)
打开 设置 → QQ 机器人(也可以在插件页找到 QQ 机器人那一行)。
1. 初始化目录
点服务卡片里的 「初始化目录」。它会创建(已存在的绝不覆盖):
~/dsh-qq-bot/ ← 默认工作目录(Windows: %USERPROFILE%\dsh-qq-bot)
├── persona/人设参考模板.md
├── stickers/
├── data/
└── onebot/napcat-docker/
├── docker-compose.yml ← 已配好端口与 WebUI 令牌
├── README.md
└── data/{qq,config,plugins}
想换位置:把「工作目录」填成别的绝对路径,再点一次「初始化目录」。
2. 启动服务并扫码登录
- 点 「环境自检」 先确认 Docker / compose / 目录都是 ✔;
- 点 「启动服务」,插件会
docker compose up -d,并自动打开 NapCat WebUI; - WebUI 里用机器人 QQ 扫码登录(首次约 2 分钟出码,过期就点「重启」重新生成)。
3. 添加机器人
在「机器人」卡片点 添加机器人,填:
| 字段 | 说明 | 例子 |
|---|---|---|
| QQ 号 | 机器人自己的 QQ | 3177752843 |
| 名字 | 日志与表情包目录用 | 千早爱音 |
| 人设 | persona/ 里的文件名(不带 .md) |
Anonther |
| 管理员 | 能用 /reload、/clear 的 QQ 号,逗号分隔 |
3635811460 |
| WS 地址 | 默认指向本机 NapCat | ws://127.0.0.1:3001 |
| WS Token | NapCat 没设就留空 |
保存后插件会重载并连接。日志里看到 qq-bot: 🤖 [名字] ... 就说明通了。
四、人格
「人格」卡片:列出 persona/*.md,点名字在页面里编辑,保存后群里发 /reload(管理员)让机器人换用新人设。
也可以新建(带模板)、删除、重命名。人设内容会作为系统提示词注入每个会话。
五、表情包
目录结构(机器人名字必须与配置里的「名字」一致):
stickers/
└── 千早爱音/
├── 开心/开心.jpg
├── 喜欢/喜欢.png
└── 震惊/震惊-这啥啊.jpg
- 分类名 = 目录名;目录里的图片文件名随意,支持 png/jpg/jpeg/gif/bmp/webp;
- 模型在回复里写
[动画表情:分类名],插件随机挑一张发出去(整条回复只有这个标记时就是单发一张表情); - 插件把「可用分类」自动写进提示词,不需要在人设里手写清单;
- 界面里可 上传图片到分类、新建分类、展开删除;
- 发送用
base64://而不是本地路径——NapCat 在容器里看不到宿主机路径,用路径会静默失败; - 回复长度限制(
chat.maxReplyLength,默认 800)作用在展开表情之前,不会把 base64 截断; - 手动测试:群里
@机器人 /表情列分类,@机器人 /表情 开心直接发一张。
旧布局兼容:
stickers/<分类>/图片也能识别(当stickers/<机器人名字>/不存在时)。根目录直接放图片不会被发送——那些只会显示在卡片的「根目录图片」里。
六、工具白名单与联网搜索(P0)
群里任何人说话都可能触发模型,所以聊天档默认不给任何工具——不能跑命令、不能写文件、不能开子代理。
要什么给什么,白名单写在每个机器人的 tools 里:
| 开关 | 工具 | 说明 |
|---|---|---|
webSearch |
web_search |
联网搜索,默认 关 |
webFetch |
web_fetch |
抓取网页正文,默认 关(打开搜索后才有意义) |
实现是 ctx.tools.restrict({ allow }):只把白名单里的工具挂在聊天会话自己的 agent 作用域上,不影响你在 Harness 里正常用的工具;不认识的工具名会被过滤,不会因为 restrict 抛错而整行挂掉。
界面:插件页 → 机器人卡片 → 「工具权限」。也有运行时开关:
/搜索 on|off(管理员):下一轮重建会话时生效,/搜索不带参数看当前状态;- 「运行状态」卡片里的 开 / 关 / 跟随配置 按钮。
搜索凭据不是这个插件管的
搜索后端是 Harness 内置的 DeepSeek 官方搜索(deepseek-official):
- 用 DeepSeek 账号登录 Harness → 自动可用;
- 或环境变量
DEEPSEEK_API_KEY; - 或「设置 → 插件 → 官方 → 网页搜索」里填 Key。
⚠️ 聊天模型如果走别的 provider(例如 SiliconFlow),搜索仍需要单独的 DeepSeek 凭据,否则报 401。插件界面的状态卡会直接给出这条提示。 💰 Messages 模式搜索 = 一次完整模型调用(60s 超时、最多 5 次),开之前先想清楚值不值。
七、谁可以调用功能(权限)
每个功能单独设置,不再是一个总开关。五个功能:
| 功能 | 管的动作 |
|---|---|
image |
/画 描述、模型自主写的 [画图:…] |
tts |
/语音 文本、模型自主写的 [语音:…] |
sticker |
/收图(写表情包目录) |
search |
/搜索(切换联网) |
manage |
/ai、/clear、/reload |
access:
mode: admin # 默认范围:all 全员 | admin 仅管理员 | list 仅白名单
users: [] # 默认白名单 QQ
groups: [] # 默认白名单群号(群里任何人都算)
denyUsers: [] # 默认黑名单,永远优先
denyGroups: []
features: # 每个功能可以覆盖默认值;mode: inherit = 跟随默认
image: { mode: all }
tts: { mode: list, users: ["10001"], groups: ["123456789"] }
sticker:{ mode: admin }
search: { mode: inherit }
manage: { mode: admin, denyUsers: ["10002"] }
- 判定顺序:黑名单(默认+该功能)→ 管理员 → 该功能 mode(inherit 时用默认 mode);
- 名单和黑名单的条目:QQ 号,或
群:群号(群里任何人都算); - 管理员始终可用,除非被黑名单点名;
- 模型自主生成媒体时按触发这一轮的人判权限,没权限就把标记抹掉,不会把
[画图:…]原文发群里。
界面里就是一张表:每个功能一行,选范围、填名单(一行一个,也吃逗号)、黑名单折叠在下面。
八、生图 / TTS 自动识别模型
「多模态」卡片里,每个端点只要填了接口地址(到 /v1)+ API Key,就会自动拉一次上游模型列表(改 key 会防抖重拉),下拉里直接选;也可以手动点「拉取模型」。
- 只查模型 id,不参与调用;模型名仍可手填(填了就用手填的);
- 实现是
GET {baseURL}/models,兼容data[]/models[],去重排序; - 对话用的聊天模型不在这里选——那是 DSH 设置里的 provider/model。
对应接口:POST /qqbot-runtime/models,body { baseURL, apiKey | apiKeyEnv }。
九、对话巡检与状态灯
插件页顶部「运行状态」:
- 绿/红状态灯:是否连上 OneBot、重连次数、最近错误、已运行时长;
- 计数:收到消息 / 发出回复 / 跳过 / 错误;
- 搜索与 AI 的当前状态(只读;运行时开关用群指令
/搜索、/ai)。
「对话巡检」卡片:
- 最近 60 条事件:谁、在哪个聊天、说了什么、bot 回没回、为什么跳过(冷却 / 没被 @ / AI 关 / 聚合中);
- 下拉选一个
data/<chat>.json直接看最近 20 条聊天记录。
事件只存在内存环形缓冲(400 条),重启清空;聊天记录本体仍在 data/。
十、关键词规则
命中关键词直接回复,不进模型:快、省钱、不受上下文影响。
rules:
- enabled: true
pattern: 在吗
mode: contains # contains | exact | regex
reply: 在的 {user}
bots: [千早爱音] # 留空 = 所有机器人
reply支持{user}(昵称)、{qq}、{bot};- 规则优先于模型,但指令优先于规则(
/ping不会被规则抢走)。
十一、定时消息
schedules:
- enabled: true
label: 早安
at: "08:00"
days: [1, 2, 3, 4, 5] # 1=周一 … 7=周日;留空 = 每天
bot: 千早爱音
chat: group:123456789 # 或 private:10001
text: 早上好呀~ {weekday}
- 每 20 秒检查一次,同一天同一分钟只发一次;
{date}{time}{weekday}会替换;- 机器人不在线就跳过并记日志(不会补发)。
十二、长期记忆
「长期记忆」卡片直接编辑 data/memory-<chat>.json:一行一条,保存时自动补日期。
新会话建立(种子)时会把这些摘要注入提示词;也可以整份删除。
十三、语音合成 / 生图
「多模态」卡片,两套端点各自填 baseURL + API Key + 模型(OpenAI 兼容):
| 能力 | 接口 | 触发 |
|---|---|---|
| TTS | POST /audio/speech |
/语音 文本,或模型回复写 [语音:文本] |
| 生图 | POST /images/generations |
/画 描述,或模型回复写 [画图:描述] |
- 不做语音转文字(ASR):QQ 自带的语音转文字已经够用,插件不再重复实现;
- Key 可直接填,也可只填环境变量名(
apiKeyEnv),避免写进配置文件; - 默认 SiliconFlow +
CosyVoice2-0.5B/Kolors,只是默认值; - 没启用/没配 key:
[语音]保留占位,/画/语音直接报错,不静默失败; - 结果以 base64 内联发 NapCat,容器里也能发。
十四、群内指令
| 指令 | 说明 |
|---|---|
/help |
指令列表 |
/ping |
延迟测试 |
/time |
服务器时间 |
/表情 [分类] |
列出表情分类 / 直接发一张 |
/echo 文本 |
复读 |
/roll |
掷骰子 |
/calc 1+2*3 |
计算 |
/clear [N] |
清除对话记忆 |
/ai on|off|status |
开关 AI 回复(受 access.features.manage 限制) |
/收图 [分类] |
把图片收进表情包(受 access.features.sticker 限制) |
/搜索 [on|off|跟随] |
联网搜索开关(受 access.features.search 限制) |
/画 描述 |
生图(需配置 media.image;受 access.features.image 限制) |
/语音 文本 |
合成语音(需配置 media.tts;受 access.features.tts 限制) |
/reload |
重读人设与表情包(管理员) |
十五、目录与清理
「目录与清理」卡片:
- 一键打开 仓库目录 / 人格 / 表情包 / 聊天数据 / OneBot 目录;
- 清理未使用镜像:
docker system prune -af(在用的容器不受影响); - 删除虚拟机:仅 macOS + colima 可用,回收约 3.5 GB,下次启动会重建并重新拉镜像; Windows 上引擎在 WSL2 里,插件不会动它(要彻底重置用 Docker Desktop → Troubleshoot → Reset)。
十六、配置项(cordis.patch.yml)
界面保存的就是这些;一般不用手写。所有字段都有默认值,最小配置只需要 bots:
- id: qq-bot
name: dsh-qq-bot
config:
repoDir: "" # 留空 = ~/dsh-qq-bot(首次启动自动创建)
autoStart: true
bots:
- qq: "3177752843"
name: 千早爱音
persona: Anonther
admins: ["3635811460"]
ws: { url: "ws://127.0.0.1:3001", accessToken: "" }
# provider: guijiliudong # 可选:缺省用 DSH 默认模型
# model: deepseek-ai/DeepSeek-V4.1-Flash
timeout: 180
tools: { webSearch: false, webFetch: false } # 聊天档工具白名单
access: # 每个功能单独设;features 里的 mode=inherit 跟随默认
mode: admin
users: []
groups: []
denyUsers: []
denyGroups: []
features:
image: { mode: inherit }
tts: { mode: inherit }
sticker: { mode: inherit }
search: { mode: inherit }
manage: { mode: inherit }
rules: [] # 关键词规则
schedules: [] # 定时消息
media: # TTS / 生图(用你自己的 key,模型可自动识别)
tts: { enabled: false, baseURL: https://api.siliconflow.cn/v1, apiKey: "", model: FunAudioLLM/CosyVoice2-0.5B, voice: alex }
image: { enabled: false, baseURL: https://api.siliconflow.cn/v1, apiKey: "", model: Kwai-Kolors/Kolors, size: 1024x1024 }
service:
onebotDir: "" # 留空 = <repoDir>/onebot/napcat-docker
webuiPort: 6099
wsPort: 3001
chat:
maxReplyLength: 800 # 作用在展开表情之前
replyCooldown: 5
leaveCooldown: 300
logMaxEntries: 300
blacklistGroups: []
aggregation:
windowTimeout: 8
maxMessages: 8
rateLimit:
tier1Count: 3 # 1 分钟 ≥4 条 → 冷却 ×1.5
tier2Count: 10 # 5 分钟 ≥11 条 → 冷却 ×2
capCount: 15 # 10 分钟 ≥16 条 → 停止回复
provider/model 缺省时使用 DSH 全局默认模型;指定时使用该 provider(须已在 DSH 设置里配好)。
十七、界面背后的接口
界面按钮打到 Harness 自带 web 服务器的两个前缀(不额外开端口):
/qqbot-service/*:status、doctor(环境自检)、init(初始化目录)、action(start/stop/restart)/qqbot-files/*:list、persona/{load,save,create,delete,rename}、sticker/{upload,category,delete}、memory/{list,read,save,delete}、chats、chat/tail、open、clean/qqbot-status:状态灯数据(连接/计数/工具策略/搜索可用性)/qqbot-inspect:巡检事件/qqbot-runtime/{search,ai}:运行时开关(不改配置文件,重载后回到配置值)/qqbot-runtime/models:POST {baseURL, apiKey|apiKeyEnv}→ 上游模型 id 列表(界面「拉取模型」)
十八、运行日志
qq-bot: 仓库目录 /Users/you/dsh-qq-bot,数据目录 /Users/you/dsh-qq-bot/data
qq-bot: 初始化工作区,创建 12 项
qq-bot: 正在连接 ws://127.0.0.1:3001 ...
qq-bot: ✅ 已连接
qq-bot: 启动监测 [千早爱音] [chat=group-42]
qq-bot: 🤖 [千早爱音] 上下文 5行, 2图
qq-bot: 📤 [千早爱音] 分段回复 (2段)
十九、开发
node --check lib/*.js # 语法检查
npm run check # 同上(含 client.js)
npm pack # 打 tarball 给别人装
| 文件 | 作用 |
|---|---|
lib/index.js |
插件入口、Config schema、装配 worker |
lib/onebot.js |
OneBot v11 WS 客户端 |
lib/hub.js |
消息分发、指令、聚合 |
lib/bot.js |
单个机器人运行时(触发判断、限频、发送) |
lib/brain.js |
与 Harness agent 的桥接、会话压缩 |
lib/chatlog.js |
data/*.json 聊天日志(与原版兼容) |
lib/cq.js |
CQ 码解析、表情包、@、分段 |
lib/files.js |
人格/表情包/目录管理路由 |
lib/service.js |
Docker/NapCat 启停与自检 |
lib/scaffold.js |
工作区初始化(目录 + compose 模板) |
lib/platform.js |
平台差异(打开目录、compose 探测、虚拟机信息) |
lib/client.js |
界面(设置分区 + 插件页配置入口) |
二十、已知行为差异(相对原 Python 版)
- 命令必须空格分隔:
@bot /ping生效,@bot/ping不生效。 data/*.json里图片以liveImages(base64)内联保存,不再落data/images/。- compact 后的记忆总结不再自动生成;已有
memory-<chat>.json会继续注入种子文本。 - 一个 (bot, 聊天) 的会话在插件进程存活期间复用;DSH 重启后首轮用聊天日志窗口整体重建。
二十一、排障:插件「消失」与 404
| 现象 | 原因 | 处理 |
|---|---|---|
| 设置侧栏没有「QQ 机器人」、插件页也无此项 | Host 侧 apply()/import 失败(最常见:软链安装缺依赖) |
看启动日志的 failed to import;v1.2.2 起软链安装已自动回退内置 WebSocket |
界面卡片在,接口 404(/qqbot-status 等) |
页面刷新只换前端,Host 还是旧进程 | 完全退出并重启 Harness,不是刷新页面 |
状态灯红、lastError 有内容 |
NapCat 没起来 / 端口不对 / token 不对 | 用「服务」卡片启动,或 docker logs napcat |
| 搜索报 401 | 聊天模型不是 DeepSeek 账号模型,搜索仍需 DeepSeek 凭据 | 「设置 → 插件 → 官方 → 网页搜索」填 Key |
致谢
| 项目 | 说明 |
|---|---|
| ezoiLZH/QQ-bot | 原项目(Python + Claude Code CLI)。本插件的人设系统、表情包协议、消息聚合、冷却与指令都移植自它 |
| NapCatQQ | 本插件默认使用的 OneBot v11 实现(Docker 镜像 mlikiowa/napcat-docker) |
| LLOneBot | 另一种 OneBot v11 实现,同样可用 |
| DeepSeek Harness | 宿主:agent 会话、模型路由、系统提示词、插件槽位 |
出处引用:本项目基于 QQ-bot(作者 ezoiLZH)改写,经原作者许可发布;转载、二次分发请保留本段署名与链接。
原项目没有附带开源许可证,所以本移植版不对原项目的代码与设计主张任何权利;新增的插件封装、界面与跨平台适配代码以 MIT 发布(见 LICENSE 与 NOTICE)。
MIT License.
No comments yet. Be the first to write one.