前言¶
DSH 的 ask_user_question 在交互上有两个常见缺口:选项文字往往只有一句话,用户想补充约束只能塞进 custom 输入框;卡片期间模型不会回答「这个选项到底是什么意思」这类追问,想确认信息得跳出当前流程另开一轮。下面介绍的插件针对这两点做了增强,不改变原有的选择协议。
这是社区目录页上的 tlewa/dsh-better-choice,由 TLEWA 维护,分类为客户端插件,GitHub 星标数为 1(截至 2026-11-06),npm 最新版本 1.0.4,许可证 MIT。一句话定位:给 DSH 的通用问题卡片补上「按选项的补充框」和「卡片内旁问模型」,左键选择、跳过、翻页、倒计时等官方行为全部保留。
插件概览¶
安装前先看清适用范围。它只接管 DSH 客户端的通用选择题卡片,计划审查(plan-review)、审批等非通用问题卡片仍走官方组件。宿主要求为 DSH 0.2.0-rc 族(engines.dsh: >=0.2.0-rc.1 <0.3.0-0,客户端内置包 ^0.2.0-rc.1),Node.js 20+;作者标明已在 DSH 0.2.2-rc.1 上验证。
它包含两个半边:
- 客户端:挂在浏览器半边,向
conversation.composer链式槽注册,priority: -10(官方默认 0),先于官方组件被询问; - 宿主:一个自己的命令
bc-ask,用来跑旁问子代理; - 样式:由官方问题卡 CSS 派生并加
bc_前缀,避免污染其他插件。
识别不到通用 PendingQuestion 载体时,增强卡片返回 null,自动落回官方组件。
核心能力¶
右键选项写补充¶
右键任意选项,即选中该项(若尚未选中)并在该选项下方展开补充说明输入框。填写内容不会替换选项,而是作为该选项的附注,提交时与所选项一起交给模型:
{
"answers": [
{
"id": "question-id",
"selected": ["方案 B"],
"custom": "方案 B: 先灰度 5%,观察一小时再全量"
}
]
}
没有填写任何附注时,请求与官方完全一致,不额外生成 custom。单选、多选都按选项分别保存补充内容,切换选项不会串稿。多选提交时一行一个附注:
方案 A: 需要保留旧接口
方案 C: 下个迭代再删
多选时给未勾选的选项写了备注,提交文本会标注 (未选),便于模型分清语气。
卡片内旁问¶
问题卡片底部有「先问一句」输入区,用来基于当前会话上下文回答用户的疑问,例如「这两个选项在生产环境下的差别是什么」「选 B 的话需要改哪些文件」。旁问的工作方式:
- 以 fork 子代理复用当前会话已完成的上下文、模型与工具声明,
delivery: 'caller'让它挂在当前命令调用上,不排队等父回合; - 旁问内容只显示在卡片里,不提交、不污染主对话,也不替用户做出选择;
- 子代理执行期挂
tools.guard,一切工具调用都被拒绝,不改文件,不继续原任务;输出上限 32000 tokens(不超过父会话上限)。
交互上的细节:把光标放进旁问框,卡片会显示「已暂停」,倒计时停住,失焦后自动恢复;点「提问」后卡片进入等待,不再因为等回答而超时;线程按题分开保存,切题再回来仍能看到原来的问答;回答中可点「取消旁问」中止,每个线程最多保留 20 轮。旁问回答目前是完成后整段出现,不是逐字流式显示。
安装与启用¶
下面命令来自 README。作者推荐从 npm 安装。
从 npm 安装(推荐):
- 打开侧边栏插件页 → 安装插件;
- 输入包名并确认:
dsh-better-choice
- 安装完成后硬刷新(
Ctrl+Shift+R);若宿主半边未生效,重启桌面端。
固定版本:
dsh-better-choice@1.0.1
命令行等价写法:
dsh plugin --profile desktop add dsh-better-choice@1.0.1
仓库的 lib/ 是可直接运行的产物,从 GitHub 安装不需要本地构建:
https://github.com/TLEWA/dsh-better-choice
固定到标签:
https://github.com/TLEWA/dsh-better-choice#v1.0.3
或直接安装 Release 附件:
https://github.com/TLEWA/dsh-better-choice/releases/latest/download/dsh-better-choice.tgz
命令行等价写法:
dsh plugin --profile desktop add github:TLEWA/dsh-better-choice#v1.0.3
从源码安装:
git clone https://github.com/TLEWA/dsh-better-choice.git
cd dsh-better-choice
npm install
npm run build
npm test
dsh plugin --profile desktop add .
安装或升级后硬刷新页面。宿主命令 bc-ask 未注册时,旁问框会提示失败,重启桌面端即可。
典型用法¶
- 等模型发起一个普通的选择题;
- 想补充约束:右键选项,写完后正常提交;
- 想先确认信息:在底部旁问框提问,看完回答再选;
- 两者可以同时使用,旁问内容不会进入最终答案。
右键在触控板上通常是双指点按;没有右键的设备仍可正常左键作答,只是用不到补充框。
实现要点¶
旁问通过本插件自己的命令 bc-ask 完成,客户端把问题、全部问题卡片、已写备注和本线程之前的旁问序列化后交给宿主。宿主侧的机制:
- 用
ctx.subagents.startActivation({ provider: 'fork', delivery: 'caller' })启动 fork 子代理,seed 是父会话最后一个turn/end之前的已完成回合,当前尚未完成的 tool-call 回合不进入 seed; - 只追加一条尾部 user 消息(旁问模式 + 问题卡片 + 之前的旁问 + 本次问题),不改 system、不改工具声明、不重写历史;
- 子代理继承父会话的 provider / model / reasoningEffort,
maxTokens取min(32000, parent.maxTokens); - 父调用的 signal 与 30 分钟 watchdog 一起透传;
- 子代理不把问答写回父 session,父会话只落
command/run、subagent/catalog与command/done,且recordInput: false不记录问题正文。
因为 fork 子代理复用了父会话已完成回合的前缀,provider 可以命中已有 prompt cache。作者实测主请求与紧随其后的 fork 子请求都会报告非零 cacheReadTokens,并随父会话已完成回合增长(本机 DeepSeek 路由为自动前缀缓存)。
适用场景与注意¶
这个插件适合在生成环境决策场景里用 ask_user_question 的项目:需要按选项补充约束,或想在当前会话上下文里先问清选项含义再作答。它解决的是信息密度问题,不解决选择本身。
几条限制来自 README:
- 只接管通用选择题,计划审查、审批等卡片保持官方实现;
- 旁问固定在当前会话的模型上,不提供单独选择模型或推理强度的入口;
- 旁问是只读的,需要读文件、跑命令才能回答的问题,应直接在对话里问;
- fork seed 只包含父会话最后一个已完成回合,正在等待回答的那一轮不会进入 seed;
- 旁问回答完成后整段出现,不是逐字流式显示,超长回答受 32K 输出上限约束;
- 没有右键输入的设备无法使用补充框,但左键作答完全不受影响。
需要注意权限边界:插件以当前 dsh 进程的权限运行。安装前应先打开源码与许可证核对,本插件为 MIT,NOTICE.md 列明了具体复用范围(问题卡组件结构与样式派生自 dsh-question-note,旁问交互参考了 dsh-btw 的设计)。DSH 升级若改动问题卡内部结构,识别失败时增强卡片不接管,官方问题卡仍可用;旁问接口变化时会报错,但不影响正常作答。
目录与来源¶
目录页:https://www.skillhub.cn/plugins/TLEWA/dsh-better-choice
GitHub:https://github.com/TLEWA/dsh-better-choice
npm:https://www.npmjs.com/package/dsh-better-choice
总结一下:它做的是「选项附注」与「卡片内旁问」两件小事,接入点都在官方 composer 链上,识别不到通用问题卡就自动退回官方组件,对现有选择流程的改动面很小。如果你在用 DSH 的 ask_user_question 做决策收集,可以先装 npm 包硬刷新试一轮,再决定是否需要固定版本。