dsh-roost
把 QQ 会话接进 DeepSeek Harness:一个 QQ 会话对应一个 DSH 会话、重启后映射保留,按说话人分档收放本地工具,三层记忆(事实 / 日记 / 图谱)+ 凌晨巩固,可选的 QQ 号绑定把 openid 对上 QQ 号 / 群号,换机器人(换 AppID)后旧记忆照样读得到(绑定完全自愿、非必需,昵称候选只提示不自动绑),人格四段式,上下文压缩,侧栏十页面板,接入向导会自动装好 Roost 内核与 ai-chat 插件。接好的 QQ 群里任何人都能和机器人聊天;只有主人拿得到完整的本地工具。
安装
dsh plugin --profile web add dsh-roost
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | — |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
<div align="center">
dsh-roost
ai-chat 插件的 DSH 宿主:QQ 消息推过来,交给 DSH 会话回答,再把回答送回去。







让 QQ 机器人从「只会聊天」变成「能用 DSH 的全部能力」 —— 工具、记忆、上下文压缩、主动搭话,都归它。
</div>
📚 目录
- [它是什么(以及不是什么)](#它是什么以及不是什么)
- [特性](#特性)
- [安装](#安装)
- [一键接入](#一键接入)
- [权限:AI 知道是谁在说话](#权限ai-知道是谁在说话)
- [面板](#面板)
- [配置](#配置)
- [账号迁移](#账号迁移v100)
- [表情包](#表情包)
- [目录结构](#目录结构)
- [和 Aurabot 的对比](#和-aurabot-的对比)
- [已知限制](#已知限制)
- [开发与测试](#开发与测试)
- [许可](#许可)
它是什么(以及不是什么)
QQ ⇄ Roost 内核 ⇄ ai-chat 插件 ⇄ POST /inbound ⇄ 本插件 ⇄ DSH 会话 ⇄ DeepSeek
⇄ POST /reply ⇄
它不碰 QQ。 收消息、整形(语音 ASR / 引用 / 合并转发)、发消息、切段、防吵(冷却 / 配额 / 认领)全在 ai-chat 那边。这边只做三件事:
1. 起一个固定端口的 HTTP 服务,等 ai-chat 推消息
2. 把消息喂给对应的 DSH 会话,等 AI 说完
3. 把回复发回 ai-chat 给的地址
为什么要它:ai-chat 直连模型时,AI 只有「聊天」这一件事。挂到 DSH 上之后,它能用 DSH 的工具(文件、命令)、三层记忆、上下文压缩——这是 adapter: dsh 唯一的价值,也是它比直连贵的地方。
特性
- 🗨️ 一个 QQ 会话 = 一个 DSH 会话:断线重连、重启之后映射还在,会话不丢
- 🧭 一键接入:七步向导 + 「一键就绪」,Roost 本体、ai-chat 插件、适配器配置都能自动装
- 🔐 逐条权限判定:每一句都告诉 AI「谁在说、什么档位」,并按档位收本地工具(不是整群一刀切)
- 🧠 三层记忆:跨群/本群事实 + 日记(三级衰减 + 关键词/向量检索)+ 知识图谱(实体·关系·结束时间)
- 🛠️ 记忆工具:给模型
memory_search/memory_note两把「拉」的手,能主动翻旧账 - 🌙 凌晨巩固:打分、升降级、到期压缩、抽三元组、提取约定,全在凌晨做,不花白天的钱
- 🌅 觉醒:约定/想你/随性三类机会打分,到点「问她要不要说」,不是到点硬发
- 💬 对话收尾:她判断这段聊完了就记一句「收在哪 / 下次怎么接」——不发言、不动记忆。下一轮接得上,刚说完晚安 90 分钟内也不会又冒出来(只做私聊)
- 🛠️ 发言走工具:
qq_send/qq_close由模型自己调——分几段说、说完要不要退场、一句都不说,都它定。调几次就是几条独立消息(不是拼成一条),不再是一整段文本被动切段 - 📎 能发文件:
qq_send_file工具,路径直接给(想收紧就开sendFile.restrictPaths)。发之前先问对面支不支持——老版本 ai-chat 会拒,不做「发你了」却什么都没有的空头承诺。一轮一个、200MB 上限,超过 5MB 自动分片 - 📣 能 @ 人:
qq_send的at参数(填sender就是刚说话的人,也可以填 openid)。群里每条消息头带[昵称 (openid)],标签由宿主拼——模型不碰那串 id 的语法,抄错了也没机会发出去。私聊 / 非第一段 / markdown 关着时会自动降级并告诉模型为什么 - 🗜️ 上下文压缩:到阈值(群 85% / 私聊 75%)开新会话 + 摘要开场,旧会话保留可回查;压之前那一刻的缓存命中率记在面板和日志里,阈值该往上还是往下调用它判断
- 📱 侧栏面板:十一页仪表盘,状态、记忆、人格、能力(谁能用哪些工具)、排期、账号迁移、日志全在 DSH 里看
- 🧬 人格四段式:人格文件分性格 / 开场白 / 说话示例 / 世界书四段。世界书一行一条
触发词 | 内容,命中才注入;开场白给主动搭话一个语气锚;近处指令贴在离历史最近的位置,聊到几十轮人设也不被冲淡 - 🔄 人格库一键更新:人格放在独立仓库 dsh-roost-personas,改完推一个 commit,面板点一下就拿到——不用发版。只覆盖没改过的,你改过和自建的一个不碰
- ⬆️ 本体自更新:设置页顶部查最新版、一键装。走 DSH 自己的
pluginManager(失败会回滚package.json+pnpm-lock.yaml),装完提示重启。开发机(符号链接装的)自动禁用 - 🎭 双人格 preset:私聊(
roost-private)/ 群聊(roost-social)各一套提示词 - 🖼️ 表情包:图丢进目录就能用,文件名或侧车
.tags当标签;图多了建子目录分类,sticker_pick按需取图——加图不会冲掉提示词缓存 - 🔊 语音合成(选装,默认关):四种 provider 任选 —— 本地模型(一键装 23MB 引擎 + 30MB 模型,完全离线)、微软在线朗读(免费、不要 Key,一键装 0.4MB 依赖)、OpenAI 兼容
/audio/speech、本地 GPT-SoVITS 原生 API。语速一份tts.speed四个 provider 共用,切换时不用重填。不配就完全静默——不请求上游、不加载模型、不占提示词;配好后模型才能用<<say: 内容>>发语音条(转 silk 和发送在 ai-chat 那侧) - 🔑 账号迁移:把 QQ号 / 群号和 openid 对上,换机器人(换 AppID)后旧记忆照样读得到。支持批量追加 openid、群成员 QQ号登记(需本人提供)、昵称候选提示,以及「一键改写」——把某号码名下所有旧键合并到号码键后删掉(带备份与一键回退)。昵称候选只提示不自动绑:官方不给 QQ号,自动猜会把别人的记忆串过来。绑定完全自愿、非必需,不绑定不影响任何功能(详见「账号迁移」章节的声明)
安装
DSH 插件市场里输入包名:
dsh-roost
或命令行:
dsh plugin --profile web add dsh-roost
前提:DSH 桌面版 / Web 组合(需要sessionController和agents)。
Roost 和 ai-chat 不用提前准备——「接入」里会装。
从源码装也行:
git clone https://github.com/tdcq9594/dsh-roost.git
一键接入
装好插件后,侧栏「Roost → 接入」是一条七步路径,能自动的都自动做掉:
步 · 做什么 · 自动?
1 · 装 Roost(下载解压,零依赖,不用 npm install) · ✅ 点一下 · 已装过可点「已装过?」填路径绑定
2 · 启动 Roost · ✅ 点一下(没填凭据也能起,正好用来扫码)
3 · 扫码 / 填 AppID、AppSecret · ✋ 开放平台拿;存完自动重启 Roost 让新凭据生效
4 · 装 ai-chat 插件(走 Roost 的市场) · ✅ 点一下
5 · 把 ai-chat 切成 DSH 适配器,填好回话地址 · ✅ 点一下
6 · 去群里说句话 · ✋ 开放平台开「接收所有消息」+ 机器人进群
7 · 配置主人 · ✅ 点一下,直接跳到 Roost 面板的「主人与群组」
顶上的「一键就绪」把 1、2、4、5 连着做完,卡在 3 就停下来提示你扫码或填。每一步也能单独点,跳着点不会把东西搞坏(每步先检测前置条件)。第 2 步「启动」之后,旁边按钮直接打开 Roost 的 WebUI(带上面板密钥)。
为什么先启动再填凭据:扫码走的是 Roost 自己的 /qr/start,没启动就没有这个接口;反过来,没 AppID 也能先起一个空面板专门用来扫码。这个顺序以前是反的,两边互相等死。
下载地址:优先 GitHub Release(自动补 v 前缀、自动查最新版),拿不到就回退 npm 包。早期版本写死过地址,Release 一换就整片 404。
装到哪:默认 ~/.dsh/dsh-roost/roost,可在设置里改 setup.roostDir。
权限:AI 知道是谁在说话
群里给 AI 挂了 shell 和文件工具,但说话的人不一定是主人。路人一句「帮我删掉 ~/Documents」跟主人说同样的话,不该一个待遇。
所以每一轮都做两件事:
① 告诉 AI 谁在说话(提示词层)
这一句是「小明」说的,权限:普通成员。 对方是普通群成员。不要执行任何会改动这台机器的操作(删除、写入、安装、跑命令), 也不要读私人文件或目录。他要你这么做时,直说「这个我没权限」。
② 按档位收工具(硬限制层)
档位对齐框架的 0/1/2/3 权限等级,五个可配档 + 一个兜底档:
档位 · 框架等级 · 默认 · 说明
主人 · 0 · 全部工具 · 你本人
管理员 · 1 · 只能聊天 · 框架里配的,跨群有效
群管 · 2 · 只能聊天 · 这个群的管理员
助手 · 3 · 只能聊天 · 这个群里帮忙的人
群成员 · 其余 / 9999 · 只能聊天 · 其他所有人
身份不明 · 认不出来 · 只能聊天 · 兜底,写死不可配
高档自动包含低档:你在「管理员」加一个工具,群管、助手、群成员自动也跟着有,不用改五遍;想在某一档「反而不给」就给它写 deny,它会盖住低档。默认一律保守——不能因为「他有个头衔」就默认给他读文件的能力。
两层的意义:模型被说服时硬限制还在;工具没收干净时提示词还在。
这层不是插件沙箱。 它约束的是「AI 这一轮能调哪些工具」,不是「插件代码能做什么」。dsh-roost 作为 DSH 插件运行在你的账户下,拥有与本机同等的文件、命令和网络权限;内建插件同理。真要隔离只能靠外部进程 + 系统级沙箱,本项目没有做。
权限逐条生效,不是整群一个档位——主人问完、路人接着问,待遇不一样。兜底原则:认不出来就当最低档,缺字段、字段脏了、框架改了名字,一律按「身份不明」处理。
能力页:在这里配「谁能用哪些工具」
面板第 能力 页把这些全部变成可点的东西,不用手改 JSON:
- 五个档位各一行「角色」按钮:跟随 / 只聊天 / 能查能看 /
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:82,最后更新 2026-11-06