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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ TIEBA_SYNC_INTERVAL_SECONDS=900
TIEBA_MAX_POOL_SIZE=240
TIEBA_DETAIL_FETCH_LIMIT=18
TIEBA_RECENT_SENT_LIMIT=30
TIEBA_RANDOM_AVOID_RECENT=10
TIEBA_RANDOM_AVOID_RECENT=30
TIEBA_PREFER_IMAGE_THREADS=true
TIEBA_BROWSER_HEADLESS=true
TIEBA_BROWSER_CHANNEL=
Expand Down
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@

## [Unreleased]

### 新增

- 群聊唤醒模块:新增唤醒延长、兴趣话题、相关性判定、答疑判定、无聊唤醒、兜底概率六类主动响应入口;配置集中在 `config/awakening.toml`,群内通过 `/awakening` 查看状态并管理规则开关。
- Web 管理后台唤醒页支持按群编辑唤醒延长、兜底概率、无聊唤醒、相关性判定和答疑判定参数,保存后通知 bot 重载规则配置。

### 变更

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

### 修复

- `/llm reload` 现在会同步刷新敏感词过滤器;`config/sensitive_words.toml` 继续仅通过服务器本地文件或部署流程维护,不在 Web Admin 中回显或编辑。
- Web Admin 唤醒参数保存后会通知 bot 重载 `config/awakening.toml`,并移除 API 响应中的服务端配置路径。
- Web Admin 诊断页健康检查改由 bot 侧动作队列执行;动作队列启用 WAL,并会回收长时间停留在 `running` 的中断任务。

## [1.6.1] - 2026-05-22

### 变更
Expand Down Expand Up @@ -427,7 +438,11 @@
- 初始化项目骨架:NoneBot2 + OneBot V11,规则驱动回复
- 时区猜测、复读检测、好姐姐接龙、文字 meme 回复

[Unreleased]: https://github.com/3aKHP/QuickQuip/compare/v1.4.4...HEAD
[Unreleased]: https://github.com/3aKHP/QuickQuip/compare/v1.6.1...HEAD
[1.6.1]: https://github.com/3aKHP/QuickQuip/compare/v1.6.0...v1.6.1
[1.6.0]: https://github.com/3aKHP/QuickQuip/compare/v1.5.0...v1.6.0
[1.5.0]: https://github.com/3aKHP/QuickQuip/compare/v1.4.5...v1.5.0
[1.4.5]: https://github.com/3aKHP/QuickQuip/compare/v1.4.4...v1.4.5
[1.4.4]: https://github.com/3aKHP/QuickQuip/compare/v1.4.3...v1.4.4
[1.4.3]: https://github.com/3aKHP/QuickQuip/compare/v1.4.2...v1.4.3
[1.4.2]: https://github.com/3aKHP/QuickQuip/compare/v1.4.1...v1.4.2
Expand Down
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ QuickQuip(双 Q 谐音 = QQ + Quip/妙语)是一个**轻量级、规则驱
- **金币经济系统** — 每日签到累加连击、好感度成长、金币排行,所有对战游戏共用下注和结算。参数集中在 `config/games.toml` 配置
- **节日自动化** — 内置 6 个中国传统节日(公历+农历),自动切换 bot 语气并发送 persona 口吻问候
- **轻娱乐与互动** — `/roll` 掷骰子、`/choose` 随机选择、`/fortune` 每日运势、`/vote` 投票、`/quote` 语录收藏、`/find` 群聊搜索、`/tell` 离线留言
- **词云生成** — `/wordcloud` 按 today/week/month 四档生成群聊词云图片
- **词云生成** — `/wordcloud` 按 today/week/month/year 四档生成群聊词云图片
- **LLM 扩展** — 兼容 OpenAI / Claude / Gemini 协议,按群切换 provider/model/persona,支持工具调用、MCP 桥接、图片理解、语音消息转写、联网搜索、故障机器人转写。详见 [docs/dev/llm-module.md](docs/dev/llm-module.md)
- **低频唤醒** — 按群配置唤醒延长、兴趣话题、相关性/答疑判定、无聊冒泡和兜底概率,所有入口受规则开关与限流保护
- **每日播报与总结** — 按群开启早/中/晚报和每日 2000 字小作文,模型级联失败自动降级
- **多贴吧随机搬运** — 多来源帖子池维护,支持随机抽取和定时同步
- **多模态能力** — 图片生成、语音合成、语音识别、歌词创作与音乐生成,统一收口 `config/generation.toml`
- **Web 管理后台** — Vue 3 SPA 仪表板:统计、规则开关、记忆编辑、对话浏览、配置在线编辑、词云生成、诊断工具、日志浏览。详见 [docs/admin/web-admin.md](docs/admin/web-admin.md)
- **Web 管理后台** — Vue 3 SPA 仪表板:统计、规则开关、唤醒管理、记忆编辑、对话浏览、配置在线编辑、词云生成、诊断工具、日志浏览。详见 [docs/admin/web-admin.md](docs/admin/web-admin.md)
- **频率限制** — 滑动窗口限流保护,支持按群独立分桶(`scope = "group"`)或全局合并(`scope = "global"`)

完整命令速查:群聊见 [docs/user/group-commands.md](docs/user/group-commands.md),私聊见 [docs/user/private-commands.md](docs/user/private-commands.md)。
Expand Down Expand Up @@ -64,7 +65,6 @@ QuickQuip(双 Q 谐音 = QQ + Quip/妙语)是一个**轻量级、规则驱
DRIVER=~fastapi
HOST=0.0.0.0
PORT=8080
SEARCH_BACKEND=auto
SEARXNG_BASE_URL=http://127.0.0.1:8888
```

Expand Down Expand Up @@ -93,7 +93,11 @@ QuickQuip(双 Q 谐音 = QQ + Quip/妙语)是一个**轻量级、规则驱

复制 `config/generation.toml.example` 为 `config/generation.toml`,按注释填入 provider 和模型。不存在时图片部分回退读取 `llm.toml` 旧版配置。

7. **可选:启用多贴吧搬运**
7. **可选:启用群聊唤醒**

复制 `config/awakening.toml.example` 为 `config/awakening.toml`,按群设置唤醒延长、兴趣话题、相关性判定、答疑判定和无聊唤醒参数。群内可用 `/awakening status` 查看生效状态。

8. **可选:启用多贴吧搬运**

安装 Playwright 浏览器:

Expand All @@ -112,7 +116,7 @@ QuickQuip(双 Q 谐音 = QQ + Quip/妙语)是一个**轻量级、规则驱

首次使用前按 [部署指南](docs/admin/deployment.md) 完成贴吧登录态导出。

8. **可选:启动 Web 管理后台**
9. **可选:启动 Web 管理后台**

```bash
# 先构建前端(需 Node.js)
Expand All @@ -127,7 +131,7 @@ QuickQuip(双 Q 谐音 = QQ + Quip/妙语)是一个**轻量级、规则驱

访问 `http://127.0.0.1:5104/ops/`。详见 [docs/admin/web-admin.md](docs/admin/web-admin.md)。

9. **启动机器人**
10. **启动机器人**

```bash
python bot.py
Expand Down Expand Up @@ -181,6 +185,9 @@ quickquip/app/ ← 应用级消息管线与共享状态装配
| [docs/user/private-commands.md](docs/user/private-commands.md) | 私聊指令速查 |
| [docs/admin/deployment.md](docs/admin/deployment.md) | 云端部署指南 |
| [docs/admin/configuration.md](docs/admin/configuration.md) | 完整配置参考 |
| [docs/admin/web-admin.md](docs/admin/web-admin.md) | Web 管理后台 |
| [docs/admin/sensitive-filter.md](docs/admin/sensitive-filter.md) | 敏感词过滤器 |
| [docs/admin/migration-napcat-to-llbot.md](docs/admin/migration-napcat-to-llbot.md) | NapCat 迁移 LLBot |
| [docs/dev/llm-module.md](docs/dev/llm-module.md) | LLM 模块详解 |
| [docs/dev/regex-tutorial.md](docs/dev/regex-tutorial.md) | 正则表达式教程 |
| [ROADMAP.md](ROADMAP.md) | 演进路线 |
Expand Down
27 changes: 16 additions & 11 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@

---

## 当前主线:v1.6.x 鲁棒性拐点
## 当前主线:v1.7.0 文档与前端收口

`v1.6.0` 完成了三轮鲁棒性加固(启动链熔断 / 运行时降级 / 语义验证),将两次已知生产事故的根因(单文件配置错误 → 全集群崩溃)转变为优雅降级。下一步重点是补齐三类敏感词扫描缺口,以及两个中大型功能
`v1.6.x` 已完成 LLM 鲁棒性加固与 Claude 协议线格式对齐。当前主线进入 `v1.7.0` 准备阶段:唤醒模块与 LLBot 迁移已经进入代码主线,接下来需要完成全仓文档校验、大修公开手册,并补一轮 Web Admin 前端整理后再准备发版

### 本轮关注点

1. **思考块(reasoning_content)扫描**:OpenAI 兼容协议的 `reasoning_content` 是纯文本,可以接入 scrub;Claude 的 signed thinking 块带签名,scrub 后签名失效,需评估是否整块丢弃或仅在写入历史时清理
2. **每日总结 / 播报 / 词云链路加固**:这些路径目前未接入敏感词过滤器,但同样会把群聊原文送给 LLM。需评估是否在消息收集阶段统一过一遍
3. **Provider 适配评估**:MiMo `mimo-v2.5-pro` / `mimo-v2-pro` 已标记为 `non_vision_models`;后续若新增国产 provider,需统一通过 `non_vision_models` 与 `style_overrides` 接入
4. **本地 TTS 服务接入**:基于 `dev/plans/2026-04-23-local-http-tts-fallback-plan.md`,补充本地 HTTP TTS provider 作为 MiniMax TTS 的 offline fallback
5. **Provider 健康检查自动故障转移**:基于已有 `quickquip/llm/health.py`,评估定时检查、provider 健康排序、自动降级或故障转移
1. **全仓文档校验**:对 README、`docs/`、配置模板、部署示例、ROADMAP 和 CHANGELOG 做一次代码面事实核对
2. **唤醒模块文档化**:补齐 `config/awakening.toml`、`/awakening` 命令、六类唤醒规则、无聊唤醒 opt-in 数据文件和限流规则说明
3. **LLBot 部署说明收口**:以 LLBot 作为推荐 OneBot V11 基座,保持 compose 示例、部署指南和 NapCat 迁移指南一致
4. **Web Admin 前端整理**:在文档大修后检查当前标签页、导航、配置编辑和移动端体验,修掉本轮能明确定位的前端问题
5. **配置参考补全**:同步 `.env.example`、`config/*.example`、代码默认值与 `docs/admin/configuration.md`,减少部署者靠读源码补配置的情况

### 退出条件

1. thinking 块扫描在所有启用 thinking 的 provider 上验证通过。
2. 每日总结/播报/词云链路在消息收集阶段统一接入敏感词过滤。
3. 关键合规事件能从日志反推到具体类别和命中位置(不需要原文)。
1. 全仓 Markdown 内链检查通过,公开文档与当前前端、部署入口和版本主线保持一致。
2. 用户手册、管理手册、开发手册均覆盖 v1.7.0 当前功能面,尤其是唤醒模块、LLBot、敏感词过滤、生成配置和 Web Admin 标签页。
3. `CHANGELOG.md` 的 `[Unreleased]` 区域能准确描述待发布变化,底部比较链接与最新 tag 对齐。
4. 前端整理项完成后通过 `npm run build` 或等价检查;Python 文档相关配置变动通过目标测试或静态校验。

---

Expand All @@ -43,6 +44,10 @@
2. provider 健康排序
3. 自动降级或故障转移(基于网关错误类型分类,含 `Content Exists Risk` 这类合规事件)

### 合规链路继续补强

敏感词过滤器已经接入 LLM 输入、输出、历史和工具调用层。后续继续评估 reasoning 内容、每日总结、播报和词云等批处理路径的统一扫描策略。

### 测试覆盖继续补强

在当前 pytest / CI 体系基础上,继续补:
Expand All @@ -59,7 +64,7 @@

### LLM 主动发言

冷场检测:群内超过 N 小时无消息且处于活跃时段时,bot 主动发一条话题引子(从词云高频词、每日总结或名言录取材)
唤醒模块已经提供低频主动响应的基础能力。后续如果继续扩展,可把冷场话题引子与词云高频词、每日总结或语录素材结合起来

### 群周报 / 月报

Expand Down
6 changes: 4 additions & 2 deletions docker-compose.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ services:
image: initialencounter/llonebot:latest
container_name: llbot
entrypoint:
- /entrypoint.sh
- /bin/sh
- -c
- "(sleep 5 && echo 'nameserver 127.0.0.11' > /etc/resolv.conf && echo 'options ndots:0' >> /etc/resolv.conf) & exec /bin/llonebot-service"
environment:
- QUICK_LOGIN_QQ=${QQ_ACCOUNT:?请设置 QQ 号}
- TZ=Asia/Shanghai
Expand All @@ -28,7 +30,6 @@ services:
volumes:
- ./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 @@ -85,6 +86,7 @@ services:
environment:
WEB_ADMIN_HOST: "0.0.0.0"
WEB_ADMIN_PORT: "5104"
SEARXNG_BASE_URL: "${SEARXNG_BASE_URL:-http://searxng:8080}"
ports:
- "127.0.0.1:5104:5104"
volumes:
Expand Down
96 changes: 92 additions & 4 deletions docs/admin/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@

| 变量 | 说明 | 默认值 |
|------|------|--------|
| `SEARCH_BACKEND` | 搜索后端选择:`auto` / `searxng` / `tavily` | `auto` |
| `SEARXNG_BASE_URL` | SearXNG 服务地址 | `http://127.0.0.1:8888` |
| `SEARXNG_BASE_URL` | Bot 内置 `search_web` 和 `/search` 使用的 SearXNG 服务地址 | `http://127.0.0.1:8888` |
| `SEARXNG_SAFE_SEARCH` | 传给 SearXNG 的安全搜索级别:`0` / `1` / `2` | `0` |
| `SEARXNG_LANGUAGE` | 传给 SearXNG 的搜索语言;空值时使用 `all` | `all` |
| `SEARXNG_PUBLIC_BASE_URL` | compose 中 SearXNG 对外展示的 base URL | `http://127.0.0.1:8888/` |
| `SEARXNG_BIND_ADDRESS` | compose 暴露 SearXNG 时绑定的宿主地址 | `127.0.0.1` |
| `SEARXNG_BIND_PORT` | compose 暴露 SearXNG 时绑定的宿主端口 | `8888` |
| `SEARXNG_SECRET` | SearXNG 实例密钥,用于容器环境变量 | — |

`SEARCH_BACKEND=auto` 时,若 `SEARXNG_BASE_URL` 已设置则优先使用 SearXNG
`search_web` 固定走项目内 SearXNG;Tavily 等外部搜索能力建议通过 MCP sidecar 暴露为工具

### LLM 调试

Expand All @@ -53,7 +58,13 @@
| `TIEBA_FORUM_KEYWORDS` | 多贴吧来源,逗号/分号/竖线/换行分隔 | — |
| `TIEBA_FORUM_KEYWORD` | 单贴吧来源(旧字段,多来源时优先用 `FORUM_KEYWORDS`) | — |
| `TIEBA_SYNC_INTERVAL_SECONDS` | 同步间隔(秒) | `900` |
| `TIEBA_MAX_POOL_SIZE` | 每个来源最多保留的帖子数,最小 `20` | `240` |
| `TIEBA_RECENT_SENT_LIMIT` | 最近发送记录保留数量,最小 `1` | `30` |
| `TIEBA_DETAIL_FETCH_LIMIT` | 单次抓取详情的帖子数量上限,最小 `1` | `18` |
| `TIEBA_RANDOM_AVOID_RECENT` | 随机抽帖时避开最近 N 条发送记录 | `30` |
| `TIEBA_PREFER_IMAGE_THREADS` | 随机抽帖时优先选择带图帖子 | `true` |
| `TIEBA_BROWSER_HEADLESS` | 浏览器是否无头模式 | `true` |
| `TIEBA_BROWSER_CHANNEL` | Playwright 浏览器 channel;空值使用默认 Chromium | — |

### MCP 挂载与开关

Expand Down Expand Up @@ -100,6 +111,12 @@
| `memory_limit` | 单次调用注入的记忆条数上限 | — |
| `memory_max_items_per_group` | 单群存储的记忆条数硬上限 | — |
| `max_prompt_chars` | system prompt 最大字符数 | — |
| `tool_calling_enabled` | 是否允许工具调用 | `false` |
| `tool_max_rounds` | 单次工具调用循环最大轮数 | `8` |
| `tool_max_calls_per_round` | 单轮最多执行工具调用数 | `16` |
| `auto_memory_enabled` | 自动记忆抽取全局默认开关 | `false` |
| `auto_memory_prompt` | 自动记忆抽取自定义判定 prompt | `""` |
| `auto_memory_max_tokens` | 自动记忆抽取判定最大输出 token | `256` |

### `[triggers]` — 触发方式

Expand All @@ -115,7 +132,18 @@
| 键 | 说明 | 默认值 |
|----|------|--------|
| `enabled` | 是否启用自动联网 | `false` |
| `search_max_calls_per_round` | 单轮最大搜索调用数 | — |
| `search_max_calls_per_round` | 单轮最大搜索调用数,范围 1-32 | `3` |

`[triggers.quick_judge]` — 快速判定模型:

| 键 | 说明 | 默认值 |
|----|------|--------|
| `provider_id` | 快速判定专用 provider ID;留空使用默认 provider | `""` |
| `model` | 快速判定专用模型;留空使用 provider 默认模型 | `""` |
| `timeout` | 判定超时秒数 | `2.0` |
| `max_tokens` | 判定最大输出 token | `64` |

快速判定用于 `context_rules` 的 `llm_context`、唤醒模块的相关性/答疑判定等短 prompt 场景。

### `[tools]` — 工具调用

Expand Down Expand Up @@ -307,6 +335,66 @@ ASR 用于把 OneBot V11 `record` 语音消息转写为文字,并注入 LLM

`[[music.providers]]` 和 `[[music.providers.models]]` 结构类似,额外包含 `supported_output_formats`、`lyrics_optimization` 等音乐特有字段。

`api_key_env` 由每个 provider 自行声明;示例配置中常见的键名包括 `MINIMAX_API_KEY`、`VOLCENGINE_API_KEY` 和 OpenAI-compatible ASR 使用的 `OPENAI_API_KEY`。

---

## config/awakening.toml

唤醒模块默认关闭,复制 `config/awakening.toml.example` 为 `config/awakening.toml` 后按需启用。配置支持全局默认值和按群覆盖。

### `[awakening.defaults]`

| 键 | 说明 | 默认值 |
|----|------|--------|
| `extend_duration` | 显式触发 AI 后继续回应同一用户的秒数;`0` 关闭 | `0` |
| `fallback_probability` | 普通消息低概率触发回应的概率;`0` 关闭 | `0` |
| `boredom_silence_seconds` | 群聊沉寂多少秒后允许无聊唤醒;`0` 关闭 | `0` |
| `boredom_probability` | 无聊检查命中时发送冒泡消息的概率 | `0` |
| `boredom_check_interval` | 无聊唤醒定时检查间隔秒数 | `300` |
| `boredom_dnd_start` | 免打扰开始时间,格式 `HH:MM`,空值关闭 | `""` |
| `boredom_dnd_end` | 免打扰结束时间,格式 `HH:MM`,空值关闭 | `""` |
| `interest_topics` | 兴趣话题关键词列表,命中后触发 `awakening_interest` | `[]` |
| `relevance_threshold` | 相关性唤醒判定阈值,`>= 1` 关闭 LLM 判定 | `1.0` |
| `qa_threshold` | 答疑唤醒判定阈值,`>= 1` 关闭 LLM 判定 | `1.0` |

### `[[awakening.group_overrides]]`

按群覆盖任意默认值:

```toml
[[awakening.group_overrides]]
group_id = "123456"
extend_duration = 10
interest_topics = ["编程", "Python"]
relevance_threshold = 0.5
qa_threshold = 0.88
```

`interest_topics` 还可写在 persona TOML 的扩展字段中:

```toml
[awakening]
interest_topics = ["角色相关关键词"]
```

### 群内管理

`/awakening status` 会展示本群六类唤醒规则的规则开关状态和已解析配置。`/awakening on <rule>` 与 `/awakening off <rule>` 复用规则开关系统;无聊唤醒还需要 `/awakening boredom on` 将本群加入 `data/awakening_boredom_groups.json`。

---

## config/sensitive_words.toml

敏感词过滤器默认在词表缺失或为空时静默放行。复制 `config/sensitive_words.toml.example` 为 `config/sensitive_words.toml` 后,按部署环境填充 block/soft 两级词表。

| 区段 | 行为 |
|------|------|
| `[block.<category>]` | 命中后阻断 LLM 输入、替换 LLM 输出,或在工具调用链路拒绝执行/替换结果 |
| `[soft.<category>]` | 只记录日志,不阻断请求 |

每个类别使用 `words = ["..."]` 定义词表。命中日志只记录类别与哈希,不记录原文。完整接入点和运维建议见 [sensitive-filter.md](sensitive-filter.md)。

---

## config/chat_rules.toml
Expand Down
Loading
Loading