🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

空转熔断器 ethanwong-hk/dsh-thinking-guard

DeepSeek 客户端v1.0.2
ethanwong-hk34 天前有提交已提供中文文档扫描:未发现敏感能力兼容 / 相关生态

拦截只思考不产出的退化回合,自动中止并提示

31.5/100
综合分
2
GitHub 星标
168
npm 周下载
—/5
用户评分

数据截至 2026/9/28 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/ethanwong-hk/dsh-thinking-guard.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
生态插件
可安装,未声明 dsh 能力
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 34 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包@ethanwong-hk/dsh-thinking-guard @ 1.0.2
✓Node 引擎要求 >=18 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/12 15:37:38

安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 拦截纯思考空转回合
  • 超时熔断
  • 推理量熔断

DSH 智能体回合里纯思考空转的熔断器——超时、推理量、退化重复三重熔断。

README

由 DeepSeek 最新模型翻译生成
dsh-thinking-guard 纯思考空转熔断器。挂在 agent/assistant-stream 事件上,对「只思考、零产出」的退化回合实施三重熔断。 安装 方式一:从 npm 安装(推荐) dsh plugin add @ethanwong-hk/dsh-thinking-guard 方式二:从 GitHub 安装 dsh plugin add github:ethanwong-hk/dsh-thinking-guard 方式三:手工挂载 把本仓库放到 ~/.dsh/plugins/dsh-thinking-guard/,然后在 ~/.dsh/cordis.patch.yml 中加入 cordis.patch.yml 里的 insert 片段(见下方「配置」)。 安装后重启 DSH 生效。验证是否加载: grep -n "thinking-guard" ~/.dsh/cordis.patch.yml 为什么需要它 dsh-agent-loop 的 step() 只在流结束后才做终止判定(lib/index.js:1115-1119)。流不结束,turn/end 就永不写入。
展开完整文档(README 剩余 1 节)
dsh-thinking-guard

纯思考空转熔断器。挂在 agent/assistant-stream 事件上,对「只思考、零产出」的退化回合实施三重熔断。

安装

方式一:从 npm 安装(推荐)

dsh plugin add @ethanwong-hk/dsh-thinking-guard

方式二:从 GitHub 安装

dsh plugin add github:ethanwong-hk/dsh-thinking-guard

方式三:手工挂载

把本仓库放到 ~/.dsh/plugins/dsh-thinking-guard/,然后在 ~/.dsh/cordis.patch.yml 中加入 cordis.patch.yml 里的 insert 片段(见下方「配置」)。

安装后重启 DSH 生效。验证是否加载:

grep -n "thinking-guard" ~/.dsh/cordis.patch.yml

为什么需要它

dsh-agent-loop 的 step() 只在流结束后才做终止判定(lib/index.js:1115-1119)。流不结束,turn/end 就永不写入。

dsh-llm-deepseek 的 idleWatchdog(lib/index.js:1627)测的是连接活性而非任务进展 —— 它在每个 SSE 事件上 pulse() 重置 5 分钟计时器(:1816 经 parseSse 喂食)。模型持续吐 reasoning-delta 时,看门狗每 chunk 重置,永不触发。

结果是:模型以比 5 分钟更密的节奏输出 thinking token 时,回合可以无限持续,只能由用户手动中止。默认 max_tokens = 256000(DEFAULT_MAX_TOKENS)量级过大,不构成实际兜底。

三重熔断

| 熔断 | 默认值 | 触发条件 |
| thinking-only-timeout | 45000 ms | 零 text、零 tool-call,且距最后一次进展已超时 |
| thinking-volume | 80000 字符 | 单次尝试 reasoning 总量超限,不依赖是否有 text 产出 |
| degenerate-loop | 3 次重复 | 尾部窗口命中:精确重复单元 / 句子级模板重复 / 稀疏复读 / N-gram 高密度 |

命中即 agent.cancel({ kind:'thinking-guard', reason, detail }),并尽力用 agent.followup() 注入一条可见说明。

「停滞时长」锚定最后一次进展(text 或 tool-call 到达的时刻),而非 attempt 起点 —— 避免慢启动的正常回合被误判。

配置

在 ~/.dsh/cordis.patch.yml 的 thinking-guard 条目 config 下调整,重启 DSH 生效:

- insert:
- id: thinking-guard
name: "dsh-thinking-guard"
config:
enabled: true
只思考、零 text/tool-call 的持续时长上限(毫秒) thinkingOnlyMs: 45000 单次尝试 reasoning 字符总量上限 maxThinkingChars: 80000 退化循环:重复次数阈值 repeatThreshold: 3 熔断后自动注入「继续当前任务」指令 autoContinue: true notify: true verbose: false

环境变量可临时覆盖(无需改配置):

| 变量 | 作用 |
| DSH_THINKING_GUARD_DISABLED=1 | 停用 |
| DSH_THINKING_ONLY_MS | 纯思考停滞阈值 |
| DSH_MAX_THINKING_CHARS | 思考容量阈值 |
| DSH_THINKING_REPEAT_THRESHOLD | 重复次数阈值 |
| DSH_THINKING_GUARD_VERBOSE=1 | 打日志 |

误报调优

| 现象 | 调整 |
| 正常长文本被误熔断 | 调高 sentenceRepeatRatio(默认 0.6)、gramDensity(默认 0.22) |
| 退化循环漏检 | 调低 repeatThreshold(默认 8) |
| 慢模型被误判停滞 | 调高 thinkingOnlyMs |

验证

node ~/.dsh/plugins/dsh-thinking-guard/test/guard.test.mjs

11 个场景覆盖:纯思考超时、退化复读、容量上限、有产出仍限容量、文本复读、稀疏复读(回归用例)、正常回合放行、工具调用放行、正常结束放行、长正常文本放行。

已修缺陷:熔断器自身的静默失效

formatNotice 是模块级函数,却在 sparse-repeat 分支引用了 apply() 内的局部 cfg(cfg.sparseWindow)。该分支一旦命中即抛 ReferenceError: cfg is not defined。

危害不是「少一条提示」,而是熔断完全失效:

1. trip() 中 formatNotice(...) 位于 agent.cancel(...) 之前,异常直接中断 trip(),cancel 永不执行;
2. st.fired = true 已在异常前置位,本 attempt 的后续检测被 if (st.fired) return 全部跳过。

线上日志实证:dsh-2026-09-26.log 记录 472 次、dsh-2026-09-27.log 记录 39 次 agent/assistant-stream listener threw: ReferenceError: cfg is not defined —— 全部来自本插件唯一的事件监听器。修复前,该档熔断在所有命中回合上都是空转的。

修复两处:

// 1) 根因:显式传参,消除模块级作用域泄漏 function formatNotice(reason, detail, st, cfg) { ... }

// 2)防御:cancel 前置,且通知文本生成失败时降级而非中断
console.warn(...);
try { agent.cancel({ ... }); } catch (error) { ... }
let text;
try { text = formatNotice(reason, detail, st, cfg); }
catch (error) { text = ...(说明文本生成失败:${error?.message}); }

原则:熔断这一关键动作不得依赖通知环节的成功。回归用例见 test/guard.test.mjs 场景 11。

语义边界

thinkingOnlyMs 只在零 text、零 tool-call 时生效。已产出文本的回合不会被它熔断 —— 那类回合至少有可见产出,不属于「纯思考空转」。maxThinkingChars 与退化检测对已产出文本的回合同样生效,用以兜住「先吐一小段文本再无限思考」。

依赖

无。仅用 harness 的 agent/assistant-stream / agent/disposed 事件与 agent.cancel / agent.followup 接口。消息工厂按候选路径显式解析 @deepseek-ai/dsh-llm,解析失败时降级为仅日志,不影响熔断本身。
预览分享卡片长什么样 ↓ethanwong-hk/dsh-thinking-guard
分享 · DeepSeek Harness Hub
ethanwong-hk/dsh-thinking-guard

拦截只思考不产出的退化回合,自动中止并提示

回到顶部