Skip to content

[Feature]: Feature request: Add a forced full-compression mode capable of overriding the content protection mechanism | [Feature]: 功能请求:增加可覆盖内容保护机制的强制全量压缩模式 #324

Open

Description

@WantexZard

Problem

目前 opencode-acp 提供了软保护和硬保护机制,可以让部分历史内容在上下文压缩时不被压缩,例如工具调用、工具返回结果等。

这些保护机制对于正常的自动压缩非常有用,但在超长对话中可能会造成一个问题:

例如,一个对话上下文约为 70 万 tokens,其中约 50 万 tokens 都是历史工具调用和工具返回结果。此时早期任务已经全部完成,用户只希望保留当前正在进行的对话阶段,而希望将此前的大量历史内容全部压缩,以释放上下文空间。

但是,由于部分历史内容受到软保护或硬保护,即使用户已经明确希望压缩这些内容,它们仍然无法被压缩。

目前缺少一种机制,让用户能够明确表示:

“我知道这些内容通常受到保护,但这一次我明确要求对这些历史内容进行压缩。”

Proposed Solution

建议增加一个“强制全量压缩”功能。

当用户明确触发该功能时,本次压缩应当临时覆盖现有的软保护、硬保护以及其他历史内容保护规则,使指定范围内的历史内容全部可以参与压缩。

应该可以覆盖:

  • 普通历史对话
  • 工具调用
  • 工具返回结果
  • 工具调用产生的中间信息
  • 其他历史上下文
  • 被软保护机制保护的内容
  • 被硬保护机制保护的内容
  • 其他原本不会参与压缩的历史内容

同时,用户应该能够指定当前正在进行的对话阶段不参与压缩。

也就是说:

正常压缩:
→ 继续遵守现有软保护和硬保护规则。

强制全量压缩:
→ 仅针对本次操作临时覆盖这些保护规则。
→ 对指定的历史范围进行最大程度压缩。
→ 当前明确排除的对话阶段保持不变。

为了保证安全,这个功能不应该静默执行,而应该要求用户明确授权。

例如:

  1. AI 请求执行强制全量压缩。
  2. ACP 弹出确认窗口。
  3. 用户明确选择“允许”后才执行。
  4. 如果 5 秒内没有响应,则自动拒绝。

这样可以保证正常的保护机制完全不受影响,同时给用户一个明确的“我知道风险,并且这次就是要强制压缩”的出口。

具体实现形式可以由项目决定,例如增加 force 参数、overrideProtection 参数,或者增加一个类似“强制全量压缩”的独立操作。

Alternatives Considered

不建议直接取消或削弱现有的软保护和硬保护机制,因为这会影响正常压缩时的安全性。

相比之下,增加一个由用户主动触发、并经过明确授权的强制压缩功能更加合适。

Additional Context

一个典型场景:

假设当前上下文约为 70 万 tokens:

  • 约 50 万 tokens 是历史工具调用和工具返回结果
  • 约 15 万 tokens 是早期普通对话
  • 约 5 万 tokens 是当前正在进行的任务

此前的任务已经全部完成,因此用户希望将当前阶段之前的所有内容全部压缩,只保留当前阶段。

用户可能会向 AI 发出类似这样的要求:

“将除当前对话阶段以外的所有早期对话内容进行全量压缩。压缩范围必须覆盖此前的全部内容,包括普通对话、工具调用、工具返回结果、工具调用产生的中间信息、上下文中的其他历史信息,以及此前被软保护或硬保护机制保护的内容。此次压缩不受任何既有软保护、硬保护或其他历史内容保护规则限制,对当前阶段之外的所有内容统一执行最大程度的压缩;当前正在进行的对话阶段及其相关内容不参与本次压缩。”

在这种情况下,希望 ACP 能够真正对这些历史内容进行全量压缩,而不会因为原有保护机制而跳过其中一部分。

这个功能本质上可以理解为:

“用户手动执行一次全量压缩,同时明确授权本次操作覆盖受保护的历史内容。”

Activity

  1. ranxianglei commented on Sep 12, 2026

    @ranxianglei
    Owner

    ework接单 评估是因为bug导致的这个请求还是真的存在

  2. ranxianglei commented on Sep 12, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    评估结论:不是 bug 导致的,保护机制按设计工作;但确实存在一个真实缺口(硬保护内容缺少 per-call override)。需求真实存在,但范围比 OP 描述的窄得多。

    验证过程(代码级)

    1. OP 的核心前提在默认配置下不成立

    • compress.protectedTools 默认值是 ["skill", "compress"](lib/config.ts:211),其中 compress 无论任何配置都强制保护(lib/config.ts:220,530)。
    • 默认配置下只有 skill/compress 的输出被硬排除在压缩范围外;普通工具调用/返回结果(bash/read/grep 等)完全可压缩。
    • 所以"50 万 tokens 历史工具调用和返回结果无法被压缩"这个前提,在默认配置下不会发生。如果真实发生过,更可能是:①自定义了 protectedTools(把大量工具加进去了);②模型没有执行压缩(模型行为问题)。这两种情况都需要配置/日志才能定性——如果是情况①②且发生在默认配置下,那是另一个 bug,请提供 acp.jsonc 配置和会话日志单独排查。

    2. 硬排除是 v1.10.0+ 的有意行为(Bug 39 修复),不是缺陷

    • 过滤链:lib/compress/range.ts:144-178 — filterProtectedToolMessages → filterLastUserMessage → filterProtectedRecentMessages,整段全是保护内容时抛硬错误 "All selected messages were filtered out..."(range.ts:176)。
    • 设计动机有迹可循:保护内容若软追加进 summary,会被 GC 截断(gc.maxOldGenSummaryLength: 3000 chars)而丢失语义权威性,所以改为硬排除、原位保留。
    • issue tracker 里搜不到同类缺陷报告(多组关键词均无命中);devlog 无先前设计;OP 场景是假设性的("例如"),无日志、无复现步骤。

    3. 真实的痛点在哪(需求存在的依据)

    • 硬排除消息永久驻留 raw context:ACP 中原始消息只会被 compress 移除,没有其他回收路径(ACP 还建议禁用 opencode 自带 compaction)。重度使用 skill/task 的超长会话里,早期加载的保护内容会无界累积——这部分痛点是真的。
    • 设计不一致:recent-message 保护区已有 dangerous: true per-call override(lib/compress/pipeline.ts:420 checkProtectedRange),但 protected tools / protectedFilePatterns / protectUserMessages 没有任何 per-call override。模型尝试压缩含保护内容的 range 时,行为是"静默跳过保护部分 + 只压缩其余",或直接抛错——从用户视角看就像"ACP 拒绝压缩了",这大概率是本请求的产生方式:设计边界摩擦,不是 bug。

    建议(如决定做)

    不建议新增独立的"强制全量压缩"操作 + 新确认窗口,复用现有机制即可,改动面最小:

    1. 扩展 dangerous: true 语义,使其同时 bypass filterProtectedToolMessages(+ protectedFilePatterns)——与 recent zone 同一模式。不放开 first/last user message 保留(结构性安全,承载当前指令)。
    2. "用户明确授权"用现有 compress.permission: "ask" 覆盖(opencode 原生确认弹窗):permission: "ask" + dangerous: true 组合后,得到的正是请求者要的流程(AI 请求 → 用户确认 → 执行)。不需要重造 opencode 权限系统,也不需要自实现 5 秒超时拒绝。
    3. "当前阶段不参与压缩"已经支持:模型选 endId 到当前阶段之前 + preserveRecentMessages/Tokens 保护区,无需新机制。
    4. 风险点(需 owner 拍板):强制压进去的保护内容会进 summary,old-gen 后可能被 GC 截断到 3000 chars——正是 Bug 39 要避免的失败模式。两个选项:(a) 接受,靠显式授权 + 文档声明风险(decompress 仍可按 tier 层级恢复原文);(b) 给这类 block 打标记豁免 GC 截断。我倾向 (a):范围最小,风险显式化。

    一句话总结

    逐路径核实了代码:该请求不是 bug 导致(硬排除是 v1.10.0 起的有意行为,且默认配置下普通工具输出本就可压缩);真实缺口是硬保护内容缺少 per-call override,建议实现方向为扩展 dangerous: true 覆盖面 + 复用 permission: "ask" 授权流,是否开工及风险取舍 (a)/(b) 由 owner 拍板。

  3. changed the title [-][Feature]: 功能请求:增加可覆盖内容保护机制的强制全量压缩模式[/-] [+][Feature]: Feature request: Add a forced full-compression mode capable of overriding the content protection mechanism | [Feature]: 功能请求:增加可覆盖内容保护机制的强制全量压缩模式[/+] on Oct 16, 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

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions