dsh-dsml-guard:抹掉正文里的 DSML 泄漏,并在「这一轮其实没产出」时自动续跑

前言

在 DeepSeek Harness(DSH)里走第三方直连的 deepseek-v4.1-flash 时,模型偶尔会把 DSML 调用标记写进助手正文。宿主侧 turn/end 仍可能是 {"kind":"completed"},看起来像正常结束,但屏幕上会出现 ||DSML|| 包裹的 invoke / tool_calls 残渣,或只有结尾闭合标签。更麻烦的是:若只在流式增量上清洗,落进会话历史的正文仍可能和 block-end 里的完整块一致且带标记,下一轮会把脏上下文再发给上游。

社区里常见的自动继续插件只认 kind === 'error' 且错误码在白名单内,对这种「已完成却泄漏」的轮次不会补发「继续」;已有 DSML 清洗插件若只匹配单竖线 |DSML|,而真实流量多为双竖线 ||DSML||,实测会原样放行。下面介绍维护者 Jessicaisleep 发布的工作流类插件 dsh-dsml-guard:在 llm/stream 与 session/event 钩子上做显示与历史一致的清洗,并在启发式判定「这一轮确实没产出」或遇到可重试的网络类失败时,通过 agent.followup() 补一条「继续」;对余额、额度、上下文超限等错误 deliberately 不续跑。

这是什么

dsh-dsml-guard 是 DSH 宿主插件(npm 包名 dsh-dsml-guard),源码与说明见 GitHub:Jessicaisleep/dsh-dsml-guard,社区目录页为 skillhub.cn/plugins/Jessicaisleep/dsh-dsml-guard。分类为工作流;许可证 MIT。当前 package 版本 0.1.2(以 package.json 为准)。

一句话:抹掉漏进助手 prose 的 DSML 标记,并只对「真的什么都没产出」的轮次或超时 / 断联等可重试失败自动补「继续」;quota、rate-limit、上下文超限等一律不自动重试。

核心功能

清洗(llm/stream,只改显示与落历史路径,不改请求)

认三种竖线写法:||DSML||(README 称实测主流)、|DSML|、||DSML||。处理四类残渣:完整 invoke / tool_calls 块(按标签深度配对摘除)、结尾连缀闭合标签、孤立外层包裹残片、无标签名的光头标记。Markdown 代码围栏与行内 `code` 内不改动。

要点在 block-end:适配器在 finish 前发出的 block-end 携带完整 block 全文;README 记录 2026-10-29 实证,脏消息落盘正文与 block-end.text 逐字节相等,与仅拼接 text-delta 不相等。插件在 block-end 上把文本块替换成实际发出去的内容,使 历史与屏幕一致,避免标记在后续轮次被反复喂回上游。README 注明 0.1.0 仅处理 text-delta,0.1.1 起 才覆盖 block-end。

插件只对新产生的回合生效;已有存档中的脏消息需 /compact、开新会话或自行批量处理(README 称 _probe/ 下有解码思路,本插件不提供改存档动作)。

续跑(session/event 的 turn/end)

在以下情况通过 agent.followup() 补 configurable 的「继续」(默认文案 "继续"):

  • invoke-block 泄漏且该轮未发出任何 tool-call-delta;
  • tail-close 泄漏且正文短于 tailCloseMinChars(默认 80);
  • turn/end 错误码属于可配置白名单,默认含 TIMEOUT、TRANSPORT、SERVER、MALFORMED_RESPONSE、PI_AI_ERROR、UNKNOWN。

不续跑的错误包括 QUOTA、QUOTA_EXCEEDED、ACCOUNT_QUOTA、RATE_LIMIT、AUTH、MISSING_CREDENTIAL、CONTEXT_WINDOW_EXCEEDED、UNKNOWN_MODEL、HTTP_413、INVALID_REQUEST,以及 aborted / interrupted。

同一会话连续续跑上限 maxConsecutive 默认 5(范围 1–100);用户手动发消息会取消待发续跑并将计数归零(插件自己补的那条不算用户干预)。

安装与启用

DeepSeek Harness 版本要求 >=0.2.1-rc.2 <0.3.0(README 实测于 0.2.1-rc.3);Node.js >=20。装到 engines.dsh 范围外时,DSH 安装阶段会按 engines 拒绝。

给别人装,从 npm 安装(资料原文命令):

dsh plugin --profile <你的 profile> add dsh-dsml-guard

--profile 须与实际环境一致:桌面应用用 desktop,自启的 dsh web 用 web。装完重启 DSH。

锁 tag 从 GitHub 安装(资料原文,勿用 github:owner/repo 简写):

dsh plugin --profile <profile> add https://github.com/Jessicaisleep/dsh-dsml-guard/archive/refs/tags/v0.1.0.tar.gz

加载成功后,profile 配置(示例路径 profiles/desktop/cordis.patch.yml)中应出现:

- id: dsml-guard
  name: dsh-dsml-guard

web profile 可用 dsh --profile web --dump-config 检查是否含 dsml-guard;desktop profile 下 --dump-config 可能被 Electron 拒绝,属 README 所述正常现象。

可选配置

在 cordis patch 里可为插件增加 config(字段以 README 为准):

- id: dsml-guard
  name: dsh-dsml-guard
  config:
    enabled: true
    sanitize: true
    autoContinue: true
    continueText: "继续"
    maxConsecutive: 5
    tailCloseMinChars: 80
    retryCodes: [TIMEOUT, TRANSPORT, SERVER, MALFORMED_RESPONSE, PI_AI_ERROR, UNKNOWN]
    neverCodes: [QUOTA, QUOTA_EXCEEDED, ACCOUNT_QUOTA, RATE_LIMIT, AUTH,
                 MISSING_CREDENTIAL, CONTEXT_WINDOW_EXCEEDED, UNKNOWN_MODEL,
                 HTTP_413, INVALID_REQUEST]

验证与测试(维护者仓库)

维护者在仓库内提供单元与回放测试,不含真实会话依赖时可跑:

node test/run.mjs

端到端用真实捕获泄漏正文:

node test/replay-real.mjs

README 称 replay-real.mjs 对 29 条样本清洗后 0 残留,续跑判定 19 条(13 invoke-block + 6 tail-close)。

适用场景与注意

适合:使用 DSH 0.2.1-rc.2 至 0.3.0 未发版区间、且通过第三方直连等方式遇到 DSML 标记漏进正文、或需要与「仅认 error 的 auto-continue」互补的场景。README 本机 28 次泄漏均来自 deepseek-v4.1-flash 第三方直连,官方通道未观察到;模型字段本身不限。

务必知晓:

  • 插件以当前 DSH 进程权限运行;安装前请自行查看源码与 MIT 许可证,确认信任维护者与 npm/GitHub 来源。
  • 只处理流式正文;标记若只出现在 reasoning-delta 而非 text-delta / block-end,插件看不到。
  • 续跑判据含启发式阈值,不改上游请求,泄漏仍可能发生,目标是界面与历史干净、且无产出轮次不白跑。
  • DSH 生态强调「一切皆插件」;skillhub 社区目录为独立站点,与 DeepSeek / 幻方无 README 所述官方从属关系。

结尾

dsh-dsml-guard 针对 DSML 泄漏与「completed 却无有效产出」两类痛点,用 block-end 级清洗切断上下文污染,并用克制的自动续跑覆盖网络类失败与实测定义的空产出形态。需要详情、Issue 与发版流程时,请打开 GitHub 仓库 或 SkillHub 目录页。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜