QQ 群机器人部署实践:NapCat + OneBot 11 + FastAPI + DeepSeek API
目录
本文面向希望在 Linux 服务器上自建 QQ 群机器人的开发者。目标是把消息接入、模型调用、群聊触发策略和常驻运维一次跑通,而不是只停留在本地弹窗 Demo。示例使用 NapCat、OneBot 11、FastAPI 和 DeepSeek API,所有账号、IP、Token 与密钥均已脱敏。

部署流程分为六步:准备 Docker、启动 NapCat、扫码登录、配置反向 WebSocket、部署 Bot、群内验证。下图给出顺序关系。

一、方案与整体架构
整个系统分为四层:
- QQ 客户端层:NapCat 在容器内运行 QQ NT 客户端,负责登录、收发消息。
- 协议适配层:NapCat 提供 OneBot 11 接口,通过反向 WebSocket 主动连接业务服务。
- 业务层:FastAPI 进程接收事件,完成去重、上下文管理、触发判断、限流和 DeepSeek 调用。
- 模型层:DeepSeek API 提供对话生成,业务层只依赖 OpenAI 兼容接口。
部署时建议把 Bot 和 NapCat 放在同一台服务器,反向 WebSocket 走 127.0.0.1,不经过公网。NapCat 的 WebUI 只在首次扫码和网络配置时使用,配置完成后通过 SSH 隧道访问。
端口规划如下:
| 端口 | 用途 | 暴露范围 |
|---|---|---|
22 | SSH | 管理入口 |
6099 | NapCat WebUI | 仅本机或 SSH 隧道 |
18080 | FastAPI Bot | 仅 127.0.0.1 |
3000/3001 | OneBot HTTP/WS(可选) | 不启用或仅本机 |
二、前置条件与资源规划
建议配置:
- Linux x86_64 服务器,
2核2 GB内存起步;NapCat 和 Bot 常驻后内存占用约400 MB到700 MB。 - 已安装 QQ NT 的 NapCat Docker 镜像;无需在宿主机单独安装 QQ。
- Python
3.10+。 - 一个独立的测试 QQ 小号,不使用主号。
- 一个可用的 DeepSeek API Key。
资源规划的核心是隔离:NapCat 与 Bot 各自独立进程,Bot 只监听本机,NapCat 的登录态落在独立数据目录。这样升级 Bot 或重启 NapCat 时,不会互相影响。
三、安装 Docker 与基础环境
在 RHEL 系发行版上可以直接从系统源或 Docker 源安装。以下命令以 dnf 为例:
dnf -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin python3-pip
systemctl enable --now docker
docker --version
如果服务器访问 Docker Hub 较慢,可以配置镜像加速。创建 /etc/docker/daemon.json:
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"],
"log-driver": "json-file",
"log-opts": {
"max-size": "20m",
"max-file": "3"
}
}
重启 Docker 并确认镜像源生效:
systemctl restart docker
docker info --format '{{json .RegistryConfig.Mirrors}}'
镜像加速地址需要按实际云厂商替换,不要直接照搬到其他网络环境。
四、启动 NapCat 并完成扫码登录
先创建持久化目录:
mkdir -p /opt/napcat/{config,QQ,plugins}
使用宿主机网络启动 NapCat,这样容器内的反向 WebSocket 可以直接访问宿主机的 127.0.0.1:18080:
docker run -d --name napcat --restart=unless-stopped \
--network host \
--memory=1300m --memory-swap=2300m --shm-size=512m \
-e WEBUI_TOKEN='<随机 WebUI Token>' \
-v /opt/napcat/QQ:/app/.config/QQ \
-v /opt/napcat/config:/app/napcat/config \
-v /opt/napcat/plugins:/app/napcat/plugins \
mlikiowa/napcat-docker:latest
参数说明:
--network host:容器与宿主机共享网络,反向 WebSocket 可以直接连127.0.0.1。--memory与--memory-swap:给 NapCat 设置上限,避免异常时拖垮整机。--shm-size=512m:QQ 客户端需要一定的共享内存。WEBUI_TOKEN:WebUI 鉴权口令,不要使用默认值。
启动后查看日志,控制台会输出二维码或二维码文件路径:
docker logs --tail 120 napcat
docker cp napcat:/app/napcat/cache/qrcode.png /tmp/qrcode.png
用手机 QQ 的测试小号扫码登录。WebUI 地址一般是:
http://<服务器 IP>:6099/webui?token=<WebUI Token>
更安全的做法是本地建立 SSH 隧道,只在本机访问:
ssh -L 6099:127.0.0.1:6099 <用户名>@<服务器 IP>
登录成功后,NapCat 会显示账号在线。若二维码过期,重启容器或重新获取二维码即可。生产环境建议在容器启动参数中指定机器人账号,启用快速登录,减少重启后的扫码次数。
五、配置 OneBot 反向 WebSocket
NapCat 登录完成后,在 WebUI 的「网络配置」中添加「WebSocket 客户端(反向 WS)」,也可以直接编辑配置文件。账号级配置通常位于 /opt/napcat/config/onebot11_<QQ号>.json:
{
"network": {
"httpServers": [],
"httpSseServers": [],
"httpClients": [],
"websocketServers": [],
"websocketClients": [
{
"enable": true,
"name": "deepseek-bot",
"url": "ws://127.0.0.1:18080/onebot",
"reportSelfMessage": false,
"messagePostFormat": "array",
"token": "<OneBot Token>",
"debug": false,
"heartInterval": 30000,
"reconnectInterval": 30000
}
],
"plugins": []
},
"musicSignUrl": "",
"enableLocalFile2Url": false,
"parseMultMsg": false
}
关键点:
url指向 Bot 的/onebot路径。token必须与 Bot 环境变量ONEBOT_ACCESS_TOKEN完全一致,否则 Bot 会以1008关闭连接。messagePostFormat使用array,业务层直接处理消息段,避免解析 CQ 码。reportSelfMessage保持false,防止机器人把自己的消息再次当成用户输入。
六、FastAPI Bot 工程结构
工程可以保持很小,核心是清晰的职责划分:
qq-deepseek-bot/
├── main.py # WebSocket、事件处理、模型调用
├── config.py # 环境变量与默认配置
├── store.py # SQLite 上下文与群配置
├── requirements.txt
├── .env
└── deploy.py # 可选的远程部署脚本
消息处理链路如下:
OneBot 事件
→ 解析消息段 / @ 判断
→ message_id 去重
→ 写入 SQLite
→ 直接触发或主动接话判断
→ 组装最近上下文
→ DeepSeek 调用
→ 输出清洗 / 分段
→ send_group_msg 或 send_private_msg
1. WebSocket 入口
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
app = FastAPI()
@app.websocket("/onebot")
async def onebot_endpoint(ws: WebSocket):
if not authorized(ws):
await ws.close(code=1008, reason="invalid token")
return
await ws.accept()
while True:
try:
event = await ws.receive_json()
except WebSocketDisconnect:
break
await handle_event(ws, event)
authorized 同时兼容 Authorization: Bearer <token> 和 ?access_token=<token>,方便不同 OneBot 实现。
2. DeepSeek 调用
DeepSeek API 与 OpenAI SDK 兼容,只需要替换 base_url 和模型名:
from openai import AsyncOpenAI
client = AsyncOpenAI(
api_key="<DeepSeek API Key>",
base_url="https://api.deepseek.com",
timeout=30,
max_retries=1,
)
response = await client.chat.completions.create(
model="deepseek-flash",
messages=messages,
temperature=1.0,
max_tokens=1024,
reasoning_effort="low",
)
reply = response.choices[0].message.content.strip()
reasoning_effort 用于控制推理模型的思考开销。群聊场景建议使用 low,降低延迟和 token 消耗。如果切换到不支持该参数的模型,把这一项去掉即可。
3. 上下文与群配置
用 SQLite 保存最近消息和群级配置,避免进程重启后完全失忆:
messages:按chat_id保存最近200条消息,生成回复时只取最近30条。group_state:每个群的主动接话开关、概率、安静时段、最近回复时间、每小时回复次数。
按 chat_id 隔离上下文,群聊和私聊分开,避免不同会话串线。
4. 触发策略
群聊默认只有被 @、被叫名字或命中前缀时必回。主动接话使用“概率门控 + 一次 YES/NO 判断”:
- 给普通群消息记录上下文。
- 按群级概率决定是否进入候选。
- 进入候选后,用一次低成本模型调用判断“此刻接话是否自然”。
- 通过后再生成正式回复,并受冷却时间和每小时上限约束。
这样普通群消息也能被处理,但不会变成刷屏机器人。每个群的开关、概率、安静时段都可以独立调整。
七、配置与 systemd 部署
.env 示例(所有敏感值都替换为占位符):
DEEPSEEK_API_KEY=<DeepSeek API Key>
DEEPSEEK_BASE_URL=https://api.deepseek.com
DEEPSEEK_MODEL=deepseek-flash
REASONING_EFFORT=low
ONEBOT_ACCESS_TOKEN=<OneBot Token>
HOST=127.0.0.1
PORT=18080
DB_PATH=bot.db
GROUP_TRIGGER_MODE=ambient
AMBIENT_DEFAULT_ENABLED=false
AMBIENT_PROBABILITY=0.15
AMBIENT_TRIAGE=true
AMBIENT_MIN_INTERVAL=25
AMBIENT_MAX_PER_HOUR=12
QUIET_START=0
QUIET_END=7
PRIVATE_ENABLED=false
REPLY_DELAY_MIN=1.5
REPLY_DELAY_MAX=4.0
创建虚拟环境并安装依赖:
cd /opt/qq-deepseek-bot
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt \
-i https://mirrors.tencentyun.com/pypi/simple
使用 systemd 托管:
[Unit]
Description=QQ DeepSeek Bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/qq-deepseek-bot
ExecStart=/opt/qq-deepseek-bot/.venv/bin/python main.py
Restart=always
RestartSec=3
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
启用并检查:
systemctl daemon-reload
systemctl enable --now qq-deepseek-bot
systemctl is-active qq-deepseek-bot
curl -s http://127.0.0.1:18080/health
journalctl -u qq-deepseek-bot -n 30
docker logs --tail 50 napcat
日志里出现 onebot connected: 127.0.0.1,说明 NapCat 的反向 WebSocket 已经连上 Bot。随后在测试群内 @ 机器人即可验证完整链路。
八、群聊行为与管理员命令
部署完成后,不建议直接在所有群开启主动接话。可以先在测试群内使用管理员命令控制:
!ai status
!ai on
!ai prob 0.15
!ai quiet 23 8
!ai off
推荐流程:
!ai status查看当前开关、概率、冷却和每小时上限。!ai on只在测试群开启主动接话。- 用
!ai prob 0.15控制触发频率,避免频繁打断正常聊天。 - 用
!ai quiet 23 8设置夜间安静时段。 - 测试结束后
!ai off或调低概率。
管理员权限可以由群主/管理员角色判断,也可以额外配置管理员 QQ 白名单。私聊默认关闭,避免陌生用户消耗模型额度。
九、常见问题
| 现象 | 排查方向 |
|---|---|
没有 onebot connected | 检查 NapCat 反向 WS 的 URL、端口、Token;确认 Bot 已启动 |
| 连接后立即断开 | 两侧 Token 不一致,或 Bot 以 1008 拒绝 |
| 二维码过期 | 重启 NapCat,重新从日志或 /app/napcat/cache/qrcode.png 获取 |
8080 端口被占用 | 换成 18080,或检查现有 nginx 配置 |
| 机器人回复重复 | 检查 message_id 去重和平台重推日志 |
| 内存持续上涨 | 用 docker stats 观察 NapCat,必要时调低 --memory 或减少插件 |
| 重启后需要重新扫码 | NapCat 登录态失效;可配置账号快速登录 |
| DeepSeek 报错 | 检查 Key、余额、模型名与网络超时 |
十、小结
本文完成了一条可常驻的 QQ 群机器人链路:NapCat 负责 QQ 登录与 OneBot 协议,FastAPI 负责消息处理、上下文和模型调用,DeepSeek 提供对话能力,systemd 负责自动拉起。部署时最重要的是隔离与边界:WebUI 不公网暴露、Bot 只监听本机、Token 两侧一致、先用测试小号和小范围群验证。
标签:QQ机器人 NapCat OneBot FastAPI DeepSeek Linux
背景说明:本文来自测试环境部署实践,服务器 IP、QQ 号、群号、Token 与 API Key 均已脱敏。QQ 机器人应使用测试小号,并遵守平台规则;本文不涉及绕过平台风控或批量自动化操作。
参考资料:
- NapCatQQ:https://github.com/NapNeko/NapCatQQ
- OneBot 11 协议:https://github.com/botuniverse/onebot-11
- DeepSeek API 文档:https://api-docs.deepseek.com/
- FastAPI 文档:https://fastapi.tiangolo.com/
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)