Skip to main content

LLM Degenerate Loop Guardrails

English README

Quality Gate Release License Python

面向国产及其他 LLM 的输出流和工具调用退化循环经验记录与检测工具。 项目最初来自 MiMo reasoning=True 场景的重复输出观察,后来发现类似现象 也可能出现在 GLM 等其他模型中。这里分享的是识别、止损和复盘方法,不是 针对任何模型的根治方案。

目录

30 秒开始

Guardrails architecture

核心流程: 模型输出 → 检测信号 → 保守决策摘要 → 上层运行器处理。 检测器和恢复层都不执行重试、模型切换或工具调用。

python3 scripts/detect_loop.py --log fixtures/loop_detected.log
python3 tests/test_detector.py
python3 scripts/benchmark_fixtures.py

机器集成使用单份 JSON 摘要和退出码:

python3 scripts/detect_loop.py --json --timeout 60 --log fixtures/loop_detected.log
# 退出码 0 = 未检测到;1 = 检测到;2 = 参数/输入错误

# 将检测摘要转成保守的恢复决策(只输出决策,不执行重试)
python3 scripts/detect_loop.py --json --timeout 60 --log fixtures/loop_detected.log | \
  python3 scripts/recovery_policy.py --retryable

典型检测摘要:

{
  "loop_detected": true,
  "details": {
    "type": "consecutive_identical_output"
  }
}
退出码 含义
0 未检测到循环
1 检测到循环
2 参数或输入错误

问题描述

在特定模型、参数、任务和上游服务条件下,LLM 可能进入退化循环状态:

  • 症状:同一段输出重复,持续时间异常增长
  • 语言切换:特定中文任务中切换为英文,且无视语言约束
  • 功能停滞:不执行有进展的工具调用,仅重复输出文本
  • 根因尚未确定:reasoning=True、上下文长度、工具链状态、服务端实现等 都可能是相关变量;本项目不把相关性写成因果结论。

类似表现并不等于同一个 bug。MiMo、GLM 或其他国产模型的案例必须分别记录 模型版本、端点、参数、任务和时间,不能把一个模型的触发概率或规避经验直接 外推到另一个模型。

三层防御体系

第一层:工程侧限制(止损,不是修复)

在运行器中设置硬性超时和 Token 限制(具体字段以所用框架官方文档为准):

# 示例结构;字段名和数值必须按实际框架、模型与任务校准。
provider:
  model: <your-model>
  timeout: <task-specific-limit>
  max_tokens: <task-specific-limit>

作用是限制单次故障的最长资源占用,不改变模型本身的循环概率。

第二层:行为检测

运行 scripts/detect_loop.py 实时监控模型输出,检测连续重复。

管道输入以空行切分输出块;--timeout 的持续时间只在流式输入期间有实际意义, 离线日志使用日志中的块时间戳。

python3 scripts/detect_loop.py --log logs/sample_degenerate_loop.log
model_output 2>&1 | python3 scripts/detect_loop.py
python3 scripts/detect_loop.py --json --log logs/sample_degenerate_loop.log

检测规则:

  • 连续 3+ 次输出块完全相同或高度相似
  • 连续 3+ 次工具调用参数完全相同
  • 已知副作用工具的重复调用
  • 显式声明中文任务后的英文漂移
  • 可选的持续时间门控

第三层:行为规则(AGENTS.md)

在 AGENTS.md 或对应运行器规则中加入检测和处置约束。详见 SKILL.md。该层是提示和流程规则,不替代运行时检测。

检测策略

默认文本重复采用持续时间门控:需要达到 --threshold 次相似输出,且 重复窗口达到 --timeout 秒。这适合日志后处理,减少短暂重复的误报。

如果上层需要在达到重复次数后立即得到信号,可显式使用:

python3 scripts/detect_loop.py --text-mode instant --log fixtures/repeated_but_short.log

工具调用重复和已知副作用工具的重复调用不受文本持续时间门控影响;生产集成仍应 结合幂等键、调用结果和重试原因做二次判断。

可复现证据

logs/sample_degenerate_loop.log 是历史观察日志;logs/fixed_normal_run.log 是一次正常运行日志。它们只说明具体案例,不构成模型故障率统计,也不证明 任何参数能“修复”模型。

当前仓库没有足够实验次数估计任何模型的通用触发概率,因此不提供“某模型 有 X% 概率出问题”之类的结论。

如何记录和分享新案例

建议至少记录以下信息,并在发布前脱敏:

  • 模型与精确版本、供应商/端点、调用时间段
  • reasoning、temperature、max tokens、上下文规模等实际参数
  • 任务类型、是否多轮、是否涉及工具调用
  • 重复发生前后的输出块摘要或哈希,不公开密钥、隐私和完整敏感工具参数
  • 是否真正发生资源浪费/副作用,检测器是否报警,检测延迟
  • 重试、切换模型或改变参数后的结果

案例记录用于复盘和横向比较,不应写成因果证明。没有原始证据时,使用 “观察到”“可能相关”“尚未复现”,不要使用“必然”“已证明”“彻底解决”。

工程侧缓解措施(不是模型修复)

措施 作用 边界
timeoutSeconds=180 限制单次资源损失 不改变模型行为
maxTokens=8000 限制输出上限 不等于不再循环
行为层检测 提供停止/切换信号 需要上层执行恢复动作

示例

每个示例都只展示输入、检测信号或决策输出;实际停止、重试、切换模型和人工复核 仍由上层运行器负责。

文件结构

mimo-stable/
├── README.md
├── SKILL.md
├── pyproject.toml
├── CHANGELOG.md
├── scripts/
│   ├── detect_loop.py        # 循环检测脚本
│   ├── benchmark_fixtures.py # 可复现 fixture 基准测试
│   └── recovery_policy.py    # 保守恢复决策层(不执行副作用)
├── tests/test_detector.py    # 行为契约测试
├── examples/                 # 最小集成示例
├── fixtures/                 # 规范化回归样例
├── logs/                     # 历史观察日志
└── references/parameters.md

测试

python3 -m py_compile scripts/*.py
bash -n scripts/*.sh
python3 tests/test_detector.py
python3 scripts/benchmark_fixtures.py
# 或使用仓库提供的入口:
bash scripts/test_short.sh
bash scripts/test_long.sh

当前 benchmark 覆盖 9 个规范化案例:循环、正常输出、短时重复、近似文本、 变化参数重试、非连续工具调用、工具 key 顺序、重复副作用工具和中文任务语言漂移。

历史日志在默认 180 秒阈值下可能不报警;复核时使用 --timeout 60。生产阈值 应按业务容忍度评估,不能把测试阈值直接当作生产配置。

安装与集成

项目保持零运行时依赖。支持通过 PyPI 安装 CLI,也支持源码直接运行。

方式一:直接运行源码

git clone https://github.com/xli498/mimo-stable.git
cd mimo-stable
python3 scripts/detect_loop.py --log fixtures/loop_detected.log

方式二:从 PyPI 安装 CLI

python3 -m pip install mimo-stable
mimo-loop-detect --json --timeout 60 --log fixtures/loop_detected.log

上层运行器不应在检测到循环后盲目重试:

  1. 保存脱敏后的事件摘要;
  2. 停止当前生成或工具链;
  3. 根据任务是否幂等决定重试;
  4. 必要时切换模型或请求人工复核。

许可

MIT

行为契约

fixtures/ 中的规范化样例用于稳定回归,历史日志用于说明观察事实;二者不互相 替代。执行 python3 tests/test_detector.py 可验证检测器行为。

Metadata

Release files for mimo-stable 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mimo-stable 1.1.2
File Size Uploaded
mimo_stable-1.1.2.tar.gz 15.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mimo-stable 1.1.2
File Interpreter ABI Platform
mimo_stable-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 31.1 kB

Release files / mimo_stable-1.1.2.tar.gz

Download URL mimo_stable-1.1.2.tar.gz
Size 15.1 kB
Tags Source
SHA-256 checksum
How to use checksums
07ccd0661142effa529092ee4f21812dc7a9d11ed6936d618e73dca591b43f9d
BLAKE2b-256 checksum
How to use checksums
90dc6b9c22f67303f45dc664a9169e7be16624b13b3693c3d0458ff856468387
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / mimo_stable-1.1.2-py3-none-any.whl

Download URL mimo_stable-1.1.2-py3-none-any.whl
Size 16.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
531b9b93aa12adff2807ffa48a8ca0fcbabb7cb81ff9f849e83a7bb561f5037d
BLAKE2b-256 checksum
How to use checksums
3cf17d3dde9499b099d49dd4b42c16366643856c0ed331afdddb702d9cad1648
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release history Release notifications | RSS feed

1.1.5

2 release files

1.1.4

2 release files

This release

1.1.2 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page