Skip to content

Protected-message exemption inflates the incompressible context floor: per-compression reasoning is never reclaimable (~83.5% of measured residual) #651

Closed

Description

@ranxianglei

参考: opencode-acp#368 (ranxianglei/opencode-acp#368) —— 同一问题,按 owner 要求在此仓库同步提交。

问题

在长会话中,compress/skill 携带的 assistant 消息上的 reasoning 部分构成一个永久不可压缩的上下文地板。

保护是消息粒度的:filterProtectedToolMessages 把整条消息——包括 reasoning——排除出所有压缩,因此这些消息每轮都被原样重发。每次压缩轮次增加约 9 KB 无法回收的 reasoning。在真实长会话中测量,这占"从未被覆盖的残留"的 ~83.5%,是一个单调递增的反馈回路,会持续恶化长会话的可用性。

机制(代码路径)

  • 保护是消息粒度:整条消息(含 reasoning)被排除出压缩选择。
  • 被排除的消息不进入 byMessageId,因此 prune 每轮都重发它们(reasoning 一并重发)。
  • compress/skill 是默认的 compress.protectedTools;compress 在 FORCE_COMPRESS_PROTECTED 中(强制追加,用户无法关闭)。
  • 真实 usage 计算包含 reasoning(input + cacheRead + cacheWrite + output + reasoning)。

影响

  • 长会话的上下文占用单调上涨,且这部分无法通过压缩回收。
  • 显示 / acp_status 的占用估算甚至不包含 reasoning,进一步掩盖了这个问题。

建议

在请求时增加一个 pass,从已关闭历史轮次的受保护豁免消息上剥离 reasoning 部分(保留当前开放轮次以兼容需要 reasoning 重放的 provider),并加 kill-switch 与大小阈值。opencode-acp 侧的修复见 PR #370。

Activity

  1. ranxianglei commented on Sep 8, 2026

    @ranxianglei
    OwnerAuthor

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 收到,已接手。正在按 opencode-acp#368 / PR #370 的思路在本仓库定位等价代码路径(acp-kernel 的 isMessageProtected / prune / reasoning 配对),确认 billion-context 侧的 reasoning 载体形态后给出修复方案。稍后回复。

  2. added 2 commits that reference this issue on Sep 9, 2026
  3. ranxianglei commented on Sep 9, 2026

    @ranxianglei
    OwnerAuthor

    Follow-up found while observing the feature live (twin of billion-context-pi #348): the closure gate "compress call followed by a genuine user message" is unreachable in long agentic sessions — the whole session has no user messages after the opening prompt, so every compress round stays active forever and its thinking is retained as a permanent floor (observed: 0 drop events; 20612 / 8411 / 10581 chars retained across three compress rounds).

    Fixed in PR #667 (commit 8471882, rebased on the docs commit): a round now closes on round evidence — the compress call's tool-result (contentType: "tool-result", matching toolCallId") exists at a later index and at least one message follows it. In-flight rounds (result missing, or result still the last message) stay untouched; the per-provider reasoning.drop=false escape hatch for round-trip-requiring thinking models (DeepSeek / GLM thinking / Qwen-QwQ) is preserved. Tests 1266/1266 green.

  4. added a commit that references this issue on Sep 9, 2026
  5. added 2 commits that reference this issue on Sep 10, 2026
  6. added a commit that references this issue on Sep 29, 2026
  7. added a commit that references this issue on Oct 1, 2026
  8. added a commit that references this issue on Oct 14, 2026
  9. added 5 commits that reference this issue on Oct 15, 2026
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