overflow 压缩会吞掉本轮工作提示,回合仍算成功 #5416
Replies: 2 comments 1 reply
|
Verified every claim against current upstream master (4e84901 = 0.1.2-alpha.4) — your analysis is exact, and the fix seam you propose is the right one. Line-level confirmation:
The one nuance worth adding to the red test: the bug bites only when the admitted user message is not the tail node. If overflow fires on the first model request after a user message (no tool calls yet), the tail node is that message and it survives — the retry is safe. The shadowing happens in tool-loop turns: user message → assistant On the two fix options: both preserve your invariant, and the code already has both exit paths — option B (refuse compaction) flows through the existing Also worth noting this is adjacent to the earlier compaction report about summary-not-smaller hard-throw (#4454) — different mechanism (selection swallowing live context vs. shrink refusing), same owner seam, so a single fixture family under |
|
补一组量级数据,另外有个调用点可能值得一起写进原帖。 环境:dsh 0.1.5-rc.1 / deepseek-flash / contextWindow 1048576 / Windows。 本机 8 次完整压缩里 7 次走 overflow。overflow 的 post/pre 分别是 调用点这边,除了
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
context-overflow压缩用retainTokens = 0选区间,只留最后一个 surface node。本轮已准入的 user 消息可以被写进 checkpoint,模型却被要求「从后面的消息继续」。schedule / goal / webhook 这类单次工作回合会在提示被吞后仍走成功 retry。对标 Hermes #100818:cron 压缩把任务提示并进摘要,模型按「只回答摘要之后的用户消息」保持沉默,调度器仍记
completed。下面写的是 DSH 树上已经存在的同类选择,不是渠道问题。树上已经这样选
packages/compaction/compaction-basic/src/index.ts在agent/request-error上对CONTEXT_WINDOW_EXCEEDED调用compactIfNeeded(agent, 'context-overflow', signal)。overflow 分支写死:
selectCompactableRange(packages/compaction/compaction-basic/src/region.ts)从尾巴往前累加,直到accumulated >= retainTokens。retainTokens = 0时第一次循环即满足,keepFromIdx停在最后一个 node。除最后一格外的 surface 都进入 shadow 区间。checkpoint(
packages/compaction/compaction-basic/src/summarizer.ts)把压缩内容当背景,要求模型从后面的消息继续任务,不要回应这条 checkpoint。压缩成功后 overflow 返回
{ kind: 'retry' }。本轮 schedule / goal / webhook 准入的 user 消息若不是最后一格,retry 时模型看不到那条工作提示,只看到「继续后面」的 checkpoint 和可能无关的最后一格(工具结果或助手碎片)。回合可以正常结束。人工
/compact(compactNow)要求空闲、且不得有未关闭回合,不在这条里。压力压缩走retainTokens = spec.retainTokens,也不是这条。只论 overflow。建议怎么改
不变量只有一条:overflow 不得 shadow 本轮已准入的 user 消息;做不到就让回合失败,不得成功 retry。
修在
@deepseek-ai/dsh-compaction-basic,不要改agent-loop,不要给 schedule / goal / webhook 各加一层 consumer 守卫,不要新增 config。具体落点二选一(或两个一起,只要不变量成立):
selectCompactableRange时把本轮已准入的 user 消息留在尾巴里,不允许它进入 shadow 区间。retainTokens = 0只表示「为腾窗口可以压得更狠」,不表示「可以丢掉当前工作提示」。compactRegion若发现本轮 user 消息会进 shadow 区间,拒绝这次压缩,overflow 保持原来的 request error,不返回{ kind: 'retry' }。checkpoint 文案可以后补。先保证模型 retry 时还能看见本轮工作提示;看不见就不该当成功。
验收
/compact才有的约束。Owner
@deepseek-ai/dsh-compaction-basicpackages/compaction/compaction-basic/src/index.ts(overflow 的retainTokens = 0与 retry)packages/compaction/compaction-basic/src/region.ts(selectCompactableRange)packages/compaction/compaction-basic/src/summarizer.ts(CHECKPOINT_PREAMBLE)packages/schedule/schedule、packages/goal、packages/webhook/webhook(往 session 写 user-role 工作提示)All reactions