dsh-btw
Ask a quick side question without interrupting the main conversation - a Claude Code /btw port for DeepSeek Harness (dsh). Type /btw <question> while the agent is working.
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:kezboardpj/dsh-btw说明文档
阅读完整 README ↗dsh-btw
在智能体干活的时候,用 /btw 快速问个小问题,完全不打断主线任务。
Claude Code /btw 的 dsh 移植版。子代理只能看(继承主对话上下文)、不能用任何工具,单轮回答;你的问题永远不落盘,子代理记录只显示「提问 + 回答」。
安装(给其他用户)
要求:dsh ≥ 0.1.1-rc.2(装了 web UI 的常规安装即可)。
任选一种:
# 方式 A:git 安装(推荐,走 GitHub)
dsh plugin --profile web add https://github.com/kezboardpj/dsh-btw
# 方式 B:本地克隆后链接安装
git clone https://github.com/kezboardpj/dsh-btw
dsh plugin --profile web add /path/to/dsh-btw
# 方式 C:发布到 npm 后按名安装
dsh plugin --profile web add dsh-btw
profile 名按你的实际配置替换(
web/tui/ 自定义)。 安装后重启 dsh(插件不支持热加载)。
用法
在 web 对话输入框输入:
/btw 刚才那个 config 文件叫什么名字?
- 主智能体继续干活,旁路用一个一次性 fork 出来的子代理回答
- 子代理只能看(继承对话历史),不能动任何工具(显式提示"无工具、禁止输出工具调用语法")
- 单轮回答;卡片展开内容 = 提问 + 清洗后的回答(不显示思维链;幻觉的 tool 调用标记会被截掉;纯工具类问题给兜底说明)
- 你的问题永远不落盘(
recordInput:false) - 旁路子会话以一次性子代理记录保留:子代理面板只读查看完整执行记录,不能继续对话(与 CC「能看到、不能继续」一致)
/btw不带问题 = 显示上一轮旁路问答- 旁路线程在进程内存里保留最近 20 条问答,回放给后续的
/btw
与 Claude Code 的差异(已知取舍)
| 维度 | Claude Code | dsh-btw(本插件) |
|---|---|---|
| 启动前提 | 需要已完成第一轮对话("Cannot fork before the first conversation turn") | 无——子会话空种子 + 历史走运行时上下文注入,第一轮就能 /btw(比 CC 更早可用) |
| 进行中 turn 的事件 | 能看到"除正在写的回复外的一切" | 能看到(派生历史含已提交事件,正在流式写的不含) |
| 问题落盘 | 不落盘(内存线程) | 不落盘(recordInput:false,已验证) |
| 答案显示 | 浮层(Esc/←/x/f) | 命令卡片(在对话里可见) |
| 子代理记录视图 | 无(fork 不可见,除非 f 转正) | 一次性子代理记录:只显示提问+回答(历史不进子会话日志) |
| 答案持久化 | 内存线程,退出即没 | command/done 事件落盘 + 子会话以一次性子代理记录保留(面板只读可看) |
| 线程上下文 | 回放最新 20 条 | 已实现(host 内存) |
为什么不删子会话文件(不要改回):dsh 的投影缓存(session_projcache.json)没有删除 API,dispose 时强制写入「live-to-cold」检查点;若删掉子会话文件,缓存行变孤儿 → 子代理面板列表永久卡在「正在加载子代理」。实测踩过并已修复。子会话文件很小,保留是系统一致性正确选择。
为什么不做浮层:dsh 的 client remote/Typert 命名空间是编译器生成的静态结构,第三方插件没有通用的 client↔host 通道(remote.$on 也不存在);要做出 CC 的零落盘浮层需要在 web 客户端自建传输层,超出当前 host 插件的扩展面,列为后续研究。
工作原理(实现要点)
/btw
→ ctx.commands(不经模型)
→ seedDescriptorTurn(childId, undefined, descriptor) —— 子会话【空种子】,
只放 subagent/descriptor 身份事件(mode: one-shot,缺它面板报"会话已损坏")
→ ctx.agents.create:一次性子代理
- childSessionMeta(parent, depth, 0) 继承 cwd/预设/lineage
- resolveChildAgentOptions(parent) 继承 provider/model
- applyChildComposition(childCtx, parent, { toolFilter: { allow: [] } })
→ join 父 preset + 滤空全部工具("只能看")
- systemPrompt.context(btw:parent-history, order 125)
→ 主对话的派生历史(deriveMessages 序列化)作为运行时上下文注入,
模型可见但【不进子会话日志】→ 记录视图只显示提问+回答
- systemPrompt.context(btw:no-tools, order 130)
→ 显式"无工具、禁止输出工具调用语法"
→ handle.agent.followup(createUserMessage(...)) 单轮唤醒
→ 监听子会话 turn/end:
- 回答 = 最终 assistant 文本,截掉 / 幻觉标记;
全为标记则为空 → 兜底说明
- 卡片输出格式:**提问** + **回答**(用户明确要求不显示思维链)
→ 收尾:handle.dispose()(停循环/退注册/出 store)
- 子会话文件 + 投影缓存行保持一致地保留(不得删除,否则面板挂起)
开发者(本地迭代)
见 scratch/ 与 dev-patch.yml:用隔离 DSH_HOME + dsh --profile web --patch dev-patch.yml --port 3091 --no-open 跑,
不碰正式服务。lib/index.js 在开发期靠 dsh-btw/node_modules(junction 到本机 dsh 依赖)解析
@deepseek-ai/*;正式安装由 npm/git 正常装依赖,无需 junction。
验证记录(2026-08-21,DeepSeek-V4-Flash-Vision-Exp / pi-ai)
- ✅ 全程不打断主任务:主 agent 运行中发 /btw,UI 同时显示主任务进行中 + 子代理并发,主任务正常收尾
- ✅ 子代理单轮、零工具、能只看主对话上下文正确回答
- ✅ 问题文本未落盘(recordInput:false)
- ✅ 首轮即可 /btw(空种子 + 上下文注入,比 CC 更早可用)
- ✅ 子代理单轮、零工具、正确引用历史回答
- ✅ 子会话文件与投影缓存保持一致(子代理面板可正常加载一次性记录)
- ✅ 问题文本未落盘