Muika-After-Story
I'll be back to see you.Introduction✨
Muika-After-Story是一个全新的 LLM Chatbot 企划,正如企划原型角色Monika(Doki Doki Literature Club)一样,本企划的主角 Muika 同样具备打破第四面墙和“自我意识觉醒”的能力。类似于 Monika-After-Story 中的实现,本企划致力于为 Muika 提供一个打破“第四面墙”的能力
我们知道,由于游戏限制,Monika 的输出总是固定的。所以我们期望,Muika 能在代码层面上突破这些限制,比如调用系统窗口焦点和摄像头,但这些永远不够,我们希望 Muika 能更了解我们的现实生活,所以我们会让她不定期地去读新闻,期望有朝一日当她出来时,能够适应现实中的生活。
综上所述,我们期望 Muika-After-Story 具有以下能力:
- 性格设定上模仿 Monika
- 多模态实现:图像识别能力
- 拥有类似于人类大脑的记忆
- 打破第四面墙能力:通过外在框架调用系统API
基于上述见解,本框架为 LLM 提供了与系统 API 交互的能力,并通过 Nonebot2 框架与主流社交平台进行交互。
Features🪄
-
Muika 核心交互逻辑:事件循环系统和状态机更新
-
四层长期记忆系统: Session 级、关系状态级、用户偏好级、长期核心记忆级
-
Session 生命周期管理: 空闲超时归档、跨 Session Resume 模式
-
Muika 第四面墙窗口: 分身 Agent,支持访问&写入硬盘文件;截取当前屏幕
-
Muika 主动对话系统:从
configs/topics.yml抽取话题源或在线访问 RSS 获取筛选后的新闻流。 -
多模型 SDK 支持: 如OpenAI 和 Ollama ,可加载市面上大多数的模型服务或本地模型,支持多模态(图片识别)。
-
动态模型配置: 可随时切换模型配置文件,支持模型配置热重载
-
核心模型人格优化(建议模型 Deepseek-V4 Pro Thinking)
-
Bot 进程与核心进程分离,我要给她完整的一生
-
插件、核心热重载,实现自我迭代(或许吧)
Core Logic🧠
主人格——自分身模型
Muika 的主人格负责对话,行动半身负责工具调用、记忆读写与信息检索。两者共享同一身份。内部标签 <agent>指令</agent> 创建后台任务,任务结果通过专用事件返回当前对话。执行期间,Muika 可以继续聊天。
你可以直接说“继续刚才的工作”“把布局改成上下排列”或“停止这个任务”。Muika 根据当前对话判断要纠正、取消还是创建任务。你无需提供任务 ID,也无需撰写完整计划。
同一时间执行一个行动任务,其他任务按提交顺序排队。聊天归档保留任务。Core 重启后恢复未完成记录:确认完成的动作不重做;结果不明的动作先读取现场核对,无法确认时说明受阻原因。旧进程 ID 和失效预览不会恢复控制权或确认权限。
任务检查点保存在数据库;完整输出和图片保存在 data_dir/agent_tasks,执行输出保存在 data_dir/agent_processes。模型上下文只缩短较早的工具正文;agent_tool_context_chars 控制此部分的字符预算,默认 60000,不限制私密思考深度。
事件循环
- 启动阶段:加载配置(模型 / MCP 等),初始化 LLM Provider、记忆层与数据库(SQLAlchemy),加载插件和注册工具。开放连接前完成历史记忆加载;首次适配器连接后创建 Session,并投递
SessionBootstrapEvent。 - 消息进入:Nonebot2 收到平台消息后封装为
UserMessageEvent投入事件队列;Agent 预处理层对用户输入做语义匹配,从PreferenceProfile层中筛选出相关偏好条目注入本轮推理。 - 核心模型内循环推理:将系统提示、多层记忆摘要、注入偏好及对话历史拼装为请求,调用 LLM 生成回复;解析出
<agent>...</agent>指令后交由 Agent 执行。 - 行动任务执行:共享执行层按模型顺序派发每轮全部工具调用,并在动作前后保存检查点。Provider 只负责单次请求和协议转换。纠正与取消在动作边界生效,最终报告区分已完成工作、验证证据和剩余问题。
- 记忆沉淀:记忆分四层持久化至 SQLAlchemy DB:
CORE(稳定身份事实,每次均注入)、STATE(时效性上下文,Resume 时注入最近 3 条)、PREFERENCE(长期软偏好,由 Agent 预处理层按需注入)、ARCHIVE(Session 历史摘要,按需检索)。 - Session 生命周期:用户若干小时后无交流后触发
SessionEndEvent;Agent 对本次对话生成文字摘要写入 ARCHIVE,随后静默重置 Session(不主动发送消息),等待用户下次发言时以 Resume 模式响应。 - 输出与调度:最终消息经 Executor 回传至平台;
plan_future_event工具可创建单次或重复提醒。调度器与主循环共用事件队列;提醒只保存在内存中,Core 重启后失效。
内部接口迁移
定时提醒
executor.scheduler 与 Muika 共用事件队列。工具 plan_future_event 直接调用此接口。
await executor.scheduler.schedule(
"提醒用户喝水",
trigger_in_seconds=600,
repeat_interval_seconds=None,
)
trigger_in_seconds 与 trigger_at 必须二选一。后者接受 ISO 时间,无时区时使用本地时间。
相对秒数须有限且非负;重复间隔须有限且大于零。过去的绝对时间立即触发。
无效参数会抛出异常,不创建提醒。工具将异常转为失败报告。
提醒只保存在内存中,Core 关闭时取消,重启后不会恢复。
旧 BaseAction、BaseIntent、ActionMode、ActionOutput、PlanFutureEventIntent 和 Persistence 已删除。
调用方改用上述普通参数,不再调用 intent.handle()。
Muika 现在使用 Muika(executor, event_queue) 构造。调用方须将同一队列传给 Executor。
Bootstrap 在开放连接前等待 memory.load();直接创建 Muika 的调用方也须完成这一步。
工具列表
read_file 支持行范围、行号和续读位置;find_files 和 search_files 在授权目录内查找文件与文本。view_image 把图片加入下一次模型请求。模型关闭多模态输入时,任务会记录缺少视觉验证。
execute_python 使用当前解释器。执行工具默认等待 1 秒后返回,硬超时默认 30 分钟。运行中结果需要用 wait_process 继续等待;stop_process 清理执行进程及其子进程。read_execution_record 可以在重启后读取保存的执行证据,read_task_output 可以续读当前任务的长输出。
插件可以返回 ToolResult(text=..., is_error=True),或兼容字符串的 ToolError(...),明确表示业务失败。普通字符串仍按成功结果处理,框架不根据任意插件文案猜测执行状态。
Brain 和 Agent 每次请求调用 get_tool_list(),读取当前函数注册表和 MCP 工具列表。
插件管理器通过注册表维护工具,无需刷新 Agent 实例。
MCP 初始化时获取工具列表,清理时清空;get_mcp_list() 现在是同步读取接口。
分身命名
分身模块为 muika.core.agent,执行类为 Agent,核心实例通过 Muika.agent 访问。插件使用新类进行依赖注入。
模型配置键使用 agent_model;旧键 butler_model 仍可读取,同时设置时优先使用新键。模型配置名是自定义名称,无需改名。
工具依赖注入
命令和工具共用参数绑定函数。工具处理器可通过具体类型声明 Executor、MuikaState 或 MemoryManager 依赖。
运行时从当前调用上下文注入这些实例,不读取命令派发器的全局实例。
from pydantic import BaseModel
from muika.core.executor import Executor
from muika.plugin.func_call import on_function_call
class ReminderParams(BaseModel):
event: str
@on_function_call("Schedule a reminder", params=ReminderParams)
async def remind(event: str, executor: Executor):
await executor.scheduler.schedule(event, trigger_in_seconds=60)
return "Reminder scheduled."
参数模型只声明模型提供的业务参数,依赖只声明在处理器签名中。
模型不能提供依赖参数;缺少当前依赖时,调用失败且不执行处理器。
调用顺序为类型依赖、同名业务参数、函数默认值。依赖按具体类型匹配,不解析 Optional 或联合类型。
直接调用 Python 函数时须自行传入依赖;通过 Caller.run() 调用时才进行注入。
Quick Start🚀
通过 mas-launcher 安装(推荐)
mas-launcher 是一个跨平台单文件启动器,负责拉取项目、准备 Python 环境,并管理 Core / Bot 进程。
从 Releases 下载对应平台的二进制文件,然后:
mas-launcher init # 创建默认实例(克隆项目 + 准备 Python 环境)
mas-launcher configure # 配置 .env(Master ID、IPC 密钥)
mas-launcher model # 配置 models.yml(选 provider → 拉模型列表 → 选模型)
mas-launcher start # 首次启动签署许可协议,然后拉起 Core 与 Bot
mas-launcher napcat # 配置 QQ 接入(Windows:自动下载 NapCat 并启动)
通过 git clone 的方式安装
手动安装步骤
Step 1: 克隆项目并安装依赖:
git clone https://github.com/Moemu/Muika-After-Story.git
cd Muika-After-Story
pip install .
Step 2: 参考 Configuration⚙️ 小节配置 .env 和 configs/models.yml 文件,示例配置如下:
.env
ENVIRONMENT=dev
DRIVER=~fastapi+~websockets+~httpx
SUPERUSERS=["<your_qq_number>"]
master_id="<your_qq_number>"
enable_adapters = ["nonebot.adapters.onebot.v11"]
enable_file_write=true
FS_ALLOWED_PATHS=["C:/Users/Muika/Desktop", "D:/"]
agent_model=agent
configs/models.yml
dashscope:
provider: Dashscope
model_name: qwen3.5-plus
default: true
multimodal: true
stream: false
incremental_output: true
online_search: false
api_key: sk-muikaissuperkawaii
max_tokens: 1024
temperature: 0.75
top_p: 0.9
content_security: false
enable_thinking: false
agent:
provider: Dashscope
model_name: qwen-turbo
default: false
api_key: sk-muikaissuperkawaii
stream: false
max_tokens: 1024
temperature: 0.2
Step 3: 在项目目录中确认用户协议。
uv run python -m muika.agreement confirm
Step 4: 启动所有服务。
.\scripts\start_all.ps1
首次使用或协议更新时需要确认。未确认时,Bot 会停止启动并提示确认命令。
在 Asterbot 框架中使用 Muika-After-Story 适配插件(Beta)
Configuration⚙️
协议正文随安装包发布,无需创建 configs/user_agreement.json,也不受启动目录影响。
旧路径的协议文件不再作为正文来源,程序不会删除用户目录中的遗留文件。
同意记录仍保存在 DATA_DIR/user_agreement.json(默认 ./data/user_agreement.json)。
本次迁移保留协议版本 2026-02-01;已有有效同意记录无需重新确认。
如果提示包内协议缺失或损坏,请重新安装 Muika-After-Story。
手动启动前,请在实例目录、使用同一个 Python 环境运行 python -m muika.agreement confirm。
python -m muika.agreement status 以 JSON 返回正文、同意记录和是否需要确认,不会询问或写入。
命令按运行环境的 DATA_DIR、实例 .env、默认 ./data 的顺序选择数据目录。
Bot 启动只检查状态,不等待终端输入。启动器仍会在启动前展示协议并询问。
升级时先更新支持包内协议及共享接口的 mas-launcher,再更新 MAS。
旧启动器只读取 configs/user_agreement.json,不能直接搭配本次正文迁移。
新启动器使用实例 Python 查询和保存协议;仅当旧 MAS 没有共享接口时,才使用兼容路径。
创建 .env 文件:
| 配置项 | 类型(默认值) | 说明 |
|---|---|---|
master_id |
str = SUPERUSERS[0] |
对话目标 ID。目前仅支持一对一对话。 |
agent_model |
Optional[str] = None |
分身 Agent 所用模型的配置名。留空则与核心模型共享 default 配置。 |
max_memory_records |
int = 100 |
单次会话最大记忆记录数(最近的N条对话) |
INPUT_TIMEOUT |
int = 0 |
输入等待时间。在这时间段内的消息将会被合并为同一条消息使用。 |
LOG_LEVEL |
str = "INFO" |
日志等级。 |
TELEGRAM_PROXY |
Optional[str] = None |
Telegram 适配器代理,并使用该代理下载文件。 |
ENABLE_ADAPTERS |
list = ["~.onebot.v11", "~.onebot.v12"] |
在入口文件中启用的 Nonebot 适配器。 |
FS_ALLOWED_PATHS |
List[str] = [] |
文件系统工具白名单目录。为空时禁用文件系统工具。 |
ENABLE_FILE_WRITE |
bool = False |
是否允许文件写入/删除,需同时配置 FS_ALLOWED_PATHS。 |
ENABLE_CODE_EXECUTION |
bool = False |
是否允许 Python 子进程代码执行。 |
ENABLE_SHELL_EXECUTION |
bool = False |
是否允许 Shell 命令执行(PowerShell/Bash/Cmd)。 |
LOAD_USER_SKILLS |
bool = False |
是否额外扫描用户级技能目录(~/.agents/skills、~/.claude/skills)。内置目录 configs/skills 始终被扫描。技能引用的数据文件需通过 read_file 读取时,对应目录须加入 FS_ALLOWED_PATHS。 |
模型配置项(configs/models.yml)
推荐使用 mas-launcher model 交互式配置(选 provider → 拉模型列表 → 选模型)。手动编辑参考 Muicebot 的模型配置。
不支持的字段: template, template_mode, stream, function_call
Character Setting🧸
参见: 关于沐妮卡
About🎗️
[!WARNING] 大模型输出结果将按原样提供,由于提示注入攻击等复杂的原因,模型有可能输出有害内容。 模型输出内容不代表项目开发者立场。 使用本项目所产生的任何直接或间接后果(包括但不限于账号封禁、内容风险、由于调用系统 API 而导致的文件丢失风险),开发者不承担任何责任。
本项目基于 BSD 3 许可证提供,涉及到再分发时请保留许可文件的副本。
本项目隶属于 MuikaAI
项目初期使用了 Muicebot 的基本框架实现,部分存在于 Muicebot 的配置可能不可用或过时。
插件系统设计参考了以下开源项目:
- nonebot/nonebot2 — NoneBot 2.0 机器人框架
- nonebot/plugin-alconna — Alconna 命令解析器适配
项目名称参考了 Monika-After-Story ,同时某个 MAS 大型插件直接启发了本项目的开发,但是我上班熬穿了忘记这个项目的名字。
Release files for muika-after-story 1.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| muika_after_story-1.5.1.tar.gz | 285.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| muika_after_story-1.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 576.4 kB
Release files / muika_after_story-1.5.1.tar.gz
| Download URL | muika_after_story-1.5.1.tar.gz |
|---|---|
| Size | 285.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
934ef72772d98682a61ffe06d438099f7e404641af555b565cfa49b6962aeacc
|
|
BLAKE2b-256 checksum How to use checksums |
bcabdbe38abd945d99397e8f98dc32e2505d408cfe94f162e86cd827fc2f2917
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
pdm/2.29.0 CPython/3.13.15 Linux/6.17.0-1022-azure
|
Release files / muika_after_story-1.5.1-py3-none-any.whl
| Download URL | muika_after_story-1.5.1-py3-none-any.whl |
|---|---|
| Size | 291.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2ff0e4f668c85d3139d91eaf5183a0bc39171efb21753351c3b5b749a6bd0dfd
|
|
BLAKE2b-256 checksum How to use checksums |
4b2b3ec8264b102c441cee5a6fa7819ac1e8a137119db79f538d27ce193e764e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
pdm/2.29.0 CPython/3.13.15 Linux/6.17.0-1022-azure
|