Skip to content

长会话范围压缩产生'缝隙残留'孤儿消息,建议孤儿回收/碎片整理机制 #355

Description

@cycle2zhou

问题背景

在一个超长 agent 会话(120K+ context,多次范围压缩)中观察到:compressible ranges 累积了 55 条"缝隙残留"消息,每条 146B~6K,合计约 60K context,且无法被自动清理。

成因分析

范围压缩(startId~endId)在多次执行后,范围边界之间的消息成为"孤儿":

  1. 单条 < minCompressRange(3000 字符)的消息,compress 工具拒绝单独压缩;
  2. 孤儿消息没有 block 覆盖,不会进入 tier 蒸馏(T1→T2→T3)的折叠范围;
  3. nudge 会持续把它们列为 compressible,但 agent 压掉 146B 的消息要花 ~100B 摘要,边际收益为负——于是永远留在缝隙里。

这是结构性必然:任何长会话只要用范围压缩,就会产生此类缝隙。

建议(按优先级)

1. 孤儿消息自动回收(Orphan sweep)— 根治缝隙残留

将 compressible 但无 block 覆盖且 < minCompressRange 的孤立消息自动并入最近邻 block 的摘要(作为补充行),而不是永远留在缝隙。或提供一次性的"碎片整理":允许把 N 条不连续的微残留归并成 1 个 block。

2. nudge/提示消息自身成为残留

每次压缩 nudge 注入的提示文本(约 150B,如"⚠️ Compressible ranges available...")会留在缝隙里,成为上述孤儿的主要来源之一。建议:nudge 消息标记为"可回收微块"(不参与保留窗口、可静默丢弃),或纳入已有的 messageFilters 体系。

3. minCompressRange 单位与文档

schema 定义其为 characters(3000 chars ≈ 750 tokens),但相邻配置(preserveRecentTokensnudgeGrowthTokens)是 token,agent 极易误判阈值量级。建议统一为 token 或至少在配置注释/schema 描述中显著标注单位。

4. (低优先级)compress 支持"不连续片段一次成块"

允许一次调用把多个不相邻的 [start,end] 片段合并为单个 block,降低碎片整理的操作成本(当前每个 entry 必须连续)。

环境

  • opencode-acp 版本:@latest(2026-09 使用)
  • 复现场景:Sisyphus 风格 agent(大量 rmux/bash 工具输出 + 手动 compress + 长会话)

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