Skip to content

Reasoning on protected messages forms a permanently-incompressible context floor; live compress-call args duplicate summaries #224

Description

@ranxianglei

问题(参考 billion-context-pi #336 / opencode-acp #368,同源)

对真实风暴会话(billion-context-paper, qwen3.8-27b)的逐项测量:

  1. 可见上下文 ~50% 是 thinking 回放。459 个 thinking 块中 31 个可见 = 75.8K tokens(CJK-aware),其中 70%(52.8K)贴在 17 条 compress 调用的锚点消息上——每次压缩前的长推理随 hide-consumed 锚点被永久保留,任何压缩选择都不会碰它。防死循环的锚本身成了最大的上下文消费者。
  2. 活锚点的调用参数与 acp_summary 二重复制:16 条可见 compress 调用的 args 携带完整 summary 文本,共 21.5K tokens,和已渲染的摘要消息几乎逐字重复。
  3. rewriteCompressTextJSON.parse(text)<acp> ref 标签前缀失败 → 返回 null → 改写不生效。这同样是 opencode-acp #368 "related finding 3"(kept.length===0 bail 残留 ~3.7KB/块)的根因类别:带前缀/非纯 JSON 的调用文本从未被瘦身。
  4. prune 的 covered 匹配在投影演进后泄漏:块内记录的 effectiveMessageIds 是压缩时的 core id(basebase#callId);投影引入 base#r0 后,新子 id 不被任何块覆盖 → 历史消息以 reasoning core 形式复活(实测 always 策略下 762K 复活)。
  5. 内核 usage/压力计算看不见 host 侧不可见质量(回放 reasoning 等),压力带与真实用量脱节。

修复(本 issue 对应 PR)

  • Config.reasoningReplay: "always" | "open-round" | "never"(默认 always 保持旧行为):新增 strip-reasoning 管线节点,按"最后一条真实用户消息"轮次闭合门控剥离历史 reasoning。provider 只要求当前未闭合轮次回放 thinking(Anthropic signature / Gemini thought_signature),门控与 provider 无关。
  • prune 覆盖判定改为 base-id 归一(base#r0 随任意兄弟投影一起被覆盖)。
  • 活锚点 args 的 summary 存根化为 200 字符前缀;JSON 定位跳过 ref 标签前缀。
  • ProcessTurnInput.extraTokens:host 上报内核不可见质量,折入 usage/压力。

实测收益(真实风暴会话重放)

  • open-round:视图 ~155K → 48.8K(thinking 75.8K→0.9K,只剩开轮)
  • compress 调用 args 21.6K → 16.5K(存根化生效)
  • always(kill-switch)行为与旧版一致(差异仅为会话后续新增内容)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions