lzyyzznl/dsh-prompt-tuner ↗★ 0
dsh-prompt-tuner
Composer prompt tuner for the DSH Web GUI: rewrites the input draft through a model you choose (by default the session's own), with the model, reasoning effort, rewrite style and optimization prompt configured on a settings page 适合需要将粗糙的草稿快速转化为清晰、可执行提示词的Web端用户。
インストール
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:lzyyzznl/dsh-prompt-tunerドキュメント
README 全文を読む ↗dsh-prompt-optimizer
在 DSH Web 界面里,把输入框里已经写好但还不够明确的内容,一键改写为指向清楚、可直接执行的提示词。
- 改写用的模型:默认跟随当前会话的模型(零配置可用),也可以固定成一个专用模型。
- 改写用的提示词:内置一份约 1.9k 字的默认提示词,可在设置页里整体替换。
- 改写结果:默认直接替换草稿并可一键撤销;也可以设成先在预览面板确认。
- 全程发生在宿主进程:浏览器不接触凭据,也不直接调用任何 provider。
界面
插件只占三个座位,没有自己的面板:
┌──────────────────────────────────────────────┐
conversation │ ✨ 改写预览 首字 0.6s · 共 2.3s │
.input.dock │ ┌─ 原文 ────────┐ ┌─ 改写后 ───────────────┐ │
(输入框上方) │ │ 帮我把登录页 │ │ 把登录页的加载与交互 │ │
│ │ 改快一点 │ │ 速度改快。… │ │
│ └───────────────┘ └────────────────────────┘ │
│ 模型标注的待确认:未指定技术栈,按「沿用现有…」│
│ [采用] [再改一次] [关闭] 标准 精简 结构化 扩写│
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ + 完全权限 ▾ ⚙️计划 ✨优化提示词 优化中 2.1s [停止] 模型▾ │
└──────────────────────────────────────────────────────────────┘
↑ conversation.input.left:权限选择器右侧
| 座位 | 内容 |
|---|---|
conversation.input.left | 工具行里的 ✨ 优化提示词 按钮 + 一行状态(进行中/已撤销/错误)。Alt+O 等价。 |
conversation.input.dock | 改写预览卡片:原文与结果并排、模型标注的待确认、档位切换、采用/撤销/再改一次/关闭。 |
settings.section | 「提示词优化」设置页:模型、思考强度、档位、应用方式、改写方式、快捷键、自定义提示词。 |
交互
一键路径(默认)。点 ✨ → 结果流式写进预览卡片 → 草稿未被改动过就直接替换,并在按钮旁给出「已优化 35 → 459 字 · 2.0s」与「撤销」。
安全规则:自动替换只在「草稿仍是你发送时的那一份」时发生。改写期间你继续打字,结果就停在预览卡片里等你确认——不会静默覆盖你新写的内容。这条规则由宿主发布的 InputState.draftRev 校验,不靠猜。
引用芯片守卫。草稿里含 @文件 / /命令 芯片时按钮禁用并说明原因:整稿替换会切断芯片节点(InputState.draft 是芯片展开后的文本),此时没有无损的改写方式。
档位:标准 / 精简 / 结构化 / 扩写。档位只往系统提示追加一条风格指令,不覆盖你的自定义提示词,可在预览卡片里逐次切换并立即重跑。
再改一次:把当前结果当作下一轮输入重跑(迭代收敛),或换个档位再跑一遍。
取消:进行中点「停止」;宿主在请求关闭时 abort 模型调用。取消发生在写回之前,草稿始终未被修改,因此不需要回滚。失败的实时错误显示在按钮旁与卡片里。
设置页
| 项 | 说明 |
|---|---|
| 优化模型 | 「跟随当前会话的模型」默认开启;关掉后可指定一个专用模型。手选模型会自动关闭跟随,清空则恢复。 |
| 思考强度 | auto / off / low / high / max,默认 off。见下方延迟一节。 |
| 默认档位 | 标准 / 精简 / 结构化 / 扩写。 |
| 改写完成后 | 直接替换(可撤销)/ 先在预览面板确认。 |
| 改写方式 | 插件直接改写(调用模型);或 交给主 agent(零模型调用:把一段打磨模板写进输入框,由当前会话的 agent 带着全部上下文改写)。 |
| 快捷键 | Alt+O 开关。 |
| 自定义优化提示词 | 留空 = 内置默认。文本框只保存你自己写的内容,不会自动填入默认,避免误存。可展开查看内置全文、也可「填入内置默认」再改。 |
配置文件:$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
}
延迟
改写是模型时间,插件管道本身几乎不耗时(实测目录 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决定「自动替换」还是「停在预览」。同类多为无条件替换 + 撤销,或在改写期间改稿被悄悄冲掉。 - 不读你的项目文件、不读会话历史:只发草稿本身。有几个同类默认把工作区文件原文与最近若干轮会话一并外发给所配网关(见下方限制)。
- 中英双语:跟随
ctx.locale,字典与键在自检里做一致性校验。
架构
浏览器(lib/client.js)
├─ conversation.input.left → ✨ 按钮(useInput 读草稿/阶段/芯片/draftRev,inputActions.setDraft 写回)
├─ conversation.input.dock → 预览卡片(共享 per-session 状态机)
└─ settings.section → 设置页
│ POST /dsh-prompt-optimizer/{state,save,optimize,optimize.stream}
▼
宿主(lib/index.js → lib/routes.js)
├─ 回环信任围栏(socket + Host + sec-fetch-site + Origin)
├─ 模型目录缓存 / 思考强度元数据缓存
├─ 失败阶梯 + 首字看门狗 + 整体超时
└─ 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 # 156 项,含宿主路由与浏览器半区
node scripts/bench.mjs --runs 3 --effort off
node scripts/bench.mjs --runs 3 --effort auto # 对照:省掉字段要多花多少时间
自检不用测试框架,三层:静态契约(注入器按字面读取的 slots.register 调用、dsh.bundle、主题 token-only CSS、中英词典键一致)、宿主路由(假 ctx/假 HTTP 驱动真实 handler:失败阶梯、强度协商、预算、SSE 帧序、信任围栏)、浏览器半区(假 React + 假 fetch 执行真实组件:自动替换 vs 等待确认、会话隔离、撤销、芯片守卫、JSON 回退、i18n)。
已知限制
- 不读会话历史 / 工作区文件。有几个同类插件这么做并因此更"懂"上下文;本插件选择只发草稿:读取需要依赖未文档化的宿主内部形状,而且会把你的文件原文发给模型。代价是「修一下这个」这类指代不清的草稿改不出理想结果。需要时可另开一个显式开关。
- 改写长度仍会波动:默认提示词要求「长度与任务相称」,实测 35 字草稿得到 640–963 字(要求 600 字以内)。这是提示词约束力的上限,不是硬截断——硬截断会切坏答案。
maxTokens是按字符数估的:极长的草稿会落在 8192 上限,可能截断后再走第 2 档重试。- 路由只服务回环地址,且不做速率限制:本机任意页面若拿到同源能力,可以消耗你的模型额度。
- 本仓库没有视觉验证:自检覆盖渲染路径与点击链路,但不含真实浏览器截图。
- 收录进 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。