dsh-loop-guard:在 DSH 里拦截推理循环与重试风暴

前言

在 DeepSeek Harness(DSH)里跑智能体对话时,模型有时会陷入「只出思考、不出正文或工具调用」的状态,整条流卡住,或反复吐出同一段文本。宿主按默认策略对同一次失败重试多次后,一次本来几秒内就能判定的异常,可能被放大成数十分钟甚至数小时的会话空转。

dsh-loop-guard 是社区维护的 DSH 工作流类插件:在流式输出路径上尽早掐断这一次尝试,并只对自己产生的失败码做有限次数的纠正重试,避免把同一确定性失败重复跑满默认重试轮次。下面介绍它的定位、规则、安装方式与使用注意。

这是什么

项目 说明
名称 dsh-loop-guard(包名与仓库一致)
维护者 zuaonew-ops
版本 0.5.1(资料来自仓库 package.json)
许可 MIT
形态 DSH 插件:宿主半区 index.js、设置页 client.js、中英界面文案 locale/*.json
发布 未发布到 npm(private: true),需从 GitHub 安装
依赖 无第三方依赖;可选 webServer(缺失时守卫仍工作,但没有设置页)

一句话:把一次可能卡几十分钟到几小时的会话,压缩成几秒钟的一次干净中止,并止住围绕同一次循环的反复重试。

它针对哪些现象

用户侧常见表述包括「对话无限重复」「卡会话」「子会话运行时间过长」。资料中的因果链可概括为:

  1. 模型推理循环、流卡死或输出退化,导致本次尝试以错误结束;
  2. 宿主默认重试策略对同一次失败再试多轮(资料写明默认可至 5 次);
  3. 每轮尝试本身可能耗时数分钟到数小时,子会话时间预算被耗尽后零产出。

插件用实测会话区分四类坏形态(另有第五条绝对时间兜底):

形态 简要现象
分片洪水 多次重试均大量推理分片、正文分片为 0
卡住不动 长时间没有任何分片到达
慢速渗流 分片持续到来但长时间仍无产出(仅盯分片数或空档的规则可能漏检)
输出退化重复 思考内容中行级或片段级高度重复

核心功能:五条规则与触发后行为

任一规则命中即掐断;优先级自上而下。判据与默认阈值以仓库 README 为准。

# 规则 默认阈值要点
1 chunk(分片洪水) 推理分片 ≥ reasoningChunkLimit 且产出分片 = 0,默认 20,000 片
2 stall(卡住不动) 距上一分片(或起始)≥ stallTimeoutMs,默认 180,000 ms(3 分钟)
3 noOutput(慢速渗流) 已耗时 ≥ noOutputMs 且产出 = 0,默认 600,000 ms(10 分钟)
4 repeat(输出退化) 行判据 + 片段兜底,见配置项 repeat* 默认值
5 absolute(兜底) 单次尝试已耗时 ≥ attemptBudgetMs,默认 1,800,000 ms(30 分钟),不看产出

关键定义:产出分片 = text-delta + tool-call-delta;reasoning-delta 不计入产出。

触发之后(资料中的链路):

  1. 掐断:停止向上游取值,向下游发送终结块 {type:'finish', reason:{kind:'error', failure:{code:'LOOP_GUARD', …}}};触发前已到达的块原样透传。
  2. 止住重试风暴:仅对 LOOP_GUARD 接管;同一 turn/step 允许 maxGuardedRetries 次纠正重试(默认 1),之后终结;其它失败码走宿主默认策略。
  3. 降档(可选):最近 120 秒内触发过循环的 agent,下一次请求将 reasoningEffort 降一档(max → high → low → off),可由配置关闭。

边界(README 明确列出):不修复模型本身的循环;不改写、不丢弃、不重排上游数据块;统计在内存、不写会话数据;只处理本插件产生的 LOOP_GUARD;不做遥测、不发网络请求(设置除写入本地设置文件外无额外落盘)。

安装与启用

前置:DSH 宿主能正常启动,环境具备 plugin_manager 工具。

从 GitHub 安装

dsh plugin add github:zuaonew-ops/dsh-loop-guard

资料注明该命令链路在作者环境中未实测;另一种已实测方式为克隆仓库后用 plugin_manager action=install_bundle 指定本地绝对路径(任务要求禁止 git clone,生产安装以上述 dsh plugin add 为准)。

重启宿主

装完后必须重启一次 DSH 宿主,否则守卫可能已生效但设置页进不了浏览器 boot graph(左侧导航无「循环守卫」)。

确认装上

  1. 打开 设置 → 左侧导航「循环守卫」;
  2. 或请求状态端点:
curl -s http://127.0.0.1:<宿主端口>/loop-guard/state

期望 ok 为 true,value.enabled 为 true,value.config 含与文档一致的配置键;对话一轮后 value.stats.attempts 会增大,表示监听已挂上。更完整的安装、升级、卸载与排障见仓库 docs/INSTALL.md。

配置与设置页

设置页路径:设置 → 循环守卫(约每 5 秒刷新)。可改总开关、11 个阈值(时间类在界面按秒填写)、「重试时降低推理档位」开关,并查看统计、按规则分布与最近触发记录。

配置分三层优先级(低 → 高):包内 cordis.patch.yml → $DSH_HOME/loop-guard-settings.json(未设 DSH_HOME 时为 ~/.dsh/loop-guard-settings.json,仅在插件挂载时读一次)→ 设置页或 POST /loop-guard/config 写盘。运行中直接改 JSON 文件不生效,需用设置页或重启宿主。

HTTP 端点(需 webServer):

方法 路径 用途
GET /loop-guard/state 开关、可改配置、统计、最近触发
POST /loop-guard/config 改配置
POST /loop-guard/reset 统计清零

资料强调 noOutput 在五条规则中最可能误杀「长时间思考后才出第一个产出」的正常请求;若有此类负载,应优先调大 noOutputMs。absolute 到 30 分钟无条件切断,属于 deliberate 兜底。

适用场景与注意

适合谁:长期在 DSH 上跑多步智能体、且遇到过流卡死、推理洪水、重复退化或子会话被重试拖垮的开发者。

权限与安全:插件以当前 DSH 进程权限运行,安装前应自行查看仓库源码与 MIT 许可证。社区插件目录(如 SkillHub)与 DeepSeek / 幻方无官方从属关系,不宜当作官方应用商店。

能力上限:上游连接彻底挂起时,iterator.return() 能否打断挂起的 next() 取决于适配器实现;插件保证的是下游在超时时刻收到终结块并结束自己的流。

结尾

dsh-loop-guard 用可配置的流式判据提前结束坏尝试,并用 LOOP_GUARD 与有限纠正重试打断默认多轮重试放大效应,配合可选推理降档,把「卡死数十分钟」收成「数秒内可判定的一次失败」。查阅插件说明与源码:

  • 目录页:https://www.skillhub.cn/plugins/zuaonew-ops/dsh-loop-guard
  • GitHub:https://github.com/zuaonew-ops/dsh-loop-guard

配套文档:仓库内 docs/INSTALL.md、docs/CONFIG.md、docs/FAQ.md。

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

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

小夜