Metadata-Version: 2.5
Name: nonebot-plugin-chat-learning
Version: 0.2.0
Summary: 迁移自 ChatLearning 的群聊词库学习插件：学习群友说话方式并概率回复
Author: TonyLiangP2010405
License: MIT
License-File: LICENSE
Keywords: chat-learning,nonebot,nonebot2,plugin,word-stock
Requires-Python: >=3.9
Requires-Dist: aiosqlite>=0.19
Requires-Dist: jieba>=0.42
Requires-Dist: nonebot-adapter-onebot>=2.4.0
Requires-Dist: nonebot2>=2.2.0
Requires-Dist: numpy>=1.24
Requires-Dist: sqlalchemy[asyncio]>=2.0
Provides-Extra: dev
Requires-Dist: nonebot2[fastapi]>=2.2.0; extra == 'dev'
Requires-Dist: nonebug>=0.3; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# [nonebot-plugin-chat-learning](https://github.com/TonyLiangP2010405/nonebot-plugin-chat-learning)

迁移自 [ChatLearning](https://github.com/LEXUU/ChatLearning) 的群聊词库学习插件：持续学习群友的说话方式，按概率在群聊中回复（NoneBot2 / OneBot v11）。

支持链式学习记录、精确/正则/余弦三级匹配、概率回复与冷却、快速删除（`!d`）、敏感词过滤与黑名单，以及旧 `.cl` 词库（WordStock）导入。

## 功能

- **链式学习记录**：记录每条消息，间隔超过阈值时上一条单独成"问"，自动积累问答词库
- **三级匹配回复**：精确匹配 → 正则匹配 → 余弦相似度模糊匹配，逐级回退
- **概率回复 / 冷却 / @ 触发**：按群配置回复概率，命中后进入冷却；被 @ 时同样按概率回复（匹配前会剥掉 @ 段，回复时带上 @ 前缀）
- **快速删除 `!d`**：任何群成员引用 bot 消息回复 `!d` 即可删除该条学习内容（可配合 `cl_replycache_size` 缓存快速生效）
- **词库管理指令**：SUPERUSER 单条指令完成开关学习、开关回复、增删问答、词库统计
- **敏感词 / 过滤 / 黑名单**：命中敏感词进黑名单，达到容错次数后该问题不再回复
- **旧词库导入**：支持私聊指令与 CLI 两种方式导入旧 ChatLearning `.cl` 词库

## 安装

### 使用 nb-cli 安装

```bash
nb plugin install nonebot-plugin-chat-learning
```

### 使用 pip 安装

```bash
pip install nonebot-plugin-chat-learning
```

### 使用 poetry 安装

```bash
poetry add nonebot-plugin-chat-learning
```

## 配置

在 `.env` 中按需覆盖（所有配置项以 `cl_` 前缀开头，全部可选，缺省使用默认值）：

| 配置项 | 默认值 | 说明 |
|---|---|---|
| `cl_database_path` | `data/chat_learning/learning.db` | SQLite 数据库路径 |
| `cl_interval` | `900` | 学习间隔秒数，超过则上一条单独成"问" |
| `cl_replychance` | `50` | 全局默认回复概率 % |
| `cl_replycd` | `3` | 每群回复冷却秒数 |
| `cl_replylength` | `100` | 回复纯文本长度上限 |
| `cl_cosmatch` | `true` | 开启余弦相似度模糊匹配 |
| `cl_cosmatching` | `0.5` | 余弦相似度阈值 |
| `cl_cosmaxlen` | `35` | 参与余弦匹配的问题最大字数 |
| `cl_blackfreq` | `5` | 敏感词命中多少次进黑名单 |
| `cl_replycache_size` | `32` | 每群快速删除缓存条数 |

## 使用方法

| 指令 | 权限 | 范围 | 说明 |
|---|---|---|---|
| `!learning [群号]` | SUPERUSER | 群聊/私聊 | 开关学习（私聊需带群号） |
| `!reply [N%] [群号]` | SUPERUSER | 群聊/私聊 | 开关回复 / 设置回复概率（私聊需带群号） |
| `!addanswer [-r] 问 => 答` | SUPERUSER | 群聊 | 自定义问答，`-r` 表示按正则匹配 |
| `!delanswer 问` | SUPERUSER | 群聊 | 删除问题及其所有答案 |
| `!check [群号]` | SUPERUSER | 群聊/私聊 | 词库统计与学习/回复状态（私聊需带群号） |
| `!importcl 路径` | SUPERUSER | 私聊 | 导入旧 `.cl` 词库（WordStock 目录） |
| 引用 bot 消息回复 `!d` | 群员 | 群聊 | 快速删除该条学习内容 |

词库答案中可使用变量：`{me}`（bot 自称）、`{name}`（发言者群名片/昵称）、`{segment}`（换行）。

## 旧词库迁移

旧 ChatLearning 的 WordStock 目录可通过以下任一方式导入：

- **私聊指令**：`!importcl <WordStock目录路径>`（仅 SUPERUSER）
- **命令行**：`python -m nonebot_plugin_chat_learning.migrate <路径> [--db 路径]`

注意：

- **pickle 有安全风险**：`.cl` 文件是反序列化执行的格式，请只导入自己生成的旧文件，不要导入来源不明的词库
- 旧库中的 `time` 字段**不迁移**，`created_at` 以导入时间为准
- 旧库中的 `freq`（出现频率）与 `same`（答案权重）字段**完整保留**

## 迁移说明

以下为原 ChatLearning 项目功能在本插件中的对应实现与完成情况：

| 原项目功能 | NoneBot 插件实现位置 | 是否完成 | 备注 |
|---|---|---|---|
| 链式学习记录 | `learning.py` | 是 | 逻辑一致，asyncio lock 修复并发 |
| 精确/正则/余弦三级匹配 | `reply.py` | 是 | 余弦向量增加内存缓存 |
| 概率回复/冷却/@触发 | `reply.py` + `__init__.py` | 是 | |
| 快速删除 `!d` | `__init__.py` | 是 | |
| 词库管理指令 | `commands.py` | 是 | 改为 SUPERUSER 单条指令 |
| 敏感词/过滤/黑名单 | `filter.py` | 是 | 统一 JSON 存储 |
| 旧 `.cl` 词库导入 | `migrate.py` | 是 | |
| TTS 语音克隆 | — | 否 | 外部服务器已失效，砍掉 |
| 定时任务 AutoTask | — | 否 | 核心范围外 |
| 管理模式多轮交互 | — | 否 | 改为单条指令 |
| COS 导出/总词库合并/词库标签 | — | 否 | 核心范围外 |

## 许可证

MIT