Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ config/generation.toml
config/chat_rules.toml
config/games.toml
config/sensitive_words.toml
config/awakening.toml
config/personas/
config/llm.local.toml
config/llm.*.local.toml
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

本文件遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/) 规范,版本号遵循[语义化版本](https://semver.org/lang/zh-CN/)。

## [Unreleased]

### 变更

- 推荐 OneBot V11 基座从 NapCat 迁移至 LLBot:更新 compose 示例模板、部署文档、README;新增迁移指南 `docs/admin/migration-napcat-to-llbot.md`。NapCat 近期因 DLL 注入特征遭腾讯高强度风控(频繁 KickedOffLine / 静默掐断),LLBot 使用 PMHQ 外部内存 Hook 规避检测

## [1.6.1] - 2026-05-22

### 变更
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ QuickQuip(双 Q 谐音 = QQ + Quip/妙语)是一个**轻量级、规则驱

- **Python** ≥ 3.11
- **NoneBot2** + **OneBot V11 适配器**
- OneBot V11 协议实现端(如 [Lagrange.OneBot](https://github.com/LagrangeDev/Lagrange.Core)、[NapCat](https://github.com/NapNeko/NapCatQQ))
- OneBot V11 协议实现端(推荐 [LLBot](https://github.com/LLOneBot/LuckyLilliaBot),备选 [NapCat](https://github.com/NapNeko/NapCatQQ))

### 安装步骤

Expand Down
22 changes: 22 additions & 0 deletions config/awakening.toml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 唤醒模块配置。默认所有功能关闭(阈值 = 0 或 >= 1)。
# 复制为 config/awakening.toml 后按需修改。

[awakening.defaults]
extend_duration = 0 # 唤醒延长秒数,0=关闭
fallback_probability = 0 # 兜底概率 0-1,0=关闭
boredom_silence_seconds = 0 # 沉寂判定秒数,0=关闭
boredom_probability = 0 # 沉寂触发概率 0-1
boredom_check_interval = 300 # 无聊检查间隔秒数
boredom_dnd_start = "" # 免打扰开始 HH:MM,空=不启用
boredom_dnd_end = "" # 免打扰结束 HH:MM
interest_topics = [] # 全局兴趣关键词
relevance_threshold = 1.0 # 相关性唤醒阈值 0-1,>=1 关闭(不产生 LLM 调用)
qa_threshold = 1.0 # 答疑唤醒阈值 0-1,>=1 关闭(不产生 LLM 调用)

# 按群覆盖(可选,取消注释并填写群号)
# [[awakening.group_overrides]]
# group_id = "123456"
# extend_duration = 10
# interest_topics = ["编程", "Python"]
# relevance_threshold = 0.5
# qa_threshold = 0.88
8 changes: 8 additions & 0 deletions config/llm.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ empty_prompt_reply = "请在触发指令或艾特后面补上想说的话。"
enabled = false
search_max_calls_per_round = 3

# 快速判定专用模型(用于 context_rules llm_context、awakening 相关性/答疑判断等)。
# 留空则回退到 default_provider / default_model。推荐使用廉价小模型以降低成本。
[triggers.quick_judge]
provider_id = "" # 引用 [[providers]] 中的 id,留空用 default_provider
model = "" # 留空用该 provider 的 default_model
timeout = 2.0 # 秒
max_tokens = 64

[tools]
enabled = []
# 工具发现:工具较多时只常驻少量核心工具,其余工具由 tool_search
Expand Down
32 changes: 17 additions & 15 deletions docker-compose.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@
name: quickquip

services:
# ── QQ 协议适配器(NapCat)─────────────────────────────────────────────
# 参考:https://github.com/NapNeko/NapCatQQ
napcat:
image: mlikiowa/napcat-docker:latest
container_name: napcat
# ── QQ 协议适配器(LLBot)───────────────────────────────────────────────
# 参考:https://github.com/LLOneBot/LuckyLilliaBot
# 登录态 / 设备指纹保存在 llbot-qq/,切勿丢失否则 QQ 视作新设备。
llbot:
image: initialencounter/llonebot:latest
container_name: llbot
entrypoint:
- /entrypoint.sh
environment:
- ACCOUNT=${QQ_ACCOUNT:?请设置 QQ 号}
- WS_ENABLE=true
- WS_HOST=0.0.0.0
- WS_PORT=6099
- QUICK_LOGIN_QQ=${QQ_ACCOUNT:?请设置 QQ 号}
- TZ=Asia/Shanghai
ports:
- "127.0.0.1:6099:6099"
- "127.0.0.1:3000:3000"
- "127.0.0.1:3001:3001" # OneBot WebSocket(正向,备用)
- "127.0.0.1:3080:3080" # WebUI(扫码登录 / 配置管理)
volumes:
- napcat-data:/app/napcat/config
- ./llbot-qq:/root/.config/QQ # 登录态持久化(关键)
- ./llbot-data:/root/llonebot # 配置文件 + 运行时数据
- ./llbot-entrypoint.sh:/entrypoint.sh:ro # DNS 修复 wrapper
restart: unless-stopped

# ── 联网搜索(SearXNG)──────────────────────────────────────────────────
Expand Down Expand Up @@ -53,14 +56,14 @@ services:
image: ghcr.io/3aKHP/quickquip:latest
container_name: quickquip
depends_on:
- napcat
- llbot
env_file:
- .env
environment:
DRIVER: "${DRIVER:-~fastapi}"
HOST: "${HOST:-0.0.0.0}"
PORT: "${PORT:-8080}"
ONEBOT_WS_URLS: '${ONEBOT_WS_URLS:-["ws://napcat:6099"]}'
ONEBOT_WS_URLS: '${ONEBOT_WS_URLS:-["ws://llbot:3001/"]}'
ONEBOT_ACCESS_TOKEN: "${ONEBOT_ACCESS_TOKEN:-}"
SEARXNG_BASE_URL: "${SEARXNG_BASE_URL:-http://searxng:8080}"
volumes:
Expand Down Expand Up @@ -117,5 +120,4 @@ services:
restart: unless-stopped

volumes:
napcat-data:
searxng-cache:
18 changes: 9 additions & 9 deletions docs/admin/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LLM 模块的详细结构、边界和群内命令说明见 [../dev/llm-module.md

- 一台 Linux 服务器(1 核 1G 即可)
- 已安装 Docker 和 Docker Compose
- QQ 账号(用于 NapCat 登录)
- QQ 账号(用于 LLBot 登录)

## 推荐服务器

Expand Down Expand Up @@ -114,16 +114,16 @@ data/tieba/storage_state.json

容器化部署时,`data/fonts/` 目录应通过 `data/` bind mount 挂载到容器内,字体文件上传一次后即可持久使用。若字体文件缺失,执行 `/wordcloud` 时 bot 会回复明确的错误提示。

### 5. 首次登录 NapCat
### 5. 首次登录 LLBot

NapCat 首次启动需要扫码登录:
LLBot 首次启动需要扫码登录:

```bash
# 查看 NapCat 日志,找到登录二维码
docker compose logs -f napcat
# 查看 LLBot 日志,找到登录二维码
docker compose logs -f llbot
```

日志中会出现二维码或登录链接,用手机 QQ 扫码确认。登录成功后,登录态会持久化在 `napcat-data/` 目录中。
日志中会出现二维码或登录链接,用手机 QQ 扫码确认。登录成功后,登录态会持久化在 `llbot-qq/` 目录中,配置文件在 `llbot-data/` 中。也可通过 WebUI(`http://<服务器IP>:3080`)扫码

### 6. 验证运行

Expand Down Expand Up @@ -221,13 +221,13 @@ docker compose down

当前项目已经同时保留 Tavily 直连能力和 MCP 扩展能力。MCP 集成的正式约定见 [../dev/mcp-integration.md](../dev/mcp-integration.md)。

### NapCat 登录态过期
### LLBot 登录态过期

换 IP 或长时间未活动后可能需要重新扫码:

```bash
docker compose restart napcat
docker compose logs -f napcat # 找新的二维码
docker compose restart llbot
docker compose logs -f llbot # 找新的二维码
```

### QQ 风控/冻结
Expand Down
180 changes: 180 additions & 0 deletions docs/admin/migration-napcat-to-llbot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# NapCat → LLBot 迁移指南

QuickQuip 设计之初即以 NapCat(Docker 镜像 `mlikiowa/napcat-docker`)作为推荐的 OneBot V11 QQ 协议适配器。截至 2026 年 5 月中下旬,NapCat 遭遇腾讯高强度风控打击,社区和我们的生产环境均反复出现以下问题:

1. **频繁 KickedOffLine**:上线后数小时内被强制踢下线
2. **静默掐断**:QQ 连接无任何错误日志直接停止推送消息,手机端 QQ 同步被踢,疑似封号前兆
3. 尝试 NapCat 反检测构建([PR #1768](https://github.com/NapNeko/NapCatQQ/pull/1768))后仍无法稳定

社区反馈([Issue #1728](https://github.com/NapNeko/NapCatQQ/issues/1728))确认此问题广泛存在。经评估其他 OneBot V11 方案后,推荐迁移至 [LLBot](https://github.com/LLOneBot/LuckyLilliaBot)(LuckyLilliaBot)。

## 为什么选 LLBot

| | NapCat | LLBot |
|---|---|---|
| 原理 | DLL 注入 QQ 进程 | PMHQ 外部内存 Hook(独立进程) |
| 被检测面 | QQ 进程内 DLL 模块可被扫描 | QQ 进程空间无修改,更难检测 |
| Docker 镜像 | `mlikiowa/napcat-docker`(~1.2GB) | `initialencounter/llonebot:latest`(~880MB) |
| 签名服务器 | 无需(QQ 自带) | 无需(QQ 自带) |
| 社区活跃度 | 9k+ stars | 3.3k+ stars,日更 |
| OneBot V11 兼容 | 反向 WS、正向 WS | 反向 WS、正向 WS、HTTP、HTTP POST |

核心区别:NapCat 把 DLL **塞进 QQ 进程内部**,腾讯可以扫描进程空间检测到外挂模块。LLBot 使用 **PMHQ(Pure Memory Hook for QQNT)**——一个独立进程通过 Linux 内存机制从外部与 QQ 交互,QQ 进程本身干干净净。

**QuickQuip 核心业务代码无需任何改动**——两者均通过标准 OneBot V11 反向 WebSocket 与 NoneBot 通信,接口完全一致。

## 迁移步骤

以下步骤基于 `docker-compose.example.yml` 的结构。如果你的部署使用了自定义 compose 文件,请对应调整。

### 1. 在 `docker-compose.yml` 中新增 LLBot 服务

```yaml
services:
llbot:
image: initialencounter/llonebot:latest
container_name: llbot
entrypoint:
- /entrypoint.sh
environment:
- QUICK_LOGIN_QQ=${QQ_ACCOUNT:?请设置 QQ 号}
- TZ=Asia/Shanghai
ports:
- "127.0.0.1:3001:3001" # OneBot WebSocket(正向,备用)
- "127.0.0.1:3080:3080" # WebUI(扫码登录 / 配置管理)
volumes:
- ./llbot-qq:/root/.config/QQ # 登录态持久化(关键,切勿丢失)
- ./llbot-data:/root/llonebot # 配置文件 + 运行时数据
- ./llbot-entrypoint.sh:/entrypoint.sh:ro # DNS 修复 wrapper
restart: unless-stopped
```

**重要**:LLBot 镜像的入口脚本会将容器 DNS 指向公网服务器,导致无法解析 Docker Compose 内部服务名。需挂载修复脚本(见下方)。

### 2. 创建 DNS 修复脚本

在 compose 同目录下创建 `llbot-entrypoint.sh`:

```bash
#!/bin/sh
echo 'nameserver 127.0.0.11' > /etc/resolv.conf
echo 'options ndots:0' >> /etc/resolv.conf
exec /bin/llonebot-service
```

```bash
chmod +x llbot-entrypoint.sh
```

### 3. 创建 OneBot 配置文件

LLBot 的配置为 JSON 格式,位于 `llbot-data/default_config.json`。最小配置(启用反向 WS):

```json
{
"webui": { "enable": true, "host": "", "port": 3080 },
"ob11": {
"enable": true,
"connect": [
{
"type": "ws-reverse",
"enable": true,
"url": "ws://quickquip:8080/onebot/v11/ws/",
"heartInterval": 60000,
"token": "",
"messageFormat": "array"
}
]
},
"log": true,
"msgCacheExpire": 120
}
```

> **注意**:容器首次启动时入口脚本会用内置默认配置覆盖此文件。建议先启动容器完成首次登录,再通过 WebUI(`http://<服务器IP>:3080`)配置反向 WS,或使用 `docker exec` 修改 `data/config_<QQ号>.json`。

### 4. 更新 QuickQuip 服务

在 compose 中将 QuickQuip 的 `depends_on` 和 `ONEBOT_WS_URLS` 更新为指向 LLBot:

```yaml
quickquip:
depends_on:
- llbot
environment:
ONEBOT_WS_URLS: '${ONEBOT_WS_URLS:-["ws://llbot:3001/"]}'
```

### 5. 启动并扫码登录

```bash
docker compose up -d llbot
# 查看日志获取二维码或访问 WebUI
docker compose logs -f llbot
# 或者浏览器打开 http://<服务器IP>:3080
```

扫码完成后重启 QuickQuip 建立新连接:

```bash
docker compose restart quickquip
```

验证连接成功:

```bash
docker compose logs quickquip | grep "Bot.*connected"
# 应输出: OneBot V11 | Bot <你的QQ号> connected
```

### 6. 移除旧 NapCat 服务(验证稳定后)

```bash
docker compose stop napcat
# 观察 24-48 小时确认稳定后
docker compose rm napcat
```

NapCat 的登录态和数据卷(`napcat-data/`)建议在确认稳定前保留,以便快速回退。

## OneBot WS 模式说明

LLBot 同时支持正向和反向 WebSocket。QuickQuip 的默认 `~fastapi` driver 使用**反向 WS**——LLBot 作为客户端连接到 QuickQuip 的 `/onebot/v11/ws/` 端点。这与 NapCat 时期的行为完全一致,无需调整 NoneBot 配置。

正向 WS(端口 3001)作为备用保留,`ONEBOT_WS_URLS` 中的默认值即指向此端口。

## 已知差异

| 项 | NapCat | LLBot | 影响 |
|---|---|---|---|
| 长消息限制 | ~667 汉字截断 | 更高(未实测) | 800 字分块策略对两者均有效 |
| QQ 版本 | 3.2.28 | 3.2.25 | 略旧,腾讯可能未来强制升级 |
| 自动登录 | `ACCOUNT` 环境变量 | `QUICK_LOGIN_QQ` 环境变量(可能不生效) | 重启后可能需要重新扫码 |
| WebUI 端口 | 6099 | 3080 | SSH 隧道端口变更 |
| 日志格式 | `账号状态变更为在线` | `PMHQ WebSocket 连接成功` | 如有自定义监控需适配 |

## 回退步骤

如 LLBot 出现严重问题:

```bash
# 停止 LLBot
docker compose stop llbot

# 恢复 ONEBOT_WS_URLS
# 将 .env 或 compose 中的 ws://llbot:3001/ 改回 ws://napcat:6099

# 恢复 depends_on(如有改动)

# 重启 QuickQuip
docker compose restart quickquip

# 启动 NapCat
docker compose start napcat
```

## 参考

- [LLBot 官方文档](https://luckylillia.com)
- [NapCat Issue #1728 - 风控掉线讨论](https://github.com/NapNeko/NapCatQQ/issues/1728)
- [NapCat PR #1768 - 反检测实验分支](https://github.com/NapNeko/NapCatQQ/pull/1768)
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ QuickQuip 是一个基于 NoneBot2 + OneBot V11 的规则驱动优先 QQ 群聊

| 文件 | 说明 |
|------|------|
| [admin/deployment.md](admin/deployment.md) | 云端部署指南——服务器选型、Docker Compose 编排、NapCat 登录、贴吧登录态、Web Admin 反代、日常维护与排障 |
| [admin/deployment.md](admin/deployment.md) | 云端部署指南——服务器选型、Docker Compose 编排、LLBot 登录、贴吧登录态、Web Admin 反代、日常维护与排障 |
| [admin/configuration.md](admin/configuration.md) | 完整配置参考——`.env` 环境变量、`llm.toml`、`generation.toml`、`chat_rules.toml`、`personas/` 所有可配项 |
| [admin/tool-discovery.md](admin/tool-discovery.md) | LLM 工具发现配置——大量 MCP 工具接入时的 `tool_search`、`tool_list`、常驻工具和排障建议 |
| [admin/game-config.md](admin/game-config.md) | 游戏系统管理——游戏开关、参数配置、数据库文件、故障排查 |
Expand Down
9 changes: 9 additions & 0 deletions plugins/awakening.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from quickquip.adapters.nonebot.awakening_plugin import (
boredom_enabled_groups,
setup,
)

__all__ = [
"boredom_enabled_groups",
"setup",
]
Loading
Loading