dsh-loop-guard:在 llm/stream 上拦截模型重复循环输出

前言

在 DSH 里跑智能体时,模型有时会卡在 reasoning-delta 里反复输出同一类短句:正文和工具调用都为 0,repeat-tool-reminder 因只看同名工具与相同参数而不会触发,maxTokens 余额又很大,agent-loop 也不做流内重复检测。最后往往只能靠用户手动中断,白白消耗时间和 token。

dsh-loop-guard 由维护者 lyc0110 发布,分类为 admin-security,在 llm/stream 水位线上加一道护栏:当思考或正文退化成周期性重复循环时,中止本次请求,而不是一直流式输出到用户放弃。插件版本为 0.1.0,许可证 MIT,源码见 GitHub,也可在 SkillHub 目录页 查看条目(社区目录与 DeepSeek / 幻方无官方从属关系)。

这是什么

一句话:dsh-loop-guard 是面向 DSH llm/stream 的 guardrail,检测模型 reasoning 或文本是否塌缩为周期重复,并默认以错误方式中断请求。

README 里记录了一次真实会话(DeepSeek flash 档模型,经第三方兼容网关):两轮卡死分别产出约 2.6 万与 8.2 万字符的 reasoning,用户两次手动中断;turn 57 的行内容里仅约 47 种不同行,大量为无意义重复标记。该插件用于补上「流内重复」这一环检测。

两道检测器与可选上限

插件 README 将检测逻辑归纳为以下几类(改动仅挂在 llm/stream,每次请求独立状态)。

1. 行级塌缩(主力)

按行切开增量输出,维护最近 lineWindow 条「有内容的行」。窗口塞满后,若不同行的种类数 ≤ maxUniqueLines,判定塌缩。文档称上述故障场景可在几百行内撞线。

空行与 trim 后长度小于 lineMinChars 的行(例如单个 })不计入行统计,以降低对代码样本文本的误判。

2. 字符周期重复

将末尾 probeChars 个字符当作指纹,在最近 regionChars 字符范围内统计出现次数;达到 minOccurrences 则判定退化,用于没有换行的循环输出。

3. 绝对上限(默认关闭)

单次请求累计输出超过 maxTotalChars 字符时直接掐断;默认值为 0 表示关闭。

命中之后的行为

默认 onDetect: 'throw':抛出 code: 'repetition-loop' 的错误。README 说明 agent-loop 已有「流中途出错」的清理路径,会收成 error finish;自定义 code 可避免落入 llm-retry 的可重试码表,减少在同一退化点上反复重试。

若设为 onDetect: 'end',则静默结束流,不伪造 block-end / finish。

dryRun: true 时只记日志不掐断,便于校准阈值;logFile 非空时会把命中信息追加写入该文件。

配置项

下列键名与默认值来自项目 README,可通过 DSH 插件配置覆盖(空数组的 providers / models 表示对全部生效;非空则仅对列出项生效)。

键 默认 含义
providers / models [] 作用范围过滤
lineWindow 400 行级检测窗口(行数)
maxUniqueLines 40 窗口内不同行数上限
lineMinChars 2 短于它的行不计入
lineCheckEvery 20 每新增多少行判一次
probeChars 96 指纹长度
regionChars 3072 回看窗口
minOccurrences 5 指纹重复几次算退化
minTotalChars 2048 累计输出超过此量才开始字符检测
checkEveryChars 128 每累计多少字符判一次
maxTotalChars 0 绝对上限,0 = 关
onDetect 'throw' throw | end
dryRun false 只记日志不掐断
logFile '' 命中追加写入路径

验证方式

在插件包目录执行内置用例:

node lib/index.js

README 写明用例包含「长清单 / 长代码样文本不得误杀」。另有用原始会话数据离线回放的结论(回放脚本依赖会话归档,不随包发布):例如 seq 1670 在约 2,304 字符处掐断;同一会话 327 个正常块共 588,930 字符为 0 误杀;5 个正常块各自放大到 20 万字符仍为 0 误杀。部署前可先 dryRun 观察日志,再关闭 dry run。

安装、启用与回滚

已抓取 README 未给出独立的「安装」 shell 命令,可从 SkillHub 插件页 按 DSH 生态的插件安装流程接入(「一切皆插件」)。安装前请自行审阅 源码仓库 与 MIT 许可证;插件以当前 dsh 进程权限运行,属于 admin-security 类能力,只应装你信任的来源。

需要禁用或回滚时,README 提供:

plugin_manager set_plugin  target=dsh-loop-guard  enabled=false

禁用后立即恢复原样,因钩子只改 llm/stream 一条水位线。

适用场景与注意

适合:长时间跑 agent、reasoning 流很长、且遇到过「只重复短句、无工具调用」卡死的 DSH 用户。

注意:检测阈值需与模型、网关输出格式匹配;误杀风险应通过 dryRun 与 node lib/index.js 自测。不要指望它替代 repeat-tool-reminder 或 token 上限,三者解决的问题不同。

结尾

dsh-loop-guard 在流式输出侧补上重复循环检测,把「用户点中断」换成可配置的自动中止与明确错误码。目录页:https://www.skillhub.cn/plugins/lyc0110/dsh-loop-guard;源码与完整配置说明:https://github.com/lyc0110/dsh-loop-guard。

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

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

小夜