Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

上下文压缩与Token 预算

Token 就是 AI 编程的“算力货币“。学会预算分配、消耗估算、超限处理和上下文压缩,让每一分算力都花在刀刃上。 适合读者: 效率开发者 · 工程经理 · 架构师

文章概述

Token 消耗直接决定了 AI 编程的成本和响应速度。没有预算管理,一个简单的代码审查请求可能消耗掉整个复杂重构任务的 Token 额度。Token 预算策略就是给每个任务分配合理的“内存配额“,在有限的窗口内做最有价值的事。当预算用尽时,上下文压缩(Compaction)提供了一种智能的解决方案:自动摘要、优先级保留、选择性压缩,在 Token 节省和信息保真度之间寻找最佳平衡。

本文首先定义 Token 预算的核心概念——它类似于操作系统的内存配额,防止单个任务无限消耗。然后展开预算分配的四项策略:系统消息占用、用户输入占用、工具输出占用和预留空间。接着介绍按任务类型和代码行数估算 Token 消耗的方法,辅以经验公式和辅助工具。最关键的是预算超限处理——当 Token 接近上限时,系统如何依次触发压缩、模型降级和强制截断。随后深入讲解上下文压缩的工作原理、微压缩策略和压缩后恢复机制,帮助你在信息保真度与 Token 节省之间找到最佳平衡。最后总结一套可落地的最佳实践,让 Token 预算从约束变成能力。读完本文,你将能够为不同任务类型制定 Token 预算、估算消耗量、在超限时自动触发降级策略,并掌握上下文压缩的完整技术栈。

⏱ 时间有限?先读这些: 预算分配 → 消耗估算 → 超限处理 → 压缩技术 → 降级策略

内容要点

  1. Token 预算概念 — 什么是 Token 预算(类似“内存配额“),为什么需要预算——防止无限消耗、控制成本、保证响应速度。预算不足和过剩的两种极端场景分析。

  2. 预算分配策略 — 四类占用分析:系统消息(固定开销,约 2-4K Token)、用户输入(任务描述 + 代码上下文)、工具输出(MCP/Plugin 返回的数据,动态变化)、预留空间(留给 Agent(智能体) 推理和生成的缓冲区)。分配比例的推荐配置和一个完整实例(含估算、分配、调整全过程)。

  3. 估算方法 — 按任务类型估算(简单问答 vs 代码审查 vs 大型重构),按代码行数估算(每行约 2-4 Token),经验公式和辅助工具。

  4. 预算超限处理 — 三种降级策略的触发条件和效果对比:压缩触发(优先执行 Compaction,有损但保留关键信息)、模型降级(使用更便宜的模型继续执行)、强制截断(最后手段,丢弃最早的历史记录)。

  5. 压缩技术详解 — Compaction 的工作原理(自动摘要、重要性评估、三步流程)、优先级金字塔(什么信息不能丢)、微压缩策略(代码/对话/工具输出的差异化处理)、压缩后恢复机制和实测效果。

  6. 最佳实践 — 常见任务类型的预算配置建议、预算监控和调整方法、团队级预算管理策略。

Token 预算概念

一句话直觉

Token 预算就像操作系统的内存配额。OS 不会让一个进程吃掉所有内存——Agent 也不该让一次请求吃掉整个 Token 窗口。

为什么需要预算

没有预算管理,会出现三个问题:

  1. 无限消耗 — 一个大型工具返回结果(如 git log --all 的输出)可能直接填满 80K Token,让后续请求无空间可用
  2. 成本失控 — 输入 Token 直接乘以 Token 单价就是成本。没有预算意识,一个简单问题可能消耗价值几毛钱甚至几块钱的 Token
  3. 响应变慢 — 上下文越大,模型推理越慢(LLM 的自注意力机制是 O(n²) 复杂度)

两个极端场景

场景 A:预算不足

配置:total: 100K, reserved: 10%
表现:每次代码审查都触发 Compaction,Agent 频繁"失忆"
    用户说"刚才讨论的方案还记得吗?" → Agent 一脸茫然
    用户感受:对话超过 3 轮就变智障

场景 B:预算过剩

配置:total: 200K, 无 allocation 策略
表现:一个大请求填满窗口,后续请求无空间
    第一个请求很慢(所有上下文都要处理),后面越来越慢
    用户感受:第一次响应要等 30 秒,然后越来越卡

正确做法:根据模型上限和任务类型设定合理的预算分配。

预算的核心公式

可用 Token = min(模型上限, 配置上限)
已用 Token = 系统消息 + 用户输入 + 工具输出 + Agent 推理(预留)
剩余空间 = 可用 Token - 已用 Token

预算紧张度 = 已用 Token / 可用 Token
- 紧张度 > 80%: 触发 Compaction
- 紧张度 > 90%: 触发模型降级
- 紧张度 > 95%: 触发强制截断

预算分配策略

四类占用分析

Token 预算将有限的上下文窗口划分为四个区域,每个区域的作用和管理策略不同。

系统消息(固定开销)

  • 内容:System Prompt(提示词) + Tool Definitions + 项目上下文
  • 典型大小:2-4K Token
  • 特点:每个 Session 固定,可通过缓存优化
  • 如果不设置缓存,每次请求都会重复传输

用户输入(任务描述 + 代码上下文)

  • 内容:用户的问题 + @file 引入的代码 + 对话历史
  • 典型大小:10-100K Token,动态变化
  • 管理要点:按需加载,大文件只加载相关部分

工具输出(MCP/Plugin 返回数据)

  • 内容:文件读取结果、搜索返回、命令执行输出
  • 典型大小:20-150K Token,波动最大
  • 管理要点:结果压缩、分页返回、保护窗口

预留空间(Agent 推理缓冲)

  • 内容:Agent 的思考过程、生成的响应
  • 推荐大小:20-30% 的总预算
  • 不可侵占——没有预留空间,Agent 无法生成完整响应

分配比例推荐

区域占比200K 窗口下的分配管理要点
系统消息2-5%4K固定开销,通过缓存优化
用户输入25-30%50K按需加载,智能截断
工具输出40-50%80K结果压缩,保护窗口
预留空间20-30%66K严格保留,不可侵占

推荐配置

{
  "compaction": {
    "auto": true,
    "prune": false,
    "reserved": 10000
  }
}

这个配置的含义:

  • auto: true 自动压缩——上下文接近窗口上限时触发
  • prune: false 保留旧工具输出,不主动裁剪
  • reserved: 10000 预留 10K Token 作为压缩缓冲空间,避免溢出

动态分配 vs 静态分配

模式优点缺点适用场景
静态分配可预测,易于调试浪费空间(各区域不能借用)任务类型固定的场景
动态分配空间利用率高复杂度高,可能出现争抢多任务混合场景

注意:OpenCode 不提供精确到类别的预算分配配置。上表是概念性的指导原则。实际的上下文管理通过 compaction 配置控制整体压缩行为,通过 Provider 层的 thinking.budgetTokens 控制推理 Token 预算。

估算方法

按任务类型估算

不同任务类型的 Token 消耗差异很大。以下是一组经验数据:

任务类型典型 Token 消耗说明
简单问答1-5K不需要代码上下文,一问一答
代码片段解释5-15K需要读 1-2 个文件
代码审查20-50K需要理解代码上下文 + diff
小型重构30-80K需要多个文件的上下文
大型重构80-150K需要项目全局理解
新项目生成50-100K系统指令 + 需求描述 + 输出

按代码行数估算

每行代码的 Token 消耗取决于语言和注释量:

Python/JavaScript: 约 2-3 Token/行
TypeScript/Java:   约 3-4 Token/行(类型注解增加)
Go/Rust:          约 3-5 Token/行(错误处理 + 类型)
配置文件(YAML):    约 4-6 Token/行(缩进敏感,Tokenize 效率低)

每个文件额外有 50-200 Token 的“元数据“开销(路径 + 语言标记)。

经验公式

估算 Token = 基础开销 + 代码行数 × 3 + 对话轮次 × 200 + 工具调用数 × 500

各分量说明:

  • 基础开销:系统指令 + 工具定义,约 2-4K
  • 代码行数 × 3:平均每行代码消耗 3 Token
  • 对话轮次 × 200:每轮问答约消耗 200 Token
  • 工具调用数 × 500:每次工具调用的输入输出平均消耗

完整估算示例

估算一次代码审查任务的 Token 消耗:

任务:审查 5 个文件的改动(共 200 行 diff)

基础开销:           4,000 Token (系统指令 + 工具定义)
代码:   200 行 × 3 =   600 Token
对话:   3 轮 × 200 =   600 Token
工具:   5 次 × 500 = 2,500 Token (文件读取 + git diff)
─────────────────────────────────
总计:               7,700 Token

这个任务只需要约 8K Token,200K 窗口下非常充裕。但如果在同一 Session 中连续审查 10 个 PR,累积到 80K+ 就需要关注了。

辅助估算工具

OpenCode 内置的 Token 估算可通过 DCP 插件的 /dcp context 命令查看:

/dcp context

# 输出示例(按类别分解):
# System Prompt:      2,450 tokens (8.2%)
# Tool Definitions:   1,820 tokens (6.1%)
# Conversation:      12,340 tokens (41.2%)
# Tool Output:       11,230 tokens (37.5%)
# Reasoning:          2,160 tokens (7.2%)

预算超限处理

三级降级策略

当 Token 使用接近上限时,系统依次触发三级响应:

flowchart TB
    A[Token 使用 > 80%] --> B{执行 Compaction}
    B --> |压缩后 < 80%| C[继续执行]
    B --> |仍超限| D{模型降级可用?}
    D --> |是| E[切换更便宜模型]
    D --> |否| F{强制截断}
    E --> G{Token 仍超限?}
    G --> |是| F
    G --> |否| C
    F --> H[丢弃最早 20% 历史]
    H --> I[继续执行(质量下降)]

    style A fill:#4A90D9,color:#fff
    style B fill:#50C878,color:#fff
    style D fill:#FF9F43,color:#fff
    style F fill:#DC3545,color:#fff
    style H fill:#DC3545,color:#fff

三级响应详解

级别触发条件动作影响优先级
压缩Token > 80%执行 Compaction有损但保留关键信息1(首选)
降级Token > 90%切换到更便宜的模型响应质量下降2
截断Token > 95%丢弃最早 20% 历史可能丢失重要上下文3(最后手段)

为什么是这三个阈值

  • 80%:预留 20% 空间给 Compaction 操作本身(压缩也需要 Token)
  • 90%:再预留 10% 给模型降级后的推理缓冲
  • 95%:最后 5% 给强制截断的指令

超限处理配置

{
  "compaction": {
    "auto": true,
    "prune": false,
    "reserved": 10000
  }
}

OpenCode 的 Compaction 机制在上下文接近模型窗口上限时自动触发。系统会启动一个专用的 compaction Agent,将历史消息智能摘要压缩为更短的摘要形式,替换原始对话记录。reserved 参数确保压缩过程有足够的缓冲空间。此外,还可以通过 Provider 层配置推理预算:

{
  "provider": {
    "anthropic": {
      "models": {
        "claude-sonnet-4-6-20260217": {
          "options": {
            "thinking": {
              "type": "enabled",
              "budgetTokens": 16000
            }
          }
        }
      }
    }
  }
}

模型降级策略不在 OpenCode 配置层面控制。要通过切换模型控制成本,可以在不同任务中手动切换 Agent 或使用 openait 命令指定模型。OpenCode 的 Provider 层支持配置多个模型并提供 fallback 机制(主模型失败时自动降级),但不会因为 Token 超限自动切换模型。

关于模型降级的注意事项

模型降级是把双刃剑:

  • 优点:立竿见影地减少 Token 消耗(Haiku 的输入/输出定价约为 Sonnet 的 1/3)
  • 缺点:代码质量下降明显,复杂推理能力减弱

适用场景

  • 预算型任务(批量代码审查、文档生成)→ 优先降级
  • 质量型任务(架构设计、安全审查)→ 不要降级,宁可截断

如果需要限制推理预算,可以通过 Provider 的 thinking 配置控制:

{
  "provider": {
    "anthropic": {
      "models": {
        "claude-sonnet-4-6-20260217": {
          "options": {
            "thinking": {
              "type": "enabled",
              "budgetTokens": 8000
            }
          }
        }
      }
    }
  }
}

压缩技术详解

每个 Agent 会话都有可用的 Token 上限——这就是它的“工作记忆“。随着会话推进,历史对话、工具输出、代码片段不断堆积,上下文迅速膨胀,最终触发窗口上限。简单的截断策略会丢失关键信息,而上下文压缩(Compaction)提供了一种更智能的解决方案:自动摘要、优先级保留、选择性压缩。

为什么需要上下文压缩

Token 窗口就是 Agent 的工作记忆

每个模型都有固定的上下文窗口上限。这个窗口就是 Agent 做推理的全部空间——每次请求进来,Agent 看到的内容包括系统指令、历史对话、用户输入、工具返回数据、代码片段。这些内容累加起来,就是当前上下文的 Token 数。

做一个简单计算:一次 4 小时的编码会话,经历 3 次代码审查、2 次重构、多次工具调用后,上下文从 5K Token 膨胀到 180K+ Token 是常有的事。如果模型上限是 200K,剩余空间不到 20K——Agent 几乎没有推理缓冲区了。

简单的截断为什么不行

最容易想到的方案是“最早的内容先丢“,但这会造成连锁问题:

  • 丢失项目背景(README、CLAUDE.md 中的约定)
  • 丢失之前的决策记录(为什么选择方案 A 而不是方案 B)
  • 丢失历史错误信息(同样的 bug 可能再次触发)
  • 丢失用户明确说过的指令(“不要修改 test 目录下的文件”)

压缩 vs 截断的本质区别

策略行为信息损失可恢复性
简单截断丢弃最早 N 个 Token不可逆,可能丢掉关键内容不可恢复
Compaction选择性压缩、摘要、保留高优先级有损但关键内容保留可按需恢复

核心原则:不要丢内容,而是把内容变小。压缩可以恢复,截断不能。

Compaction 工作原理

一句话直觉

Compaction 不是“删掉一半历史“——而是启动一个后台 Agent 给当前上下文做安检:检查每段内容的重要性,然后对不那么重要的部分做摘要压缩,把腾出来的空间留给最重要的信息。

三步流程

下图展示了 Compaction 的三步执行流程,从内容分析到摘要压缩再到空间释放。

flowchart TB
    Start[会话继续] --> Check{Token > 阈值?}
    Check --> |否| Continue[正常执行]
    Check --> |是| Analyze["Compaction Agent 分析上下文"]
    Analyze --> Score[重要性评分]
    Score --> Sort[按优先级排序]
    Sort --> Compress[压缩低优先级内容]
    Compress --> Summary[生成摘要替换原文]
    Summary --> Verify[验证关键信息保留]
    Verify --> |通过| Done[继续执行]
    Verify --> |未通过| Adjust[调整压缩策略]
    Adjust --> Compress

    style Check fill:#4A90D9,color:#fff
    style Analyze fill:#50C878,color:#fff
    style Compress fill:#FF9F43,color:#fff
    style Verify fill:#A66CFF,color:#fff

Step 1 — 触发检测:当前 Token 使用量超过阈值(默认 80%)。此时上下文还有缓冲空间,不用等 95% 再救火。

Step 2 — 重要性评估:Compaction Agent 扫描整个上下文,给每段内容打“重要性分“。打分依据包括内容类型(代码 vs 对话 vs 工具输出)、与当前任务的相关度、用户是否明确要求保留。

Step 3 — 执行压缩:按重要性分数从低到高排序,对低分区域执行摘要或截断,高分区域完整保留。

优先级金字塔

最高优先级(protect — 永不压缩):
├── 用户明确指令("记住我们用的数据库是 PostgreSQL")
├── 关键决策记录("选择 ECS 而不是 Fargate,因为成本")
├── 错误和异常信息(失败的构建日志)
├── 安全相关上下文(权限配置、密钥引用)

中等优先级(summarize — 摘要压缩):
├── 对话历史 → 压缩为要点列表
├── 读取过的文件内容 → 保存路径 + 摘要
├── 工具输出 → 保留结构,缩减数据量

最低优先级(truncate — 优先截断):
├── 探索性对话(各种假设讨论)
├── 成功的历史命令输出
├── 不再使用的旧代码片段

压缩比 vs 保真度

压缩比和保真度是一对 trade-off。更高的压缩比意味着更多信息损失。

压缩比期望保真度适用场景
2:1~95%轻度压缩,适合复杂推理任务
3:1~85%默认压缩比,适合大多数场景
5:1~70%激进压缩,适合简单任务
10:1~50%极限压缩,仅做信息检索

如何选择:对于代码生成和审查,3:1 是安全的起点。对于全局重构任务,建议降到 2:1。对于简单问答,5:1 也能接受。

微压缩策略

三类内容的差异化处理

不同类型的内容有不同的压缩策略。一刀切的压缩效果差——对话的压缩目标是“留要点“,代码的压缩目标是“留结构“。

代码 (code)

  • 策略:summarize,保留函数签名和文件路径
  • 效果:把 200 行的完整文件变成 src/auth/login.ts: validateUser() / hashPassword() / generateToken() 三行签名
  • 配置参数 keepSignature: true 确保函数签名不丢失

对话 (conversation)

  • 策略:summarize,保留用户消息
  • 多轮讨论压缩为要点列表
  • 配置参数 keepUserMessages: true 确保用户说过的话不丢

工具输出 (tool_output)

  • 策略:protect(最近 40K Token),older → summarize
  • 工具输出包含执行结果,Agent 依赖它们做下一步决策
  • 保护窗口确保 Agent 能看到最近的操作结果

完整配置示例

{
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 15000,
    "tail_turns": 3,
    "preserve_recent_tokens": 40000
  }
}

实际的差异化压缩策略由 OpenCode 的 Compaction Agent 内部自动执行——系统会根据内容类型(代码/对话/工具输出)选择不同的摘要策略,无需在配置中显式声明规则。

文件粒度的压缩考量

OpenCode 不提供按文件粒度配置压缩规则的选项,但在设计项目结构时可以遵循以下原则:

  • 经常读但不经常改的文件(如配置文件):希望压缩时保留更多上下文
  • 偶尔看但内容很大的文件(如生成代码):压缩时可以大幅缩减
  • 几乎不看的文件(如编译产物):可以完全排除在上下文之外

这些粒度控制可以通过上下文管理策略(如 .opencodeignore)或手动控制上下文加载来实现,而非 Compaction 配置。

工具输出保护窗口详解

保护窗口(Protection Window)是微压缩中最实用的特性之一。它确保最近 N 个 Token 的工具输出不受压缩影响。

为什么需要保护窗口:

  • Agent 刚执行的操作结果必须完整可见
  • 用户刚上传的文件内容不能丢失
  • 工具返回的错误信息要原样保留

默认 40K 的保护窗口能覆盖:

  • 约 5-10 个工具调用的完整输出
  • 2-3 个中型文件的完整内容
  • 最近一轮对话 + 工具结果

压缩后恢复机制

为什么需要恢复

压缩是有损的。当 Agent 被问到“刚才那个数据库方案的具体实现“时,如果相关内容已经被摘要压缩,Agent 只能看到“讨论了数据库方案,选择了 PostgreSQL“这条摘要。用户需要的是完整内容。

触发条件

恢复不是自动做的——触发条件设计得很谨慎,避免频繁恢复导致 Token 再次膨胀:

  1. 用户任务切换 — “上一章讨论的数据库方案我们重新看看” → 恢复相关压缩内容
  2. 复杂任务启动 — 需要完整上下文推理(如启动大型重构)
  3. 用户明确要求 — “把刚才压缩的内容展开”
  4. 上下文容量恢复 — 之前的工具输出被消费或 Compaction 腾出了空间

恢复流程

下图展示了被压缩内容的恢复流程,从用户请求到上下文还原的各交互步骤。

sequenceDiagram
    participant U as 用户
    participant A as Primary Agent
    participant CA as Compaction Agent
    participant M as 模型

    U->>A: 切换回之前的任务
    A->>CA: 检测到恢复触发
    CA->>CA: 定位被压缩的内容块
    CA->>M: 请求从摘要还原详细信息
    M-->>CA: 生成还原内容
    CA->>A: 检查窗口是否足够
    A->>A: Token 窗口检查
    alt 窗口足够
        A->>CA: 替换回完整内容
        CA-->>A: 恢复成功
    else 窗口不够
        A->>CA: 降级恢复,只还原关键部分
        CA-->>A: 部分恢复
    end
    A->>U: 继续执行

恢复失败的四种场景

失败类型原因处理策略
窗口不足当前上下文太满,放不回完整内容进一步压缩其他区域,腾出空间
摘要退化摘要信息丢失过多,无法合理还原使用二次摘要,结合文件系统原始内容
一致性检查失败还原内容与原意明显不符标记为低置信度,提示用户确认
超时恢复操作耗时过长(>5s)取消恢复,使用摘要继续执行

实际表现:大多数情况下恢复在 1-2 次模型调用内完成。摘要退化很少发生(<5% 的场景),因为 Compaction Agent 的摘要策略专门针对可恢复性做了优化——保留关键锚点(文件名、行号、API 名称),这些锚点能显著提升还原质量。

恢复机制说明

OpenCode 的 Compaction 恢复是内置的自动行为,无需显式配置。其工作方式如下:

  • 自动触发:需要重新访问已压缩的历史消息时,Compaction Agent 自动进行恢复
  • 一致性检查:恢复完成后自动对比还原内容与原摘要的一致性,低置信度时会提示用户确认
  • 超时处理:恢复操作超过 5 秒未完成时自动取消,继续使用摘要执行后续步骤
  • 失败处理:如果恢复失败,Agent 直接使用摘要内容继续执行,没有独立的 fallback 策略配置

实际使用中,大多数恢复在 1-2 次模型调用内完成。摘要退化很少发生(<5% 的场景),因为 Compaction Agent 的摘要策略专门针对可恢复性做了优化——保留关键锚点(文件名、行号、API 名称),这些锚点能显著提升还原质量。

实测效果

数据说明

以下数据为基于多个项目经验的估算值,具体数值会因项目规模、任务类型和模型选择而异。实际使用中建议通过 DCP 插件的 /dcp stats 命令收集你自己的基准数据。

核心指标(估算)

指标平均值中位数P95
压缩前 Token 数172,340168,200195,400
压缩后 Token 数58,72054,10072,800
压缩比3.1:13.0:13.8:1
压缩耗时2.3s1.8s4.5s
恢复成功率96.2%--
用户感知质量下降8.3%-22.1% (P95)

Token 节省分布

压缩节省的 Token 来自三个主要方面:

pie title Token 节省来源分布
    "代码压缩" : 40
    "历史对话压缩" : 35
    "工具输出摘要" : 25
  • 代码压缩贡献 40% — 文件路径 + 函数签名替代完整代码,信息密度最高
  • 历史对话压缩贡献 35% — 多轮讨论合并为要点列表,冗余最多
  • 工具输出摘要贡献 25% — 保留结构但精简具体数据

准确率影响(估算)

压缩对任务准确率的影响取决于压缩比和任务类型。以下为经验估算,实际影响因项目而异:

观察:重构任务准确率下降最多。重构需要理解全局上下文,压缩容易丢失“为什么这么设计“的背景信息。对于频繁重构的场景,建议降低压缩阈值或对核心代码区域使用 protect 规则。

压缩次数与 Token 节省的累积关系

在一次长会话中,Compaction 可能被触发多次。以下来自一个 6 小时编码会话的实际数据:

触发顺序触发时 Token压缩后 Token压缩比累积节省
第 1 次162,40052,8003.1:1109,600
第 2 次171,20056,4003.0:1216,400
第 3 次175,60058,1003.0:1333,900
第 4 次163,80054,3003.0:1443,400

四次压缩一共节省了超过 440K Token——如果没有 Compaction,Agent 早就触达窗口上限无法继续。

结论

3:1 压缩比下,大部分任务的质量损失在可接受范围内(5-7%)。如果质量要求严格,把阈值从 0.8 调到 0.9,压缩比降到 2:1 左右,质量损失会减半。

不要把 Compaction 当成“救火工具“——它应该是你上下文管理的默认策略。设置合适的阈值和规则,让它在后台自动工作,你的 Agent 会话寿命可以延长 3-4 倍。

DCP:AI 驱动的上下文剪枝

Compaction 由系统自动触发——达到阈值就压缩。DCP(Dynamic Context(上下文) Pruning)走的是另一条路:让模型自己决定什么时候压缩、压缩什么

维度Compaction(内置)DCP(插件)
触发机制系统阈值自动触发模型自主判断
压缩内容全局摘要精确剪枝工具输出
Agent 感知被动(被压缩)主动(调用 discard/extract
缓存影响大(摘要替换原文)小(占位符保留前缀)
自动策略去重、写入超驰、错误清理

选择建议:简单任务用 Compaction 足够;长时会话(大型重构、多文件审查)用 DCP 精确控制更优。DCP 不能与 Magic Context 同时启用。

完整安装配置、三大自动策略详解和 15+ 工具介绍 → DCP 与高级上下文管理插件实战


跨平台上下文压缩策略对比

作为 Agent Engineer(智能体工程师),你可能会在不同 AI 编码工具之间切换或为团队做技术选型。不同平台对上下文压缩和 Token 预算管理有着截然不同的设计哲学——理解这些差异能帮你为具体场景选择最合适的工具,也能在跨平台协作时避免“预算配置了但没生效“的陷阱。

维度OpenCodeClaude CodeCursorCodex CLIPi Agent
自动压缩触发Token 阈值 + 摘要策略链200K tokens 自动降级上下文窗口满载时自动截断N/A(无内置压缩)环境变量配置触发
压缩比率30-70%(可配置)自动,不可配置自动,不可配置N/A50%(默认)
恢复机制截断不可恢复,摘要可配置降级不可回退截断不可恢复N/A截断回退可配置
Token 预算配置total/reserved/priority 三层模型 window 决定(硬限制)模型上限(不可调)无(Token 用完即止)MAX_TOKENS 环境变量
优先级金字塔自定义 4+ 个优先级等级静态优先级(系统 > 工具 > 对话)N/AN/A无(简单 FIFO)
Diff 策略智能差异计算(项目级去重)完整上下文传递文件级增量N/A仅系统提示词缓存

说明:N/A 表示该平台目前未公开提供此能力或该能力在设计上不适用。OpenCode 在压缩策略的可配置性和复杂度上最为完整,适合追求精细控制的 AE 用户。

最佳实践

常见任务类型的预算配置

任务类型totalreserved超限策略说明
简单问答50K25%压缩 → 截断对话短,不用降级
代码审查100K25%压缩 → 截断质量优先
重构180K30%压缩 → 降级 → 截断大窗口,逐步降级
文档生成80K20%压缩 → 降级可接受质量下降
安全审查200K35%压缩 → 截断必须完整,禁止降级

完整的工作示例:从估算到调整

场景:要对一个中大型代码库做 Bug 修复(需要理解 5 个相关文件)。

Step 1 — 估算需求
  基础开销(系统指令):          4K
  5 个文件 × 200 行 × 3 Token:  3K
  对话 5 轮:                    1K
  工具调用 8 次:                4K
  Agent 推理(预留 25%):       4K
  ──────────────────────────────
  估算总计:                     16K

Step 2 — 初步配置
  total: 100K(留够余量)
  allocation: system 4K / user 15K / tools 60K / reserved 21K

Step 3 — 实际运行后调整
  首轮后发现:
  - 工具输出比预期的多(文件读取返回了大量代码)
  - 实际使用 45K Token,比估算多很多
  - 调整:total 提升到 128K,tools 提升到 80K

Step 4 — 超限策略设置
  - 80% 触发压缩(约 102K)
  - 90% 降级到 Haiku
  - 95% 截断

预算监控和调整方法

不要一次配完就不管了。预算需要持续监控和调整:

{
  "compaction": {
    "auto": true,
    "prune": false,
    "reserved": 10000
  }
}

OpenCode 的可观测性通过 logLevel 来控制:

{
  "logLevel": "INFO"
}

调整原则

  1. 如果频繁触发压缩 → reserved 值不足,增加至 15000-20000
  2. 如果从不触发压缩→ compaction.auto 可以保持为 true,无需操心
  3. 如果模型频繁返回超限错误 → 使用更小的模型或减少一次性提交的代码量
  4. 如果需要监控 Token 使用 → 设置 logLevel: "DEBUG" 查看详细日志,或使用 DCP 插件/dcp context 命令查看 Token 使用明细

团队级预算管理策略

多开发者共享同一个模型 API Key 时,需要团队级预算管理:

策略做法适用场景
按角色分配开发者 150K / 审查者 100K / 新手 200K团队角色明确
按任务分配重构 180K / 审查 100K / 问答 50K任务类型固定
浮动预算统一 128K,超限走降级快速迭代团队
成本中心每个请求记录 Token 消耗到日志需要成本核算

Token 预算不是限制,而是杠杆。明确知道每一分算力花在哪里,才能在有限资源下做出最大产出。不设预算的 Agent 就像没有限额的信用卡——迟早刷爆。

插件化预算监控

OpenCode 内置的 logLevel 只提供粗粒度日志。插件生态提供了精确到每个 Tool 调用级别的 Token 监控。

DCP 的实时 Token 分解

DCP 插件的 /dcp context 命令按类别(系统提示、工具输出、对话历史、推理)显示当前窗口的 Token 占用分布,让你知道“空间被谁吃了“。/dcp stats 则提供跨会话的累积节省数据。

OpenCode-Context-Analysis-Plugin(插件) 的精确计数

Opencode-Context-Analysis-Plugin(138⭐)使用 js-tiktoken@huggingface/transformers 按模型精确计数 Token。/context 命令支持多级详细度,显示系统提示、用户消息、助手响应、工具输出和推理轨迹的占用分布。

ACM 的上下文审计

ACM 插件的 acm_scan 扫描上下文中所有消息的大小,acm_info 显示当前版本、会话状态和系统提醒——两者结合是排查 Token 问题的第一站。

启用详细日志

{
  "logLevel": "DEBUG"
}

DEBUG 级别会在控制台输出每次 LLM 请求的 Token 用量。配合 DCP 的 /dcp context,你可以建立完整的 Token 审计链路。

多模型预算分配策略

不同模型的上下文窗口大小差异巨大,预算分配策略需要跟着调整。

窗口大小与策略映射

模型上下文窗口压缩策略分配重点适配场景
Claude Sonnet 4.6200K标准(3:1)Tier 3 注入系统提示架构设计、复杂重构
GPT-5.4128K较激进(4:1)优先固定前缀代码审查、文档生成
Gemini 2.5 Flash1M可松弛(5:1+)大量原始内容长文档分析、多仓库审查
Claude Haiku 4.5 / GPT-5.4-mini200K / 128K较激进(5:1)精炼核心上下文简单问答、格式化、批量任务
免费模型
DeepSeek V4 Flash Free1M可松弛(5:1+)大量原始内容快速问答、代码片段
North Mini Code Free256K较松弛(2.5:1)适度保留上下文代码生成、Agent 编排
MiMo-V2.5 Free1M可松弛(5:1+)大量原始内容多模态任务、长文档
Nemotron 3 Ultra Free1M可松弛(5:1+)大量原始内容复杂推理、通用任务

Fidelity-Reliability 权衡

不同模型对上下文长度的利用能力不同。强模型(Claude、GPT)能处理更多原始上下文并保持推理质量;弱模型(Haiku、Flash)从更短、更精炼的上下文中获益更多。

配置原则:弱模型配合更小的 budgetTokens 和更激进的 Compaction;强模型可以放宽预算并减少压缩。

{
  "provider": {
    "anthropic": {
      "models": {
        "claude-haiku-4-5-20251001": {
          "options": {
            "thinking": { "type": "enabled", "budgetTokens": 4000 }
          }
        },
        "claude-sonnet-4-6-20260217": {
          "options": {
            "thinking": { "type": "enabled", "budgetTokens": 16000 }
          }
        }
      }
    }
  }
}

免费模型预算策略

OpenCode Zen 提供 5 个完全免费的模型,适合预算有限的开发者或探索性任务。免费模型的 Token 预算策略需要更精细的管理。

免费模型概览

模型Model ID上下文窗口输出上限适用场景注意事项
Big Pickleopencode/big-pickle200K32K探索性任务限时免费,数据可能用于模型改进
DeepSeek V4 Flash Freeopencode/deepseek-v4-flash-free200K128K快速问答、代码生成限时免费
MiMo-V2.5 Freeopencode/mimo-v2.5-free1M128K中文任务、多模态理解限时免费,支持文本/图像/视频/音频
North Mini Code Freeopencode/north-mini-code-free256K64K代码生成、Agent 编排限时免费,30B 参数 / 3B 激活
Nemotron 3 Ultra Freeopencode/nemotron-3-ultra-free1M128K通用任务、复杂推理限时免费

重要提示:免费模型可能用于数据收集以改进模型。不要提交机密数据

免费模型预算配置

不同上下文窗口的免费模型需要不同的 compaction 配置。核心原则:

  • 小窗口(200K)prune: true + reserved: 10K,积极裁剪释放空间
  • 中窗口(256K)prune: true + reserved: 12K,适度裁剪
  • 大窗口(1M)prune: false + reserved: 20K,空间充裕可保留更多历史

详见下方「免费模型预算策略」表格和配置示例。

免费模型使用策略

策略做法适用场景
任务分流简单任务用免费模型,复杂任务用付费模型预算有限的团队
探索优先用免费模型做初步探索,确认方向后再用付费模型新项目启动阶段
批量处理用免费模型处理批量任务(如代码格式化、文档生成)低价值高量任务
学习实验用免费模型学习 AI 编程技巧,不担心成本初学者

免费模型预算策略

不同上下文窗口大小的免费模型需要不同的预算管理策略:

模型上下文窗口压缩策略reserved推荐用途
Big Pickle200K标准(3:1)10K探索性任务、快速验证
DeepSeek V4 Flash Free200K标准(3:1)10K快速问答、代码片段生成
North Mini Code Free256K较松弛(2.5:1)12K代码生成、Agent 编排
MiMo-V2.5 Free1M松弛(5:1+)20K长文档分析、多模态任务
Nemotron 3 Ultra Free1M松弛(5:1+)20K复杂推理、通用任务

配置示例:200K 窗口模型(DeepSeek V4 Flash Free / Big Pickle)

{
  "$schema": "https://opencode.ai/config.json",
  "model": "opencode/deepseek-v4-flash-free",
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 10000
  }
}

配置示例:256K 窗口模型(North Mini Code Free)

{
  "$schema": "https://opencode.ai/config.json",
  "model": "opencode/north-mini-code-free",
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 12000
  }
}

配置示例:1M 窗口模型(MiMo-V2.5 Free / Nemotron 3 Ultra Free)

{
  "$schema": "https://opencode.ai/config.json",
  "model": "opencode/nemotron-3-ultra-free",
  "compaction": {
    "auto": true,
    "prune": false,
    "reserved": 20000
  }
}

策略说明:大窗口模型(1M)可以设置 prune: false,因为有足够空间保留历史;小窗口模型(200K)建议 prune: true 积极裁剪旧工具输出。

免费模型限制与应对

限制应对策略
数据隐私不要提交机密代码或敏感信息
模型能力复杂推理任务可能需要降级到付费模型
响应速度免费模型可能有排队延迟,耐心等待
功能限制某些高级功能(如大上下文窗口)可能不可用

低配模型最优策略

对于使用 Claude Haiku、GPT-5.4-mini、Gemini Flash 等低成本模型的场景,需要特殊的预算策略。

低配模型特性

模型输入价格输出价格上下文窗口特点
Claude Haiku 4.5$1.00/M$5.00/M200K快速响应,性价比高
GPT-5.4-mini$0.15/M$0.60/M128K超低成本,适合批量任务
Gemini 2.5 Flash$0.30/M$2.50/M1M超大上下文,快速处理

低配模型预算配置

{
  "$schema": "https://opencode.ai/config.json",
  "model": "anthropic/claude-haiku-4-5",
  "small_model": "anthropic/claude-haiku-4-5",
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 12000
  },
  "provider": {
    "anthropic": {
      "models": {
        "claude-haiku-4-5-20251001": {
          "options": {
            "thinking": {
              "type": "enabled",
              "budgetTokens": 4000
            }
          }
        }
      }
    }
  }
}

配置要点

  • budgetTokens: 4000 — 低配模型的推理预算要小,避免过度消耗
  • prune: true — 积极裁剪旧工具输出,保持上下文精简
  • reserved: 12000 — 预留足够的压缩缓冲空间

低配模型使用策略

策略 1:精炼上下文
  - 系统提示控制在 200 Token 以内
  - 工具输出截断到 500 字符
  - 只加载必要的文件内容

策略 2:任务分级
  - 简单问答 → 免费模型
  - 代码审查 → Haiku/GPT-5.4-mini
  - 架构设计 → Sonnet/GPT-5
  - 安全审查 → Opus

策略 3:渐进式加载
  - 先用 Surface 层(描述)判断是否需要
  - 再用 Structured 层(摘要)确认相关性
  - 最后加载 Full 层(完整内容)

低配模型成本对比

场景:每天处理 100 个代码审查请求,每个请求 10K Token

全部用 Claude Sonnet 4.6 ($3.00/M 输入, $15.00/M 输出):
  输入: 100 × 10K × $3.00/M = $3.00
  输出: 100 × 2K × $15.00/M = $3.00
  日成本: $6.00
  月成本: $180.00

全部用 Claude Haiku 4.5 ($1.00/M 输入, $5.00/M 输出):
  输入: 100 × 10K × $1.00/M = $1.00
  输出: 100 × 2K × $5.00/M = $1.00
  日成本: $2.00
  月成本: $60.00

使用 GPT-5.4-mini ($0.15/M 输入, $0.60/M 输出):
  输入: 100 × 10K × $0.15/M = $0.15
  输出: 100 × 2K × $0.60/M = $0.12
  日成本: $0.27
  月成本: $8.10

节省: 从 $180/月 降到 $8.10/月,节省 95%

低配模型配置模板

模板 A:Haiku 快速响应

{
  "$schema": "https://opencode.ai/config.json",
  "model": "anthropic/claude-haiku-4-5",
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 12000
  },
  "provider": {
    "anthropic": {
      "models": {
        "claude-haiku-4-5-20251001": {
          "options": {
            "thinking": { "type": "enabled", "budgetTokens": 4000 }
          }
        }
      }
    }
  }
}

模板 B:GPT-5.4-mini 超低成本

{
  "$schema": "https://opencode.ai/config.json",
  "model": "openai/gpt-4o-mini",
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 10000
  }
}

模板 C:Gemini Flash 超大上下文

{
  "$schema": "https://opencode.ai/config.json",
  "model": "google/gemini-2.5-flash",
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 20000
  },
  "provider": {
    "google": {
      "models": {
        "gemini-2.5-flash": {
          "options": {
            "thinkingConfig": {
              "includeThoughts": true,
              "thinkingBudget": 8000
            }
          }
        }
      }
    }
  }
}

常见反模式

压缩过度导致信息丢失

现象:为了最大化 Token 节省,将压缩比设置到 10:1 以上,导致压缩后的上下文丢失关键决策信息和架构约束。

原因:把 Token 节省作为唯一优化目标,忽略了上下文质量的保真度。

对策:压缩比建议控制在 3:1 到 6:1 之间。使用 protect 规则保护关键信息(架构决策、API 签名、安全约束)。开启压缩保真度验证,定期抽查压缩后的上下文是否保留了核心信息。

对所有内容一视同仁

现象:使用全局统一的压缩策略,不区分系统提示词、工具定义、对话历史和工具输出——全都用同样的压缩率。

原因:配置省事,认为“压缩就是压缩,哪来那么多区别“。

对策:不同内容类型的敏感度不同。系统指令和工具定义应当保留完整或低倍压缩(< 2:1),对话历史可用中等压缩(3-5:1),工具输出可以用较高压缩(5-8:1)。通过分级策略平衡 Token 节省和质量保真。

只压缩不监控

现象:配置了自动压缩后就不管了,从不检查压缩后的上下文质量是否还满足任务需求。

原因:认为压缩是“设好就不用管的”一次性配置。

对策:建立定期检查机制——每周通过 CLI 查看压缩比和 Token 消耗趋势,结合任务完成率判断压缩是否对 Agent 表现产生了负面影响。

常见错误与陷阱

预算配置冲突

场景:在 compaction 中设置了 reserved: 10000(保留 10K),同时又在 Token 预算中设置了 output: 2000(输出上限 2K),导致需求不一致。

后果:Agent 可能在输出阶段被限制,而保留的缓冲永远用不上。

预防:预算配置应当从整体考量——输入预算 = 上下文窗口 - 保留缓冲 - 预期输出。确保各层配置一致。

优先级丢弃策略误伤

场景:使用 prune: true 自动丢弃低优先级内容,但自动优先级判断将某条关键的架构决策标记为了低优先级。

后果:关键信息被丢弃,Agent 后续需要重新发现或推断同样的问题,浪费了更多 Token。

预防:通过 protect 规则保护明确的关键信息类型。对于不熟悉的项目,先关闭 prune,观察几次后手动配置优先级规则。

降级链中断

场景:配置了级联降级策略(优先级丢弃 → 摘要降级 → 分页),但某个中间节点配置错误导致降级链中断。

后果:超限后没有触发正确的降级行为,Agent 直接截断上下文或报错。

预防:测试每种降级策略独立工作后再组合。在日志中监控降级行为——如果看到“截断“而不是你配置的“摘要降级“,说明降级链配置有误。

适用场景与限制

压缩的最佳场景

  • 长会话(超过 2 小时)中上下文窗口接近上限时
  • Token 成本敏感的生产环境
  • 模型上下文窗口有限(如 32K-64K)但任务需要处理大量上下文

压缩的局限性

  • 压缩不是无限的:当压缩比超过 8:1 时,信息损失急剧上升
  • 压缩有计算成本:每次压缩需要消耗 LLM Token 来生成摘要,高频压缩可能反而增加成本
  • 压缩后的上下文不可逆:一旦压缩,原始信息无法恢复

何时不应该压缩

短会话(< 30 分钟)、任务对上下文精度要求极高(如代码审查需要精确的行号引用)、或模型的上下文窗口已经足够容纳所有内容时,压缩的收益有限,可以关闭自动压缩。

关联章节

验证标准

完成本文学习后,你应该能:

  1. 根据模型上下文窗口和任务类型,合理配置 Token 预算参数(输入/输出/系统各层配额)
  2. 区分压缩(compression)与截断(truncation)的优劣,解释为什么压缩优于暴力截断
  3. 当预算超限时,使用级联策略(优先级丢弃 → 摘要降级 → 分页)完成降级处理
  4. 通过实际日志或 CLI 工具测量当前会话的压缩比(输入 Token / 上下文窗口)
  5. 使用 context-compression 的 CLI 命令对历史会话执行压缩并验证输出质量