Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
2619f6c
feat(v2): add embedding and reranker provider abstraction layer
NickCharlie Feb 20, 2026
4c1ba08
feat(jargon): add statistical pre-filter to reduce LLM cost
NickCharlie Feb 20, 2026
04c3c27
feat(v2): add few-shot exemplar library with vector similarity search
NickCharlie Feb 20, 2026
368cad1
feat(v2): add LightRAG-based knowledge manager
NickCharlie Feb 20, 2026
a5a026b
feat(v2): add mem0-based memory manager with semantic retrieval
NickCharlie Feb 20, 2026
411aae6
feat(v2): add social graph analyzer with community detection and infl…
NickCharlie Feb 20, 2026
b0f21e5
refactor(v2): replace safe_parse_llm_json with guardrails-ai in socia…
NickCharlie Feb 20, 2026
2c9f1c7
feat(v2): add tiered learning trigger mechanism
NickCharlie Feb 20, 2026
366965e
feat(v2): add V2LearningIntegration facade wiring all new modules
NickCharlie Feb 20, 2026
755bf90
fix(jargon): fix pagination, search filter, and v2 persistence bugs
NickCharlie Feb 20, 2026
1b25d19
feat(v2): wire V2LearningIntegration into main learning manager
NickCharlie Feb 20, 2026
d2b64f0
feat(v2): wire V2LearningIntegration directly into main.py
NickCharlie Feb 20, 2026
173392a
debug(v2): add config value diagnostic log at V2 init
NickCharlie Feb 20, 2026
2e88f25
fix(config): change embedding/reranker fields to text input
NickCharlie Feb 20, 2026
3d2cc01
fix(lightrag): guard initialize_pipeline_status for older versions
NickCharlie Feb 20, 2026
b7e4707
feat(perf): add timing metrics to LLM hook and V2 context injection
NickCharlie Feb 20, 2026
308ced2
feat(webui): add Hook injection performance chart to dashboard
NickCharlie Feb 20, 2026
5cd5187
fix(exemplar): upgrade embedding_json column to MEDIUMTEXT for high-d…
NickCharlie Feb 20, 2026
580c139
perf(hook): parallelize context retrieval with asyncio.gather
NickCharlie Feb 20, 2026
f74b9cb
refactor(main): extract business logic into dedicated modules (2518→1…
NickCharlie Feb 20, 2026
531a728
refactor(services): reorganize 51 flat files into 14 domain subpackages
NickCharlie Feb 20, 2026
1e5b4fa
refactor(config): migrate PluginConfig from dataclass to pydantic Bas…
NickCharlie Feb 20, 2026
414216a
refactor(core): add @cached_service decorator and remove dead code
NickCharlie Feb 20, 2026
f53dfef
refactor(main): extract plugin lifecycle into dedicated modules
NickCharlie Feb 20, 2026
c706945
refactor(db): remove DatabaseConnectionPool and clean up exports
NickCharlie Feb 20, 2026
910201e
refactor(db): add BaseFacade base class and facades package
NickCharlie Feb 20, 2026
111517c
refactor(db): add 10 domain repository classes for ORM access
NickCharlie Feb 20, 2026
2fef549
refactor(db): add core data facades for message, learning, and jargon
NickCharlie Feb 20, 2026
ddb6a41
refactor(db): add social, persona, affection, and psychological facades
NickCharlie Feb 20, 2026
0ecbbeb
refactor(db): add expression, reinforcement, metrics, and admin facades
NickCharlie Feb 20, 2026
97e6ea4
refactor(db): rewrite SQLAlchemyDatabaseManager as thin DomainRouter
NickCharlie Feb 20, 2026
76dcc54
docs: bump version to Next-2.0.0 and add changelog
NickCharlie Feb 20, 2026
94f8225
style: strip emoji and separator comments from source code
NickCharlie Feb 20, 2026
3383e19
fix(db): correct method signatures in DomainRouter and LearningFacade
NickCharlie Feb 20, 2026
fe0367f
fix(db): resolve DomainRouter signature mismatches and WebUI breakages
NickCharlie Feb 20, 2026
2b0fc56
fix(db): add timestamp coercion to prevent Data truncated on Float co…
NickCharlie Feb 20, 2026
4e9308a
fix(social): add member_count and relation_count to group analysis query
NickCharlie Feb 20, 2026
6473d1e
fix(webui): add offset support to persona review pagination
NickCharlie Feb 20, 2026
9b6fd05
feat(learning): inject approved few-shot dialogues into LLM responses
NickCharlie Feb 20, 2026
02b2110
perf(learning): parallelize sequential LLM calls in style analysis
NickCharlie Feb 20, 2026
c759af5
fix(db): add group_id parameter to backup_persona signature
NickCharlie Feb 20, 2026
f219f72
fix(learning): replace shared current_session with per-group dict
NickCharlie Feb 20, 2026
9d746fc
chore(webui): remove unused source directory
NickCharlie Feb 20, 2026
30a140f
refactor(analysis): migrate expression_pattern_learner to ORM
NickCharlie Feb 20, 2026
373c09d
refactor(state): rewrite time_decay_manager with ORM
NickCharlie Feb 20, 2026
9961c99
refactor(social): migrate enhanced_social_relation_manager to ORM
NickCharlie Feb 20, 2026
29b763b
refactor(response): migrate intelligent_responder to ORM
NickCharlie Feb 20, 2026
53108a7
refactor(analysis): migrate multidimensional_analyzer to ORM
NickCharlie Feb 20, 2026
9fa2bdf
refactor(state): migrate affection_manager to ORM
NickCharlie Feb 20, 2026
c2aedad
refactor(learning): migrate dialog_analyzer to ORM
NickCharlie Feb 20, 2026
d2a14ae
refactor(db): migrate remaining service files to ORM
NickCharlie Feb 20, 2026
aee1273
refactor(db): delete legacy database layer and clean DomainRouter
NickCharlie Feb 20, 2026
a69c89a
docs: update changelog for ORM migration and legacy cleanup
NickCharlie Feb 20, 2026
750ba0f
fix(db): add DatabaseManager alias for backward compatibility
NickCharlie Feb 20, 2026
aa6c636
fix(social): add sender_name to user statistics query
NickCharlie Feb 20, 2026
f9b96ba
fix(social): map from_user/to_user to ORM column names
NickCharlie Feb 20, 2026
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
109 changes: 104 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,111 @@
# 🧧 新年快乐!Happy Lunar New Year!
# Changelog

> 祝所有用户和社区贡献者马年大吉、万事如意!
所有重要更改都将记录在此文件中。

---
## [Next-2.0.0] - 2026-02-21

### 🏗️ 架构重构

#### 全量 ORM 迁移(消除所有硬编码 SQL)
- 将 7 个服务文件中残留的硬编码 raw SQL 全部迁移至 SQLAlchemy ORM
- `expression_pattern_learner`:`_apply_time_decay`、`_limit_max_expressions`、`get_expression_patterns` 改用 `ExpressionPatternORM` 模型
- `time_decay_manager`:完全重写,消除 f-string SQL 注入风险,用显式 ORM 模型处理器替代动态表名拼接,移除对不存在表的引用
- `enhanced_social_relation_manager`:4 个方法改用 `UserSocialProfile`、`UserSocialRelationComponent`、`SocialRelationHistory` 模型
- `intelligent_responder`:3 个方法改用 `FilteredMessage`、`RawMessage` 模型及 `func.count`/`func.avg` 聚合
- `multidimensional_analyzer`:2 个 GROUP BY/HAVING 查询改用 ORM `select().group_by().having()`
- `affection_manager`:3 层级联查询改用 `RawMessage`、`FilteredMessage`、`LearningBatch` 模型
- `dialog_analyzer`:`get_pending_style_reviews` 改用 `StyleLearningReview` 模型
- `progressive_learning`、`message_facade`、`webui/learning` 蓝图同步迁移

#### 遗留数据库层清理(-7600 行)
- 删除 `services/database/database_manager.py`(6035 行硬编码 SQL 单体)
- 删除 `core/database/` 下 5 个遗留后端文件:`backend_interface.py`、`sqlite_backend.py`、`mysql_backend.py`、`postgresql_backend.py`、`factory.py`(共 1530 行)
- DomainRouter 移除 `_legacy_db` 回退、`get_db_connection()`/`get_connection()` shim、`__getattr__` 安全网
- `core/database/__init__.py` 精简为仅导出 `DatabaseEngine`
- `services/database/__init__.py` 移除 `DatabaseManager` 导出

#### 未使用资源清理
- 删除 `web_res/static/MacOS-Web-UI/` 源码目录(已迁移至 `static/js/macos/` 和 `static/css/macos/`)

#### 服务层重组
- 将 `services/` 下 51 个平铺文件重组为 14 个领域子包,提升内聚性和可维护性
- 每个子包职责明确:`learning/`、`social/`、`jargon/`、`persona/`、`expression/`、`affection/`、`psychological/`、`reinforcement/`、`message/` 等

#### 主模块瘦身
- 将 `main.py` 业务逻辑提取至独立生命周期模块(`initializer`、`event_handler`、`learning_scheduler` 等)
- 代码量从 2518 行精简至 207 行(减少 92%)

#### 数据库单体拆分
- 将 4308 行的 `SQLAlchemyDatabaseManager` 重写为约 800 行的薄路由层(DomainRouter)
- 引入 `BaseFacade` 基类和 11 个领域 Facade,实现关注点分离
- 所有 62 个消费者方法显式路由到对应 Facade,消除隐式回退

#### 领域 Facade 清单
| Facade | 职责 | 方法数 |
|--------|------|--------|
| `MessageFacade` | 消息存储、查询、统计 | 17 |
| `LearningFacade` | 学习记录、审查、批次、风格学习 | 29 |
| `JargonFacade` | 黑话 CRUD、搜索、统计、全局同步 | 14 |
| `SocialFacade` | 社交关系、用户画像、偏好 | 9 |
| `PersonaFacade` | 人格备份、恢复、更新历史 | 4 |
| `AffectionFacade` | 好感度、Bot 情绪状态 | 6 |
| `PsychologicalFacade` | 情绪画像 | 2 |
| `ExpressionFacade` | 表达模式、风格画像 | 8 |
| `ReinforcementFacade` | 强化学习、人格融合、策略优化 | 6 |
| `MetricsFacade` | 跨域统计聚合 | 3 |
| `AdminFacade` | 数据清理与导出 | 2 |

#### Repository 层扩展
- 新增 10 个类型化 Repository 类,总数从 29 增至 39
- 新增:`RawMessageRepository`、`FilteredMessageRepository`、`BotMessageRepository`、`UserProfileRepository`、`UserPreferencesRepository`、`EmotionProfileRepository`、`StyleProfileRepository`、`BotMoodRepository`、`PersonaBackupRepository`、`KnowledgeGraphRepository`

# Changelog
### 🔧 重构

所有重要更改都将记录在此文件中。
#### PluginConfig 迁移
- 从 `dataclass` 迁移至 pydantic `BaseModel`
- 采用 `ConfigDict(extra="ignore", populate_by_name=True)` 实现健壮验证和未知字段容忍

#### 服务缓存优化
- 新增 `@cached_service` 装饰器,消除冗余服务实例化
- 替换手工单例模式,减少样板代码

#### 数据库连接清理
- 移除旧版 `DatabaseConnectionPool`,改用 SQLAlchemy 异步引擎内置连接池管理
- 移除未使用的 `EventBus`、`EventType`、`EventManager` 等事件基础设施

### ⚡ 性能优化

#### LLM 缓存命中率提升
- 上下文注入从 `system_prompt` 拼接改为 AstrBot 框架 `extra_user_content_parts` API
- 动态上下文(社交关系、黑话、多样性、V2 学习)作为额外内容块附加在用户消息之后,不再修改系统提示词
- **system_prompt 保持稳定不变**,最大化 LLM API 前缀缓存(prefix caching)命中率,显著降低 token 消耗和响应延迟
- 旧版 AstrBot 自动回退到 system_prompt 注入(附带缓存命中率下降警告)

#### 上下文检索并行化
- LLM Hook 的 4 个上下文提供者(社交、V2 学习、多样性、黑话)通过 `asyncio.gather` 并行执行
- Hook 总延迟降低约 60-70%(从串行累加改为取最慢单项)
- 每个提供者独立计时,便于识别性能瓶颈

#### 服务实例化缓存
- 29 个服务方法通过 `@cached_service` 装饰器缓存,避免重复创建服务实例
- `ServiceFactory` 和 `ComponentFactory` 共享同一缓存字典,跨工厂复用

#### 数据处理流水线优化
- 消息批量写入改为 `asyncio.gather` 并发插入
- 渐进式学习中消息筛选与人格检索并行执行
- 强化学习与风格分析并行执行
- DomainRouter 显式方法路由消除 `__getattr__` 运行时属性查找开销

### 📊 统计
- **净代码减少**:约 21,700 行(ORM 迁移 + 遗留层删除 + 未使用资源清理)
- **遗留 SQL 层**:6035 + 1530 = 7565 行硬编码 SQL 代码删除
- **ORM 迁移**:7 个服务文件、约 800 行 raw SQL 替换为类型安全的 ORM 查询
- **安全修复**:`time_decay_manager` f-string SQL 注入漏洞已消除
- **新增文件**:11 个 Facade + 10 个 Repository + 1 个 BaseFacade = 22 个文件
- **`SQLAlchemyDatabaseManager`**:4308 行 → ~777 行(减少 82%),零遗留回退
- **变更文件**:51+ 个服务文件重组、`main.py` 重构、数据库层完全重写

---

## [Next-1.2.9] - 2026-02-19

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<br>

[![Version](https://img.shields.io/badge/version-Next--1.2.8-blue.svg)](https://github.com/NickCharlie/astrbot_plugin_self_learning) [![License](https://img.shields.io/badge/license-GPLv3-green.svg)](LICENSE) [![AstrBot](https://img.shields.io/badge/AstrBot-%3E%3D4.11.4-orange.svg)](https://github.com/Soulter/AstrBot) [![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
[![Version](https://img.shields.io/badge/version-Next--2.0.0-blue.svg)](https://github.com/NickCharlie/astrbot_plugin_self_learning) [![License](https://img.shields.io/badge/license-GPLv3-green.svg)](LICENSE) [![AstrBot](https://img.shields.io/badge/AstrBot-%3E%3D4.11.4-orange.svg)](https://github.com/Soulter/AstrBot) [![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)

[核心功能](#-我们能做什么) · [快速开始](#-快速开始) · [管理界面](#-可视化管理界面) · [社区交流](#-社区交流) · [贡献指南](CONTRIBUTING.md)

Expand Down
2 changes: 1 addition & 1 deletion README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<br>

[![Version](https://img.shields.io/badge/version-Next--1.2.8-blue.svg)](https://github.com/NickCharlie/astrbot_plugin_self_learning) [![License](https://img.shields.io/badge/license-GPLv3-green.svg)](LICENSE) [![AstrBot](https://img.shields.io/badge/AstrBot-%3E%3D4.11.4-orange.svg)](https://github.com/Soulter/AstrBot) [![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
[![Version](https://img.shields.io/badge/version-Next--2.0.0-blue.svg)](https://github.com/NickCharlie/astrbot_plugin_self_learning) [![License](https://img.shields.io/badge/license-GPLv3-green.svg)](LICENSE) [![AstrBot](https://img.shields.io/badge/AstrBot-%3E%3D4.11.4-orange.svg)](https://github.com/Soulter/AstrBot) [![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)

[Features](#what-we-can-do) · [Quick Start](#quick-start) · [Web UI](#visual-management-interface) · [Community](#community) · [Contributing](CONTRIBUTING.md)

Expand Down
131 changes: 131 additions & 0 deletions VIDEO_SCRIPT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Self-Learning 插件 Bilibili 视频脚本

> 预计时长:约 5 分钟 | 定位:功能讲解 + 使用教程 | 语气:口语化、轻松

---

## 一、开场 Hook(约 30 秒)

各位好,先问大家一个问题——

你有没有觉得,现在的 AI 聊天机器人,虽然什么都能答,但说话总是……一股"AI味儿"?

你跟它说"6",它回你"您的意思是数字六吗?"。你在群里发个梗,它给你来一段百科解释。

说白了,它不懂你们群的"语言",也不知道你们平时怎么聊天。

那有没有办法,让 AI 自己去"偷师",学会像真人一样说话?

今天给大家介绍的这个插件,就是专门干这件事的。

---

## 二、一句话介绍(约 20 秒)

这个插件叫 **Self-Learning**,是给 AstrBot 用的一个自主学习插件。

它能做的事情用一句话概括就是——**让你的 Bot 潜伏在群里,自动学习大家的说话方式,然后越聊越像真人。**

不需要你手动喂数据,不需要你写什么 prompt 模板,它全自动完成。

---

## 三、核心功能讲解(约 3 分钟)

接下来我挨个说说它到底能干什么。

### 1. 自动学群友说话(约 40 秒)

首先,最核心的能力——**表达模式学习**。

插件开启之后,它会在后台默默收集群里的聊天消息。然后定时触发一次学习,用大模型分析这些对话:**在什么场景下,大家会用什么样的表达方式。**

比如它可能会学到:表示赞同的时候,群友喜欢说"确实"而不是"我同意你的看法"。

这些学到的表达模式会被自动注入到 Bot 的回复里,这样 Bot 说话就不会那么正式、那么像机器了。

而且它有一个时间衰减机制,过时的表达会自动降权,新学到的会优先使用。所以 Bot 的说话风格会跟着群聊氛围一起"进化"。

### 2. 听得懂黑话(约 30 秒)

第二个功能——**黑话挖掘**。

每个群都有自己的"黑话"对吧?比如某个群里"发财了"可能是表示"太好了"的意思,"下次一定"其实是在拒绝。

这些东西你不教,AI 是真不懂。

这个插件会自动检测群里的高频特殊用语,然后调用大模型根据上下文推断它的真实含义,保存下来。之后 Bot 在回复消息的时候,就能正确理解这些黑话了,不会再闹笑话。

### 3. 社交关系网络(约 30 秒)

第三个——**社交关系分析**。

插件不光学说话,它还会"看人"。它会自动记录群里谁跟谁聊得多、谁 at 了谁、谁经常回复谁,把这些互动关系整理成一张社交网络图。

这有什么用呢?Bot 回复的时候,它知道这个群里谁跟谁关系好、谁是活跃分子、谁是边缘人。这样它聊天的时候就能更"懂事",不会在两个关系很好的人面前说不合时宜的话。

在管理后台里你还能看到一张可视化的关系图谱,节点越大说明这个人越活跃,连线越粗说明两个人互动越频繁,挺有意思的。

### 4. 好感度系统(约 30 秒)

第四个——**好感度和情绪系统**。

插件会记录每个人跟 Bot 的互动。经常夸它、跟它友好聊天,好感度就会涨;反过来骂它,好感度就掉。

好感度会影响 Bot 的回复态度。对喜欢的人说话更热情、更主动,对不喜欢的人就冷淡一些。

Bot 自己还有一套情绪系统,每天会自动切换心情。开心的时候活泼一点,低落的时候话少一点。这样聊起来就更有"人味儿"了。

### 5. 人格审查——你说了算(约 30 秒)

可能有人会担心:Bot 自己学习,万一学歪了怎么办?

放心,插件有一个**人格审查机制**。Bot 学完之后生成的人格更新建议,不会直接应用,而是先提交到审查队列里。

你可以在管理后台看到它打算怎么改、改了哪些内容,觉得没问题就批准,觉得不对就驳回。**最终决定权始终在你手里。**

### 6. 可视化管理后台(约 30 秒)

可能有人会担心:Bot 自己学习,万一学歪了怎么办?

放心,插件有一个**人格审查机制**。Bot 学完之后生成的人格更新建议,不会直接应用,而是先提交到审查队列里。

你可以在管理后台看到它打算怎么改、改了哪些内容,觉得没问题就批准,觉得不对就驳回。**最终决定权始终在你手里。**

### 5. 可视化管理后台(约 30 秒)

最后说一下**WebUI 管理界面**。

插件带了一个完整的网页后台,默认端口 7833,浏览器直接就能访问。

里面能看到消息收集的数据统计、学习进度、社交关系网络图、好感度排行榜,还有刚才说的人格审查和风格学习详情。

基本上 Bot 在做什么、学到了什么、效果怎么样,一目了然。不需要去翻日志,也不用敲命令,全部可视化搞定。

---

## 四、安装使用(约 30 秒)

说了这么多,怎么用呢?非常简单。

第一步,确保你已经在跑 AstrBot,版本不低于 4.11.4。

第二步,在 AstrBot 的插件商店里搜索 **self-learning**,一键安装。

第三步,到 AstrBot 后台的插件配置里,把"启用消息抓取"和"启用自动学习"打开。

然后你就不用管了。它会自动开始收集消息、自动学习。过几个小时你再去看,Bot 说话就已经开始变了。

如果你想看详细数据,浏览器打开 `你的服务器地址:7833`,登录管理后台就行。默认密码在配置里,记得第一次登录之后改掉。

---

## 收尾(约 20 秒)

总结一下,这个插件做的事情就是:**让你的 AI Bot 从一个"什么都会但不会说人话"的机器,变成一个能融入群聊、听得懂黑话、记得住谁对它好的"拟人化 Bot"。**

感兴趣的话,GitHub 搜 **astrbot_plugin_self_learning** 就能找到,觉得有用欢迎给个 Star。

遇到问题或者想交流,可以加 QQ 群 **1021544792**。

好,这期就到这里,我们下期见。
37 changes: 37 additions & 0 deletions _conf_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -552,5 +552,42 @@
"default": 7
}
}
},
"V2_Architecture_Settings": {
"description": "v2架构升级配置",
"type": "object",
"hint": "高级功能配置:Embedding向量化、Reranker重排序、知识引擎和记忆引擎。需要先在AstrBot中配置对应类型的Provider",
"items": {
"embedding_provider_id": {
"description": "Embedding 提供商 ID",
"type": "string",
"hint": "填写Embedding提供商的完整ID(如 'openai/text-embedding-3-large')。需要先在AstrBot的Provider管理中创建Embedding类型的提供商,然后将其ID填写到此处。格式通常为 '来源名/模型名'",
"default": ""
},
"rerank_provider_id": {
"description": "Reranker 提供商 ID",
"type": "string",
"hint": "填写Reranker提供商的完整ID(如 'openai/qwen3-rerank')。需要先在AstrBot的Provider管理中创建Reranker类型的提供商,然后将其ID填写到此处。格式通常为 '来源名/模型名'",
"default": ""
},
"rerank_top_k": {
"description": "重排序保留结果数",
"type": "int",
"hint": "Reranker重排序后保留的Top-K结果数量,值越小越精准但可能遗漏",
"default": 5
},
"knowledge_engine": {
"description": "知识引擎",
"type": "string",
"hint": "知识存储引擎类型。legacy=现有NetworkX实现,lightrag=使用LightRAG进行向量+图谱混合检索(需配置Embedding提供商)",
"default": "legacy"
},
"memory_engine": {
"description": "记忆引擎",
"type": "string",
"hint": "记忆管理引擎类型。legacy=现有实现,mem0=使用mem0进行自动记忆提取和检索(需配置Embedding提供商)",
"default": "legacy"
}
}
}
}
Loading
Loading