先说一下,我不太好知道这个bug到底是https://github.com/modusensus/dsh-mneme出错,还是https://github.com/chen731215-dev/dsh-tavern-v2导致出错,不过特别容易复现: 只要新开对话,说一句带{{user}}的词,或者上下文或者你工作区文件有这个,然后被读取到了,比如你可以新建对话 “我有时候使用dsh搞一些ai聊天工具“酒馆”的一些设计时候,会报错unknown prompt variable "{{user}}" in context "memory"; registered variables: provider, model, cwd,我不知道是我现在dsh那个插件报错,所以想让你排查一下。不过是不是存在一个问题,就是你现在就跑在dsh,既要触发错误也要排查是不是有难度啊?” 然后dsh就会报错啦! unknown prompt variable "{{user}}" in context "memory"; registered variables: provider, model, cwd <img width="3152" height="1339" alt="Image" src="https://github.com/user-attachments/assets/aa001e2f-3261-4971-a2b5-35fd57bbd62f" /> 记忆里也有这个{{user}} <img width="1837" height="1354" alt="Image" src="https://github.com/user-attachments/assets/d11ac893-0e2f-4173-9b73-41198ca32db6" /> <img width="1839" height="1354" alt="Image" src="https://github.com/user-attachments/assets/6e1be470-1ccf-45c6-ae4c-383aaed32933" /> 而且一旦有了报错,你不断开新对话问dsh 为啥上下文有{{user}},你自己会报错,然后dsh就会真的又报错unknown prompt variable "{{user}}" in context "memory"; registered variables: provider, model, cwd 特好玩
Activity
NaughtDZ commentedon Sep 14, 2026
NaughtDZ commentedon Sep 14, 2026
chen731215-dev/dsh-tavern-v2#9 (comment)
OK,看来酒馆那边作者和我想的一致,这个记忆插件有问题,是不是可以搞个可用户添加修改的正则来转义这种有特殊东西内容。我咋感觉这玩意搞到最后会变成注入攻击的口子啊?
比如我搞个文档,里面有利用你这个记忆回调的功能的恶意指令什么的,然后别的用户下载文档,用dsh分析,你的插件把我设计好的这东西记忆进去了,然后哪天一触发,直接dsh执行记忆中的指令。
Anans-Amarre commentedon Sep 14, 2026
感谢这么详细的复现和排查!先确认一下:这个锅确实是我们 dsh-mneme 的,和酒馆那边作者的排查结论一致(
memory这个 context 确实是我们注册的)。根因:DSH 组装 prompt 时会把注入内容里的
{{...}}当模板变量去解析。我们 v0.7.x 的 memory 注入路径漏掉了花括号转义,所以记忆里出现{{user}}这类字面量(酒馆角色卡/世界书里很常见)就会被当成未注册变量直接抛错,而且会一直粘在上下文里反复炸。已修复:这个问题在 v0.8.0(#165,9/13 发布)已经修掉——三条注入出口(记忆块 / 热记忆 / 用户设置)都恢复了花括号转义,默认开启。转义发生在注入那一刻,所以已经存进记忆里的旧数据也会被一起挡住,不用手动删。
麻烦升级到 v0.8.0 再试一下;如果还复现,希望带上版本号和最小复现步骤,我们继续查。
关于你担心的注入安全问题,正面回应一下:
{{}}的记忆就能让整轮对话崩掉、还粘住)——已经堵死,这是最直接的 DoS 类风险。再次感谢帮忙复现和标记,对我们很有帮助!
modusensus commentedon Sep 14, 2026
补充两条复验细节(与上面 @Anans-Ivresse 的结论一致,补一点判断依据):
1. 版本窗口可以钉得更准:花括号转义 v0.7.4 引入(#40)、v0.7.11 起被误删,v0.7.11–v0.7.32 全部受影响,v0.8.0 恢复。你的报错文本(
unknown prompt variable "{{user}}" in context "memory"; registered variables: provider, model, cwd)与该窗口内版本的行为完全吻合——方便的话确认一下 dsh-mneme 与 dsh 宿主版本(dsh --version或桌面端关于页),帮我们对齐版本矩阵。2. 用宿主插值器做了对照验证:直接调用 dsh 0.1.5-rc.1 的
renderPrompt,未转义的同样文本原样复现unknown prompt variable报错;套用 0.8.0 的注入转义后正常通过、{{user}}以可读形式保留,且转义幂等(同一文本经热记忆再次进入注入路径也不会二次变形)。另外在 0.8.0 的真实会话里,带{{user}}字面量的消息跑了长时间重度工具调用,全程零插值报错。3. 归属确认:核对了 dsh-tavern-v2 的源码,它没有注册任何
systemPrompt.context——报错里的context "memory"确定来自 dsh-mneme,与酒馆作者的判断一致。安全话题同意上面的定性:记忆是「上下文文本」而非执行通道,宿主的审批/沙箱仍在动作前生效;转义解决的是「一条记忆崩掉整轮」的确定性故障,语义层的提示注入是记忆/检索类系统的共性问题,我们会从来源标注等方向继续加固。
NaughtDZ commentedon Sep 15, 2026
哦我傻了。我最早安装mneme指定版本了,导致我后面cmd升级其实一直没升级这个插件到0.8,怪我怪我。
feat(version): 插件自检新版本——设置页偏差横幅 + /version-check 只读路由(#174 后续) (#176)