nonebot-plugin-aigf-master 0.1.0__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-0.1.0/LICENSE +21 -0
- nonebot_plugin_aigf_master-0.1.0/PKG-INFO +492 -0
- nonebot_plugin_aigf_master-0.1.0/README.md +472 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/__init__.py +624 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/api_hooks.py +229 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/command_learner.py +164 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/config.py +77 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/context_bus.py +30 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/image_handler.py +117 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/llm_client.py +89 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/meme_store.py +193 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/memory_store.py +255 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/models.py +82 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/peer_client.py +41 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/plugin_discovery.py +63 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/plugin_invoker.py +86 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/preset_store.py +54 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/processor.py +375 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/prompt_builder.py +325 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/response_parser.py +91 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/search_client.py +123 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master/vlm_client.py +24 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master.egg-info/PKG-INFO +492 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master.egg-info/SOURCES.txt +27 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master.egg-info/dependency_links.txt +1 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master.egg-info/requires.txt +11 -0
- nonebot_plugin_aigf_master-0.1.0/nonebot_plugin_aigf_master.egg-info/top_level.txt +1 -0
- nonebot_plugin_aigf_master-0.1.0/pyproject.toml +27 -0
- nonebot_plugin_aigf_master-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Funny1Potato
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nonebot-plugin-aigf-master
|
|
3
|
+
Version: 0.1.0
|
|
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
|
+
<div align="center">
|
|
22
|
+
<a href="https://v2.nonebot.dev/store">
|
|
23
|
+
<img src="https://raw.githubusercontent.com/fllesser/nonebot-plugin-template/refs/heads/resource/.docs/NoneBotPlugin.svg" width="310" alt="logo"></a>
|
|
24
|
+
|
|
25
|
+
## ✨ AI-group-friend-manager ✨
|
|
26
|
+
|
|
27
|
+
群聊特化 LLM 聊天机器人,具备表情包管理、记忆存储、联网搜索、跨插件感知、插件调用、LLM 命令学习等能力。
|
|
28
|
+
|
|
29
|
+
<p>
|
|
30
|
+
<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.3+-red?style=flat-square" alt="nonebot">
|
|
32
|
+
</p>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
## 📖 介绍
|
|
36
|
+
|
|
37
|
+
一个基于 NoneBot2 的群聊 AI 助手插件,能够自主收集和发送表情包、联网搜索知识、对群内信息进行记忆,还能够感知同实例内其它插件的输出、通过 LLM 调用其它插件、自主学习群内命令用法,并能通过子插件与其它 bot 通信获取消息和远程调用命令。
|
|
38
|
+
|
|
39
|
+
### 核心能力
|
|
40
|
+
|
|
41
|
+
- 🔌 **跨插件感知**:LLM 能看到同实例内其它插件的输出(如 rollpig 的小猪卡片、搜索结果等)
|
|
42
|
+
- 🤖 **插件调用**:LLM 可通过 function calling 调用其它插件(如 `/roll`、`/天气`)
|
|
43
|
+
- 🧠 **LLM 命令学习**:通过观察群聊自动学习命令用法,支持学习、编辑、删除
|
|
44
|
+
- 🌐 **跨 bot 通信**:通过 HTTP 获取其它 bot(同一 QQ 号下)的插件输出,并可远程调用其命令
|
|
45
|
+
- 🖼️ **表情包功能**:AI 自主决定发表情包;自动从群聊中收藏
|
|
46
|
+
- 🔍 **联网搜索**:支持 Tavily / Bocha / Bing,自动搜索不懂的梗和网络用语
|
|
47
|
+
- 🧠 **四层记忆系统**:短期记忆、长期记忆、群友信息、文化记忆,LLM 自主管理
|
|
48
|
+
|
|
49
|
+
### 基础能力
|
|
50
|
+
|
|
51
|
+
- 🎭 **社交能量系统**:动态能量影响回复意愿,形成自然的"话多→累了→安静→恢复"周期
|
|
52
|
+
- 💬 **口语化回复**:像平时聊天一样自然,回复长度有变化,允许敷衍
|
|
53
|
+
- 📨 **消息合并**:同一用户连续消息自动合并,避免碎片化上下文
|
|
54
|
+
- ⏱️ **不完整消息检测**:纯 @ 消息或连续发送时自动延长等待时间
|
|
55
|
+
- 🔒 **强制 JSON 输出**:确保 LLM 始终返回正确格式
|
|
56
|
+
- ⚡ **轻量高效**:单次 LLM 调用完成对话 + 记忆管理 + 命令学习
|
|
57
|
+
|
|
58
|
+
## 💿 安装
|
|
59
|
+
|
|
60
|
+
> [!IMPORTANT]
|
|
61
|
+
> 要使用本插件, 你至少需要
|
|
62
|
+
>
|
|
63
|
+
> - 一个有效的 openai 规范接口 api key,你需要在 `.env` 文件中配置对应的 api 地址
|
|
64
|
+
|
|
65
|
+
<details open>
|
|
66
|
+
<summary>使用 nb-cli 安装</summary>
|
|
67
|
+
在 nonebot2 项目的根目录下打开命令行, 输入以下指令安装(测试中,还未上架)
|
|
68
|
+
|
|
69
|
+
nb plugin install nonebot-plugin-aigf-master --upgrade
|
|
70
|
+
|
|
71
|
+
</details>
|
|
72
|
+
|
|
73
|
+
<details>
|
|
74
|
+
<summary>使用包管理器安装</summary>
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install nonebot-plugin-aigf-master
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
在 `pyproject.toml` 中添加:
|
|
81
|
+
|
|
82
|
+
```toml
|
|
83
|
+
[tool.nonebot]
|
|
84
|
+
plugins = ["nonebot-plugin-aigf-master"]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
</details>
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## 配置
|
|
91
|
+
|
|
92
|
+
在 `.env` 或 `.env.prod` 中添加:
|
|
93
|
+
|
|
94
|
+
### 必填
|
|
95
|
+
|
|
96
|
+
```env
|
|
97
|
+
AIGFM_LLM_API_KEY="sk-xxxxxxxxxxxx" # LLM API Key
|
|
98
|
+
AIGFM_LLM_BASE_URL="https://api.deepseek.com" # LLM API 地址
|
|
99
|
+
AIGFM_LLM_MODEL="deepseek-v4-flash" # LLM 模型名称
|
|
100
|
+
AIGFM_ENABLED_GROUPS=[123456, 789012] # 启用的群号列表
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 可选
|
|
104
|
+
|
|
105
|
+
```env
|
|
106
|
+
# --- 基础 ---
|
|
107
|
+
AIGFM_MEME_ENABLED=true # 是否启用表情包功能(默认 true)
|
|
108
|
+
AIGFM_MEME_MAX_COUNT=200 # 自动收集的表情包最大数量(默认 200)
|
|
109
|
+
AIGFM_DEFAULT_PRESET=default # 默认预设名称(默认 "default")
|
|
110
|
+
|
|
111
|
+
# --- 请求控制 ---
|
|
112
|
+
AIGFM_BATCH_COUNT=10 # 攒满多少条消息后触发 LLM 请求(默认 10)
|
|
113
|
+
AIGFM_BATCH_TIMEOUT=30.0 # 距最后一条消息多少秒后触发(默认 30.0)
|
|
114
|
+
AIGFM_INCOMPLETE_TIMEOUT=40.0 # 检测到消息可能不完整时的等待时间/秒(默认 40.0)
|
|
115
|
+
AIGFM_RECENT_MESSAGES=20 # prompt 中包含的最近历史消息条数(默认 20,最大 50)
|
|
116
|
+
AIGFM_MERGE_WINDOW=5.0 # 消息合并时间窗口/秒(默认 5.0)
|
|
117
|
+
|
|
118
|
+
# --- LLM ---
|
|
119
|
+
AIGFM_JSON_MODE=true # 是否强制 LLM 输出 JSON(默认 true)
|
|
120
|
+
AIGFM_ENERGY_BASELINE=0.7 # 社交能量基线(默认 0.7,范围 0.0~1.0)
|
|
121
|
+
|
|
122
|
+
# --- 联网搜索 ---
|
|
123
|
+
AIGFM_SEARCH_ENABLED=false # 是否启用联网搜索(默认 false)
|
|
124
|
+
AIGFM_SEARCH_API=tavily # 搜索API: tavily / bocha / bing / openwebsearch(默认 tavily)
|
|
125
|
+
AIGFM_SEARCH_API_KEY="xxx" # 搜索 API Key(api=tavily/bocha/bing 时必填)
|
|
126
|
+
AIGFM_SEARCH_MAX_RESULTS=3 # 最大搜索结果数(默认 3)
|
|
127
|
+
AIGFM_OPENWEBSEARCH_URL="" # open-websearch 本地服务地址(api=openwebsearch 时必填,如 http://127.0.0.1:3210)
|
|
128
|
+
|
|
129
|
+
# --- 代理 ---
|
|
130
|
+
AIGFM_PROXY_ENABLED=false # 是否启用代理(默认 false)
|
|
131
|
+
AIGFM_HTTP_PROXY="http://127.0.0.1:7890" # HTTP 代理地址
|
|
132
|
+
AIGFM_HTTPS_PROXY="http://127.0.0.1:7890" # HTTPS 代理地址
|
|
133
|
+
|
|
134
|
+
# --- 图片理解(VLM) ---
|
|
135
|
+
AIGFM_IMAGE_MODE="vlm" # 图片模式: vlm / llm(默认 vlm)
|
|
136
|
+
AIGFM_VLM_ENABLED=true # 是否启用VLM(仅 vlm 模式有效,默认 true)
|
|
137
|
+
AIGFM_VLM_MODEL="..." # VLM 模型名称(vlm 模式必填)
|
|
138
|
+
AIGFM_VLM_BASE_URL="https://..." # VLM API 地址
|
|
139
|
+
AIGFM_VLM_API_KEY="" # VLM API Key(为空时使用 chat 的 key)
|
|
140
|
+
|
|
141
|
+
# --- 跨插件感知 ---
|
|
142
|
+
AIGFM_CAPTURE_PLUGINS=[] # 要捕获输出的插件名列表,为空则捕获所有
|
|
143
|
+
AIGFM_CAPTURE_IMAGES=true # 是否捕获并解析其它插件输出的图片(默认 true)
|
|
144
|
+
AIGFM_CONTEXT_IN_PROMPT=10 # 注入到 prompt 中的其它插件消息条数(默认 10)
|
|
145
|
+
|
|
146
|
+
# --- 插件调用 ---
|
|
147
|
+
AIGFM_INVOKE_ENABLED=true # 是否允许 LLM 调用其它插件(默认 true)
|
|
148
|
+
AIGFM_INVOKE_TIMEOUT=30.0 # 插件调用超时时间(秒,默认 30.0)
|
|
149
|
+
|
|
150
|
+
# --- 命令学习 ---
|
|
151
|
+
AIGFM_LEARN_COMMANDS=true # 是否通过群聊学习未注册的命令(默认 true)
|
|
152
|
+
AIGFM_LEARN_MIN_CONFIDENCE=3 # 命令学习的最小置信度(默认 3)
|
|
153
|
+
|
|
154
|
+
# --- 跨 bot 通信 ---
|
|
155
|
+
AIGFM_PEER_BOTS=[] # 其它 bot 列表,每项含 name/port/token,如:
|
|
156
|
+
# [{"name": "botB", "port": 8080, "token": "aaa114514"}]
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 其它 bot 配置(安装子插件 [nonebot-plugin-aigfm-peer](https://github.com/Funny1Potato/nonebot-plugin-aigfm-peer))
|
|
160
|
+
|
|
161
|
+
在其它 bot 的 `.env` 中配置:
|
|
162
|
+
|
|
163
|
+
```env
|
|
164
|
+
AIGFM_PEER_PUSH_PORT=14514 # 主插件(aigf-master所在bot)的 HTTP 端口
|
|
165
|
+
AIGFM_PEER_TOKEN="aaa114514" # 与 AIGFM_PEER_BOTS 中对应项的 token 一致
|
|
166
|
+
AIGFM_PEER_BOT_NAME="botB" # 本 bot 名称(与 AIGFM_PEER_BOTS 的 name 对应)
|
|
167
|
+
AIGFM_PEER_CAPTURE_PLUGINS=[] # 要捕获输出的插件名列表,为空则捕获所有
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 命令
|
|
171
|
+
|
|
172
|
+
| 命令 | 说明 | 权限 |
|
|
173
|
+
|------|------|------|
|
|
174
|
+
| `status` / `状态` | 查看机器人状态(角色、社交能量、最近消息) | SUPERUSER |
|
|
175
|
+
| `set_role <名字> <设定>` | 设置机器人角色 | SUPERUSER |
|
|
176
|
+
| `reset` / `重置` | 重置会话(清空所有记忆) | SUPERUSER |
|
|
177
|
+
| `presets` | 查看可用的角色预设 | SUPERUSER |
|
|
178
|
+
| `set_preset <预设名>` | 加载指定的角色预设 | SUPERUSER |
|
|
179
|
+
| `reload_meme` / `重载表情包` | 热重载表情包配置 | SUPERUSER |
|
|
180
|
+
|
|
181
|
+
## 触发机制
|
|
182
|
+
|
|
183
|
+
- 攒够 **10 条**(可配置)新消息,或最后一条消息后 **30 秒**(可配置)内无新消息,触发一次处理
|
|
184
|
+
- 纯 @ 消息或检测到同一用户连续发送时,以及调用的插件返回图片时,等待时间会延长至 `AIGF_INCOMPLETE_TIMEOUT`(默认 40 秒)
|
|
185
|
+
- 消息合并窗口内的同一用户连续消息会被合并为一条
|
|
186
|
+
- 每次处理时,LLM 收到最近 **15 条**(可配置)聊天记录 + 四层记忆 + 预设 + 表情包列表 + 其它插件响应
|
|
187
|
+
- LLM 一次调用同时完成:回复决策 + 记忆管理 + 表情包选择 + 命令学习
|
|
188
|
+
|
|
189
|
+
## 🔌 跨插件感知
|
|
190
|
+
|
|
191
|
+
### 工作原理
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
其它插件发消息
|
|
195
|
+
↓
|
|
196
|
+
自动捕获插件输出
|
|
197
|
+
├─ 文本 → 直接进入上下文
|
|
198
|
+
└─ 图片 → 先转成文字描述再进入上下文
|
|
199
|
+
↓
|
|
200
|
+
LLM 在聊天记录中看到:[插件名] 插件的输出
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 示例
|
|
204
|
+
|
|
205
|
+
用户发送 `今日小猪`,rollpig 插件响应后:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
[用户] 今日小猪
|
|
209
|
+
[rollpig] [图片]这张图片展示了一个卡通形象:一只粉红色的猪...
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
LLM 能看到完整的交互过程。
|
|
213
|
+
|
|
214
|
+
## 🤖 插件调用
|
|
215
|
+
|
|
216
|
+
LLM 可通过 function calling 调用插件,有两个工具:
|
|
217
|
+
- **`invoke_plugin`**:调用**本机**插件
|
|
218
|
+
- **`invoke_peer_plugin`**:调用**其它 bot** 上的插件(需指定 `bot` 名)
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
用户:@小助手 帮我摇一个今日小猪
|
|
222
|
+
↓
|
|
223
|
+
LLM 调用:invoke_plugin(command="今日小猪")
|
|
224
|
+
↓
|
|
225
|
+
自动分发给 rollpig 插件执行
|
|
226
|
+
↓
|
|
227
|
+
响应作为新消息进入缓冲
|
|
228
|
+
↓
|
|
229
|
+
下一批处理时 LLM 看到:[用户] 命令 → [插件] 图片响应
|
|
230
|
+
↓
|
|
231
|
+
LLM 基于插件响应回复
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
> 调用时可通过 `user_id` 参数指定以哪位群友的身份调用(从"相关群友信息"中选择 QQ 号),**不同 QQ 号调用可能得到不同结果**。
|
|
235
|
+
|
|
236
|
+
### 命令前缀自动适配
|
|
237
|
+
|
|
238
|
+
- LLM 调用命令时**始终传不带前缀的命令**(如 `今日小猪`)
|
|
239
|
+
- 执行时自动按各 bot 的 `COMMAND_START` 配置补充前缀:
|
|
240
|
+
- `COMMAND_START=[""]` → 命令无前缀
|
|
241
|
+
- `COMMAND_START=["/"]` → 自动补 `/`(如 `/今日小猪`)
|
|
242
|
+
- 本地与 peer 插件均按各自所在 bot 的配置适配前缀
|
|
243
|
+
|
|
244
|
+
## 🌐 跨 bot 通信
|
|
245
|
+
|
|
246
|
+
利用子插件 [nonebot-plugin-aigfm-peer](https://github.com/Funny1Potato/nonebot-plugin-aigfm-peer) 通过 HTTP 与其它 bot 通信,实现:
|
|
247
|
+
1. **消息获取**:其它 bot 的插件输出推送到本插件,进入 LLM 上下文(标注 `[bot名]`)
|
|
248
|
+
2. **远程插件调用**:LLM 调用其它 bot 的命令,路由到对应 bot 远程执行
|
|
249
|
+
|
|
250
|
+
### 工作原理
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
其它 bot 的插件发消息
|
|
254
|
+
↓
|
|
255
|
+
子插件 nonebot-plugin-aigfm-peer 捕获消息并推送到本插件
|
|
256
|
+
├─ 文本 → 直接加入消息缓冲
|
|
257
|
+
└─ 图片 → VLM 描述后加入消息缓冲
|
|
258
|
+
↓
|
|
259
|
+
下一批处理时 LLM 看到:[bot名] 响应
|
|
260
|
+
|
|
261
|
+
LLM 要调用其它 bot 的命令时:
|
|
262
|
+
指定目标 bot 和命令 → 发送到该 bot 执行
|
|
263
|
+
→ 响应推回本插件 → LLM 下一批看到
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 部署
|
|
267
|
+
|
|
268
|
+
1. 在其他bot上安装 [nonebot-plugin-aigfm-peer](https://github.com/Funny1Potato/nonebot-plugin-aigfm-peer)
|
|
269
|
+
2. 在本插件 `.env` 配置 `AIGFM_PEER_BOTS`,在其它 bot `.env` 配置推送端口/token/bot名
|
|
270
|
+
3. 两端 token 必须一致
|
|
271
|
+
|
|
272
|
+
> 说明:peer 命令可由 LLM 命令学习自动发现,无需手动配置命令列表。
|
|
273
|
+
|
|
274
|
+
## 🧠 LLM 命令学习
|
|
275
|
+
|
|
276
|
+
### 工作原理
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
用户发命令 → 其它插件响应
|
|
280
|
+
↓
|
|
281
|
+
LLM 在聊天记录中同时看到"命令"和"插件的响应"
|
|
282
|
+
↓
|
|
283
|
+
判断这是命令 → 自动学习(记录命令、参数、用法、示例)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### 命令管理
|
|
287
|
+
|
|
288
|
+
LLM 可以:
|
|
289
|
+
- **学习新命令**:记录命令、可选参数、使用方法、示例
|
|
290
|
+
- **编辑命令**:修正参数、用法或示例
|
|
291
|
+
- **删除命令**:移除错误或过时的命令(需达到阈值才会真正删除)
|
|
292
|
+
|
|
293
|
+
### 命令静默
|
|
294
|
+
|
|
295
|
+
- 有插件对命令做出响应 → LLM 不回复(避免重复)
|
|
296
|
+
- 没有插件响应 → LLM 可视情况回复(如告知命令无响应)
|
|
297
|
+
|
|
298
|
+
## 🎭 社交能量系统
|
|
299
|
+
|
|
300
|
+
机器人拥有动态的"社交能量"(范围 0.0~1.0,初始 0.75):
|
|
301
|
+
|
|
302
|
+
| 能量范围 | 状态描述 | 表现 |
|
|
303
|
+
|---------|---------|------|
|
|
304
|
+
| ≥ 0.8 | 精力充沛 | 看到什么都想插嘴 |
|
|
305
|
+
| ≥ 0.6 | 状态不错 | 有兴趣的话题会主动参与 |
|
|
306
|
+
| ≥ 0.4 | 一般般 | 有人找就回,不太主动 |
|
|
307
|
+
| ≥ 0.2 | 有点懒 | 倾向于潜水 |
|
|
308
|
+
| < 0.2 | 不想说话 | 完全不想说话 |
|
|
309
|
+
|
|
310
|
+
- 每次消息处理时自然恢复(向基线 0.7 靠拢)+ 随机漂移(±0.08)
|
|
311
|
+
- 被 @ 时兴奋加成 +0.1
|
|
312
|
+
- 回复后消耗能量:基础消耗 0.03 + 按回复文字长度增加
|
|
313
|
+
- 形成自然的"话多→累了→安静→恢复→又想聊"周期
|
|
314
|
+
|
|
315
|
+
## 🔍 联网搜索系统
|
|
316
|
+
|
|
317
|
+
启用后,LLM 通过 **function calling** 自主决定是否调用 `search_internet` 工具搜索。
|
|
318
|
+
|
|
319
|
+
### 搜索 API
|
|
320
|
+
|
|
321
|
+
| API | 说明 | 额外依赖 |
|
|
322
|
+
|-----|------|---------|
|
|
323
|
+
| `tavily`(默认) | 专为 AI 设计,返回格式友好 | `tavily-python` |
|
|
324
|
+
| `bocha` | 国产 AI 搜索 API,中文搜索效果好 | 无 |
|
|
325
|
+
| `bing` | 微软必应搜索 | 无 |
|
|
326
|
+
| `openwebsearch` | 本地 Node.js 搜索服务,聚合多引擎(bing/baidu/duckduckgo 等) | 需先启动 daemon:`cd open-webSearch && npm install && npm run serve`,配置 `AIGFM_OPENWEBSEARCH_URL` |
|
|
327
|
+
|
|
328
|
+
## 🧠 记忆系统
|
|
329
|
+
|
|
330
|
+
机器人拥有四层记忆,由 LLM 在每次回复时自主管理:
|
|
331
|
+
|
|
332
|
+
### 短期记忆
|
|
333
|
+
|
|
334
|
+
存储在 `<插件数据目录>/memory/<群号>/short_term.json`,内容为 LLM 维护的信息列表,包括对话摘要、临时上下文、有趣的梗等。LLM 可以添加、修改、删除条目。
|
|
335
|
+
|
|
336
|
+
### 长期记忆
|
|
337
|
+
|
|
338
|
+
存储在 `<插件数据目录>/memory/<群号>/long_term.json`,内容为 LLM 认为值得长期记住的信息,如群内发生的事件、群规、群友分享的有用知识等。LLM 可添加、修改、删除。不应记录临时对话或常识信息。
|
|
339
|
+
|
|
340
|
+
### 群友信息
|
|
341
|
+
|
|
342
|
+
存储在 `<插件数据目录>/memory/friends/<QQ号>.json`,每个群友一个文件,以 QQ 号命名。LLM 记录群友的昵称、职业、爱好、说过的话、与其他群友的关系等。
|
|
343
|
+
|
|
344
|
+
| 字段 | 来源 | 说明 |
|
|
345
|
+
|------|------|------|
|
|
346
|
+
| `nickname` | 系统自动更新 | QQ 全局昵称 |
|
|
347
|
+
| `aliases` | LLM 管理 | 群友对 ta 的称呼 |
|
|
348
|
+
| `past_nicknames` | 系统自动记录 | 曾用 QQ 昵称 |
|
|
349
|
+
| `info` | LLM 管理 | 一般信息(职业、爱好等) |
|
|
350
|
+
| `groups` | 系统自动维护 | 所在的群列表 |
|
|
351
|
+
|
|
352
|
+
### 文化记忆
|
|
353
|
+
|
|
354
|
+
存储在 `<插件数据目录>/memory/<群号>/culture.json`,记录梗、网络用语、流行语。LLM 主动学习和存储,根据聊天内容自动匹配。
|
|
355
|
+
|
|
356
|
+
## 🖼️ 表情包功能
|
|
357
|
+
|
|
358
|
+
### 工作原理
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
群聊中有人发图片/表情包
|
|
362
|
+
↓
|
|
363
|
+
下载图片 → VLM 分析内容和情感
|
|
364
|
+
↓
|
|
365
|
+
保存到缓存目录(<缓存目录>/sticker_cache/)
|
|
366
|
+
↓
|
|
367
|
+
下一次消息处理时,LLM 在 Prompt 中看到缓存的表情包
|
|
368
|
+
↓
|
|
369
|
+
LLM 决定是否收藏 → 保存到 memes 目录
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### 表情包素材库
|
|
373
|
+
|
|
374
|
+
存放在 `<插件数据目录>/memes/` 下:
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
memes/
|
|
378
|
+
├── memes.json ← 管理员手动配置
|
|
379
|
+
├── collected.json ← 机器人自动收集
|
|
380
|
+
└── *.jpg/png/gif ← 表情包图片文件
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### 管理员手动配置
|
|
384
|
+
|
|
385
|
+
编辑 `memes.json`:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
[
|
|
389
|
+
{
|
|
390
|
+
"id": "happy_spin",
|
|
391
|
+
"path": "happy_spin.jpg",
|
|
392
|
+
"keywords": ["开心", "高兴", "庆祝"],
|
|
393
|
+
"description": "开心到转圈的小人"
|
|
394
|
+
}
|
|
395
|
+
]
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
| 字段 | 必填 | 说明 |
|
|
399
|
+
|------|------|------|
|
|
400
|
+
| `id` | ✅ | 唯一标识符,AI 用这个选择表情包 |
|
|
401
|
+
| `path` | ✅ | 图片文件名(相对于 memes 目录) |
|
|
402
|
+
| `keywords` | ✅ | 适用场景关键词 |
|
|
403
|
+
| `description` | ✅ | 一句话描述内容 |
|
|
404
|
+
|
|
405
|
+
修改后执行 `/重载表情包` 即可生效,无需重启。
|
|
406
|
+
|
|
407
|
+
#### 自动收集
|
|
408
|
+
|
|
409
|
+
机器人收到图片时,VLM 分析后保存到缓存。LLM 在回复时看到缓存的表情包,决定是否收藏。
|
|
410
|
+
|
|
411
|
+
- 图片按 MD5 hash 去重
|
|
412
|
+
- 每个表情包记录**使用次数**和**保存时间**
|
|
413
|
+
- 超过 `AIGFM_MEME_MAX_COUNT` 上限时,按**归一化加权**清理:`保存时间旧 + 使用次数少 → 优先删除`,最近发过的表情包不会删除
|
|
414
|
+
|
|
415
|
+
## 📷 图片理解模式
|
|
416
|
+
|
|
417
|
+
| 模式 | 流程 | 适用场景 |
|
|
418
|
+
|------|------|---------|
|
|
419
|
+
| `vlm`(默认) | 图片 → VLM 分析 → 文字描述给 LLM | LLM 不支持图片输入 |
|
|
420
|
+
| `llm` | 图片 → base64 直接附在 LLM prompt 中 | LLM 支持视觉 |
|
|
421
|
+
|
|
422
|
+
## 🎭 预设系统
|
|
423
|
+
|
|
424
|
+
首次运行后在 `<插件配置目录>/presets/` 下生成 `default.json`:
|
|
425
|
+
|
|
426
|
+
```json
|
|
427
|
+
{
|
|
428
|
+
"name": "小助手",
|
|
429
|
+
"role": "一个友好的群聊助手",
|
|
430
|
+
"knowledges": [],
|
|
431
|
+
"hidden": false
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
在 `presets/` 目录下创建新的 JSON 文件即可添加新预设,执行 `set_preset <预设名>` 加载。
|
|
436
|
+
|
|
437
|
+
## 📨 消息格式
|
|
438
|
+
|
|
439
|
+
LLM 支持以下回复类型:
|
|
440
|
+
|
|
441
|
+
| 类型 | 格式 | 说明 |
|
|
442
|
+
|------|------|------|
|
|
443
|
+
| 文本 | `{"type": "text", "content": "..."}` | 纯文本消息 |
|
|
444
|
+
| @ | `{"type": "at", "name": "群友昵称"}` | 艾特群友 |
|
|
445
|
+
| 表情包 | `{"type": "meme", "id": "表情包id"}` | 发送表情包 |
|
|
446
|
+
|
|
447
|
+
## 📁 数据存储
|
|
448
|
+
|
|
449
|
+
```
|
|
450
|
+
{data_dir}/
|
|
451
|
+
memory/
|
|
452
|
+
{group_id}/
|
|
453
|
+
short_term.json # 短期记忆
|
|
454
|
+
long_term.json # 长期记忆
|
|
455
|
+
culture.json # 文化记忆
|
|
456
|
+
friends/
|
|
457
|
+
{user_id}.json # 群友信息
|
|
458
|
+
memes/
|
|
459
|
+
memes.json # 管理员表情包索引
|
|
460
|
+
collected.json # 自动收集表情包索引(含 usage_count/saved_at)
|
|
461
|
+
{hash}.{ext} # 表情包文件
|
|
462
|
+
learned_commands.json # 当前实例学习到的命令
|
|
463
|
+
peer_commands.json # 其它 bot 的命令
|
|
464
|
+
|
|
465
|
+
{cache_dir}/
|
|
466
|
+
image_cache/
|
|
467
|
+
{md5}.json # 图片 VLM 描述缓存
|
|
468
|
+
raw/{fileid} # 原始图片缓存
|
|
469
|
+
sticker_cache/
|
|
470
|
+
{hash}.{ext} # 表情包缓存文件
|
|
471
|
+
|
|
472
|
+
{config_dir}/
|
|
473
|
+
presets/
|
|
474
|
+
default.json # 默认预设
|
|
475
|
+
*.json # 自定义预设
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## 依赖
|
|
479
|
+
|
|
480
|
+
```
|
|
481
|
+
必需:nonebot2, nonebot-adapter-onebot, nonebot-plugin-localstore,
|
|
482
|
+
openai, httpx, anyio, pillow, pydantic, numpy
|
|
483
|
+
可选:tavily-python(Tavily 搜索)
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
## 兼容性
|
|
487
|
+
|
|
488
|
+
- **Function Calling**:插件调用和搜索需要模型支持 tool_call
|
|
489
|
+
|
|
490
|
+
## License
|
|
491
|
+
|
|
492
|
+
MIT
|