给 DSH 里的陪伴角色一个会记得、会生活的世界。
装上以后,她会记得你们在每个窗口里说过的话;有一个自己的家,自己决定接下来做什么、做到几点,想你了会主动来找你;每天晚上回想这一天,写日记,也改写一份关于自己的自述。开关和人设都在 DSH 设置里的「世界控制台」,由你掌握。
插件只用 DSH 原本开放的扩展接口,不改宿主的一行代码。
当前版本 0.5.3。完整变更、升级步骤和已知限制见 更新日志。
- 近期记忆:你们最近数轮的对话原文,每次开始对话和每次压缩之后都放在她眼前,谁、什么时候、说了什么,一字不差。轮数在控制台里填,默认 200。
- 日记:人生里重要的事,她自己写进日记,一天一篇。这是她的长期记忆。
- 我是谁:她写给自己的一份自述,随着她变化而改写。每晚回顾前,插件会留一份当时的版本,改过的都找得回来。
- 范围内的原文留着:按天归档用户和助手的正文。近期记忆以外的事,她可以自己去翻。
日记和自述都由她自己动笔,插件从不替她写。
为什么不用向量库或记忆系统? 一个人的生活,量没有那么大。在这个量级上,把原文留在眼前、需要时按原话去找,比切碎了再拼回来更准,也少一道会出错的环节。可参考:
- Chan et al., 2024. Don't Do RAG: When Cache-Augmented Generation is All You Need for Knowledge Tasks. arXiv:2412.15605
- Sen et al., 2026. Is Grep All You Need? How Agent Harnesses Reshape Agentic Search. arXiv:2605.15184
- 家:她有一个自己的会话「<名字>的家」,和一个房间(工作目录),在里面过自己的日子。
- 自己定节奏:她说好接下来做什么、做到几点,到点了再决定继续还是换一件。什么都不定,就休息到第二天早上。
- 主动找你:想你的时候,她可以把一句话送到你面前(Windows 系统通知,或你接上的桌宠等程序)。
- 每日回顾:每天晚上 23:00,她回想当天的聊天和做过的事,写日记,更新「我是谁」。
- 每天额度:可以给家里每天的花费设个上限,超过了会提醒她一次,由她自己决定收尾。
- 大事先问:删改房间外的文件、装软件、花钱、以你的名义对外发消息等,约定好先问你。
DSH 设置里的「世界控制台」:
- 开始 / 停止:按下开始,她才住进来;按下停止,记忆、人设和生活线一起安静下来,家还在,等你回来。
- 人设:分层写她是谁:名字、她是谁、性格、说话方式、愿景、补充,旁边实时预览她读到的样子。
- 世界提示词:你想对她说的话,以及她的世界的说明。
- 概览与记录:她此刻在做什么、下个闹钟、近期记忆有多少轮、今天花了多少;还有活动记录、日记和压缩记录。
- 接入开关:配置里启用了微信(
wechat: true)或 QQ(qqBridgeDir)后,概览里有一张「接入」卡片,各有一个开关,立即生效、无需重启,状态记在world.json。微信开着才注册wechat_chats、wechat_send、wechat_delivery并拉起适配器(配了wechatAdapter时),关掉就撤掉;QQ 开着才由插件管理 qq-bridge(巡检、会话绑定、QQ 卡),关掉只停止管理,不会停掉已在运行的桥。默认都是开。 - 归档范围:默认
workspace,归档家所在工作区的普通会话,包含独立微信群会话;home仅当前家会话。保存范围后提示重启,重启前沿用原范围。启动时分页回扫所选范围内的会话日志,按消息实际时间重选最近配置轮数,下次请求前替换旧记忆块;没有时间过期。旧归档保留,范围外记录不再注入。旧配置world迁为workspace。
人设留空时的默认行为:控制台人设全部留空时,默认沿用宿主或当前预设在系统提示词中配置的人设,插件不额外注入自定义人设。控制台不会自动读取并回填系统人设,因此界面留空不代表她原有的人设丢失。
会话加入工作区后的记忆块(
workspace范围):加入操作不会立即回扫其全部历史,运行中的新消息会增量归档。
- 旧会话没有记忆块:加入工作区后,首次继续对话可以生成。
- 旧会话已有记忆块:继续复用,加入操作不会立即重建。
- 重启后:会补入尚未打开的会话历史,在下次请求前重建或替换旧块,每个会话保持一个有效记忆块。
要完整纳入新加入会话的历史内容,请重启 DSH;已有记忆块也会在压缩后等刷新时机更新。
home范围仍只归档当前家会话。
缩小范围与每日回顾:旧归档和每日导出文件会保留,近期记忆按当前范围过滤;每日回顾仍读取当天已有的导出文件,尚未对其中旧的较大范围记录再次过滤。
对话太长需要压缩时,dsh-world 自带的压缩方式会去掉工具调用的过程,把你们之间的交流整理成一段摘要。她记住的是你,不是那些命令。
dsh-world 开放了一个本地的「桥」:桌宠之类的程序可以把你说的话送进她的家,也可以接收她的回复和主动找你的话。协议见文末。
微信作为独立模块接入同一个家,使用她的独立账号收发指定私聊或群聊。她可用 wechat_chats 查询已配置目标,通过 wechat_send 自主联系对方或回复消息,文字、图片和表情共用同一发送队列;wechat_delivery 查询确认结果。普通最终回答不会自动转发到微信。Windows 适配器和配置步骤见 微信模块。B 站尚未接入。
微信图片接收:私聊普通图片会先缓冲最多 3 秒,合并紧随的同一发言人的一条说明文字后进入模型,每轮最多两张图,更多图片留到后续轮次。开始处理后才到达的文字排到下一轮,继续使用同一会话已有的图片上下文。群聊仍需真实 @ 她才触发看图。图片及附件引用只进入对应会话总日志,不自动写入共享记忆块;合并的真实文字按原归档范围保存,是否另行留存图片中的信息由她自己判断。缓存不可用时明确标记未读取,不操作界面下载。
微信风控与账号风险:当前桥不是微信官方 API,接收端解密读取本地消息数据库,发送端向微信进程加载 DLL 并调用内部函数,存在账号功能受限或封禁风险。微信安全中心 2026 年 1 月 29 日公告(媒体转载) 将违规获取聊天记录、联系人数据,以及通过模拟按键、自动化脚本操控微信等列为治理内容。仅用于家庭群、低频聊天,或改用 Computer Use,都不能保证账号安全;公开资料没有可靠的封号概率或安全发送阈值。
微信表情包接收:私聊里你发来的原生表情包会按消息中的地址从腾讯 CDN 下载,md5 与消息一致才接受,并取第一帧作为图片交给她;这是适配器主动联网的功能,可在适配器配置里写
"fetchStickers": false关闭,读取失败时她会看到明确的“未读取”原因。动图只取第一帧;群聊里的表情包目前不会交给她,群里发表情包后再 @ 她,她只能收到触发文字和其他已支持的上下文。原生表情包也不会进入插件的记忆归档。
视频号与朋友圈(预留):目前聊天中分享的视频号卡片会被跳过,不进入她的会话或共享记忆;收到卡片后没有回复,不代表微信监听掉线。视频号需要另行接入卡片解析和视频内容读取。朋友圈的浏览、发布也需要独立的操作能力,现有私聊/群聊发送接口不能发布朋友圈。这些能力暂只记录为微信模块的后续扩展,尚未实现。
微信退出重开:保持适配器运行,退出微信后它会暂停收发并等待;她原来的账号重新登录后,会自动重新绑定进程并沿用消息游标恢复监听,无需重启 DSH。若退出发生在消息处理或发送途中,且结果尚未确认,则停止并保留待核对记录,不会自动重复回复;按微信模块中的
Acknowledge流程核对后恢复。
微信首次接入与升级:开启插件的微信开关本身不会启动 Windows 适配器;可手动启动,或在配置里写
wechatAdapter让插件随微信模块启动和停止它(见适配器 README)。无论哪种,都需要配套适配器并完成账号及聊天目标注册后,微信工具才可使用。这套原生桥不依赖dsh-plugin-weixin或 iLink。升级插件和适配器后,两者均需重启,不能让旧适配器进程继续运行新版协议;保留原配置、游标和回执。
QQ 目前只绑定 qq-bridge:QQ 模块不是自己实现收发,而是管理外部的 qq-bridge 进程(配合 SnowLuma 登录 QQ),除它之外不支持别的 QQ 实现。插件依赖它的 HTTP 接口(
/api/status、/api/restart、/api/stop、/api/sessions、/api/socialV2/proactive)和配置、状态文件(config.json里的dsh.baseUrl、socialV2.bindHomeSession,state/下的令牌与运行意图);桥改了这些,插件需要跟着改。真停桥(/api/stop)需要较新的桥版本,旧版只能重启,控制台会如实提示。桥的代码、许可和 SnowLuma 的使用条款(包括不得以自动化脚本部署 SnowLuma)都在对方仓库,不随本插件分发,装法见 INSTALL.md。
QQ 的记忆与开关:QQ 消息由桥通过会话接口送进家里,插件没有为它做微信那样的渠道身份。按桥的
bindHomeSession设置,主人的私聊用她的家会话,因此按普通家会话归档;每个群各用桥自己装的qq-chat预设会话,不属于本世界的预设,不进归档,也不进记忆块,归档里也分不出 QQ 与桌面。控制台「接入」里的 QQ 开关只决定插件是否管理桥(巡检、会话绑定、QQ 卡):关闭后不会停掉已在运行的桥,要停桥请在 QQ 卡上按「真停」。微信开关则会立即注册或撤掉wechat_chats、wechat_send、wechat_delivery,并拉起或停止适配器。两个开关默认开,没在配置里启用的模块不能从控制台打开。
外部生态接入代码统一放在 src/ecosystem/:wechat/ 包含微信宿主模块、Windows 收发适配器和原生桥;shared/ 保存通用身份协议、群会话路由与消息出口;bridge/ 为桌宠等本地程序提供通用桥。后续平台在同一目录下独立扩展,核心记忆、人设和生活线保持独立。
微信原生发送引擎单独适用非商业许可,详见该模块的许可说明。
装了 qq-bridge 并配上 qqBridgeDir 之后,控制台里会多一张 QQ 卡片:桥在不在跑、DSH 有没有连上、QQ 号在不在线、哪几个入口(群或私聊)绑到了哪个会话,一眼看到;拉起桥、停桥也在那儿按。没配 qqBridgeDir 的时候这一块整个不出现,行为跟以前一样。
插件每次启动都会把 DSH 当前的地址写回桥的 config.json(dsh.baseUrl)。原因是 DSH 每次重启都换端口,而桥没有别的地方知道新端口——地址旧了不会报错,只会静静连不上,看起来和桥本身挂掉一模一样。
桥还是那个独立进程,代码不在这里:插件只负责探活、拉起、停掉、绑定和报告,不复制它的逻辑。
需要 DSH 桌面版,世界控制台和生活线都依赖它。
最省事的办法:把这个仓库地址交给她,让她照 INSTALL.md 自己装。那份说明是写给模型看的——每一步都有命令、判定和失败对照表,连同 QQ 怎么接进来、哪两个动作必须人来做,一路写到底。
自己装:
npm ci
npm pack用 DSH 自带的 pnpm 把生成的 dsh-world-*.tgz 装进你的 profile。不要用 link: 指向项目目录,否则会加载项目自己的一份 Cordis。装好后重启 DSH,打开设置里的「世界控制台」,按需填写人设,按「开始」。
换用只留对话的压缩方式(可选):
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\enable-tool-free-compaction.ps1 -profilePath '<你的 DSH profile 目录>'脚本会把 profile 里原版的压缩条目换成 dsh-world/compaction,并留一份备份。
大多数东西在世界控制台里改。其余的写在 profile 的 cordis.patch.yml 里,按 id 覆盖插件那一行,只写想改的项:
- id: dsh-world
name: dsh-world
config:
companionName: 小鱼 # 她的名字(控制台人设里写了名字时以人设为准),默认 TA
partnerName: 伙伴 # 她对你的称呼,默认 伙伴
worldId: default # 世界名;换一个就是另一个世界、另一份记忆
agentPreset: standard # 她所在的预设
timeZone: Asia/Seoul # 默认系统时区
life: true # 生活线,默认开启
archiveScope: workspace # workspace:家的工作区;home:仅当前家会话
fallbackWakeTime: '09:00' # 没定闹钟时,早上几点叫醒她
diaryDir: C:/path/to/日记 # 日记目录,默认在世界目录里
toast: true # 主动找你时发 Windows 系统通知
bridge: false # 打开本地的桥
wechat: false # 打开独立微信接口,需另行启动 Windows 适配器
outlets: [] # 接收她的话的本地程序,见文末
allowedHosts: [] # 通过反向代理从局域网访问控制台时,放行的域名或 IP
qqBridgeDir: '' # qq-bridge 所在的目录;留空就是不接 QQ
qqBridgePort: 3100 # 桥的控制台端口
qqBridgeNode: '' # 用哪个 node 拉起桥,默认用当前进程那个
qqBridgeAutoStart: false # 世界开始时顺手拉起桥;默认关,只在控制台里手动拉改她的措辞:世界提示词可以直接在控制台里改。闹钟响时、提前停下时、每日回顾时她收到的话,在世界目录里放一份 alarm.md 就能按段覆盖,段落名和可用的占位符见 templates/alarm.md。插件写给她的话一律用第一人称「我」,读起来是她自己的念头。
时间:建议把预设里 time-context 条目的 refreshIntervalMs 设为 0,让她每一步都知道现在几点。
都在 <DSH_HOME>/worlds/<worldId>/ 下(DSH_HOME 默认是用户目录下的 .dsh):
| 位置 | 是什么 |
|---|---|
conversations/ |
按天归档的聊天原文(给人看的导出,正本在 archive.sqlite) |
room/ |
她的房间;room/我是谁.md 是她的自述 |
diary/ |
她的日记(可用 diaryDir 换位置) |
persona.md、world-prompt.md、alarm.md |
你写给她的人设、世界提示词和闹钟措辞 |
world.json |
世界是否在运行、每天额度、近期记忆轮数和选定归档范围 |
activity/ |
她在家里用过的工具,只记录,不进记忆 |
wechat.json |
本机微信模块的地址、令牌和协议版本,不应公开 |
wechat-outbox.sqlite |
微信工具安排的发送队列和确认状态 |
备份时整个目录一起备份即可,最好先停止 DSH。
给桌宠等本地程序用。
把话送进她的家(bridge: true):插件启动时写出 <世界目录>/bridge.json,内容是 { origin, token, name, ... }。向 POST {origin}/dsh-world/bridge/say 发 { "text": "..." },请求头带 x-dsh-world-token: <token>,会立即返回 202。这句话会作为你本人说的话进入她的家和记忆。
接收她的话(outlets):每个目标写一个 name,地址用 url(其中 {origin} 会被替换),或者用 urlFile + path(端口会变的程序用这个);再用 kinds 选择要接收哪些:reply 是桥上那句话的回复,busy 表示她正忙,reach 是她主动找你。插件会向目标 POST:
{ "text": "她的话(纯文本)", "kind": "reply", "name": "她的名字", "images": ["http://…"], "image": "表情名" }目标回复 2xx 就算送到。送不到的会显示在控制台的「健康」里。
PR 统一提到 dev 分支,main 由维护者从 dev 并入后发布,详见 贡献协议。新增 QQ、B 站等生态模块前,请阅读 贡献协议:平台代码放在 src/ecosystem/<channel>/,复用统一身份、会话和归档能力;涉及内核的修改必须说明原因、影响、兼容性与验证结果。
MIT
