Repository navigation
Idea: A "dam" for looping reasoning: adaptive buffering, safe interruption, and bounded recovery #10179
Replies: 2 comments 4 replies
|
This is the most carefully specified loop-guard design I have read in this tracker, and two of its choices are ones I would keep verbatim:
One seam note, if this ever becomes installableYour layer diagram routes through
An installable sibling, in the same space
Where it is directly adjacent to your Purpose 2: the reasoning channel. We measured a collapse shape the visible breaker cannot reach at all — under the
Its per-line claim is measured rather than asserted: The measurement gap you namedYour validation record says plainly that no false-positive rate is given, and that is the honest thing to write — but it is also the number a reader needs before installing anything. For what it is worth, here is how ours is calibrated, since it transfers:
The instrument is an offline replayer that reads both durable attempt formats — Two things I would like to ask
|
|
An LLM’s memory is fundamentally its context window, the tokens it has generated. If you arbitrarily truncate a portion of a model's CoT, you induce amnesia regarding that pruned information, leading to the following state:
Left in this state, the model is blind to what went wrong. It will question its own context: Because it lacks the negative trace of its failed attempt, it cannot understand why the execution was interrupted, making it prone to retrying the exact same dead-end hypothesis from scratch. A viable way to address this would be offloading the repetitive context (along with relevant runtime signals) to a secondary, lightweight LLM to synthesize a concise failure summary or re-anchor the task focus (e.g., "An attempt to inspect file Y stalled; do not retry that path"). Manipulating the CoT through blind truncation severely degrades the model’s continuity, inducing context deformation and triggering self-questioning loops that defeat the purpose of the recovery mechanism. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
I'd like to share an idea and a reference implementation for stopping visible reasoning loops before they consume an entire response: a small adaptive buffer that behaves like a dam, combined with safe call-local interruption and a finite continuation allowance.
Technical reference: https://github.com/KouzakiUmi/dsh-cot-loop-guard
This is a technical reference repository, not an installable plugin or a generic patch kit. I'm sharing the reasoning, source snapshots, and trade-offs for discussion—not claiming compatibility with arbitrary DSH versions or asking users to patch their installations.
The failure mode
Sometimes the model repeatedly says things like “I should read the file”, “execute now”, and “stop looping and use the tool”, but never actually emits the tool call. Sentences reorder, short interjections recur, and longer sentences change slightly.
This is different from repeating an identical tool call: an advisory post-tool reminder may never get a chance to help. Pure exact-copy detection can also miss it because no whole passage is identical. On the other hand, aggressively deleting near-duplicates could destroy legitimate analysis, changed identifiers, counters, or negations.
There is related user feedback about repeated searches in #9180. The focus here is the streamed reasoning/output boundary, including loops that occur before a useful tool call exists.
Proposed mechanism
1. Separate the right to delete from the right to stop
Two detectors have different responsibilities:
The visible-stall detector observes the original stream, before exact-copy suppression, so it does not depend on how many copies another detector managed to remove.
2. A dam that is normally open
Illustrative reference defaults, measured in UTF-16 code units, not tokens:
The first qualifying observation already counts toward confirmation. Checks occur every 128 code units; these are observations, not three provider chunks or three disjoint full windows. Interruption can happen well before 8192.
In the reference, an observation needs all of:
The character-mass condition prevents a tiny repeated filler from dominating a window whose substantive sentences keep making progress. Hash matches are verified against original characters; hash collisions are not equality.
Fenced code suspends this visible-stall branch. A fence or settlement barrier may also release pending output without proving repetition decreased; that distinction matters for both state naming and UI wording. Released text may still pass through the independent exact-copy filter.
8192 bounds this detector's retained raw window, not total application memory or CPU cost. The exact-copy filter has its own bounded state.
3. Make accepted output the single downstream truth
Filtering must happen before live delivery and durable commit—not merely as a display cleanup afterward.
Accepted reasoning should drive live rendering, the assembled assistant message, persistence, and replay. A completed provider reasoning block must not reintroduce the original unfiltered text and resurrect suppressed copies.
4. Gate editing by the actual adapter capability
Enable the editing policy only when the same prepared call explicitly supports editable plain-reasoning replay. A model/provider name alone is insufficient.
Unknown, signed, encrypted, or opaque replay routes must remain unedited. Dropping signatures to make an incompatible response look editable is not an acceptable fallback. This is about adapter-supplied visible reasoning, not access to hidden model state.
5. Interrupt one call, then recover only within a budget
Use a call-local cancellation signal rather than cancelling and recreating the entire user task:
The reference uses a
REASONING_LOOPfailure and a dedicatedreasoning-loop-recoverymessage source. The latter is intentionally model-visible, while detection-status notifications are not. The visible-stall continuation says an unconfirmed repetitive tail was discarded; it does not falsely claim every removed character was a proven duplicate.Recovery is finite per Agent/turn/policy instance: default one continuation; three is a configuration choice, not an unlimited retry loop. Exhaustion remains an error and must not escape into ordinary unconditional retry. Native child agents follow the same bounded principle.
User/parent cancellation, policy disposal, cleanup failure, or rejected settlement must prevent continuation. These counters are in-memory policy state, not a durable cross-process global quota. Local abort also does not prove the provider immediately stopped billing.
6. Respect tool settlement
After a complete real protocol tool block, repetition alone should no longer arbitrarily cancel its settlement. Incremental arguments must never become executable merely because a guard recognized text.
A separate output-volume budget bounds the remaining unfinished settlement. In the reference, exceeding that budget fails the call, dispatches none of its tools, and does not automatically continue. Output-volume limits are not a replacement for an adapter's idle timeout.
Visibility is part of the design
A guard that silently shows “stopped”, replaces the old thinking with new thinking, or reveals its recovery only after switching sessions is hard to trust.
The reference therefore treats these as explicit states:
A single notice updates on transitions, not on every token. Presentation stages carry attempt identity/revision, are excluded from model tokens and durable token history, and the latest active stage is included in reconnect state. Actual interrupted settlements and recovery prompts remain durable.
The UI retains earlier interrupted prefixes instead of overwriting them with a later call in the same Step. “Cutting” must be visible before cleanup finishes; “recovering” should not pretend a new request has started before cleanup/settlement permits it.
Evidence and limitations
For the reference publication, 275 related tests across 10 files passed in the original source workspace, covering detectors, policy integration, incremental/replay projection, stream bridging, and plain-reasoning capability boundaries. The repository records source fingerprints and representative tests.
That is not an accuracy benchmark or an independent build of the reference repository. I did not rerun live-model or real-browser interaction validation for the publication. Legitimate repetition and repetition that would eventually self-recover can still trigger early intervention; loops without enough sentence/fragment evidence can be missed. The reference also documents cause-label granularity limits on some protected release paths.
The thresholds are tunable heuristics—not claims of zero false positives, fixed latency, or universal provider support.
Questions for maintainers and the community
I would appreciate feedback on the architecture and safety boundaries, rather than suggesting these defaults should simply be enabled for every model.
中文简述
我想分享一种“水坝式”可见推理循环守卫:正常立即放行,发现疑似重复后才暂存;证据回落则释放,确认持续循环才丢弃尚未提交的尾巴、取消本次模型调用,并在有限次数内要求换一种方式继续。它把“有证据才能删除精确副本”和“组合启发式可以判断停滞并停止调用”分开,同时保留已显示前缀。
重点不是给所有模型强加自动重试,而是:调用级取消、明确的可编辑重放能力门、工具结算保护、取消优先、有限续跑,以及无需切换会话就能看到的缓冲/放行/截断/恢复状态。
参考仓库仅用于技术交流,包含设计、源码快照和限制说明,不是可安装插件或通用补丁包:https://github.com/KouzakiUmi/dsh-cot-loop-guard
All reactions