dsh-prompt-tuner
Manifest valid★ 1Composer prompt tuner for the DeepSeek Harness Web GUI: rewrites the input draft through a model you choose, with a review card, SSE streaming, and a settings page for model / reasoning effort / style / optimization prompt.
DSH 插件优化集合(dsh-prompt-tuner)
一个个人向的 DSH Web 插件集合:把日常真正用得上的优化做进输入框旁边,而不是只做一件事。目前两件:
- ✨ 提示词改写:把输入框里已经写好但还不够明确的内容,一键改写为指向清楚、可直接执行的提示词。
- 💬 旁路提问(
/btw):主任务跑着的时候,顺手问一个小问题——答案只浮在输入框上方,不写进主对话、不打断 agent(见「旁路提问」一节)。
共同的取向(按个人工作习惯定的):
- 改写用的模型:默认跟随当前会话的模型(零配置可用),也可以固定成一个专用模型。
- 改写用的提示词:内置一份约 1.9k 字的默认提示词,可在设置页里整体替换。
- 改写结果:默认直接替换草稿并可一键撤销;也可以设成先在预览面板确认。
- 旁路提问带的上下文:默认整个会话的完整历史——进入会话就自己把更早的分页补齐,不靠你向上滚动(见「旁路提问」一节)。
- 全程发生在宿主进程:浏览器不接触凭据,也不直接调用任何 provider。
包名、路由前缀(
/dsh-prompt-optimizer/*)、设置与旁路历史文件名、dspo-类名前缀等标识符保持不变:它们是已装实例与用户设置的引用点,改名会丢配置或需要重装,不属于定位更名。
界面
插件占四个座位(五个注册入口),没有自己的面板(集合里的每个功能各占一格):
┌──────────────────────────────────────────────┐
conversation │ ✨ 改写预览 首字 0.6s · 共 2.3s │
.input.dock │ ┌─ 原文 ────────┐ ┌─ 改写后 ───────────────┐ │
(输入框上方) │ │ 帮我把登录页 │ │ 把登录页的加载与交互 │ │
│ │ 改快一点 │ │ 速度改快。… │ │
│ └───────────────┘ └────────────────────────┘ │
│ 模型标注的待确认:未指定技术栈,按「沿用现有…」│
│ [采用] [再改一次] [关闭] 标准 精简 结构化 扩写│
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
conversation │ 旁路提问 已带全部 8 条会话消息 历史 关闭 │ ← 头部固定
.input.overlay │ 第 1 轮 这个接口为什么要加锁? │
(输入卡内浮层) │ 因为写入路径可能并发进来… │
│ [复制] [写入输入框] │
│ 追问(同一话题继续问)… 0 / 2000 │
│ [提问] [新问题] 首字 0.6s · 共 0.9s│
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ + 完全权限 ▾ ✨优化提示词 💬旁路提问 模型▾ │
└──────────────────────────────────────────────────────────────┘
↑ conversation.input.left:权限选择器右侧
| 座位 | 内容 |
|---|---|
conversation.input.left | 工具行里的 ✨ 优化提示词 按钮 + 一行状态(进行中/已撤销/错误)。Alt+O 等价。 |
conversation.input.left | 同排的 💬 旁路提问 按钮。Alt+B、斜杠命令 /btw 等价。浮动面板标了 aria-modal(宿主认的分层标记),所以面板开着时 Esc 归面板而不是主对话的 Esc Esc 停止串。 |
conversation.input.dock | 改写预览卡片:原文与结果并排、模型标注的待确认、档位切换、采用/撤销/再改一次/关闭。 |
conversation.input.overlay | 旁路提问浮层:本话题的问答线、追问输入框、历史列表。刻意不是模态框——主对话仍在后面继续跑。 |
settings.section | 「插件优化集合」设置页:标题下一条页签导轨(模型 / 改写 / 提示词 / 旁路提问),每个页签一组设置,只有当前页签的面板可见(切换形态与 shell 的插件页一致)。 |
交互
一键路径(默认)。点 ✨ → 结果流式写进预览卡片 → 草稿未被改动过就直接替换,并在按钮旁给出「已优化 35 → 459 字 · 2.0s」与「撤销」。
安全规则:自动替换只在「草稿仍是你发送时的那一份」时发生。改写期间你继续打字,结果就停在预览卡片里等你确认——不会静默覆盖你新写的内容。这条规则由宿主发布的 InputState.draftRev 校验,不靠猜。
引用芯片守卫。草稿里含 @文件 / /命令 芯片时按钮禁用并说明原因:整稿替换会切断芯片节点(InputState.draft 是芯片展开后的文本),此时没有无损的改写方式。
档位:标准 / 精简 / 结构化 / 扩写。档位只往系统提示追加一条风格指令,不覆盖你的自定义提示词,可在预览卡片里逐次切换并立即重跑。
再改一次:把当前结果当作下一轮输入重跑(迭代收敛),或换个档位再跑一遍。
取消:进行中点「停止」;宿主在请求关闭时 abort 模型调用。取消发生在写回之前,草稿始终未被修改,因此不需要回滚。失败的实时错误显示在按钮旁与卡片里。
旁路提问(/btw)
主任务跑着的时候,你经常只想问一句、不想打断它、也不想让那句问答污染会话历史。三个入口打开同一个浮层:工具行的 💬 旁路提问、Alt+B、斜杠菜单里的 /btw。浮层自己滚动,头部(标题、「已带全部 N 条会话消息」、历史 / 清空历史 / 关闭)固定不动;Esc 收起浮层——若历史列表开着,第一次 Esc 先收历史列表。
| 能力 | 实现 |
|---|---|
| 不写主对话 | 宿主路由直接调 ctx.llm.stream(...),绕开 agent loop——它不产生任何会话事件,所以主对话既看不到这次提问、也不会被它触发新的轮次。已用会话事件做对照验证。 |
| 带上会话上下文 | 默认带全部历史消息,且不依赖你滚动:DSH 打开一个会话时只装载事件日志的最新一页(至少 50 条、至多 500 条),更早的分页只在阅读者滚到顶部时才拉。插件的会话座位一挂载就用会话面自己的 loadOlder() 把窗口一路走回该会话的第一条事件(有页数/时限兜底),所以进入历史会话时等一会儿,整个会话就在位了;提问前若窗口还在补齐,会先等它落定再取上下文。上下文本身从 shell 已经渲染好的 chat 快照里在本地抽出(工具行、上下文注入、命令、压缩摘要全部丢掉),不按条数、也不按字数截断。面板如实报状态:已带全部 N 条会话消息 / 正在载入更早的历史…(已带 N 条) / 已带当前已加载的 N 条会话消息(更早的历史未载完)。设置页可改成「不带」或「最近 N 条」。 |
| 追问 | 同一话题内的追问把该话题全部先前轮次作为真实的多轮消息再发一次,无条数上限;上下文只在第一问里带一次,省 token。每个 assistant 轮次都带 source(DSH 在挑选适配器时会读 message.source.replayState,手搓的 assistant 消息不带来源会在分发阶段抛错——这正是「第一次追问就报 Cannot read properties of undefined (reading 'replayState')」的原因);万一某个适配器仍然拒绝多轮形状,阶梯会自动折成单轮重问一次(同一问题、同一上下文、历史写进正文),并在面板上说明这一轮走了兜底。 |
| 流式 | 与主对话同一套观感:宿主每来一个增量就下发一帧 SSE,面板逐字长出答案并带一个闪烁光标,done 帧再给权威全文与首字/总耗时(首字 0.6s · 共 0.9s)。 |
| 只读 | 提示词层与实现层双重保证:模型没有工具(不能读文件、跑命令、联网),链路也不碰会话(不发送消息、不写会话事件、不写草稿)。唯一的写入是你点击「写入输入框」把答案放进草稿,由你自己决定发不发。 |
| 历史 | 每个会话独立,落在 $DSH_HOME/prompt-tuner-btw.json(原子写、容错读、超限自动裁剪);浮层里可展开历史话题、可一键清空。历史只存你问过的内容,与主会话无关;这是插件自己的本地记录,可在设置页关掉。 |
| 转正式提问 | 「写入输入框」把答案放进草稿而不是替你发送——你可以改完再发,永远不会有一次你没按过发送的会话写入。 |
| 时限 | 首字看门狗 25s、整体 60s(比改写更紧,因为旁路提问是"顺手问一句"),超时如实报错并可「停止」。 |
| 上限 | 问题 2000 字;上下文 100 万字——超了就直接拒绝并点名要改哪个设置,绝不静默截断(半个转录会让模型对着它没见过的对话作答)。历史文件每会话 20 个话题、总 50 个会话,按时间裁剪。 |
一句话回答会被截到 1–6 行:旁路提问的系统提示词要求「只用给出的上下文、不编造、不反问、不承诺动作、不执行任何操作」——它不能读文件、跑命令、上网,也不能写文件、写草稿或写会话。需要动手的事,回答只会让你回主对话里做。
与「不读会话历史」的关系:改写那条链路仍然只发草稿;旁路提问这条链路按定义要读会话上下文,默认读的是整个会话(进入会话时由插件自己把更早的分页补齐)在浏览器里已经渲染出来的那份快照,摘要在本地做完,且只发给你自己配置的模型路由。设置页里可以收窄到最近 N 条、选「不带上下文」,或关闭历史保存。
设置页
设置页按功能模块分成 4 个页签:模型 / 改写 / 提示词 / 旁路提问。切换形态与 shell 自己的插件页一致(同一条下划线导轨、同一个 13px 标签与 2px 激活条、同一套焦点环),← → 与 Home/End 可在页签间走。切走的页签保持挂载,所以写在提示词框里的草稿不会因为切页签丢掉。页签只是分组——每一项的名称、默认值与生效逻辑都和以前完全一样,原来单页上的 10 项正好分到四组(3 / 4 / 1 / 2),不重不漏。
| 页签 | 项 | 说明 |
|---|---|---|
| 模型 | 跟随当前会话的模型(推荐) | 默认开启;关掉后可在下面指定一个专用模型。 |
| 模型 | 优化模型 | 只在关闭跟随后生效;只列已配置的模型路由。手选会自动关闭跟随,清空则恢复。 |
| 模型 | 思考强度 | auto / off / low / high / max,默认 off。见下方延迟一节。 |
| 改写 | 默认档位 | 标准 / 精简 / 结构化 / 扩写。 |
| 改写 | 改写完成后 | 直接替换(可撤销)/ 先在预览面板确认。 |
| 改写 | 改写方式 | 插件直接改写(调用模型);或 交给主 agent(零模型调用:把一段打磨模板写进输入框,由当前会话的 agent 带着全部上下文改写)。 |
| 改写 | 启用 Alt+O 触发优化 | 快捷键开关(旁路提问是 Alt+B)。 |
| 提示词 | 自定义优化提示词 | 留空 = 内置默认。文本框只保存你自己写的内容,不会自动填入默认,避免误存。可展开查看内置全文、也可「填入内置默认」再改。 |
| 旁路提问 | 携带上下文 | 默认 全部历史消息(不截断);也可选「不带上下文」或最近 4 / 8 / 16 条。选「最近 N 条」时是刻意收窄,不是隐藏上限。 |
| 旁路提问 | 保存旁路历史 | 默认开启。关掉后回答仍会在当前浮层里显示,只是不落盘、也不列历史(此时旁路提问全程零写盘)。 |
页签之外(任何页签下都看得到):配置文件路径、旁路历史文件路径(宿主上报时)、保存结果与错误提示。
配置文件:$DSH_HOME/prompt-optimizer.json(默认 ~/.dsh/prompt-optimizer.json),设置页底部显示实际路径。
{
"systemPrompt": null,
"provider": null,
"model": null,
"reasoningEffort": "off",
"followSessionModel": true,
"style": "standard",
"applyMode": "auto",
"route": "plugin",
"shortcut": true,
"btwContextTurns": "all",
"btwSaveHistory": true
}
延迟
改写是模型时间,插件管道本身几乎不耗时(实测目录 3–26ms、路由解析 0ms)。真正决定体感的是三个开关,都在宿主侧:
| 配置 | 首字 | 总耗时 | 思考字数 | 说明 |
|---|---|---|---|---|
effort=off(默认) | 0.4–0.7s | 2.6–3.7s | 0 | 改写任务不需要长推理 |
effort=auto(省略字段) | 10.9s | 17.5s | 5362 | 适配器默认是 high,这些推理全部被丢弃 |
同一份 35 字草稿的对照(scripts/bench.mjs --effort off|auto)。输出预算另有一道闸:maxTokens = clamp(2048, 草稿字数×2+512, 8192)——下限刻意给足,因为中文接近 1 字 1 token,768 的上限会把 800 字的答案截断,而一次截断要赔上整整一次额外调用。
失败阶梯(每次点击最多 3 次调用)
失败判定走结构化字段(finish.reason.failure.code、finish.reason.kind),不匹配错误文本——厂商改措辞,字段不会:
| 档 | 触发 | 动作 |
|---|---|---|
| 1 | — | 按配置的强度 + 预算调用 |
| 2 | EMPTY_LENGTH(预算没撑到正文)或截断 | 强度改 off,预算 ×3 |
| 3 | 其它任何失败,或第 2 档仍失败 | 两个字段都不发,让拒绝参数的网关也能跑通 |
另有两道超时:首字看门狗 45s(模型一个字都没吐)、整体 120s。两者都如实报错,不会让按钮永远转。
与其他同类插件的差异
(同类条目已有十余个,差异只写可对着代码核的事实,不作评价。)
- 配置在设置页,且默认跟随会话模型:模型、思考强度、档位、应用方式都在
settings.section里;不少同类把模型写死或直接继承会话选择而无 UI。 - 思考强度有协商与降级:读取路由自报的
efforts,不支持就降级;被网关拒绝就去参重试。默认off是刻意的选择,见上表。 - 草稿修订号校验:
draftRev决定「自动替换」还是「停在预览」。同类多为无条件替换 + 撤销,或在改写期间改稿被悄悄冲掉。 - 改写不读你的项目文件、不读会话历史:只发草稿本身。有几个同类默认把工作区文件原文与最近若干轮会话一并外发给所配网关。旁路提问是唯一的例外:它按定义要带上下文,但只带浏览器已渲染的 user/assistant 文本,条数可配、可设
0(见下方限制)。 - 中英双语:跟随
ctx.locale,字典与键在自检里做一致性校验。
架构
浏览器(lib/client.js)
├─ conversation.input.left → ✨ 按钮(useInput 读草稿/阶段/芯片/draftRev,inputActions.setDraft 写回)
├─ conversation.input.left → 💬 旁路提问按钮(Alt+B / 斜杠命令 /btw)
├─ conversation.input.dock → 预览卡片(共享 per-session 状态机)
├─ conversation.input.overlay → 旁路提问浮层(useChat 取会话快照 → 本地抽上下文)
│ └─ ctx.commandUi.register('/btw')(拿不到就静默跳过,不影响其它座位)
└─ settings.section → 设置页
│ POST /dsh-prompt-optimizer/{state,save,optimize,optimize.stream}
│ POST /dsh-prompt-optimizer/{btw,btw.stream,btw.history,btw.save,btw.clear}
▼
宿主(lib/index.js → lib/routes.js)
├─ 回环信任围栏(socket + Host + sec-fetch-site + Origin)
├─ 模型目录缓存 / 思考强度元数据缓存
├─ 失败阶梯 + 首字看门狗 + 整体超时(改写 45s/120s,旁路 25s/60s)
├─ 旁路历史读写($DSH_HOME/prompt-tuner-btw.json)
└─ ctx.llm.stream(...) → SSE(delta / done / failed)
浏览器半区不 import 任何 @deepseek-ai/* 包(只用部署注入的 react),因此预发布 harness 上不会出现 peer 范围冲突。
| 文件 | 作用 |
|---|---|
lib/index.js | 宿主入口:声明 inject,挂载路由 |
lib/routes.js | 路由层:状态、设置、改写、旁路提问(含 SSE、失败阶梯、历史) |
lib/prompt.js | 默认优化提示词、档位指令、模板、输出规范化、待确认提取、旁路系统提示词与多轮消息组装 |
lib/store.js | 配置读写(原子写、容错读)+ 旁路历史存储(每会话分片、裁剪) |
lib/http.js | JSON 信封、有上限的 body 读取、回环信任围栏 |
lib/client.js | 浏览器半区:四个座位 + per-session 状态机 |
scripts/check.mjs | 自检(静态契约 + 宿主路由 + 浏览器半区) |
scripts/bench.mjs | 实测延迟 |
自检与基准
npm run check # 345 项,含宿主路由与浏览器半区
npm run check:shape # 对**已安装**的 DSH 复核旁路提问的消息形状(需要本机有 DSH)
node scripts/bench.mjs --runs 3 --effort off
node scripts/bench.mjs --runs 3 --effort auto # 对照:省掉字段要多花多少时间
自检不用测试框架,三层:静态契约(注入器按字面读取的 slots.register 调用(现为五处)、dsh.bundle、主题 token-only CSS、中英词典键一致、同座位不得重复 id、旧项目名已无残留)、宿主路由(假 ctx/假 HTTP 驱动真实 handler:失败阶梯、强度协商、预算、SSE 帧序、信任围栏、旁路提问的拒绝分支与历史落盘/清空,以及「全部历史原样收下、超长响亮拒绝、每个增量一帧、不给模型工具、assistant 轮次带 source、多轮形状被拒时改用单轮重问」)、浏览器半区(假 React + 假 fetch 执行真实组件:自动替换 vs 等待确认、会话隔离、撤销、芯片守卫、JSON 回退、i18n、旁路提问的上下文抽取与面板状态机,以及「进入会话就自动补齐历史、提问带的是补齐后的整段、分页不前进时如实报 partial、三种上下文标签各说各的真话、选『不带上下文』时不去拉历史」,以及设置页的页签分组:四组设置项互不重叠、并集等于改动前单页的那 10 项、aria 连线与方向键走查、访问过的页签保持挂载)。
历史窗口(浏览器半区里的独立一组):用一个假会话面(loadOlder() 把 fixture 页前插进面板读的那个数组,getSnapshot() 像真实现一样缓存引用)驱动真实的 ensureFullHistory:一路拉回最早一页 → complete;页请求不前进 → 一次就停并报 partial;没有 sessions 服务 → unavailable;座位挂载即触发;提问时读的是补齐后的窗口。
已知限制
- 改写不读会话历史 / 工作区文件;旁路提问按定义要读。改写那条链路只发草稿——读取需要依赖未文档化的宿主内部形状,而且会把你的文件原文发给模型;代价是「修一下这个」这类指代不清的草稿改不出理想结果。旁路提问只在你主动打开浮层提问时才发上下文,默认就是整个会话的 user/assistant 文本(工具行、系统注入、文件原文都不在其中),设置页可收窄到最近 N 条或完全不带,且只会发到你自己配置的那条模型路由。工作区文件两边都不读。
- 为了「整个会话」真实成立,插件会替你把历史分页补齐:DSH 打开会话时只装载最新一页事件(≥50、≤500 条),更早的只在滚动到顶部时拉取。插件的会话座位一挂载就沿会话面自己的
loadOlder()往回走(上限 40 页 / 30 秒),所以进入历史会话后稍等片刻,整段历史就都在位了——不依赖你滚动。代价是长会话会把整段历史装进浏览器内存(这也是宿主默认分页的原因);不想要这份代价时,把设置里的「携带上下文」改成「不带上下文」,插件就不会去拉历史。上限内没走完的极端情况会在面板上如实写成「更早的历史未载完」,不会假装。 - 改写长度仍会波动:默认提示词要求「长度与任务相称」,实测 35 字草稿得到 640–963 字(要求 600 字以内)。这是提示词约束力的上限,不是硬截断——硬截断会切坏答案。
maxTokens是按字符数估的:极长的草稿会落在 8192 上限,可能截断后再走第 2 档重试。- 路由只服务回环地址,且不做速率限制:本机任意页面若拿到同源能力,可以消耗你的模型额度。
- 本仓库没有自动化视觉验证:自检覆盖渲染路径与点击链路,但不含真实浏览器截图。旁路提问浮层在真实 GUI 里手动验证过(按钮、浮层、流式答案与光标、追问带全部轮次、写入输入框、历史列表)。
- 追问依赖 DSH 的 assistant 消息契约:手搓的多轮消息必须给 assistant 轮次带
source,否则会在适配器分发阶段失败(自检锁住这个形状,npm run check:shape直接驱动已安装包的LlmRuntime#forAdapter复核,含一条「不带 source 必须被拒」的反向对照)。这条契约不在插件的控制范围内,所以阶梯还留了「折成单轮」的兜底:即使形状被拒,追问也答得出来,只是面板会注明这一轮走了兜底。 - 收录进 awesome 列表不等于安全审查。
安装
dsh plugin add github:lzyyzznl/dsh-prompt-tuner
仓库根有 cordis.patch.yml(一条 insert),package.json 声明 dsh.bundle.patch 与 dsh.client.platform=web;不含构建步骤,lib/ 即源码。
许可
BSD-3-Clause。
Comments
Loading…
From the same category
by awesome-dsh-plugin
A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表
★ 18.3k
CC0-1.0
Python
Oct 10, 2026
by 0xsline
DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.
★ 1.2k
CC0-1.0
Python
Oct 10, 2026
by pax-beehive
Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub
★ 450
MIT
TypeScript
Oct 6, 2026
by xiajiajun516
DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.
★ 176
MIT
TypeScript
Oct 8, 2026
dsh plugin --profile web add dsh-config-managerby yjh051108
推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。
★ 164
TypeScript
Sep 18, 2026
dsh plugin --profile web add @dsh-external/dsh-super-injectorby jigjoy-ai
A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.
★ 124
MIT
TypeScript
Oct 2, 2026