为 AstrBot 提供按会话独立的固定记忆、可编辑 AI 摘要与 Token 预算上下文管理。
astrbot_plugin_context_manager 是一个 AstrBot V1 插件,适合希望自行决定何时压缩上下文、以及压缩后保留什么内容的使用者。
插件接管会话摘要管理,但不修改 AstrBot 核心源码。AstrBot 仍然负责消息发送、Provider 调用、Agent、工具调用,以及异常时的最终安全截断。
- 固定记忆:用户手动维护的长期事实、规则和偏好,永远不参与压缩,也不会被 AI 改写。
- 可编辑 AI 摘要:先由当前会话模型生成摘要,再由用户审阅、修改和保存。
- 手动压缩:只有在用户点击按钮或执行命令时才生成新摘要,不依赖自动策略。
- 按会话隔离:每个群聊和私聊各自保存固定记忆与 AI 摘要,互不干扰。
- Token 预算管理:按 Token 预算保留尽可能多的最近聊天,而不是固定保留若干轮。
- 复用当前模型:压缩时自动使用该会话正在使用的 Provider 与模型,无需单独配置压缩模型。
每次发送给模型的上下文会按以下顺序组成:
System Prompt
↓
===== Fixed Memory =====
↓
===== AI Summary =====
↓
按 Token 预算选择的最近聊天记录
↓
当前用户消息
===== Fixed Memory ===== 与 ===== AI Summary ===== 是明确的分段标记,帮助模型稳定理解两类记忆的职责。
固定记忆始终保留在摘要之前;它不会被发送给压缩模型,也不会被压缩结果覆盖。
- AstrBot
>= 4.26.7 - 目标会话已配置可用 Provider
- 如需在网页中编辑记忆和摘要,需要可访问 AstrBot WebUI
将本仓库复制到 AstrBot 插件目录:
AstrBot/
└── data/
└── plugins/
└── astrbot_plugin_context_manager/
├── main.py
├── metadata.yaml
├── context_logic.py
├── storage.py
└── pages/
复制完成后重启 AstrBot。插件会在首次启动时创建一个空白 SQLite 数据库,因此全新安装时不需要复制任何 .db 文件。
当 AstrBot 运行在 Docker 中时,请将插件目录复制到宿主机上挂载为 /AstrBot/data 的目录:
<astrbot-data>/plugins/astrbot_plugin_context_manager/
随后只重启 AstrBot 容器。不要只将文件复制进正在运行的容器,否则容器重建后文件会丢失。
本插件应作为唯一的 LLM 摘要生成器。请关闭 AstrBot 官方 LLM 压缩,保留本地按轮截断作为极端情况下的安全兜底:
{
"provider_settings": {
"context_limit_reached_strategy": "truncate_by_turns",
"max_context_length": -1
}
}原因如下:
llm_compress与本插件同时启用会对同一会话生成两份摘要。- 双摘要会重复消耗 Token,也可能造成记忆相互矛盾。
truncate_by_turns仅在 AstrBot 必须实施安全限制时作为后备机制。
配置不符合要求时,插件会在启动日志中给出警告。
在 AstrBot 的插件页面中打开 上下文管理。
- 从已发现的群聊或私聊中选择会话。
- 编辑 固定记忆,点击 保存。
- 点击 立即压缩,让该会话当前模型生成新的 AI 摘要。
- 审阅或修改 AI 摘要 后,点击 保存修改。
会话会在 AstrBot 首次为该聊天发起模型请求后自动出现。页面使用内部会话 ID,不要求用户输入 unified_msg_origin 或其他平台专用 ID。
在对应聊天中执行以下任一命令:
/立即压缩
/context_compress
/compress_context
命令会压缩当前 AstrBot 会话历史,并保存该会话的 AI 摘要;不会改动固定记忆。
触发压缩时,插件会:
- 读取当前会话完整的 AstrBot 历史记录。
- 排除 AstrBot 的 checkpoint 记录。
- 通过 AstrBot 获取当前会话正在使用的 Provider。
- 使用该 Provider 当前模型生成摘要。
- 仅将生成结果写入本地 AI 摘要字段。
默认压缩提示词要求模型保留事实、用户偏好、已做决定、未解决问题和继续对话所需的上下文,同时禁止虚构历史中不存在的信息或回答历史问题。
V1 按估算 Token 成本保留最近聊天记录,不采用“最近 8 轮”或“最近 10 轮”这类固定轮数策略。
数据库中预留的默认值为:
| 配置项 | 默认值 | 用途 |
|---|---|---|
recent_context_token_budget |
100000 |
包含系统提示词、固定记忆、摘要和当前输入的总上下文预算;可设置为 1024-1000000 |
summary_target_tokens |
1500 |
默认压缩提示词中的摘要目标长度 |
选择最近聊天记录前,插件会先计算系统提示词、固定记忆、AI 摘要、当前请求、额外用户内容及安全预留所消耗的预算;随后从最新消息向前加入完整的用户/助手消息序列,直到预算用尽。默认总预算和摘要目标长度可在页面中修改,也可以只应用到当前会话或批量应用到全部会话。
历史工具调用会在发送给模型的副本中转换为普通文本,避免不同 Provider 对原生工具消息顺序的兼容性问题;AstrBot 保存的原始历史不会被修改。
插件只使用 AstrBot 插件数据目录中的本地 SQLite:
<AstrBot data>/plugin_data/astrbot_plugin_context_manager/context_manager.db
数据库使用 WAL 模式,每个会话对应一行数据,并预留以下字段:
session_id
display_name
platform
fixed_memory
summary
compress_prompt
recent_context_token_budget
summary_target_tokens
last_seen_at
updated_at
V1 不包含云同步、历史版本、Diff、导入导出或第三方记忆服务。
AstrBot 会在 OnAgentDone 生命周期点之后保存对话历史。插件在构建模型请求时会投影出符合 Token 预算的最近历史,但会在 AstrBot 保存历史前恢复完整原始历史,避免短上下文覆盖完整会话记录。
如果未来 AstrBot 版本不再提供预期历史对象,插件会记录错误并停止动态历史投影,而不会冒险覆盖历史。固定记忆与可编辑 AI 摘要仍会继续注入。
| 现象 | 检查方式 |
|---|---|
| 出现两份摘要或 Token 消耗异常 | 确认 context_limit_reached_strategy 为 truncate_by_turns,而不是 llm_compress。 |
| 页面中没有会话 | 先在目标群聊或私聊中发送一条会触发 LLM 请求的消息。 |
| 立即压缩失败 | 确认当前会话已有历史记录且存在可用 Provider。 |
| 插件没有加载 | 确认目录名为 astrbot_plugin_context_manager,并且 AstrBot 版本不低于 4.26.7。 |
| 最近历史较短 | 固定记忆、AI 摘要、系统提示词与当前输入同样会占用总上下文预算。 |
使用 AstrBot Python 运行环境执行测试:
python -m unittest discover -s tests -v
python -m py_compile main.py storage.py context_logic.py tests\test_context_manager.py测试覆盖提示词分段顺序、总预算上下文选择、历史工具消息规范化、历史子序列恢复、SQLite 会话隔离,以及手动压缩复用当前 Provider 和模型的行为。
已实现:
- 手动压缩
- 可编辑 AI 摘要
- 固定记忆
- 按会话独立存储
- 按 Token 预算选择最近历史
- AstrBot 插件页面与聊天命令
V1 暂不实现:
- 自动压缩策略
- 摘要历史与 Diff 对比
- 导入导出
- Markdown 编辑器
- 页面内多压缩模板
- 云同步
本项目仅使用 AstrBot 公开插件 API,不修改 AstrBot 核心源码。