# AstrBot self-learning plugin: a review queue between group chat and the next LLM call

> This plugin attaches to three points in an AstrBot conversation, learns expression patterns and group jargon from real user to bot message pairs, and holds every learned artefact behind an approval queue before it reaches the model. The review gate and the personality rollback path are the parts that make it usable in a live group, and the WebUI dependency installer is the part that will cost you an afternoon.

**NickCharlie/astrbot_plugin_self_learning** — AstrBot 自主学习插件 — 让 AI 聊天机器人自主学习对话风格、理解群组黑话、管理社交关系与好感度、自适应人格演化，像真人一样自然对话。

- Repository: https://github.com/NickCharlie/astrbot_plugin_self_learning
- Stars: 412 · Forks: 33
- Language: Python
- License: AGPL-3.0
- Published: 2026-09-17 · Updated: 2026-09-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/nickcharlie-astrbot-plugin-self-learning

## The plugin hooks three points, and never replaces the reply path

A first thing to be clear about: the plugin does not swap out AstrBot's reply logic. It augments the bot at three named positions in the lifecycle. It sees the message event, it sees the outbound event after the bot has replied, and it fires before the next LLM request. The architecture diagram in the README names the moving parts inside each: a `PluginLifecycle`, a `FactoryManager` and `ServiceFactory` for wiring, a `LLMHookHandler` for the injection point, and a management command layer.

Those three positions explain the whole design. Data has to be collected before the reply, has to be paired with the bot's own output afterwards, and can only be handed to the model at request time. A tool that wanted to rewrite replies inline would have to reimplement generation. This one composes context instead, which is why it can be added to an existing group without touching the model or the provider.

## Every learned artefact lands in a review queue, and nothing reaches the model without approval

The learning path does not write straight into the persona. Raw messages are filtered, expression patterns are mined from them, and when a group crosses the `min_messages_for_learning` threshold a batch session starts that writes into a personality review and a style review. Both are queues. The README's WebUI section lists the actions available on them as approve, reject, delete and roll back, and the core feature table adds an automatic apply policy as a fourth route. Approved style records become the few-shot examples injected later; unapproved ones sit there.

Two consequences follow. Learning that produces nothing reviewable produces nothing at injection time, so a misconfigured group can accumulate data indefinitely and still change nothing. And the rollback path is the reason the plugin is safe to leave running: a persona that was rewritten from bad group data can be put back.

## Jargon is counted before it is understood, then injected as explanation

Group slang gets its own pipeline because it is not an expression pattern. The mechanism is two stage. High frequency terms are pre-filtered by counting, and meaning is inferred from the surrounding context, with the LLM doing the second part. The result is a jargon entry carrying a candidate word, a meaning, a count, and the group it came from, and the WebUI page for it handles syncing between group level and global level entries.

At request time the jargon is injected as an explanation alongside the other context, not as an instruction. That is the conservative choice and it has a cost worth naming: a term the model already knows badly will be corrected, a term the model handles well gains little, and a term inferred wrongly from a small sample will be injected with a confident wrong meaning. Nothing in the plugin's description suggests a confidence threshold on jargon entries, and the count column in the WebUI is the only signal exposed for filtering them by hand.

## The plugin will not install its own dependencies, and the install API needs a WebUI confirmation

This is the sharpest edge in the whole project. The README states plainly that the code does not install pip dependencies at plugin install time or at startup. Instead you open the WebUI dashboard, go to the full settings page, and click either the base capability dependency button or the full capability dependency button. The dependency install endpoint accepts a request only after explicit WebUI confirmation, and the payload it expects is a JSON object with `manual_confirmed` set to true and `source` set to `webui_settings`.

If your deployment forbids WebUI installs, there is an environment variable to turn the whole thing off:

```powershell
$env:ASTRBOT_ENABLE_WEB_DEP_INSTALL="false"
```

The dependency list itself is small, since AstrBot core already provides fastapi and uvicorn, and `requirements.txt` declares them plus `itsdangerous` and `jinja2` so the standalone WebUI also works on a minimal install. The consequence of getting this wrong is a plugin that loads and then fails, and the troubleshooting section names the symptom exactly: a load failure for missing dependencies, with the fix being the manual WebUI step.

## PostgreSQL is the default and it will try to create its own database

The default backend is PostgreSQL, and the startup sequence is more ambitious than a connection. It first connects to the maintenance database `postgres`, creates `astrbot_self_learning` if the target does not exist, then creates missing schemas and ORM tables. The database user therefore needs permission to create databases, schemas and tables, which managed Postgres services frequently do not grant to application users. The documented fallback is explicit: set `Database_Settings.db_type=sqlite` and it runs on a local file instead. MySQL is available as a third option via `mysql+aiomysql`.

The data layer is SQLAlchemy's async ORM, and `SQLAlchemyDatabaseManager` keeps its old interface while routing internally through domain facades for messages, learning, jargon, persona, social, expression, psychological state, reinforcement, metrics and admin. Table creation runs `Base.metadata.create_all`, then checks for missing tables and missing columns, creates ORM tables absent from the database, and adds new columns to existing ones. Automatic migration is additive only. It will not drop a column, rename one, or change a type, so a schema change that needs any of those needs a human.

## Nine checks in order, because a bot that learns nothing has nine possible causes

The troubleshooting section for learning nothing is a numbered list of nine, and reading it tells you how many independent switches this plugin has. In order: `enable_message_capture=True`, the user or group not excluded by a blacklist, `RawMessage` growing, message length over a threshold, `enable_expression_patterns=True`, the bot's outbound text reaching `BotMessage`, the group reaching `min_messages_for_learning`, no pending review records left unapproved, and the provider being available.

Item eight is the one that surprises people. A batch that ran and produced review records changes nothing until someone approves it, so a correctly working system and a broken one look identical from the outside. Item nine explains the degradation rule stated in the setup section: with no provider configured the plugin still loads, and LLM features degrade and log rather than fail. The management commands cover the manual path, including `/start_learning`, `/force_learning` for a single forced pass, and `/remember <context> => <expression example>`, which links a context to an expression and a dialogue example by hand.

## The WebUI is the control plane, and it defaults to no authentication

The dashboard listens on `http://127.0.0.1:7833` by default and, as the README says, currently requires no password. Setting `web_interface_host=0.0.0.0` makes it reachable from the LAN by server IP, which turns an unauthenticated panel that can approve persona changes, install dependencies and read raw message content into a LAN-wide one. Anyone who can reach that port can rewrite the bot's voice.

That is also why the settings page is the documentation. Full settings reads its schema from `/api/config/schema` and edits every public config key, the learning content page reads from `/api/style_learning/content_text` to show raw messages, filtered messages, expression patterns, batches and review records side by side, and the log level page adjusts AstrBot output from `error` to `debug` at runtime. Restart requirements are inconsistent by design: changing the database type, data directory or WebUI host and port needs a plugin restart, while log level and most learning thresholds take effect immediately.

## AGPL-3.0, a derivative of AstrBot, and a warning about backing up your persona

The licence is AGPL-3.0, and the project describes itself as incorporating and deriving from AstrBot, which is on the same licence, with modifications and derivative works required to ship under it. Copyright runs 2025 to 2026 with all rights reserved held for the personal components, and there is a separate contributor and maintainer credited alongside the author.

The README opens with a warning that deserves to be read before installation rather than after: back up the current personality in AstrBot's native persona management first, because the learning, review and rollback mechanisms cannot substitute for an external backup. That is the correct framing for a component that rewrites a persona from group conversation. The disclaimer alongside it restricts use to learning, research and lawful purposes, requires the operator to obtain authorisation before collecting user messages, and disclaims liability for data loss, persona errors and crashes. The repository ships SECURITY.md, CHANGELOG.md, CONTRIBUTING.md, `pytest.ini`, `ruff.toml` and separate test requirements, and the last push was 2026-09-30.

## Conclusion

Adopt astrbot_plugin_self_learning if you run a public AstrBot group where the bot's voice has drifted from the group and you want the drift tracked as reviewable records rather than as silent edits to the persona. Do not adopt it on a fresh install without reading the dependency step, because the plugin never installs its own pip requirements and the first run depends on a click in the WebUI. Verify three things before enabling capture: that a PostgreSQL user can create the `astrbot_self_learning` database, that `Database_Settings.db_type=sqlite` is what you want if that is not possible, and that you have a persona backup outside AstrBot, since the review and rollback path is not one. Releases move weekly, 4.2.5 on 2026-09-19, 4.2.6 on 2026-09-26, 4.2.7 on 2026-09-30, so pin the version your group has been running rather than tracking main.

## FAQ

### What is AstrBot?

AstrBot is the chatbot framework this plugin extends. The plugin hooks its message, after-send and pre-request events, adds a WebUI dashboard on port 7833, and uses the same fastapi and uvicorn stack that AstrBot core provides.

### Does astrbot_plugin_self_learning install its own Python dependencies?

No. The code does not run pip install at plugin install time or at startup. You click the base or full capability dependency button in the WebUI full settings page, and the endpoint only accepts a request carrying `manual_confirmed` and `source` set to `webui_settings`.

### What database does the AstrBot self-learning plugin use by default?

PostgreSQL, through `postgresql+asyncpg`, and at startup it connects to the maintenance database `postgres` to create `astrbot_self_learning` plus any missing schemas and tables. SQLite via `sqlite+aiosqlite` is the explicit fallback, set with `Database_Settings.db_type=sqlite`, and MySQL is a third option.

### How do I install the AstrBot self-learning plugin?

Clone the repository into the AstrBot plugin directory, then restart AstrBot or reload it from the plugin management page. Default configuration is PostgreSQL, which is created automatically, and the recommended order is to back up your persona first, set the learning targets, configure the providers, then enable the learning features you want.

### Why is my bot not learning anything?

Check the nine items in order: message capture enabled, the group not blacklisted, `RawMessage` growing, message length over threshold, expression patterns enabled, bot output reaching `BotMessage`, the group past `min_messages_for_learning`, no unapproved pending review records, and a usable provider. Unapproved review records are the usual answer, since a completed batch changes nothing until approved.

### Can I roll back a personality change made by the AstrBot self-learning plugin?

Yes, the review queue supports approve, reject, delete and roll back, alongside an automatic apply policy. The README still warns you to back up the persona in AstrBot's native management, since review and rollback are not a substitute for an external backup.

## Sources

- [Issues](https://github.com/NickCharlie/astrbot_plugin_self_learning/issues)
- [License: AGPL-3.0](https://github.com/NickCharlie/astrbot_plugin_self_learning/blob/main/LICENSE)
- [NickCharlie/astrbot_plugin_self_learning on GitHub](https://github.com/NickCharlie/astrbot_plugin_self_learning)
- [README](https://github.com/NickCharlie/astrbot_plugin_self_learning/blob/main/README.md)
- [Releases](https://github.com/NickCharlie/astrbot_plugin_self_learning/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nickcharlie-astrbot-plugin-self-learning
