nonebot-plugin-aigf-master 1.6.2__tar.gz → 2.0.0b0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nonebot_plugin_aigf_master-1.6.2/nonebot_plugin_aigf_master.egg-info → nonebot_plugin_aigf_master-2.0.0b0}/PKG-INFO +76 -31
- nonebot_plugin_aigf_master-1.6.2/PKG-INFO → nonebot_plugin_aigf_master-2.0.0b0/README.md +71 -48
- nonebot_plugin_aigf_master-2.0.0b0/nonebot_plugin_aigf_master/__init__.py +795 -0
- nonebot_plugin_aigf_master-2.0.0b0/nonebot_plugin_aigf_master/api_hooks.py +226 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/config.py +9 -2
- nonebot_plugin_aigf_master-2.0.0b0/nonebot_plugin_aigf_master/context_bus.py +30 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/meme_store.py +13 -13
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/models.py +1 -1
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/peer_client.py +5 -2
- nonebot_plugin_aigf_master-2.0.0b0/nonebot_plugin_aigf_master/plugin_invoker.py +199 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/processor.py +32 -26
- nonebot_plugin_aigf_master-2.0.0b0/nonebot_plugin_aigf_master/session.py +273 -0
- nonebot_plugin_aigf_master-2.0.0b0/nonebot_plugin_aigf_master/unimsg.py +436 -0
- nonebot_plugin_aigf_master-1.6.2/README.md → nonebot_plugin_aigf_master-2.0.0b0/nonebot_plugin_aigf_master.egg-info/PKG-INFO +93 -28
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master.egg-info/SOURCES.txt +2 -1
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master.egg-info/requires.txt +3 -1
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/pyproject.toml +5 -3
- nonebot_plugin_aigf_master-1.6.2/nonebot_plugin_aigf_master/__init__.py +0 -882
- nonebot_plugin_aigf_master-1.6.2/nonebot_plugin_aigf_master/api_hooks.py +0 -260
- nonebot_plugin_aigf_master-1.6.2/nonebot_plugin_aigf_master/context_bus.py +0 -30
- nonebot_plugin_aigf_master-1.6.2/nonebot_plugin_aigf_master/message_builder.py +0 -92
- nonebot_plugin_aigf_master-1.6.2/nonebot_plugin_aigf_master/plugin_invoker.py +0 -111
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/LICENSE +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/anime_recognizer.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/animetrace_client.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/cache_cleanup.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/command_learner.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/image_gen_client.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/image_handler.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/llm_client.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/memory_store.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/plugin_discovery.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/preset_store.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/prompt_builder.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/response_parser.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/search_client.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master/vlm_client.py +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master.egg-info/dependency_links.txt +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/nonebot_plugin_aigf_master.egg-info/top_level.txt +0 -0
- {nonebot_plugin_aigf_master-1.6.2 → nonebot_plugin_aigf_master-2.0.0b0}/setup.cfg +0 -0
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nonebot-plugin-aigf-master
|
|
3
|
-
Version:
|
|
4
|
-
Summary: 群聊特化LLM
|
|
3
|
+
Version: 2.0.0b0
|
|
4
|
+
Summary: 群聊特化LLM聊天机器人(增强版),具有记忆、表情包、跨插件调用、跨bot通信与跨适配器支持
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: <4.0,>=3.10
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
|
-
Requires-Dist: nonebot2>=2.
|
|
9
|
+
Requires-Dist: nonebot2>=2.5.0
|
|
10
10
|
Requires-Dist: nonebot-adapter-onebot>=2.2.0
|
|
11
11
|
Requires-Dist: nonebot-plugin-localstore>=0.5.0
|
|
12
|
+
Requires-Dist: nonebot-plugin-alconna>=0.62
|
|
13
|
+
Requires-Dist: nonebot-plugin-uninfo>=0.11
|
|
12
14
|
Requires-Dist: openai>=1.0.0
|
|
13
15
|
Requires-Dist: httpx>=0.24.0
|
|
14
16
|
Requires-Dist: anyio>=4.0.0
|
|
@@ -24,21 +26,30 @@ Dynamic: license-file
|
|
|
24
26
|
|
|
25
27
|
## ✨ AI-group-friend-master ✨
|
|
26
28
|
|
|
27
|
-
群聊特化 LLM 聊天机器人,具备表情包管理、记忆存储、联网搜索、跨插件感知、插件调用、LLM
|
|
29
|
+
群聊特化 LLM 聊天机器人,具备表情包管理、记忆存储、联网搜索、跨插件感知、插件调用、LLM 命令学习等能力,并以适配器无关的方式收发消息(OneBot / Satori / Telegram / Discord 等 alconna 支持的适配器均可)。
|
|
28
30
|
|
|
29
31
|
<p>
|
|
30
32
|
<img src="https://img.shields.io/badge/python-3.10+-blue?style=flat-square&logo=python&logoColor=white" alt="python">
|
|
31
|
-
<img src="https://img.shields.io/badge/nonebot-2.
|
|
33
|
+
<img src="https://img.shields.io/badge/nonebot-2.5+-red?style=flat-square" alt="nonebot">
|
|
32
34
|
</p>
|
|
33
35
|
</div>
|
|
34
36
|
|
|
37
|
+
> [!WARNING]
|
|
38
|
+
> **这是 beta 分支(2.0.0 开发中):跨适配器改造版**,与 1.6.x(main)不兼容,请勿直接覆盖生产环境的稳定版:
|
|
39
|
+
> - 会话改用 `适配器:会话id` 为键(旧版 `memory/{群号}` 目录会在启动时**自动迁移**为 `onebot11_群号`),新增私聊会话支持
|
|
40
|
+
> - 新增依赖 `nonebot-plugin-alconna`(统一消息)与 `nonebot-plugin-uninfo`(跨适配器会话/成员信息)
|
|
41
|
+
> - 插件调用改为「复制真实消息事件」,合成事件里携带**真实发送者的昵称/群名片/角色**(见「无法代为执行的命令」)
|
|
42
|
+
>
|
|
43
|
+
> 稳定版请留在 main 分支(1.6.x),beta 的功能验证完成后再合并发版。
|
|
44
|
+
|
|
35
45
|
## 📖 介绍
|
|
36
46
|
|
|
37
|
-
一个基于 NoneBot2 的群聊 AI 助手插件,能够自主收集和发送表情包、联网搜索知识、对群内信息进行记忆,还能够感知同实例内其它插件的输出、通过 LLM 调用其它插件、自主学习群内命令用法,并能通过子插件与其它 bot
|
|
47
|
+
一个基于 NoneBot2 的群聊 AI 助手插件,能够自主收集和发送表情包、联网搜索知识、对群内信息进行记忆,还能够感知同实例内其它插件的输出、通过 LLM 调用其它插件、自主学习群内命令用法,并能通过子插件与其它 bot 通信获取消息和远程调用命令。消息收发走 [nonebot-plugin-alconna](https://github.com/nonebot/plugin-alconna) 的通用消息层、会话与成员信息走 [nonebot-plugin-uninfo](https://github.com/nonebot/plugin-uninfo),因此同一份代码可以在多个适配器上工作(详细边界见「多适配器支持」)。
|
|
38
48
|
> 本项目有AI高度参与,若有做得不够好及需要改进的地方,欢迎在issue提出意见。
|
|
39
49
|
|
|
40
50
|
### 核心能力
|
|
41
51
|
|
|
52
|
+
- 🧩 **多适配器支持**:消息收发与会话身份走通用层,OneBot / Satori / Telegram / Discord 等适配器共用同一套聊天、记忆、表情包与命令逻辑(跨插件感知、插件调用等能力仍以 OneBot 为主,见下文边界)
|
|
42
53
|
- 🔌 **跨插件感知**:LLM 能看到同实例内其它插件的输出(如 rollpig 的小猪卡片、搜索结果等)
|
|
43
54
|
- 🤖 **插件调用**:LLM 可通过 function calling 调用其它插件(如 `/roll`、`/天气`),支持传递参数与 @ 群友(如 `决斗 @张三 10`)
|
|
44
55
|
- 🧠 **LLM 命令学习**:通过观察群聊自动学习命令用法,支持学习、编辑、删除
|
|
@@ -66,20 +77,20 @@ Dynamic: license-file
|
|
|
66
77
|
> 要使用本插件, 你至少需要
|
|
67
78
|
>
|
|
68
79
|
> - 一个有效的 openai 规范接口 api key,你需要在 `.env` 文件中配置对应的 api 地址
|
|
80
|
+
>
|
|
81
|
+
> 从 2.0 起插件还依赖 `nonebot-plugin-alconna` 与 `nonebot-plugin-uninfo`(跨适配器收发与会话/成员信息),用下面的方式安装时会自动装上。
|
|
69
82
|
|
|
70
|
-
|
|
71
|
-
<summary>使用 nb-cli 安装</summary>
|
|
72
|
-
在 nonebot2 项目的根目录下打开命令行, 输入以下指令安装
|
|
83
|
+
### 安装 beta 版本(2.0.0b0)
|
|
73
84
|
|
|
74
|
-
|
|
85
|
+
`2.0.0b0` 是**预发布(pre-release)版本**,因此:
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
- `pip install nonebot-plugin-aigf-master` 装的仍是稳定版 **1.6.x**
|
|
88
|
+
- `nb plugin install nonebot-plugin-aigf-master` 同样只装稳定版,而且 nb-cli **不支持指定版本**,所以 beta 只能用 pip 装
|
|
77
89
|
|
|
78
|
-
|
|
79
|
-
<summary>使用包管理器安装</summary>
|
|
90
|
+
要装 beta,**必须显式写出版本号**:
|
|
80
91
|
|
|
81
92
|
```bash
|
|
82
|
-
pip install nonebot-plugin-aigf-master
|
|
93
|
+
pip install nonebot-plugin-aigf-master==2.0.0b0
|
|
83
94
|
```
|
|
84
95
|
|
|
85
96
|
在 `pyproject.toml` 中添加:
|
|
@@ -89,7 +100,8 @@ pip install nonebot-plugin-aigf-master
|
|
|
89
100
|
plugins = ["nonebot-plugin-aigf-master"]
|
|
90
101
|
```
|
|
91
102
|
|
|
92
|
-
|
|
103
|
+
> 需要装 beta 分支上尚未发版的改动时,可以直接从分支安装:
|
|
104
|
+
> `pip install git+https://github.com/Funny1Potato/nonebot-plugin-aigf-master.git@beta`
|
|
93
105
|
|
|
94
106
|
|
|
95
107
|
## 配置
|
|
@@ -103,7 +115,8 @@ plugins = ["nonebot-plugin-aigf-master"]
|
|
|
103
115
|
AIGFM_LLM_API_KEY="sk-xxxxxxxxxxxx" # LLM API Key
|
|
104
116
|
AIGFM_LLM_BASE_URL="https://api.deepseek.com" # LLM API 地址
|
|
105
117
|
AIGFM_LLM_MODEL="deepseek-v4-flash" # LLM 模型名称
|
|
106
|
-
AIGFM_ENABLED_GROUPS=[123456, 789012] #
|
|
118
|
+
AIGFM_ENABLED_GROUPS=[123456, 789012] # 启用的群/频道会话(可写 `适配器:会话id`,只写数字按 OneBot V11 识别)
|
|
119
|
+
AIGFM_ENABLED_PRIVATE=[] # 启用的私聊会话(同上写法;留空则私聊不响应)
|
|
107
120
|
|
|
108
121
|
# --- 图片理解(VLM) ---
|
|
109
122
|
AIGFM_IMAGE_MODE="vlm" # 图片模式: vlm / llm(默认 vlm)
|
|
@@ -187,7 +200,6 @@ AIGFM_ANIME_RECOGNIZE_MAX_CHARACTERS=3 # 展示的角色标签数量上限(
|
|
|
187
200
|
AIGFM_ANIME_NSFW_THRESHOLD=0.5 # explicit 概率超过该值标注 [NSFW](默认 0.5;仅本地后端提供画风分级)
|
|
188
201
|
AIGFM_ANIMETRACE_URL="https://api.animetrace.com" # AnimeTrace API 地址(公共 API、无需鉴权;识别会把图片上传到该服务)
|
|
189
202
|
AIGFM_ANIMETRACE_TIMEOUT=20.0 # AnimeTrace 请求超时/秒(默认 20.0)
|
|
190
|
-
AIGFM_ANIME_RECOGNIZE_ENABLED=false # 【已被 AIGFM_ANIME_BACKEND 取代,仅兼容保留】为 true 且 backend=off 时按 anime-recognize 处理
|
|
191
203
|
|
|
192
204
|
# --- 缓存清理 ---
|
|
193
205
|
AIGFM_IMAGE_CACHE_MAX_FILES=500 # 描述/角色识别缓存(image_cache 下的 JSON)最大数量,超出按 mtime 最旧删除(默认 500,0=不清理)
|
|
@@ -225,6 +237,30 @@ AIGFM_PEER_CAPTURE_PLUGINS=[] # 要捕获输出的插件名列表,为
|
|
|
225
237
|
- 每次处理时,LLM 收到最近 **20 条**(可配置)历史聊天记录 + 四层记忆 + 预设 + 表情包列表 + 其它插件响应;本批消息只出现在「新消息」段,同一条插件响应也只注入一次(不会在历史与新消息里重复)
|
|
226
238
|
- LLM 一次调用同时完成:回复决策 + 记忆管理 + 表情包选择 + 命令学习
|
|
227
239
|
|
|
240
|
+
## 🧩 多适配器支持
|
|
241
|
+
|
|
242
|
+
插件的消息**收发**(文本、@、图片、语音、视频、群文件、链接分享、回复、合并转发等)走 [nonebot-plugin-alconna](https://github.com/nonebot/plugin-alconna) 的通用消息层,**会话与成员信息**(昵称、群名片、角色、群名、@ 目标解析)走 [nonebot-plugin-uninfo](https://github.com/nonebot/plugin-uninfo)。因此只要适配器被这两个库支持,聊天 / 记忆 / 表情包 / 生图 / 命令学习等功能就能直接工作,不需要为每个适配器改代码。
|
|
243
|
+
|
|
244
|
+
### 会话与启用清单
|
|
245
|
+
|
|
246
|
+
- 会话以 **`适配器:会话id`** 为键,例如 `onebot11:617770183`(群)、`console:console-chat`(频道)、`onebot11:20001`(私聊)
|
|
247
|
+
- `AIGFM_ENABLED_GROUPS` 管群/频道会话、`AIGFM_ENABLED_PRIVATE` 管私聊会话;条目可写带前缀的完整键,也可以只写 id(**按 OneBot V11 识别**,旧配置无需改动)
|
|
248
|
+
- 落盘目录名不能含 `:`,因此磁盘上写作 `onebot11_617770183`;`memory/` 下旧版裸数字目录会在启动时**一次性自动迁移**(目标已存在则跳过,幂等)
|
|
249
|
+
- 非启用会话不发请求、不入缓冲:插件只会为启用的会话解析成员信息与图片
|
|
250
|
+
|
|
251
|
+
### 各能力在非 OneBot 适配器上的边界
|
|
252
|
+
|
|
253
|
+
| 能力 | 其它适配器 | 说明 |
|
|
254
|
+
|---|---|---|
|
|
255
|
+
| 聊天、记忆、表情包、生图、命令学习、管理命令 | ✅ 可用 | `status` / `reset` / `set_role` / `presets` / `set_preset` / `reload_meme` 已改为 alconna 响应器,各适配器通用 |
|
|
256
|
+
| 跨插件感知(捕获其它插件的输出) | ✅ 一般可用 | 依赖 NoneBot 基类的 `on_calling_api` 钩子(所有适配器);会话取自当前事件,消息取自适配器消息对象,取不到就静默跳过 |
|
|
257
|
+
| 插件调用(`invoke_plugin`) | ⚠️ 尽力支持 | 通过复制该会话最近一条真实事件来投递命令;事件类型、消息类都由适配器自己决定,不需 onebot 专属类型。目标插件若依赖适配器特有能力(例如 OneBot 的 `get_msg`)仍可能失败 |
|
|
258
|
+
| 群系统通知(戳一戳/禁言/进出群/撤回) | ❌ 仅 OneBot | 这些是 OneBot 专属事件类型,其它适配器没有统一的通知模型,不处理 |
|
|
259
|
+
| 跨 bot 通信(子插件 `/peer/capture`) | ❌ 仅 OneBot | 其它 bot 都是同号 OneBot 实例,推送按 `onebot11:` 会话映射 |
|
|
260
|
+
| 群名片记录 | ✅ 有则记录 | 成员信息来自 uninfo,适配器不提供名片时该项为空 |
|
|
261
|
+
|
|
262
|
+
> 适配器完全不被 alconna/uninfo 支持时,该会话的消息会被静默跳过(只留 debug 日志),不会报错、也不会影响其它适配器。
|
|
263
|
+
|
|
228
264
|
## 🔌 跨插件感知
|
|
229
265
|
|
|
230
266
|
### 工作原理
|
|
@@ -365,23 +401,30 @@ LLM 只能调用 prompt 里「可用的群功能」/「其它 bot 的命令」
|
|
|
365
401
|
|
|
366
402
|
### 无法代为执行的命令
|
|
367
403
|
|
|
368
|
-
`invoke_plugin` / `invoke_peer_plugin`
|
|
404
|
+
`invoke_plugin` / `invoke_peer_plugin` 并不是让真人发消息,而是**复制该会话里最近一条真实消息事件**、把消息体换成命令文本后投递(2.0 起改为这种做法,此前是手工拼一个 `GroupMessageEvent`)。因此事件的适配器字段、发送者信息都来自那条真实消息,比过去准确得多,但仍与"真的有人发了这条命令"有差别,下列命令**调不动**(表现为投递后聊天记录里始终不出现该插件的响应):
|
|
369
405
|
|
|
370
406
|
| 命令类型 | 无法执行的原因 |
|
|
371
407
|
|---|---|
|
|
372
|
-
| 需要 @机器人 或呼叫昵称才触发 |
|
|
373
|
-
|
|
|
374
|
-
|
|
|
375
|
-
|
|
|
376
|
-
|
|
|
377
|
-
|
|
408
|
+
| 需要 @机器人 或呼叫昵称才触发 | 合成消息里没有 @机器人,`to_me` 沿用被复制那条消息的值(通常为 `False`) |
|
|
409
|
+
| 私聊命令 / 与事件类型强相关 | 复制的是群/频道事件(`message_type` 保持原样),不会命中只监听私聊或其它事件类型的 Matcher |
|
|
410
|
+
| 必须先回复/引用某条消息才能执行 | 合成消息不含回复段,事件里的 `reply` 也被清空 |
|
|
411
|
+
| 依赖群名片 / 头衔 / 等级 / 地区判断身份 | 发送者昵称、群名片、角色已按真实身份填好(`refresh` 不到的字段仍为空:头衔、等级、地区等) |
|
|
412
|
+
| 需要特殊 `message_id` 语义的操作 | `message_id` 是**被复制那条消息的真实 id**(不再是占位 `0`):引用回复可用,但插件若对"这条消息"做撤回/编辑等操作,作用的其实是那条真实消息 |
|
|
413
|
+
|
|
414
|
+
关于**权限**:合成事件的发送者是**提出请求的那位群友**(`user_id`、昵称、群名片、角色都按真实身份填),所以:
|
|
415
|
+
|
|
416
|
+
- 需要管理员/群主权限的命令,**请托者本身有相应权限时可以被执行**(1.6.x 及更早版本里 `role` 固定为 `member`,一律拒绝);请托者没有权限时仍会被目标插件拒绝
|
|
417
|
+
- `SUPERUSERS` 相关的命令同理:以请托者的身份通过检查
|
|
418
|
+
- 本插件自己的管理命令(`status`/`reset`/`set_role`/…)**无论谁请托都一律拒绝**,不会代为执行(避免真实用户恰好是 SUPERUSER 时被 LLM 触发)
|
|
378
419
|
|
|
379
420
|
两点补充:
|
|
380
421
|
|
|
381
422
|
- `on_keyword` / `on_regex` / `on_message` 型插件(不用 `on_command` 注册)**不会出现在静态命令列表**里,无法被自动发现;但它们的 rule 只匹配文本时,合成事件仍会命中,所以可以靠 LLM 命令学习掌握后调用。
|
|
382
423
|
- 命令学习会**主动跳过**上表中无法代为执行的命令(不会为它们生成用法记录),避免 LLM 反复误调用。
|
|
383
424
|
|
|
384
|
-
>
|
|
425
|
+
> 需要多步确认的命令(执行中等待用户再回复)不在上表内:会话按适配器的会话 id 归组(OneBot V11 为 `group_{group_id}_{user_id}`),只要后续真实消息来自同一个 `user_id`,等待流程仍能接上。
|
|
426
|
+
|
|
427
|
+
> 若目标插件是用 alconna 写的,插件会在投递前把 alconna 按 `message_id` 缓存的那条消息**替换成命令内容**——否则它会把命令读成"原来那条用户消息",永远匹配不上。
|
|
385
428
|
|
|
386
429
|
## 🌐 跨 bot 通信
|
|
387
430
|
|
|
@@ -581,7 +624,7 @@ memes/
|
|
|
581
624
|
| 后端 | 工作方式 | 擅长 | 代价 |
|
|
582
625
|
|---|---|---|---|
|
|
583
626
|
| `anime-recognize` | 本地 WD14 推理服务([aigfm-anime-recognize](https://github.com/Funny1Potato/aigfm-anime-recognize)),**需自行部署** | 动漫 / 手游角色,输出英文 booru 标签(如 `hu_tao_(genshin_impact)`)+ 数值置信度 + 画风分级 | 本地推理、免费无限量;**对 gal / 视觉小说角色识别率低** |
|
|
584
|
-
| `animetrace` | [AnimeTrace](https://ai.animedb.cn/) 公共 API,**无需部署、无需鉴权** | gal / 视觉小说角色,并给出作品名(如「胡桃(原神)」) |
|
|
627
|
+
| `animetrace` | [AnimeTrace](https://ai.animedb.cn/) 公共 API,**无需部署、无需鉴权** | gal / 视觉小说角色,并给出作品名(如「胡桃(原神)」) | 图片会上传到该第三方公共服务;有使用配额;不返回数值置信度、无画风分级;对gal以外游戏角色的识别率一般 |
|
|
585
628
|
|
|
586
629
|
`both` 模式先问本地服务,本地置信度不足(低于 `AIGFM_ANIME_RECOGNIZE_MIN_CONFIDENCE`)再问 AnimeTrace,两边都没有可信结果才渲染 `[角色识别: 未能识别]`——平时不消耗公共 API 配额。
|
|
587
630
|
|
|
@@ -592,8 +635,10 @@ memes/
|
|
|
592
635
|
```bash
|
|
593
636
|
git clone https://github.com/Funny1Potato/aigfm-anime-recognize.git
|
|
594
637
|
cd aigfm-anime-recognize
|
|
638
|
+
# 安装
|
|
595
639
|
# Windows: install.bat ;Linux/macOS: chmod +x install.sh && ./install.sh
|
|
596
|
-
#
|
|
640
|
+
# 启动
|
|
641
|
+
# Windows: start.bat ; Linux / macOS: chmod +x start.sh && ./start.sh
|
|
597
642
|
```
|
|
598
643
|
|
|
599
644
|
**插件配置**:
|
|
@@ -603,14 +648,14 @@ cd aigfm-anime-recognize
|
|
|
603
648
|
AIGFM_ANIME_BACKEND=both
|
|
604
649
|
|
|
605
650
|
# 本地后端地址(backend 含 anime-recognize 时必填;服务端未启用鉴权时 token 留空)
|
|
606
|
-
AIGFM_ANIME_RECOGNIZE_URL=http://127.0.0.1:8000
|
|
651
|
+
AIGFM_ANIME_RECOGNIZE_URL="http://127.0.0.1:8000"
|
|
607
652
|
# AIGFM_ANIME_RECOGNIZE_TOKEN=可选
|
|
608
653
|
|
|
609
654
|
# 可选调参(默认值如下)
|
|
610
655
|
# AIGFM_ANIME_RECOGNIZE_MIN_CONFIDENCE=0.85 # 展示角色标签的最低置信度;both 模式下也用它判断本地是否有结果
|
|
611
656
|
# AIGFM_ANIME_RECOGNIZE_MAX_CHARACTERS=3 # 展示的角色标签数量上限
|
|
612
657
|
# AIGFM_ANIME_NSFW_THRESHOLD=0.5 # explicit 概率超过该值标注 [NSFW](只标注不拦截;仅本地后端提供分级)
|
|
613
|
-
# AIGFM_ANIMETRACE_URL=https://api.animetrace.com
|
|
658
|
+
# AIGFM_ANIMETRACE_URL="https://api.animetrace.com"
|
|
614
659
|
# AIGFM_ANIMETRACE_TIMEOUT=20 # AnimeTrace 请求超时(秒)
|
|
615
660
|
```
|
|
616
661
|
|
|
@@ -632,8 +677,8 @@ AIGFM_ANIME_RECOGNIZE_URL=http://127.0.0.1:8000
|
|
|
632
677
|
- 改 `AIGFM_ANIME_RECOGNIZE_MIN_CONFIDENCE` 只影响此后新识别的图片;已缓存图片要重新判定需删除其 `{md5}_anime.json`
|
|
633
678
|
|
|
634
679
|
**已知局限**:
|
|
635
|
-
- **本地后端**:训练数据截止 2024 年前后,新游/新角色可能认不出,**gal / 视觉小说角色识别率尤其低(建议改用 `animetrace` 或 `both
|
|
636
|
-
- **AnimeTrace
|
|
680
|
+
- **本地后端**:训练数据截止 2024 年前后,新游/新角色可能认不出,**gal / 视觉小说角色识别率尤其低(建议改用 `animetrace` 或 `both`)**;多人合影可能会漏识别;3D 战斗小人/游戏内截图识别率不高;输出为英文标签(中文映射需自行扩展)
|
|
681
|
+
- **AnimeTrace**:对gal以外的游戏角色识别率一般;不返回数值置信度,只有服务自己的低置信判定——被判低置信时一律按「未能识别」处理,日志 `[角色识别] AnimeTrace 无可信结果,低置信候选: …` 会给出它认为最可能的候选,便于排查;其检测框可能包含误检,多人提示仅供参考;`[NSFW]` 标记只由本地后端提供
|
|
637
682
|
- 识别结果(角色名)会进入 LLM 上下文,也就是群里能看到;在意隐私请只用 `anime-recognize`(纯本地)或关闭本功能
|
|
638
683
|
|
|
639
684
|
> 仅 `AIGFM_IMAGE_MODE=vlm` 模式生效;`llm` 模式图片不经过 VLM,无二次元判断。
|
|
@@ -1,44 +1,33 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: nonebot-plugin-aigf-master
|
|
3
|
-
Version: 1.6.2
|
|
4
|
-
Summary: 群聊特化LLM聊天机器人(增强版),具有记忆、表情包、跨插件调用和跨bot通信能力
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
Requires-Python: <4.0,>=3.10
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Requires-Dist: nonebot2>=2.3.0
|
|
10
|
-
Requires-Dist: nonebot-adapter-onebot>=2.2.0
|
|
11
|
-
Requires-Dist: nonebot-plugin-localstore>=0.5.0
|
|
12
|
-
Requires-Dist: openai>=1.0.0
|
|
13
|
-
Requires-Dist: httpx>=0.24.0
|
|
14
|
-
Requires-Dist: anyio>=4.0.0
|
|
15
|
-
Requires-Dist: pillow>=9.0.0
|
|
16
|
-
Requires-Dist: numpy>=1.20.0
|
|
17
|
-
Provides-Extra: tavily
|
|
18
|
-
Requires-Dist: tavily-python>=0.3.0; extra == "tavily"
|
|
19
|
-
Dynamic: license-file
|
|
20
|
-
|
|
21
1
|
<div align="center">
|
|
22
2
|
<a href="https://v2.nonebot.dev/store">
|
|
23
3
|
<img src="https://raw.githubusercontent.com/fllesser/nonebot-plugin-template/refs/heads/resource/.docs/NoneBotPlugin.svg" width="310" alt="logo"></a>
|
|
24
4
|
|
|
25
5
|
## ✨ AI-group-friend-master ✨
|
|
26
6
|
|
|
27
|
-
群聊特化 LLM 聊天机器人,具备表情包管理、记忆存储、联网搜索、跨插件感知、插件调用、LLM
|
|
7
|
+
群聊特化 LLM 聊天机器人,具备表情包管理、记忆存储、联网搜索、跨插件感知、插件调用、LLM 命令学习等能力,并以适配器无关的方式收发消息(OneBot / Satori / Telegram / Discord 等 alconna 支持的适配器均可)。
|
|
28
8
|
|
|
29
9
|
<p>
|
|
30
10
|
<img src="https://img.shields.io/badge/python-3.10+-blue?style=flat-square&logo=python&logoColor=white" alt="python">
|
|
31
|
-
<img src="https://img.shields.io/badge/nonebot-2.
|
|
11
|
+
<img src="https://img.shields.io/badge/nonebot-2.5+-red?style=flat-square" alt="nonebot">
|
|
32
12
|
</p>
|
|
33
13
|
</div>
|
|
34
14
|
|
|
15
|
+
> [!WARNING]
|
|
16
|
+
> **这是 beta 分支(2.0.0 开发中):跨适配器改造版**,与 1.6.x(main)不兼容,请勿直接覆盖生产环境的稳定版:
|
|
17
|
+
> - 会话改用 `适配器:会话id` 为键(旧版 `memory/{群号}` 目录会在启动时**自动迁移**为 `onebot11_群号`),新增私聊会话支持
|
|
18
|
+
> - 新增依赖 `nonebot-plugin-alconna`(统一消息)与 `nonebot-plugin-uninfo`(跨适配器会话/成员信息)
|
|
19
|
+
> - 插件调用改为「复制真实消息事件」,合成事件里携带**真实发送者的昵称/群名片/角色**(见「无法代为执行的命令」)
|
|
20
|
+
>
|
|
21
|
+
> 稳定版请留在 main 分支(1.6.x),beta 的功能验证完成后再合并发版。
|
|
22
|
+
|
|
35
23
|
## 📖 介绍
|
|
36
24
|
|
|
37
|
-
一个基于 NoneBot2 的群聊 AI 助手插件,能够自主收集和发送表情包、联网搜索知识、对群内信息进行记忆,还能够感知同实例内其它插件的输出、通过 LLM 调用其它插件、自主学习群内命令用法,并能通过子插件与其它 bot
|
|
25
|
+
一个基于 NoneBot2 的群聊 AI 助手插件,能够自主收集和发送表情包、联网搜索知识、对群内信息进行记忆,还能够感知同实例内其它插件的输出、通过 LLM 调用其它插件、自主学习群内命令用法,并能通过子插件与其它 bot 通信获取消息和远程调用命令。消息收发走 [nonebot-plugin-alconna](https://github.com/nonebot/plugin-alconna) 的通用消息层、会话与成员信息走 [nonebot-plugin-uninfo](https://github.com/nonebot/plugin-uninfo),因此同一份代码可以在多个适配器上工作(详细边界见「多适配器支持」)。
|
|
38
26
|
> 本项目有AI高度参与,若有做得不够好及需要改进的地方,欢迎在issue提出意见。
|
|
39
27
|
|
|
40
28
|
### 核心能力
|
|
41
29
|
|
|
30
|
+
- 🧩 **多适配器支持**:消息收发与会话身份走通用层,OneBot / Satori / Telegram / Discord 等适配器共用同一套聊天、记忆、表情包与命令逻辑(跨插件感知、插件调用等能力仍以 OneBot 为主,见下文边界)
|
|
42
31
|
- 🔌 **跨插件感知**:LLM 能看到同实例内其它插件的输出(如 rollpig 的小猪卡片、搜索结果等)
|
|
43
32
|
- 🤖 **插件调用**:LLM 可通过 function calling 调用其它插件(如 `/roll`、`/天气`),支持传递参数与 @ 群友(如 `决斗 @张三 10`)
|
|
44
33
|
- 🧠 **LLM 命令学习**:通过观察群聊自动学习命令用法,支持学习、编辑、删除
|
|
@@ -66,20 +55,20 @@ Dynamic: license-file
|
|
|
66
55
|
> 要使用本插件, 你至少需要
|
|
67
56
|
>
|
|
68
57
|
> - 一个有效的 openai 规范接口 api key,你需要在 `.env` 文件中配置对应的 api 地址
|
|
58
|
+
>
|
|
59
|
+
> 从 2.0 起插件还依赖 `nonebot-plugin-alconna` 与 `nonebot-plugin-uninfo`(跨适配器收发与会话/成员信息),用下面的方式安装时会自动装上。
|
|
69
60
|
|
|
70
|
-
|
|
71
|
-
<summary>使用 nb-cli 安装</summary>
|
|
72
|
-
在 nonebot2 项目的根目录下打开命令行, 输入以下指令安装
|
|
61
|
+
### 安装 beta 版本(2.0.0b0)
|
|
73
62
|
|
|
74
|
-
|
|
63
|
+
`2.0.0b0` 是**预发布(pre-release)版本**,因此:
|
|
75
64
|
|
|
76
|
-
|
|
65
|
+
- `pip install nonebot-plugin-aigf-master` 装的仍是稳定版 **1.6.x**
|
|
66
|
+
- `nb plugin install nonebot-plugin-aigf-master` 同样只装稳定版,而且 nb-cli **不支持指定版本**,所以 beta 只能用 pip 装
|
|
77
67
|
|
|
78
|
-
|
|
79
|
-
<summary>使用包管理器安装</summary>
|
|
68
|
+
要装 beta,**必须显式写出版本号**:
|
|
80
69
|
|
|
81
70
|
```bash
|
|
82
|
-
pip install nonebot-plugin-aigf-master
|
|
71
|
+
pip install nonebot-plugin-aigf-master==2.0.0b0
|
|
83
72
|
```
|
|
84
73
|
|
|
85
74
|
在 `pyproject.toml` 中添加:
|
|
@@ -89,7 +78,8 @@ pip install nonebot-plugin-aigf-master
|
|
|
89
78
|
plugins = ["nonebot-plugin-aigf-master"]
|
|
90
79
|
```
|
|
91
80
|
|
|
92
|
-
|
|
81
|
+
> 需要装 beta 分支上尚未发版的改动时,可以直接从分支安装:
|
|
82
|
+
> `pip install git+https://github.com/Funny1Potato/nonebot-plugin-aigf-master.git@beta`
|
|
93
83
|
|
|
94
84
|
|
|
95
85
|
## 配置
|
|
@@ -103,7 +93,8 @@ plugins = ["nonebot-plugin-aigf-master"]
|
|
|
103
93
|
AIGFM_LLM_API_KEY="sk-xxxxxxxxxxxx" # LLM API Key
|
|
104
94
|
AIGFM_LLM_BASE_URL="https://api.deepseek.com" # LLM API 地址
|
|
105
95
|
AIGFM_LLM_MODEL="deepseek-v4-flash" # LLM 模型名称
|
|
106
|
-
AIGFM_ENABLED_GROUPS=[123456, 789012] #
|
|
96
|
+
AIGFM_ENABLED_GROUPS=[123456, 789012] # 启用的群/频道会话(可写 `适配器:会话id`,只写数字按 OneBot V11 识别)
|
|
97
|
+
AIGFM_ENABLED_PRIVATE=[] # 启用的私聊会话(同上写法;留空则私聊不响应)
|
|
107
98
|
|
|
108
99
|
# --- 图片理解(VLM) ---
|
|
109
100
|
AIGFM_IMAGE_MODE="vlm" # 图片模式: vlm / llm(默认 vlm)
|
|
@@ -187,7 +178,6 @@ AIGFM_ANIME_RECOGNIZE_MAX_CHARACTERS=3 # 展示的角色标签数量上限(
|
|
|
187
178
|
AIGFM_ANIME_NSFW_THRESHOLD=0.5 # explicit 概率超过该值标注 [NSFW](默认 0.5;仅本地后端提供画风分级)
|
|
188
179
|
AIGFM_ANIMETRACE_URL="https://api.animetrace.com" # AnimeTrace API 地址(公共 API、无需鉴权;识别会把图片上传到该服务)
|
|
189
180
|
AIGFM_ANIMETRACE_TIMEOUT=20.0 # AnimeTrace 请求超时/秒(默认 20.0)
|
|
190
|
-
AIGFM_ANIME_RECOGNIZE_ENABLED=false # 【已被 AIGFM_ANIME_BACKEND 取代,仅兼容保留】为 true 且 backend=off 时按 anime-recognize 处理
|
|
191
181
|
|
|
192
182
|
# --- 缓存清理 ---
|
|
193
183
|
AIGFM_IMAGE_CACHE_MAX_FILES=500 # 描述/角色识别缓存(image_cache 下的 JSON)最大数量,超出按 mtime 最旧删除(默认 500,0=不清理)
|
|
@@ -225,6 +215,30 @@ AIGFM_PEER_CAPTURE_PLUGINS=[] # 要捕获输出的插件名列表,为
|
|
|
225
215
|
- 每次处理时,LLM 收到最近 **20 条**(可配置)历史聊天记录 + 四层记忆 + 预设 + 表情包列表 + 其它插件响应;本批消息只出现在「新消息」段,同一条插件响应也只注入一次(不会在历史与新消息里重复)
|
|
226
216
|
- LLM 一次调用同时完成:回复决策 + 记忆管理 + 表情包选择 + 命令学习
|
|
227
217
|
|
|
218
|
+
## 🧩 多适配器支持
|
|
219
|
+
|
|
220
|
+
插件的消息**收发**(文本、@、图片、语音、视频、群文件、链接分享、回复、合并转发等)走 [nonebot-plugin-alconna](https://github.com/nonebot/plugin-alconna) 的通用消息层,**会话与成员信息**(昵称、群名片、角色、群名、@ 目标解析)走 [nonebot-plugin-uninfo](https://github.com/nonebot/plugin-uninfo)。因此只要适配器被这两个库支持,聊天 / 记忆 / 表情包 / 生图 / 命令学习等功能就能直接工作,不需要为每个适配器改代码。
|
|
221
|
+
|
|
222
|
+
### 会话与启用清单
|
|
223
|
+
|
|
224
|
+
- 会话以 **`适配器:会话id`** 为键,例如 `onebot11:617770183`(群)、`console:console-chat`(频道)、`onebot11:20001`(私聊)
|
|
225
|
+
- `AIGFM_ENABLED_GROUPS` 管群/频道会话、`AIGFM_ENABLED_PRIVATE` 管私聊会话;条目可写带前缀的完整键,也可以只写 id(**按 OneBot V11 识别**,旧配置无需改动)
|
|
226
|
+
- 落盘目录名不能含 `:`,因此磁盘上写作 `onebot11_617770183`;`memory/` 下旧版裸数字目录会在启动时**一次性自动迁移**(目标已存在则跳过,幂等)
|
|
227
|
+
- 非启用会话不发请求、不入缓冲:插件只会为启用的会话解析成员信息与图片
|
|
228
|
+
|
|
229
|
+
### 各能力在非 OneBot 适配器上的边界
|
|
230
|
+
|
|
231
|
+
| 能力 | 其它适配器 | 说明 |
|
|
232
|
+
|---|---|---|
|
|
233
|
+
| 聊天、记忆、表情包、生图、命令学习、管理命令 | ✅ 可用 | `status` / `reset` / `set_role` / `presets` / `set_preset` / `reload_meme` 已改为 alconna 响应器,各适配器通用 |
|
|
234
|
+
| 跨插件感知(捕获其它插件的输出) | ✅ 一般可用 | 依赖 NoneBot 基类的 `on_calling_api` 钩子(所有适配器);会话取自当前事件,消息取自适配器消息对象,取不到就静默跳过 |
|
|
235
|
+
| 插件调用(`invoke_plugin`) | ⚠️ 尽力支持 | 通过复制该会话最近一条真实事件来投递命令;事件类型、消息类都由适配器自己决定,不需 onebot 专属类型。目标插件若依赖适配器特有能力(例如 OneBot 的 `get_msg`)仍可能失败 |
|
|
236
|
+
| 群系统通知(戳一戳/禁言/进出群/撤回) | ❌ 仅 OneBot | 这些是 OneBot 专属事件类型,其它适配器没有统一的通知模型,不处理 |
|
|
237
|
+
| 跨 bot 通信(子插件 `/peer/capture`) | ❌ 仅 OneBot | 其它 bot 都是同号 OneBot 实例,推送按 `onebot11:` 会话映射 |
|
|
238
|
+
| 群名片记录 | ✅ 有则记录 | 成员信息来自 uninfo,适配器不提供名片时该项为空 |
|
|
239
|
+
|
|
240
|
+
> 适配器完全不被 alconna/uninfo 支持时,该会话的消息会被静默跳过(只留 debug 日志),不会报错、也不会影响其它适配器。
|
|
241
|
+
|
|
228
242
|
## 🔌 跨插件感知
|
|
229
243
|
|
|
230
244
|
### 工作原理
|
|
@@ -365,23 +379,30 @@ LLM 只能调用 prompt 里「可用的群功能」/「其它 bot 的命令」
|
|
|
365
379
|
|
|
366
380
|
### 无法代为执行的命令
|
|
367
381
|
|
|
368
|
-
`invoke_plugin` / `invoke_peer_plugin`
|
|
382
|
+
`invoke_plugin` / `invoke_peer_plugin` 并不是让真人发消息,而是**复制该会话里最近一条真实消息事件**、把消息体换成命令文本后投递(2.0 起改为这种做法,此前是手工拼一个 `GroupMessageEvent`)。因此事件的适配器字段、发送者信息都来自那条真实消息,比过去准确得多,但仍与"真的有人发了这条命令"有差别,下列命令**调不动**(表现为投递后聊天记录里始终不出现该插件的响应):
|
|
369
383
|
|
|
370
384
|
| 命令类型 | 无法执行的原因 |
|
|
371
385
|
|---|---|
|
|
372
|
-
| 需要 @机器人 或呼叫昵称才触发 |
|
|
373
|
-
|
|
|
374
|
-
|
|
|
375
|
-
|
|
|
376
|
-
|
|
|
377
|
-
|
|
386
|
+
| 需要 @机器人 或呼叫昵称才触发 | 合成消息里没有 @机器人,`to_me` 沿用被复制那条消息的值(通常为 `False`) |
|
|
387
|
+
| 私聊命令 / 与事件类型强相关 | 复制的是群/频道事件(`message_type` 保持原样),不会命中只监听私聊或其它事件类型的 Matcher |
|
|
388
|
+
| 必须先回复/引用某条消息才能执行 | 合成消息不含回复段,事件里的 `reply` 也被清空 |
|
|
389
|
+
| 依赖群名片 / 头衔 / 等级 / 地区判断身份 | 发送者昵称、群名片、角色已按真实身份填好(`refresh` 不到的字段仍为空:头衔、等级、地区等) |
|
|
390
|
+
| 需要特殊 `message_id` 语义的操作 | `message_id` 是**被复制那条消息的真实 id**(不再是占位 `0`):引用回复可用,但插件若对"这条消息"做撤回/编辑等操作,作用的其实是那条真实消息 |
|
|
391
|
+
|
|
392
|
+
关于**权限**:合成事件的发送者是**提出请求的那位群友**(`user_id`、昵称、群名片、角色都按真实身份填),所以:
|
|
393
|
+
|
|
394
|
+
- 需要管理员/群主权限的命令,**请托者本身有相应权限时可以被执行**(1.6.x 及更早版本里 `role` 固定为 `member`,一律拒绝);请托者没有权限时仍会被目标插件拒绝
|
|
395
|
+
- `SUPERUSERS` 相关的命令同理:以请托者的身份通过检查
|
|
396
|
+
- 本插件自己的管理命令(`status`/`reset`/`set_role`/…)**无论谁请托都一律拒绝**,不会代为执行(避免真实用户恰好是 SUPERUSER 时被 LLM 触发)
|
|
378
397
|
|
|
379
398
|
两点补充:
|
|
380
399
|
|
|
381
400
|
- `on_keyword` / `on_regex` / `on_message` 型插件(不用 `on_command` 注册)**不会出现在静态命令列表**里,无法被自动发现;但它们的 rule 只匹配文本时,合成事件仍会命中,所以可以靠 LLM 命令学习掌握后调用。
|
|
382
401
|
- 命令学习会**主动跳过**上表中无法代为执行的命令(不会为它们生成用法记录),避免 LLM 反复误调用。
|
|
383
402
|
|
|
384
|
-
>
|
|
403
|
+
> 需要多步确认的命令(执行中等待用户再回复)不在上表内:会话按适配器的会话 id 归组(OneBot V11 为 `group_{group_id}_{user_id}`),只要后续真实消息来自同一个 `user_id`,等待流程仍能接上。
|
|
404
|
+
|
|
405
|
+
> 若目标插件是用 alconna 写的,插件会在投递前把 alconna 按 `message_id` 缓存的那条消息**替换成命令内容**——否则它会把命令读成"原来那条用户消息",永远匹配不上。
|
|
385
406
|
|
|
386
407
|
## 🌐 跨 bot 通信
|
|
387
408
|
|
|
@@ -581,7 +602,7 @@ memes/
|
|
|
581
602
|
| 后端 | 工作方式 | 擅长 | 代价 |
|
|
582
603
|
|---|---|---|---|
|
|
583
604
|
| `anime-recognize` | 本地 WD14 推理服务([aigfm-anime-recognize](https://github.com/Funny1Potato/aigfm-anime-recognize)),**需自行部署** | 动漫 / 手游角色,输出英文 booru 标签(如 `hu_tao_(genshin_impact)`)+ 数值置信度 + 画风分级 | 本地推理、免费无限量;**对 gal / 视觉小说角色识别率低** |
|
|
584
|
-
| `animetrace` | [AnimeTrace](https://ai.animedb.cn/) 公共 API,**无需部署、无需鉴权** | gal / 视觉小说角色,并给出作品名(如「胡桃(原神)」) |
|
|
605
|
+
| `animetrace` | [AnimeTrace](https://ai.animedb.cn/) 公共 API,**无需部署、无需鉴权** | gal / 视觉小说角色,并给出作品名(如「胡桃(原神)」) | 图片会上传到该第三方公共服务;有使用配额;不返回数值置信度、无画风分级;对gal以外游戏角色的识别率一般 |
|
|
585
606
|
|
|
586
607
|
`both` 模式先问本地服务,本地置信度不足(低于 `AIGFM_ANIME_RECOGNIZE_MIN_CONFIDENCE`)再问 AnimeTrace,两边都没有可信结果才渲染 `[角色识别: 未能识别]`——平时不消耗公共 API 配额。
|
|
587
608
|
|
|
@@ -592,8 +613,10 @@ memes/
|
|
|
592
613
|
```bash
|
|
593
614
|
git clone https://github.com/Funny1Potato/aigfm-anime-recognize.git
|
|
594
615
|
cd aigfm-anime-recognize
|
|
616
|
+
# 安装
|
|
595
617
|
# Windows: install.bat ;Linux/macOS: chmod +x install.sh && ./install.sh
|
|
596
|
-
#
|
|
618
|
+
# 启动
|
|
619
|
+
# Windows: start.bat ; Linux / macOS: chmod +x start.sh && ./start.sh
|
|
597
620
|
```
|
|
598
621
|
|
|
599
622
|
**插件配置**:
|
|
@@ -603,14 +626,14 @@ cd aigfm-anime-recognize
|
|
|
603
626
|
AIGFM_ANIME_BACKEND=both
|
|
604
627
|
|
|
605
628
|
# 本地后端地址(backend 含 anime-recognize 时必填;服务端未启用鉴权时 token 留空)
|
|
606
|
-
AIGFM_ANIME_RECOGNIZE_URL=http://127.0.0.1:8000
|
|
629
|
+
AIGFM_ANIME_RECOGNIZE_URL="http://127.0.0.1:8000"
|
|
607
630
|
# AIGFM_ANIME_RECOGNIZE_TOKEN=可选
|
|
608
631
|
|
|
609
632
|
# 可选调参(默认值如下)
|
|
610
633
|
# AIGFM_ANIME_RECOGNIZE_MIN_CONFIDENCE=0.85 # 展示角色标签的最低置信度;both 模式下也用它判断本地是否有结果
|
|
611
634
|
# AIGFM_ANIME_RECOGNIZE_MAX_CHARACTERS=3 # 展示的角色标签数量上限
|
|
612
635
|
# AIGFM_ANIME_NSFW_THRESHOLD=0.5 # explicit 概率超过该值标注 [NSFW](只标注不拦截;仅本地后端提供分级)
|
|
613
|
-
# AIGFM_ANIMETRACE_URL=https://api.animetrace.com
|
|
636
|
+
# AIGFM_ANIMETRACE_URL="https://api.animetrace.com"
|
|
614
637
|
# AIGFM_ANIMETRACE_TIMEOUT=20 # AnimeTrace 请求超时(秒)
|
|
615
638
|
```
|
|
616
639
|
|
|
@@ -632,8 +655,8 @@ AIGFM_ANIME_RECOGNIZE_URL=http://127.0.0.1:8000
|
|
|
632
655
|
- 改 `AIGFM_ANIME_RECOGNIZE_MIN_CONFIDENCE` 只影响此后新识别的图片;已缓存图片要重新判定需删除其 `{md5}_anime.json`
|
|
633
656
|
|
|
634
657
|
**已知局限**:
|
|
635
|
-
- **本地后端**:训练数据截止 2024 年前后,新游/新角色可能认不出,**gal / 视觉小说角色识别率尤其低(建议改用 `animetrace` 或 `both
|
|
636
|
-
- **AnimeTrace
|
|
658
|
+
- **本地后端**:训练数据截止 2024 年前后,新游/新角色可能认不出,**gal / 视觉小说角色识别率尤其低(建议改用 `animetrace` 或 `both`)**;多人合影可能会漏识别;3D 战斗小人/游戏内截图识别率不高;输出为英文标签(中文映射需自行扩展)
|
|
659
|
+
- **AnimeTrace**:对gal以外的游戏角色识别率一般;不返回数值置信度,只有服务自己的低置信判定——被判低置信时一律按「未能识别」处理,日志 `[角色识别] AnimeTrace 无可信结果,低置信候选: …` 会给出它认为最可能的候选,便于排查;其检测框可能包含误检,多人提示仅供参考;`[NSFW]` 标记只由本地后端提供
|
|
637
660
|
- 识别结果(角色名)会进入 LLM 上下文,也就是群里能看到;在意隐私请只用 `anime-recognize`(纯本地)或关闭本功能
|
|
638
661
|
|
|
639
662
|
> 仅 `AIGFM_IMAGE_MODE=vlm` 模式生效;`llm` 模式图片不经过 VLM,无二次元判断。
|