Stella_project
Health Uyari
- License — License: NOASSERTION
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Basarisiz
- rm -rf — Recursive force deletion command in .github/workflows/release.yml
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
A cost-efficient, model-agnostic QQ-group AI agent built around an ~8K-token context window. Powered by NoneBot 2 + OneBot V11, it supports both local and online LLMs through a unified integration layer and extends its capabilities through compatibility with the AstrBot plugin ecosystem.
Stella 不只是把消息丢给大模型换一句回复。它把群聊里零散的信息沉淀成可检索、可验证、会遗忘的记忆,并在合适的时机主动开口了解你。
Stella 的设计前提是上下文窗口很小 —— 基准上限是 8192 tokens。人格、记忆、历史对话、工具结果要在这么小的预算里共存,靠堆 prompt 是不可能的。所以这个预算被拆开了:记忆在库里筛完才注入,工具在聊天上下文之外执行、只交回一句结论,滚出窗口的对话自动压缩成回顾。插件装再多,占的也不是对话窗口。 小窗口能跑,大窗口自然更宽裕;但反过来不成立——假设窗口无限的架构,换到 8K 上会直接失控。
模型从哪里来由你定。
- 全本地:聊天用 GPU 上的模型,记忆整理用 CPU 上的小模型,互不抢占资源,没有任何一条群聊内容离开你的机器。
- 全在线:填一个 OpenAI 兼容的 API 就能跑,不需要显卡。
- 混合:把对话生成交给在线模型,记忆整合、会话压缩这类高频低难度的活留在本地,只有需要强推理的那一步出网。
注:选择全本地部署运行的模式时,数据不出网是彻底的。需要联网的工具(查天气、查番剧)由插件自己发送请求和返回实际的数据,而判断该不该用工具、把结果压缩成摘要、把插件卡片渲染成图片,全部在本地完成。
🔌 三种部署模式
| 模式 | 聊天模型 | 记忆整理 | 适合谁 |
|---|---|---|---|
| 全本地 | 本地(LM Studio 等) | 本地 | 有显卡、在意隐私、不想付费 |
| 混合(推荐) | 在线 API | 本地 | 想要更好的对话质量,但不想把高频小任务的 token 钱也付出去(本机仍要跑得动小模型) |
| 全在线 | 在线 API | 在线 API | 没有显卡 / 轻量服务器 / 想尽快跑起来看看效果 |
三种模式共用同一套记忆、人格与插件配置,换模式只是改配置,不丢数据。配置界面里三种模式各有一个一键预设(
纯本地/混合(对话在线 · 整合本地)/纯在线(双 key)),点一下把六个角色一起配好,之后还能逐个微调。用在线模型时,对话生成与记忆整理各用一个独立的 API key,两边的前缀缓存互不冲刷;能力路由跟着聊天端点走,复用同一份前缀。
向量检索(embedding)恒定跑在本机,不参与模式切换——换 embedding 模型等于换向量维度,整库向量都要重算,不能随「今天用在线」这种决定漂。没启用它时检索退回 SQLite 全文索引。
如果您选择了在线模型,就意味着对应那一步的聊天内容会发给你选定的服务商。您需要注意:仅当聊天与记忆两侧都用本地模型时,Stella 才是零出网的。
✨ 特性
在 8192tokens 的上下文预算里工作
🧰 工具能力与人格解耦 —— Router 先判断这句话需要什么能力,工具在聊天上下文之外执行,只把压缩后的一句结论交回给 Stella。工具描述与原始返回都不进人格 prompt,插件装再多也挤不掉对话窗口
🗜 长对话不断线 —— 滚出上下文窗口的早期对话自动压缩成回顾,三层上下文(会话摘要 / 原始尾巴 / 话题摘要)按消息 id 划分绝不重叠,且各自的预算分开可调
🎯 记忆分区注入 —— 聊天素材与行为约束严格分离,敏感信息(边界、忌口、冲突)永不作为聊天话题被提起。只注入筛过的那几条,不把全部记忆倒进 prompt
🧠 两层记忆过滤 —— 捕获宽松(允许不确定信息进入候选),晋升严格(置信度分档 + 交叉验证 + 每用户配额)。过滤发生在有数据、可审计、可回滚的那一层,而不是 prompt 里——在库里筛完才花窗口,候选与置信度不占对话预算
🔄 模型可替换 —— 对话、能力路由、插件借用、会话压缩、记忆整合、记忆提取六个角色各自指定用哪个端点,本地与在线任意搭配;向量检索固定在本机。换模型不动记忆,换模式也不用重建库
💰 花了多少钱是可见的 —— 在线 token 用量按角色/端点/模型记日账,GUI 与
deploy status里能看到今日用量、厂商前缀缓存的命中率(验证省钱手段真的生效的唯一手段)与预算余量;可设每日预算,撞破后默认只暂停记忆整理,群里照常能说话
记忆系统
🔍 记忆需要证据 —— 同一件事被反复提到才会累积置信度;用户直接对 Bot 说的话视为高密度证据,单次即可采信;长期无新证据的候选自动淘汰
💬 主动获取信息 —— 群聊被动摄入的信息密度极低,因此 Stella 会主动 @ 活跃用户搭话或确认记忆。有每日配额、用户级冷却与「连续无回应即退避」保护
🏠 多群共享空间 —— 多个 QQ 群可归入同一空间,共享用户画像、长期记忆与人格;而消息尾巴、话题状态、静音开关仍按群隔离,不会在 A 群回应 B 群的对话
🔎 混合检索 —— SQLite FTS5 全文索引 + 多维加权排序,可选接入本地 embedding 语义检索,服务不可用时自动降级
♻️ 会遗忘 —— 按记忆类型设定生命周期,低价值记忆自动归档,长记忆拆分为原子事实
工程
🔗 兼容 AstrBot 插件 —— 现成的 AstrBot 插件放进
data/plugins/就能跑,不改源码。插件的卡片模板由本地 Chromium 出图,不依赖外部渲染服务🔌 可扩展 —— Pipeline 前后置 Hook 机制,扩展目录自动加载
🧪 可验证 —— 1450+ 单元测试覆盖记忆晋升、跨用户隔离、两层归属、防编造护栏、路由降级与工具隔离;接在线端点后还多一层厂商中立契约测试(请求体多带一个字段就红、参数差异只许按错误措辞自适应而不许写厂商白名单)与前缀缓存守卫;另有探针脚本对真实模型做回归验证(含一个专门复现「噪音环境下漏掉信息」的用例),以及一份量化四类路由错误的基准
🚀 快速开始
本节面向 Windows 桌面部署。Linux / 远程服务器请直接看 Docker 部署指南。
📦 下载 & 安装(普通用户)
第一步:按使用场景准备组件:
- 如果要接入 QQ:准备 NapCatQQ Desktop,并按照其中的指示配置反向 websocket 链接。记录下您配置的端口号并打开链接。
- 如果要使用本地模型:可选择 LM Studio,或使用 Stella Runtime 的可选
llama.cppprofile。使用在线模型时不需要安装 LM Studio。
AI 可以关闭。关闭 AI 或本地模型暂不可用时,基础 Bot、OneBot 诊断和部署管理仍可运行。
第二步:到 Releases 下载最新的
Stella-*-win64.zip,解压后有两种启动方式:- 图形界面(推荐):双击
Stella.exe,首次运行会自动下载约 100MB 的嵌入式 Python 并安装依赖;之后每次启动自动跑一遍环境自检——尚未配置会打开「配置」页,有阻塞问题会打开「环境自检」页,一切正常则直接进入「运行状态」页。 - 命令行:双击
start.bat,同样会自动下载 Python 并安装依赖,然后进入配置向导并启动 Bot。
- 图形界面(推荐):双击
小提示:首次运行会下载并运行 Python,此行为可能会被您电脑上的安全防护软件报告为可疑操作并拦截,需加入信任列表。
- 第三步:
- 1.首次打开
Stella.exe后会出现配置界面。先填监听端口(就是第一步在 NapCat 里配的反向 WS 端口)与要让 Stella 进的群号。 - 2.往下到「模型服务」分区,按你的部署方式点一个一键预设,再把对应的端点卡片填完:
- 全本地 → 点「纯本地」,在本机 OpenAI 兼容端点卡片里填 LM Studio、llama.cpp 或其他兼容服务的地址与模型 ID。点卡片上的「测试连接」可以读取服务端模型列表。
- 全在线 / 混合 → 点「纯在线(双 key)」或「混合(对话在线 · 整合本地)」,在两张在线卡片里各填一次服务商地址、API key 与模型 ID。两把 key 要填不同的,原因见三种部署模式。
- 3.配置完成后,单击“保存并检查”,程序会自动跳转至“运行状态”界面。单击“启动”即可。
- 1.首次打开
遇到了问题?你可以加入开发者所在的QQ群:263402786,在群里@(目前唯一的)开发者Eternal-Wanderer-Vegetable。
⬆️ 从旧版本升级
- 运行
stop.bat停止程序 - 把新版本解压到一个新目录
- 双击
Stella.exe(或start.bat)→ 确认「配置导入」
配置、记忆、人格、空间设置与已装插件会自动搬过来,数据库自动升级,runtime/ 自动复用(省一次
约 100MB 的下载)。全程只读旧目录——无论成败旧安装都还在原地能跑,可以放心重试;导入报告
写在当前 STELLA_HOME/migration_report.md。命令行等价操作:
python -m deploy migrate --dry-run # 先看预览(会在数据库副本上真跑一遍)
python -m deploy migrate # 执行
从 2.x 升级也不需要丢记忆:旧库会自动迁移(列改名、按共享空间重新归属、用户画像归入其消息
最多的那个空间)。全新安装会把用户数据放在程序目录同级的 StellaData/:
D:\你的目录\
Stella-vX.Y.Z-win64\ ← 程序(升级时整个换掉,可以放心删)
StellaData\ ← 你的数据(升级时一动不动)
此后升级只需替换程序目录,数据不用动;清理旧的版本文件夹不会碰到数据。
想让程序与数据自包含(整体拷进 U 盘),在程序目录里手工建一个 StellaData\ 子目录即可,
程序会优先用它——代价是它会跟着程序目录一起被替换或删除,升级前务必先导入或备份。
用 python -m deploy paths 可以查看数据目录的实际位置与命中的是哪条规则。
开发者测试
git clone https://github.com/Eternal-Wanderer-Vegetable/Stella_project.git
cd Stella_project
pip install -r requirements.txt
环境要求
| 组件 | 要求 |
|---|---|
| Python | 3.10+(Release 包内置嵌入式 Python,无需自装) |
| 框架 | NoneBot 2 |
| QQ 协议端 | NapCat 或其他 OneBot V11 实现(推荐用 NapCatQQ Desktop 安装并登录) |
| 模型服务 | 可选的本地 LM Studio / llama.cpp Runtime,或任意 OpenAI 兼容的在线 API(填地址 + API key 即可),两者可混用;也可以关闭 AI |
配置
建议使用 Stella.exe 中内置的“高级选项”表单来进行修改。不建议手动修改.env。
完整配置项及其说明见 配置文档。
启动
普通用户:在 Stella.exe 的「运行状态」页点「启动」(会先跑一遍 doctor 自检);或双击 start.bat 走命令行流程。
开发者:
# 1. 安装依赖
pip install -r requirements.txt
# 2. 生成配置
python -m deploy init
# 3. 用 NapCatQQ Desktop 安装并登录 NapCat(需扫码,必须人工),
# 在 NapCat WebUI 的网络配置里添加「WebSocket 客户端」指向 Bot(反向 WS):
# ws://127.0.0.1:8080/onebot/v11/ws
# (若用正向 WS 则改在 .env 里配 ONEBOT_WS_URLS)
# 4. 启动 Stella(会先跑一遍 doctor 自检)
python -m deploy start
在群里 @ 机器人即可开始对话。
🔗 装插件(可选)
Stella 能直接跑 AstrBot 生态的插件,不用改插件源码:
把插件目录整个放进 data/plugins/<插件名>/
如果插件带 requirements.txt,装一下它的依赖
重启 Stella
目录名不用改:GitHub「Download ZIP」解出来的 xxx-master / xxx-main 后缀照样能装。但压缩包本身要先解压——data/plugins/ 下的 .zip 不会被加载。
启动后看 logs/boot_debug.log,里面会写清发现了哪些插件、加载成功还是失败、失败原因。
插件的 @command 指令(默认前缀 /)装完就能用。插件用 @llm_tool 注册的函数工具要能在聊天里被自动调用,还需要一份能力声明——按 插件接入规范 写的插件自带 capability.toml,这种插件装完就是完整的,你什么都不用配。
插件没自带(多数现存的 AstrBot 插件都没有),或者它自带的那份不合你的用法时,就在 config/capabilities/<域名>.toml 里补一条 / 覆盖一条——用户目录里的声明优先级最高,同一个工具被它认领后,插件自带的那条整条跳过。仓库里有一份真实样例(config/capabilities/entertainment.toml)可以照抄,格式说明见 config/capabilities/information.toml.example,怎么写才准见 插件接入规范 §6.3。
为什么需要这份声明:插件的工具描述是写给「看着全部工具做选择」的决策器的指令句,而 Stella 的路由是拿它和用户的问句算语义相似度——两种用途要求的文本形态不同,直接拿来用会让同类工具互相抢。实测数据与取舍见 能力系统。
写插件或想确认一份声明写得对不对,跑 python -m deploy plugin-check <插件目录>:16 项检查,零 error 才算达标。不想从零手写 examples,可以先跑 python -m deploy plugin-scaffold <插件目录> 生成一份草稿(capability.toml.draft),它同时用真实 embedding 打一份量化报告告诉你这份语料准不准;草稿要人审、改名并把 reviewed 置为 true 才会生效——没审过的语料到不了路由。
装完想知道它到底进没进路由,三个地方看的是同一份清单:在群里 @ 机器人问一句「你能做什么」、跑 python -m deploy capabilities、或者打开 Stella.exe 的「插件」页点开这个插件(绿点=该工具已被声明认领、能被聊天自动触发)。列的都是哪些能力能被聊天自动触发、哪些不能,以及不能的原因(没有声明 / 工具名拼错 / 被更高优先层顶掉 / 实现正在退避)。这比翻启动日志直接。
调试插件时可以打开热重载(ASTRBOT_PLUGIN_HOT_RELOAD_ENABLED=true,默认关闭),改完代码在群里发「@Stella 重载插件 <插件目录名>」就能不重启生效。它不等于重启——裸 asyncio.create_task 起的任务、插件起的线程与 monkeypatch 都收不回来,所以怀疑状态不干净就重启,细节见 插件接入规范 §13。
插件的卡片图由本地 Chromium 渲染,首次需要出图时会自动后台下载约 270MB 的浏览器内核,期间插件照常回纯文本,装好后自动生效、不用重启。
🔍 出问题先看哪里
所有运行期日志都在 logs/:
| 现象 | 看这个 |
|---|---|
| 回复内容不对 | logs/stella_thought_logs.md(完整 prompt、原始输出、路由判定、工具结果) |
| 插件没加载 / 工具从不被调用 | logs/boot_debug.log |
| 记忆没生成 | logs/memory_consolidation_log.md |
| 说不清哪里坏了 | python -m deploy doctor |
📖 文档
| 文档 | 内容 |
|---|---|
| 架构说明 | 目录结构、消息处理流程、模块职责、AstrBot 兼容层 |
| 记忆系统 | 两层过滤的设计理由、晋升规则、检索策略 |
| 能力系统 | Capability Router 与 Comes:工具如何在聊天上下文之外执行 |
| 插件接入规范 | 写一个 Stella 能完整用起来的插件:声明格式、两条通路、失败契约、自检工具 |
| 配置参考 | 端点 × 角色两层模型配置、全部配置项与调参建议 |
| Docker 部署指南 | 远程服务器容器化部署:构建、配置、从 Windows 迁移、升级与备份 |
| 开发指南 | 测试、探针脚本、CI、贡献流程 |
设计过程记录(规范草案、检查点、缺陷报告、测试清单)在
design_docs/。
🧠 记忆形成流程
graph LR
A[群聊消息] --> B[短期摘要]
B --> C[记忆候选]
C -->|证据不足| C
C -->|置信度 + 交叉验证| D[长期记忆]
D --> E[Policy 过滤]
E --> F[分区注入 Prompt]
D -->|超期 / 低价值| G[归档]
三条设计原则:
- 捕获宽,晋升严。 允许不确定的信息先进入候选并如实标注置信度,但只有经过复现或高密度证据确认的才成为长期记忆。在 prompt 里做过滤不可审计、不留数据、无法改进。且小模型会根据过滤要求设定的正面提示词/负面提示词做出过度反应,不具备任何实用价值。
- 有价值的信息不会很多。 每个用户的长期记忆有明确且可调整的数量上限,到顶后新记忆必须挤掉最弱的一条。
- 相关 ≠ 应该使用。 检索到的记忆还要经过模式匹配、用途兼容、可见性三层过滤才能进入回复。
整合分两阶段执行,各用适合的模型:
| 阶段 | 任务 | 角色 | 全本地时用什么 |
|---|---|---|---|
| 阶段 1 | 短期摘要 + 用户画像 + 「本批是否含自我披露」判断 | CONSOLIDATION |
CPU 上的小模型 |
| 阶段 2 | 精确提取记忆候选 | EXTRACT |
GPU 上的主聊天模型 |
两个角色都可以单独指到在线端点(阶段 2 尤其适合换强模型),代价是这一步的群聊原文会发给服务商。
阶段 2 只在阶段 1 判定有自我披露时唤醒 —— 日常刷屏与寒暄既不消耗 GPU,也不花在线 token。这样拆是因为小模型能总结主题,却在噪音环境下会把候选提取判空(实测:信息明确出现在它自己写的摘要里,但候选返回空数组)。
细节见 记忆系统文档。
🛠 技术栈
Bot 后端:NoneBot 2 · OneBot V11 · SQLite (FTS5) · OpenAI 兼容 API · APScheduler · httpx
可选 Runtime:Rust runtime-manager · llama.cpp / llama-server · Runtime manifest/state contract
插件兼容与渲染:Jinja2 · Playwright(本地 Chromium,仅用于把插件卡片渲染成图片)
桌面安装器:Tauri 2 · Rust(stella-installer/,原生 HTML/JS 前端,无前端构建步骤)
容器化部署:Docker · docker compose(Dockerfile + stella/napcat 双容器编排,另有可选 llama profile;Chromium 与中文字体已内置镜像;见 Docker 部署指南)
开发与验证:pytest · ruff · pyright
开发中使用的本地模型
- 语言模型:
google/gemma-4-26b-a4b-qat(聊天,GPU上运行)、google/gemma-4-e4b(记忆整理,CPU上运行) - 向量模型:
text-embedding-qwen3-embedding-0.6b
关键在于分工与部署:整合模型设置 GPU Offload = 0 走纯 CPU 推理,聊天/提取模型独占 GPU。两者同时常驻、互不挤显存,因此记忆整理与聊天可以真正并行。这是两阶段方案可行的前提。
应用层为每个模型设了串行闸门(LM Studio 本身不限并发,多请求同时打到同一模型只会互相拖慢)。
以上是开发者基于自身设备的配置,仅作为理解代码库的补充,不构成配置建议。如果你探索出了更好的方案,欢迎提交 PR 和 issue。
开发过程中测试用模型可能变更,具体会在 release 说明中标注。
📄 License
本项目基于 GNU Affero General Public License v3.0 (AGPL v3.0)发布,且带有不与主协议冲突的附加条款。详见 LICENSE 文件与各源文件头部的版权声明。
💛 致谢
本项目在开发过程中得到了很多人和组织的鼓励和支持:
- 我的父母给予了最重要的经济支持。没有他们,这一切都无从开始。
- 灵感来源于和 @t1mb2rg 的讨论和 @CST-Cat 的争执中。感谢他们贡献了属于自己的想法。
- @MIO-456 开发的 Lumi_Nox 项目激励了本项目的开发。
- 感谢 @vowm3440 , @CST-Cat , @higashitaniyume 为我寻找到了支持这个项目的公益站资源。没有他们的慷慨分享,这个项目就不可能出现。
- 感谢 @qian-o 和他的伙伴们,以及 @MIO-456 和他的伙伴们。没有他们的鼓励,就没有最初开发这个项目的动力。
- 感谢 @vowm3440 在QQ群中的持续部署和测试。有许多改进的方向正是因观察这个部署的实例而产生。
- 感谢Bilibili平台UP主 Ruuuuusty 将我和chat-GPT对Stella徽标的想法变为现实。
- 本项目开发中得到了来自如下组织的支持:
- 模型提供商:Deepseek,OpenAI(ChatGPT),Google(Gemini,Gemma),通义千问(text-embedding-qwen3-embedding-0.6b)和 Anthropic。没有他们的优秀模型作为基础,这个项目不可能诞生。
- Coding Agent:Opencode,感谢 Opencode 对本项目的大力支持。
- 开源代码库:nonebot2,NapCatQQ,以及源代码中引用的所有第三方库。向与之相关的所有开发与维护者致敬。此外本项目也是为了向 AstrBot 与 MaiBot 两位前辈看齐,创造一个真正的、能够完整本地循环、不必把群聊信息和个人隐私交出去的 AI 朋友。
- 开发者社区:Linux Do
- 特别致谢 Freya,这是献给你的作品。我的探索之旅因你的馈赠而起,是时候交出一份并不完美的回礼了。
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi
_Compressed_version.jpg)