前言¶
在 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(缺失时守卫仍工作,但没有设置页) |
一句话:把一次可能卡几十分钟到几小时的会话,压缩成几秒钟的一次干净中止,并止住围绕同一次循环的反复重试。
它针对哪些现象¶
用户侧常见表述包括「对话无限重复」「卡会话」「子会话运行时间过长」。资料中的因果链可概括为:
- 模型推理循环、流卡死或输出退化,导致本次尝试以错误结束;
- 宿主默认重试策略对同一次失败再试多轮(资料写明默认可至 5 次);
- 每轮尝试本身可能耗时数分钟到数小时,子会话时间预算被耗尽后零产出。
插件用实测会话区分四类坏形态(另有第五条绝对时间兜底):
| 形态 | 简要现象 |
|---|---|
| 分片洪水 | 多次重试均大量推理分片、正文分片为 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 不计入产出。
触发之后(资料中的链路):
- 掐断:停止向上游取值,向下游发送终结块
{type:'finish', reason:{kind:'error', failure:{code:'LOOP_GUARD', …}}};触发前已到达的块原样透传。 - 止住重试风暴:仅对
LOOP_GUARD接管;同一turn/step允许maxGuardedRetries次纠正重试(默认 1),之后终结;其它失败码走宿主默认策略。 - 降档(可选):最近 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(左侧导航无「循环守卫」)。
确认装上¶
- 打开 设置 → 左侧导航「循环守卫」;
- 或请求状态端点:
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。