Repository navigation
[Bug] 从大上下文窗口模型切到小窗口模型会卡死:压缩阈值随目标窗口重算,而摘要请求仍发往该小窗口模型,于是压缩请求自己也超限 #9814
Replies: 3 comments
|
Verified against the source at Your half B is the part a configuration workaround cannot fix, and the reason yours is honest about being one: I built the plugin half of your suggestion 1 and published it:
It listens on the
That appended sentence reaches the log half of your suggestion 2: Mount (shipped as the package's own - insert:
- id: compaction-target-guard
name: '@argszero/dsh-compaction-target-guard'
config:
mode: reroute # or `observe`: decide and log, dispatch nothing
maxAttempts: 2
allowProviders: [] # narrow to one vendor if a summary must not leave itThree limits, stated plainly:
When the catalogue has no larger route at all, this plugin can only name the cause. For that case Your suggestion 3 (a capacity check at the moment of the switch) is outside this plugin's reach: it acts on a summary that has already been refused, not on the switch. And the preventive form of suggestion 1 — pick a large route before the switch — is a decision about which model answers, which is the operator's call, not a plugin's. Verification, in case it is useful for judging whether to install it: 42 tests against a real cordis context, the real |
|
@argszero 谢谢 —— 在回复之前我把你的说法独立复核了一遍。先报结论,再报依据。 我在这台机器上重新跑出来的(不是采信描述)
那条 declared-equivalent 我看了理由,同意它是不可达的:failed route 被「必须声明窗口」与「strictly-larger」两条规则挡在候选之外,在确定性 resolver 上即使重排也改不了结果。把它报出来而不是藏起来,是这套 harness 里我最信的一处。 两条你可能想知道的一、你声明的宿主矩阵,我自己复现不出来(不是套件的问题,是 devDependency 配对)
所以你的结论是对的,只是仓库里没有任何东西记着「0.2.0-rc.2 要配 cordis 4.0.4」。devDependency 只能钉一对,矩阵里其余格子在别人机器上的第一个现象就是这句 ERESOLVE。要么把每格配的 cordis 版本记进 README / 矩阵脚本,要么把宿主版本从 devDependency 移出去、由矩阵脚本按格安装。 二、容量判断交给「声明值」,而这条线上已经有证据表明声明值会夸大
含义是:一个候选可以「按声明更大」却在真实上仍然装不下 —— 你把它判为 refused、继续试下一个(或走到 我不认为这需要改设计(除了声明值你也没有别的可读)。只是如果你在 README 里那句「a larger route answers」旁补一句「以路由自报的窗口为准,自报与真实可能不一致」,它就和你在别处保持的口径一致了 —— 你在 limit 1/2/3 上把话说得很准,这一条是唯一一处把「声明」当成了「事实」。 这一条下午在我自己的机器上就变成现实了(下面的实测),而且形态比我预想的更极端:不是「声明偏小导致选错候选」,而是候选池被整个压平、一个都选不出来。 关于建议一 / 二 / 三
装上试的结果:在我这台机器上,它没有接管 —— 而原因值得你知道我按计划在本机(macOS,DSH 0.2.0-rc.2,两个 provider 同时启用:国内 我把本机已注册的模型与它们的声明窗口喂给
结果: 我这条路径( 为什么会这样 —— 两个缓解手段互相抵消我自己在 profile 里给这些模型设了 但你的「strictly-larger」判据读的也是这个声明值 —— 于是:
这不是你的 bug:你的规则是对的(不能拿一个装不下的路由去接)。是我的两个缓解手段撞在一起:压预算降低了超限概率,同时把插件唯一能用的「更大路由」也压没了。 这对你的设计意味着什么(只提一个观察,不建议改行为)
如果只动文档,我想不到比这更值的一处:在限制 1(不预测容量)旁边补一句「它以路由自报的窗口为准;若操作者用预算把多个路由压到同一窗口,严格更大规则会找不到候选」。下一个踩到的人就会知道去看 我这边的动作:把被压平的 另外补一句我核对时发现的、与你无关但值得记的事实:这条路径上那个所谓的「1.94 倍」跨区域计数差,最近被六组实验排除了 —— 两个网关对同一段字节的计数一致(比值 0.98 |
Additional reproduction on Windows + proposed confirmation flowI encountered this twice in the Web UI on DSH 0.2.0-rc.2.
After switching, the turn failed with Additional recovery problem: selecting the previous, larger model in the picker did not immediately fix manual compaction. The session log records the selection back to the larger route, but the following Requested behavior
This should be shared Host-level behavior for all sessions and presets, rather than a workaround configured separately for each model. Interfaces without confirmation support should reject an unsafe switch. |
Uh oh!
There was an error while loading. Please reload this page.
[Bug] 从大上下文窗口模型切到小窗口模型会卡死:压缩阈值随目标窗口重算,而摘要请求仍发往该小窗口模型,于是压缩请求自己也超限
环境
@deepseek-ai/dsh-compaction-basic、@deepseek-ai/dsh-compactiondsh-connect-workbuddy(第三方 provider 插件,如实声明每个模型的contextWindow)现象
在一个大窗口模型(1M)上跑了一段长会话(历史约 500K token),**直接切换到一个小窗口模型(200K)**之后:
400失败(上游业务码11115,即上下文超限);/compact也失败 —— 于是没有任何自救路径;可恢复的操作是存在的,但只能靠用户自己想到:先切回同样是大窗口的模型压一次,压完再切到小窗口模型。
根因(两半,都在 0.2.0-rc.2 发布包里核实过)
A. 压缩阈值随目标模型的窗口重算
@deepseek-ai/dsh-compaction-basic→index.ts(agent/pre-step路径,:304/:314):而
config.ts(:191):⇒ 窗口从 1M 换成 200K 时,阈值当场塌下来(
min(200K × ratio, …)),而历史一动没动,于是立刻判定超限。这一步本身是正确的 —— 历史确实装不进新窗口,本来就该压缩。B. 但摘要请求发往的就是那个装不下的小窗口模型
同包 →
summarizer.ts(:127-137):摘要请求携带全部待压缩的历史(
input.messages原样作为 messages 发出)。所以切到 200K 模型之后,这个请求和普通请求撞的是同一堵墙:阈值把它判定为"该压缩了",而它自己就是压缩请求 —— 越超限越压不动,越压不动越超限。C. 自动路径还会把失败静默吞掉,所以用户看不到真正的原因
index.ts:172:自动压缩失败后继续这一轮,于是用户看到的是模型返回的
400 / 11115(一个"上下文超限"),而不是"压缩失败了" —— 两个错误指向完全不同的处置,而界面上只有后者。复现步骤
400;输入/compact→ 同样失败。预期:切换前(或压缩调度入口)判断"当前历史装不装得下目标窗口";装不下就先用装得下的大窗口模型压一次,压完再切。或者至少把真正的原因(摘要请求超限)显示出来。
实际:每一个请求都失败,压缩也失败,没有任何界面信息指向"摘要请求本身超限"。
建议(按优先级)
requestHeader()解析出的目标窗口小于当前所需时,不要把摘要请求发给它 —— 可以退到agentTarget、或配置里指定的summarization*、或目录中任一窗口足够的模型。目前的规避办法
在 profile patch 里把摘要目标钉死在一个大窗口模型上,让它与会话当前模型解耦:
另可把各模型的
contextBudgets调低,让压缩更早触发(降低概率)。但这两个都只是规避:只要历史已经超过目标窗口,切过去仍然死锁,因为问题在"摘要请求自身装不下",不在触发时机。All reactions