最近折腾了个好玩的东西:给我一个 QQ 号装上了 DeepSeek 的大脑。别人在 QQ 上给它发消息,它会像真人一样回,会潜水、会接梗、会分几条短句回你,甚至能自己去搜资料、发表情包。整条链路跑通那天我截图发群里,好几个人问我是不是偷偷雇了个客服。

这篇文章把整个部署过程完整记下来,包括我踩的几个坑——尤其是 npm 新版本那个安装脚本拦截的坑,网上中文资料还很少。

先搞清楚:这套东西一共几个零件

一开始我也被三个名词绕晕了,其实打个比方就明白了:大脑、嘴巴、神经。

DSH(DeepSeek Harness)是大脑。DeepSeek 官方出的 agent 运行时,一个跑在本地的 Web 服务,负责「想」——你给它 API Key,它管会话、管记忆、管调用模型。默认地址 127.0.0.1:3080。

SnowLuma是嘴巴。它通过原生组件挂进 QQ 客户端进程,把 QQ 收到的消息变成 OneBot v11 标准事件往外吐,也能把指令变成 QQ 消息发出去。注意:它只有 Windows 版,因为要注入 Windows 上的 QQ 客户端。自带一个 WebUI 管理界面。

qq-bridge是中间的神经。一个开源的 Node.js 桥接项目,把 SnowLuma 收到的 QQ 消息投给 DSH 的会话,再把 AI 的回复发回 QQ。它还带了一个挺漂亮的自带控制台(3100 端口),白名单、防刷屏、表情包、语音、token 用量统计这些都做进去了。

三个零件各自装,各自启动,靠端口互相连。数据流向就是:QQ 消息 → SnowLuma → qq-bridge → DSH → DeepSeek 服务器 → 原路返回。

装在哪?我先走了弯路

我的第一反应是扔服务器上。还真部署了一轮——服务器上 Node 环境现成的,克隆仓库 npm install 一气呵成。但跑到一半我反应过来一个问题:SnowLuma 只有 Windows 版,而且它要注入的是 QQ 客户端进程。也就是说不管怎么部署,都必须有一台 Windows 电脑常年挂着 QQ。这台电脑一关机,整个机器人都哑了。

既然命门在本地电脑上,那 DSH 和桥接放服务器就没什么意义了,反而要搞 SSH 隧道跨公网连接,多一个故障点。所以最后的架构很朴素:四样东西全装在一台 Windows 电脑上,全部 127.0.0.1 本机互通,零隧道。服务器那份部署留着当备份。

如果你也想玩,先想清楚一件事:那台电脑得常开。我家是拿一台挂机的小主机专门干这个的。

准备清单

开始之前把这几样备齐:

  • 一台 Windows 电脑(要一直开着),内存最好空闲 4G 以上——QQ 本身就吃内存

  • Node.js 22.19 以上,官网 nodejs.org/zh-cn 下 LTS 版一路下一步

  • DeepSeek API Key,去 platform.deepseek.com 创建,sk- 开头那个

  • 一个当机器人的 QQ 号 + 你自己的号(用来测试和当管理员)

要下载的就两个压缩包,DSH 是 npm 命令装的:

第一步:装 DSH,先过一个新坑

开个 CMD,两条命令:

npm install -g @deepseek-ai/dsh
dsh web

第一次跑会下载 300 多 MB 依赖,屏幕一直滚字没有进度条,等个几分钟到十来分钟是正常的,别以为死机了。最后打印出 http://127.0.0.1:3080 就算起来来了,浏览器打开,设置里把 API Key 填上。

这里就是今天最大的坑。我装完启动,日志里刷了一排 npm warn allow-scripts 5 packages have install scripts not yet covered by allowScripts,当时没当回事。后来 DSH 各种功能不对劲才发现:npm 从 12 版本开始,默认不执行依赖包的安装脚本了(防供应链攻击的新安全机制),它只给你 warning 不给你报错,包装得「看起来很成功」,实际缺胳膊少腿。被拦的里面 koffi、node-pty 这些都是 DSH 跑起来的关键原生模块。

更坑的是网上搜到的 npm approve-scripts 那套批准流程只对项目内安装有效,我全局装的时候跑它,只会回你一句「No packages with unreviewed install scripts」,纯纯误导。全局安装得用另一套:直接放开限制再重装。

npm config set allow-scripts=all --location=user
npm install -g @deepseek-ai/dsh

第一条把 npm 的行为恢复成老样子(写进用户级配置,一劳永逸),第二条重装让刚才被拦的脚本补跑。这次没有那串 warn 才算干净。

顺带一提,如果你 npm 版本还是 11.x,只会 warning 不会拦截,可以不折腾。用 npm -v 自己看。

第二步:装 qq-bridge 并挂进 DSH

解压 qq-bridge-main 到任意目录(我放 Downloads 了),CMD 里进目录:

cd C:\Users\你的用户名\Downloads\qq-bridge-main
npm install
copy config.example.json config.json
node scripts/setup-dsh.mjs

最后这条是重点,它会把两个聊天预设(qq-chat / qq-chat-v2)和三个 MCP 工具挂进 DSH 的配置里。不跑这条,AI 在 QQ 上永远不会回话——桥接会拒绝给 QQ 会话使用默认预设,这是刻意设计的安全机制,防止群友的会话落到带文件读写权限的完整工具面上。

脚本跑完有一行提示:dsh plugin --profile web install 返回退出码 1,要手动补跑。而我补跑的时候又踩一坑:

dsh plugin --profile web install
'pnpm' 不是内部或外部命令,也不是可运行的程序

DSH 这条命令底层要调 pnpm,电脑上没装。补上就行:

npm install -g pnpm
dsh plugin --profile web install

看到 Already up to date. Done in 10s using pnpm v12.16.1 就成功了。

然后重启 DSH(Ctrl+C 停掉再 dsh web),重启后浏览器打开 3080,新建会话时预设列表里能看到「QQ 聊天角色」和「QQ 聊天角色(二代仿真)」两项,说明挂载成功。

第三步:SnowLuma 和 QQ 扫码

SnowLuma 解压后先别急着启动,顺序很重要:先把 QQ 客户端打开并登录,再运行 SnowLuma 目录里的 launcher.exe,因为它要注入 QQ 进程,QQ 不在线注入不上。

launcher 跑起来后,看它日志里印的 WebUI 地址(一般是 http://localhost:5099)和初始密码。浏览器打开,用初始密码登录,走引导:同意条款 → 设自己的密码 → 扫码登录 QQ(拿 bot 号的手机 QQ 扫)。

登录完在 OneBot 配置里开两个东西:

  • WebSocket 服务端,端口 3001

  • HTTP API,端口 3000

这两个端口就是等会儿桥接要连的,跟默认配置正好对上,不用改桥接的 config。

第四步:启动桥接,看成功标志

双击 qq-bridge 目录里的 start.bat(守护模式,崩了会自动拉起)。窗口里出现这两行,整条链路就通了:

[bridge] DSH 已连接
[bridge] SnowLuma 已连接:ws://127.0.0.1:3001

启动时它还会打两条 warning:白名单为空、未配置 ownerQQ。这两个不处理的话 bot 对任何消息都装死,所以接着配。

浏览器开 http://127.0.0.1:3100,这是桥接自带控制台,做得很完整:运行总览、会话审批、人格角色、令牌与花费统计都有。访问令牌在 qq-bridge 目录 state\console-token 文件里,记事本打开复制。进「访问与安全」页:

  • 把你自己的 QQ 号填进私聊白名单(allow.private)

  • ownerQQ 填你的号(解锁管理命令和工具审批)

  • 要玩群聊就把群号填进 allow.groups

配完用你自己的号私聊 bot 发句「你好」,第一次它会慢一点(要建会话挂预设),之后就是拟人化的节奏了——二代仿真模式下它会先观察、会潜水、分几条短句回你,不是那种客服腔。

踩坑清单,快速对号

最后把今天踩的坑汇总一下,遇到同款报错直接对号:

现象

原因

解决

npm warn allow-scripts 一串,装完功能不对

npm 12 默认拦截依赖安装脚本

npm config set allow-scripts=all --location=user 后重装

npm approve-scripts 说没有待审脚本

该命令只对项目内安装有效,全局安装不适用

全局安装用上面那条 config 命令

dsh plugin 报 pnpm 不是内部或外部命令

没装 pnpm

npm install -g pnpm 后重跑

QQ 发消息 bot 完全不回

白名单为空是刻意的 fail-closed 设计;或者 setup-dsh.mjs 没跑/DSH 没重启

控制台填白名单,确认预设已挂载并重启 DSH

桥接日志先报 1006 断开又报已连接

SnowLuma 的 HTTP 和 WS 是两个 token,首次连接被拒后自愈,正常现象

不用管,除非后面出现「token 自愈失败」

跑起来之后

三个窗口(dsh web、start.bat、SnowLuma)加一个 QQ 客户端都得开着,哪个关了链路就断。等哪天想让它开机自启、后台常驻,再做成 Windows 服务也不迟。

玩的时候注意两点:一是 API 按量计费,控制台的「令牌与花费」页能看到烧了多少钱,群聊模式开着的话消耗会比私聊快不少,先白名单再放开;二是 SnowLuma 的 EULA 禁止脚本化批量部署,自己玩没问题,别拿去封装分发。

就这些。从零到 bot 在 QQ 上开口说话,顺利的话一个多小时,不顺利的话——参考我,大半天,全填坑里了。