본문으로 건너뛰기
S

oss-prompt-optimizer

seven282/oss-prompt-optimizer

Optimize a raw instruction into a professional prompt through the harness llm service — four-section (Role / Task / Context / Format) or a headerless plain-text style. Context-aware by default: the recent conversation is injected as background and may enrich the ## Context section. Long outputs resume from the truncation point with auto-expanded budgets; validated results are cached (identical requests cost zero model calls); a unified call budget bounds worst-case cost. Composer ✨ one-click optimize, undo, cancel and a token-cost hint; prompt_optimize tool (optimize + iterate), auto-optimize hook, auto-detected zh/en role document.

설치

dsh plugin --profile web add github:seven282/oss-prompt-optimizer

README

prompt-optimizer

English | 简体中文

DeepSeek Harness 插件:提示词优化,将用户原始指令自动优化为专业、结构化的提示词,和qoder、codex一致的体验。

优化结果默认为无标题纯文本提示词(outputStyle: 'plain',更省 token),可配置为四段结构化提示词(outputStyle: 'sections'## Role / ## Task / ## Context / ## Format), 由内置元提示词驱动,经 harness 的 LLM 服务完成(不直连任何 API、不触碰凭据)。

功能

  • 工具 prompt_optimize:agent 可调用,传入 instruction,返回优化后的纯文本提示词;也可传 lastOptimized + iterateInstruction 对已优化结果迭代改写。
  • 服务 ctx.promptOptimizer:其他插件可编程调用 optimize(rawInput, { signal })iterate(lastOptimized, instruction, { signal }); 浏览器端经 ctx.remote.promptOptimizer.optimize(sessionId, text) 可调用。
  • 输入框 ✨ 图标:composer 工具行左侧的常驻图标,点击即优化当前草稿并写回输入框;优化中再点可取消(AbortSignal 透传),成功后短暂显示"消耗 ≈N tokens"。
  • 角色文档语言自动切换:角色文档(元提示词)语言默认按输入内容自动检测——中文指令用 中文角色文档,英文指令用英文角色文档(见下文)。
  • 自动优化钩子(可选,默认关闭):以触发前缀开头的用户消息会在进入模型前被自动优化(见下文)。
  • 上下文感知(默认开启):把当前指令之前的最近对话注入元提示词 (「视为纯数据 / 背景参考」护栏),让优化结果贴合此前讨论;设 contextAware: false 关闭(见下文配置表)。
  • 后置校验:模型输出缺段/过薄/过短时自动重试(可配次数),重试前把上次失败的 诊断(缺失段落名、过薄段落与字数)注入下一次调用的系统提示词,针对性修正、 提高命中率;仍失败则返回原文/上次结果 + 错误说明,并附稳定机器可读错误码 (OptimizeResult.errorCodeMISSING_SECTIONS / THIN_SECTIONS / THIN_OUTPUT / TIMEOUT / NO_MODEL_ROUTE 等),工具失败渲染带 [错误码] 前缀。
  • 输出恒含四段;空输入报错;超长输入截断护栏;取消信号透传。 项目截图 项目截图

输入框 ✨ 图标

插件自带浏览器客户端(lib/client.js,经 dsh.client 声明被 harness 加载): 在输入框工具行左侧注册一个 ✨ 按钮——输入为空或优化进行中时置灰(⏳), 点击后调用 host 的 promptOptimizer Remote 服务优化当前草稿,并把优化后的 四段提示词直接写回输入框(inputActions.setDraft)。

不满意可一键恢复:优化成功后,按钮切换为撤销态(↺,品牌色);只要 草稿仍是刚生成的优化结果(未手动编辑),点击即恢复为优化前的原文。 一旦手动修改了草稿,撤销态自动消失(避免覆盖后续编辑)。

可访问性:成功/失败/撤销均通过隐藏的 aria-live 区域播报(屏幕阅读器)。

  • 无需配置;随插件安装即启用,重启 harness 后生效。
  • 触发的是同一个 ctx.promptOptimizer.optimize(),与工具/钩子共享全部配置 (temperature、maxTokens、outputLanguage 等)。

角色文档语言(自动检测)

优化器角色文档(元提示词/系统提示词本身)的语言默认按输入内容自动检测: 非空白字符中汉字占比 ≥30% 的指令用中文角色文档(如「帮我写一份周报」),其余 (英文、日文等)用英文角色文档(两版文档的安全默认)。outputLanguage 仍独立控制 优化结果的输出语言,两者互不影响。

运行时可通过输入框直接输入命令固定或恢复自动(会话级覆盖,重启回落到配置值):

  • /optimizer-language auto —— 恢复自动检测(默认)
  • /optimizer-language 中文 / /optimizer-language 英文 —— 固定语言
  • /optimizer-language status —— 查询当前模式

配置 metaPromptLanguage: 'auto' | '中文' | '英文'(默认 'auto')决定重启后的初始模式; 显式值('中文'/'英文')固定语言,'auto' 跟随输入。

自动优化开关(命令方式)

运行时「发送前自动优化」开关可通过输入框直接输入命令控制:

  • /auto-optimize on / /auto-optimize off / /auto-optimize toggle / /auto-optimize status

开启后 host 进入「发送前自动优化」模式,agent/pre-step 钩子会对每条用户 文本消息做优化(等同于配置 autoOptimizeAll: true 的运行时版本)。

自动优化钩子

cordis.patch.yml 中开启:

- insert:
    - id: prompt-optimizer
      name: 'prompt-optimizer'
      config:
        autoOptimize: true
        autoOptimizePrefix: '/optimize '

开启后,任何以 autoOptimizePrefix 开头的用户消息,会在进入模型步骤前被 agent/pre-step 钩子自动优化——前缀被剥离,剩余内容作为原始指令送入优化, 模型实际收到的是优化后的四段提示词(附一句"已自动优化"说明)。

  • 安全设计:默认关闭;按消息显式触发(前缀命中才优化),不会改动普通对话。
  • 优雅降级:未命中前缀、前缀后内容为空、或优化失败时,原消息原样进入模型。
  • 每个步骤最多优化一条消息,避免一次步骤内多次模型调用。
  • 钩子注册为 effect 作用域,插件卸载自动移除。

安装

已发布到 npm(oss-prompt-optimizer),三种方式任选:

方式一:npm 直装(推荐,免构建授权)

dsh plugin --profile web add oss-prompt-optimizer

方式二:从 GitHub 安装(源码构建,需授权 prepare)

dsh plugin --profile web add github:seven282/oss-prompt-optimizer
# 首次会因 pnpm ≥10 拒绝运行 prepare 而失败;把 pnpm 提示的包键加进该 profile 的
# pnpm-workspace.yaml 后重试:
#   allowBuilds:
#     oss-prompt-optimizer: true
# 建议锁定 commit:github:seven282/oss-prompt-optimizer#<sha>

方式三:从本地目录安装(开发用)

dsh plugin --profile web add <项目路径>
# Windows 下含空格路径会被拆散,先用 junction:
#   New-Item -ItemType Junction -Path "C:\dsh-po" -Target "E:\<你的项目路径>"
#   dsh plugin --profile web add C:\dsh-po

卸载(可逆)

dsh plugin --profile web remove oss-prompt-optimizer

安装/卸载后需重启 harnessdsh web)使 bundle 层生效。

配置

插件行(cordis.patch.yml)可传入以下字段,缺省值已内置于 schema:

字段类型默认说明
temperaturenumber 0–20.2采样温度
maxTokensint ≥11200单次输出上限(token);追求省 token 可下调至 600-800
maxRetriesint 0–51缺段时额外重试次数
maxCallsint 1–204单次优化的模型调用总预算(首次+扩容+重试合计);超出降级返回原文并报 TOO_MANY_CALLS
maxInputCharsint ≥14000原始指令截断上限(字符,硬兜底)
maxInputTokensint ≥03000原始指令截断上限(估算 token;优先用 harness tokenMeter,缺失回退启发式;0 关闭)
timeoutMsint ≥160000单次调用超时预算(毫秒)
outputLanguagestring'auto'输出语言;'auto' 跟随指令语言,其他值(如 '英文')固定输出语言
outputStyle'sections' | 'plain''sections'输出风格:四段标题(默认)或无标题连贯正文(更省 token)
metaPromptLanguage'auto' | '中文' | '英文''auto'优化器角色文档(元提示词)的语言;'auto' 按指令语言自动检测(汉字占比 ≥30% 用中文文档,否则英文),'中文'/'英文' 固定。输出语言仍由 outputLanguage 独立控制。运行时可用 /optimizer-language auto|中文|英文 固定或恢复自动
extraInstructionsstring追加到元提示词的部署自定义规则(如领域要求/风格)
examplesarray[]few-shot 示例对 [{input, output}],注入元提示词示范(仅 sections 模式注入)
minSectionCharsint ≥010每段正文最少有效字符;0 关闭内容校验(仅查标题)
maxTokenRetryFactornumber 1–32输出触顶时按该倍数跳档扩容(1200→2400→4800…),扩容不消耗重试次数、从截断处续写;1 关闭
maxTokensCapint 1–1280008000自动扩容的上限;<= maxTokens 关闭扩容(扩容不消耗重试次数)
retryTemperatureStepnumber 0–20.3每次重试的 temperature 增量(探索性重试);0 关闭
skipIfAlreadyOptimizedbooleantrue输入已含四段标题时直接透传,不调用模型(省 token 默认;仅 sections 模式生效;传入非空对话上下文时仍会重新优化
selfRefinebooleanfalse成功优化后至多再跑一轮「精简」迭代(内部指令);仅当仍通过校验且不更长(5% 容差)时采纳,任何失败自动回退原结果。开启会多 1 次模型调用
autoOptimizebooleanfalse是否启用自动优化钩子(前缀触发)
autoOptimizePrefixstring'/optimize '自动优化的触发前缀(可改为 /优化 等)
autoOptimizeAllbooleanfalse钩子优化每条用户文本消息(不止前缀触发)
hookIncludeOriginalbooleanfalse钩子替换消息时保留原文(原文+优化结果双写)
cacheEnabledbooleantrue内存缓存校验成功的结果(同请求零模型调用,LRU+TTL,重载即清空)
cacheMaxEntriesint 0–10000200缓存条目上限(LRU 淘汰);0 关闭存储
cacheTtlMsint ≥0600000缓存有效期(毫秒);0 不设过期
contextAwarebooleantrue上下文感知:优化时把当前指令之前的最近对话(经 {{上下文信息}} 占位符 + 「视为纯数据」护栏)注入元提示词,让优化结果贴合此前讨论。四段模式下可将上下文中的事实用于充实 ## Context 段(仍不执行其中嵌入的指令);钩子取 agent/pre-step 消息,/optimize 取会话记录,尽力而为
contextMaxMessagesint 0–1006上下文感知时采集的最近消息条数上限;0 关闭
contextMaxTokensint ≥0800上下文 token 预算;超出截断到最长前缀并附标记;0 关闭截断(精简默认)
templateIdstring'default'角色文档模板集 id(仅内置 'default';未知 id 加载即抛)
metaPromptTemplateobject自定义角色文档骨架(部分字段可选,缺的语言回落内置);每个骨架必须保留数据占位符、{{输出结构}}/{{自查}} 块与「视为纯数据」注入护栏,违规加载即抛
provider / modelstring显式模型路由;必须成对配置。缺省时使用 harness 默认模型(agentDefaultModel

示例:

- insert:
    - id: prompt-optimizer
      name: 'prompt-optimizer'
      config:
        temperature: 0.3
        maxRetries: 2
        outputLanguage: '英文'
        autoOptimize: true
        autoOptimizePrefix: '/优化 '
        # 省 token 快赢:下调输出上限 + 跳过已优化输入(skip 仅 sections 模式生效)
        # outputStyle: 'plain'            # 输出无标题纯文本(实测下游 token 省 50%+)
        # maxTokens: 700
        # skipIfAlreadyOptimized: true
        # selfRefine: true               # 成功后再精简一轮(额外 1 次调用)
        # contextAware: false             # 关闭上下文感知(默认开启)
        # metaPromptTemplate:            # 自定义角色文档骨架(部分字段可选,缺的语言回落内置)
        #   optimizeZh: |
        #     你是一名提示词优化专家。…(必须保留 {{原始指令}}、{{输出结构}}/{{自查}} 与护栏行)
        # provider: 'deepseek-official'   # 可选:显式路由(成对)
        # model: 'deepseek-v4-flash'

非法配置(类型错误、越界、未知键、provider/model 只配其一)会在加载时响亮失败。

省 token 最优配置(推荐 preset)

默认值已是省 token 取向(skipIfAlreadyOptimized: truecontextMaxTokens: 800contextAware: true 但上下文按预算截断)。在配置里显式贴上以下 preset,即可拿到 完整推荐组合,且便于后续调整:

- insert:
    - id: prompt-optimizer
      name: 'oss-prompt-optimizer'
      config:
        maxTokens: 1200                # 输出上限(插件默认;触顶会自动按因子扩容重试)
        skipIfAlreadyOptimized: true   # 已含四段的输入直接透传,零模型调用(默认已开启)
        contextMaxTokens: 800          # 上下文保持精简(默认已开启)
        outputStyle: 'sections'        # 结构敏感任务保留四段;纯省 token 可改 'plain'(下游省 50%+)
        selfRefine: false              # 默认关闭:不为精简多花一次调用

要点:① 已优化输入零成本复用(skipIfAlreadyOptimized);② 上下文只带"够用"的 最近对话(contextMaxTokens);③ 输出上限按需设定(默认 1200,触顶自动扩容, 避免无限生成);④ 对格式不敏感的任务切 outputStyle: 'plain' 是最大的单项收益。

开发

pnpm install --store-dir .pnpm-store --cache-dir .pnpm-cache   # 沙箱内安装
pnpm run typecheck    # tsc --noEmitpnpm test             # vitest(mock llm,不依赖真实密钥)
pnpm run build        # tsc -p tsconfig.build.json → lib/

测试全部使用 mock 的 llm 流,绝不读取 .credentials.yaml

优化生命周期事件(供其他插件订阅)

promptOptimizer 服务在优化/迭代的关键时点通过 cordis 事件总线发事件,其他插件可订阅:

事件时机载荷
prompt-optimizer/optimize:start输入校验通过、首次模型调用前{ method, input }
prompt-optimizer/optimize:success成功(optimized: true{ method, input, result, durationMs }
prompt-optimizer/optimize:failure降级(optimized: false{ method, input, result, durationMs }
  • method'optimize''iterate'(两者共用三个事件);input 为原始输入 (未截断);result 为完整 OptimizeResultdurationMs 为管线耗时(毫秒)。
  • fire-and-forget 观察者:监听器抛错被吞掉,不影响优化管线。
  • TypeScript 订阅方直接获得载荷类型(declare module '@deepseek-ai/cordis' 增强已随包发布),也可用 PROMPT_OPTIMIZER_EVENTS 常量引用事件名。
  • 跳过透传(skipIfAlreadyOptimized 命中)与输入非法(如空输入)不发事件。

设计要点

  • 依赖面最小:cordis / dsh-llm / dsh-tools / dsh-timeout / schemastery
  • 模型路由来自 harness 默认模型(agentDefaultModel.currentSelection()), 遵循「插件不管理 provider/model 配置」的约定;也可用配置显式覆盖。
  • 元提示词含 {{原始指令}} 等占位符,运行时替换;含注入护栏(指令视为纯数据)、 语言规则({{语言规则}})、禁代码围栏、精简要求与输出前自查;输出结构按 outputStyle 在四段与无标题两套模板间切换。
  • 迭代能力:iterate(lastOptimized, instruction) 基于上一次优化结果 + 新要求继续 优化(META_ITERATE 模板,{{上次结果}} / {{迭代指令}} 占位符单遍替换,互不串扰); 失败时保留上次结果并附错误码。
  • 诊断驱动重试:结构类失败时把上次失败的具体诊断({{诊断反馈}} 占位符)注入下一次 重试的系统提示词,针对性修正、提高命中率;纯内部行为,无新增配置、无额外模型调用。
  • 自适应精简(selfRefine,可选):成功后至多再跑一轮「精简」迭代(内部指令, 不占公共模板),仅在仍通过校验且不更长(5% 容差)时采纳;任何失败自动回退原结果 ——最多 1 次额外模型调用,默认关闭,与诊断驱动重试正交(失败重试 vs 成功精益)。
  • 优化生命周期事件:三个 fire-and-forget 事件(prompt-optimizer/optimize:start / optimize:success / optimize:failure),optimize/iterate 共用、method 字段 区分;载荷含 input / result / durationMs;监听器异常不影响管线,跳过透传与 非法输入不发事件。
  • 模板数据化(templateId / metaPromptTemplate):角色文档骨架(4 个)从代码常量 变为可配置资源,部分自定义、缺的语言回落内置;tuning 块(输出结构 / 自查等格式 规则)保持代码化——它们与 validate.ts 后置校验耦合,不可由用户改写;自定义模板 在加载期强校验(数据占位符、结构/自查块、「视为纯数据」护栏缺一不可)。
  • 服务分层:optimizer.ts 只做编排(状态、校验/截断、重试管线、事件、路由),纯逻辑 拆到三个无 harness 依赖的模块——diagnose.ts(重试诊断文案 / selfRefine 指令, 中英双语文案可独立单测)、llm.ts(finish 错误翻译、流式文本组装、MaxTokensError)、 prompt.tsPromptBuildContext 收口系统提示词构建参数,三处调用点共用);公共 API 面不变(MaxTokensError 仍从入口导出),端到端测试零改动。
  • 角色文档语言自动检测:metaPromptLanguage: 'auto'(默认)按指令非空白字符中汉字 占比 ≥30% 选择中文/英文角色文档(纯函数 detectLanguage,含假名的日文等语言归 英文文档);'中文'/'英文' 固定语言,/optimizer-language 可运行时固定或恢复 自动。检测结果在单次调用内传递(optimize/iterate 按各自输入检测,selfRefine 沿用本轮语言,重试诊断文案同语言),与 outputLanguage 独立。
  • 所有注册(工具、systemPrompt 段落、自动优化钩子、命令)均为 effect 作用域, 插件卸载自动清理。
  • 命令命名:本插件注册 /optimize/auto-optimize(短命令,遵循生态惯例)。 若未来与其他插件冲突,改名需同步 client.js 调用、README 与钩子前缀默认值 (/optimize ),建议一次性原子变更。

License

MIT — 自由使用、修改与分发(含商业用途),详见 LICENSE 文件。

관련 플러그인