Skip to content
 
 

Repository files navigation

动态上下文裁剪插件

ko-fi

通过管理对话上下文,自动减少 OpenCode 中的 token 使用量。

🇨🇳 已汉化版本 — 用户界面、命令输出、错误提示均已翻译为中文。

DCP in action

安装

通过命令行安装(克隆后从本地路径安装):

git clone https://github.com/LOVEYIKANUOSI/opencode-dynamic-context-pruning-zh
cd opencode-dynamic-context-pruning-zh
npm install --production && npm run build
opencode plugin file:///%cd%/dist/index.js --global

注意:需先安装 Node.js 才能执行 npm 命令。

工作原理

DCP 通过压缩工具和自动清理来减少上下文大小。你的会话历史不会被修改,DCP 在将请求发送给 LLM 之前,会用占位符替换被裁剪的内容。

压缩

压缩是一个暴露给模型的工具,它用高保真的技术摘要替换已关闭的、过时的对话内容。你可以把它理解为 Opencode 压缩流程的更智能版本。与在会话达到最大上下文时静态触发、对整个编码会话进行压缩不同,压缩工具允许模型根据任务完成情况自行决定何时激活,并且只压缩不再需要逐字保留的特定消息。

DCP 支持两种压缩模式:

  • range 模式将连续的对话片段压缩为一个或多个摘要。
  • message 模式(实验性)独立压缩单条原始消息,让模型能更精细地管理上下文。

range 模式下,当新的压缩与之前的压缩重叠时,之前的摘要会被嵌套在新摘要内部,这样信息通过层层压缩得以保留,而不是被稀释掉。在两种模式下,受保护的工具输出(如子代理和技能)以及受保护的文件模式都会保留在压缩摘要中,确保最重要的信息不会丢失。你还可以启用 protectUserMessages 来在压缩过程中逐字保留你的消息,但请注意,较大的提示内容(例如在提示中粘贴日志文件)将永远不会被压缩。

去重

识别重复的工具调用(相同工具、相同参数),只保留最新的输出。在压缩工具运行时重新计算,因此提示缓存仅在压缩时受到影响。

清除错误

在可配置的轮次之后(默认:4),裁剪出错工具调用的输入内容。错误消息会被保留,只有可能很大的输入内容会被移除。在压缩工具使用时重新计算。

配置

DCP 使用自己的配置文件,按以下顺序查找:

  1. 全局:~/.config/opencode/dcp.jsonc(或 dcp.json),首次运行时自动创建
  2. 自定义配置目录:$OPENCODE_CONFIG_DIR/dcp.jsonc(或 dcp.json),如果设置了 OPENCODE_CONFIG_DIR
  3. 项目:.opencode/dcp.jsonc(或 dcp.json),位于项目的 .opencode 目录中

每一层会覆盖前一层,因此项目设置优先于全局设置。修改配置后请重启 OpenCode。

Note

如果你使用上下文窗口较小的模型,如 GitHub Copilot 模型或本地模型,请在配置中降低 compress.minContextLimitcompress.maxContextLimit 以匹配可用上下文。

Important

默认值会自动应用。如果你想查看或覆盖设置,请展开此部分。

默认配置(点击展开)
{
    "$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json",
    // Enable or disable the plugin
    "enabled": true,
    // Enable debug logging to ~/.config/opencode/logs/dcp/
    "debug": false,
    // Notification display: "off", "minimal", or "detailed"
    "pruneNotification": "detailed",
    // Notification type: "chat" (in-conversation) or "toast" (system toast)
    "pruneNotificationType": "chat",
    // Slash commands configuration
    "commands": {
        "enabled": true,
        // Additional tools to protect from pruning via commands (e.g., /dcp sweep)
        "protectedTools": [],
    },
    // Manual mode: disables autonomous context management,
    // tools only run when explicitly triggered via /dcp commands
    "manualMode": {
        "enabled": false,
        // When true, automatic cleanup (deduplication, purgeErrors)
        // still runs even in manual mode
        "automaticStrategies": true,
    },
    // Protect from pruning for <turns> message turns past tool invocation
    "turnProtection": {
        "enabled": false,
        "turns": 4,
    },
    // Experimental settings
    "experimental": {
        // Allow DCP processing in subagent sessions
        "allowSubAgents": false,
        // Enable user-editable prompt overrides under dcp-prompts directories
        // When false (default), prompt override files/directories are ignored
        "customPrompts": false,
    },
    // Protect file operations from pruning via glob patterns
    // Patterns match tool parameters.filePath (e.g. read/write/edit)
    "protectedFilePatterns": [],
    // Unified context compression tool and behavior settings
    "compress": {
        // Compression mode: "range" (compress spans into block summaries)
        // or experimental "message" (compress individual raw messages)
        "mode": "range",
        // Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
        "permission": "allow",
        // Show compression content in a chat notification
        "showCompression": false,
        // Let active summary tokens extend the effective maxContextLimit
        "summaryBuffer": true,
        // Soft upper threshold: above this, DCP keeps injecting strong
        // compression nudges (based on nudgeFrequency), so compression is
        // much more likely. Accepts: number or "X%" of model context window.
        "maxContextLimit": 100000,
        // Soft lower threshold for reminder nudges: below this, turn/iteration
        // reminders are off (compression less likely). At/above this, reminders
        // are on. Accepts: number or "X%" of model context window.
        "minContextLimit": 50000,
        // Optional per-model override for maxContextLimit by providerID/modelID.
        // If present, this wins over the global maxContextLimit.
        // Accepts: number or "X%".
        // Example:
        // "modelMaxLimits": {
        //     "openai/gpt-5.3-codex": 120000,
        //     "anthropic/claude-sonnet-4.6": "80%"
        // },
        // Optional per-model override for minContextLimit.
        // If present, this wins over the global minContextLimit.
        // "modelMinLimits": {
        //     "openai/gpt-5.3-codex": 50000,
        //     "anthropic/claude-sonnet-4.6": "25%"
        // },
        // How often the context-limit nudge fires (1 = every fetch, 5 = every 5th)
        "nudgeFrequency": 5,
        // Start adding compression reminders after this many
        // messages have happened since the last user message
        "iterationNudgeThreshold": 15,
        // Controls how likely compression is after user messages
        // ("strong" = more likely, "soft" = less likely)
        "nudgeForce": "soft",
        // Tool names whose completed outputs are appended to the compression
        "protectedTools": [],
        // Preserve your messages during compression.
        // Warning: large copy-pasted prompts will never be compressed away
        "protectUserMessages": false,
    },
    // Automatic pruning strategies
    "strategies": {
        // Remove duplicate tool calls (same tool with same arguments)
        "deduplication": {
            "enabled": true,
            // Additional tools to protect from pruning
            "protectedTools": [],
        },
        // Prune tool inputs for errored tools after X turns
        "purgeErrors": {
            "enabled": true,
            // Number of turns before errored tool inputs are pruned
            "turns": 4,
            // Additional tools to protect from pruning
            "protectedTools": [],
        },
    },
}

命令

DCP 提供 /dcp 斜杠命令:

  • /dcp — 显示可用的 DCP 命令
  • /dcp context — 显示当前会话按类别(system、user、assistant、tools 等)的 token 使用量细分,以及通过裁剪节省的量。
  • /dcp stats — 显示所有会话的累计裁剪统计。
  • /dcp sweep — 裁剪自上次用户消息以来的所有工具。接受可选数量:/dcp sweep 10 裁剪最近 10 个工具。遵循 commands.protectedTools 设置。
  • /dcp manual [on|off] — 切换手动模式或设置明确状态。开启后,AI 不会自主使用上下文管理工具。
  • /dcp compress [focus] — 触发一次压缩工具执行。可选的焦点文本指示要压缩的内容,遵循当前的 compress.mode
  • /dcp decompress <n> — 通过 ID 恢复特定的活动压缩(例如 /dcp decompress 2)。不带参数运行会显示可用的压缩 ID、token 大小和主题。
  • /dcp recompress <n> — 通过 ID 重新应用用户已解压的压缩(例如 /dcp recompress 2)。不带参数运行会显示可重新压缩的 ID、token 大小和主题。

提示覆盖

DCP 暴露六个可编辑的提示:

  • system
  • compress-range
  • compress-message
  • context-limit-nudge
  • turn-nudge
  • iteration-nudge

此功能默认禁用。在 DCP 配置中将 experimental.customPrompts 设置为 true 以激活。

启用后,托管的默认值会以纯文本提示文件的形式写入 ~/.config/opencode/dcp-prompts/defaults/。该目录中的一个 README.md 文件会解释每个提示以及如何创建覆盖。

要自定义行为,在覆盖目录下添加同名文件并以纯文本编辑即可。

要重置覆盖,从覆盖目录中删除对应文件。

受保护的工具

默认情况下,以下工具始终受保护,不会被裁剪: taskskilltodowritetodoreadcompressbatchplan_enterplan_exitwriteedit

commandsstrategies 中的 protectedTools 数组会添加到此默认列表中。

对于 compress 工具,compress.protectedTools 确保特定工具的输出会被附加到压缩摘要中。默认包含 taskskilltodowritetodoread

对提示缓存的影响

LLM 提供商基于精确前缀匹配来缓存提示。当 DCP 裁剪内容时,会改变消息,从而从该点开始使缓存前缀失效。

权衡: 你会损失一些缓存命中,但能从减少的上下文大小中节省 token,并减少因过时上下文导致的幻觉。在大多数情况下,尤其是在长会话中,节省的开销超过了缓存未命中的代价。

Note

在测试中,使用 DCP 时缓存命中率约为 85%,不使用时约为 90%。

不受影响的情况:

  • 按请求计费 — 如 GitHub Copilot 等按请求而非 token 计费的提供商。
  • 统一 token 定价 — 如 Cerebras 等对缓存和未缓存 token 收取相同费率的提供商。

许可证

AGPL-3.0-or-later

About

Dynamic context pruning plugin for OpenCode - intelligently manages conversation context to optimize token usage

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages