通过管理对话上下文,自动减少 OpenCode 中的 token 使用量。
🇨🇳 已汉化版本 — 用户界面、命令输出、错误提示均已翻译为中文。
通过命令行安装(克隆后从本地路径安装):
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 使用自己的配置文件,按以下顺序查找:
- 全局:
~/.config/opencode/dcp.jsonc(或dcp.json),首次运行时自动创建 - 自定义配置目录:
$OPENCODE_CONFIG_DIR/dcp.jsonc(或dcp.json),如果设置了OPENCODE_CONFIG_DIR - 项目:
.opencode/dcp.jsonc(或dcp.json),位于项目的.opencode目录中
每一层会覆盖前一层,因此项目设置优先于全局设置。修改配置后请重启 OpenCode。
Note
如果你使用上下文窗口较小的模型,如 GitHub Copilot 模型或本地模型,请在配置中降低 compress.minContextLimit 和 compress.maxContextLimit 以匹配可用上下文。
Important
默认值会自动应用。如果你想查看或覆盖设置,请展开此部分。
默认配置(点击展开)
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 暴露六个可编辑的提示:
systemcompress-rangecompress-messagecontext-limit-nudgeturn-nudgeiteration-nudge
此功能默认禁用。在 DCP 配置中将 experimental.customPrompts 设置为 true 以激活。
启用后,托管的默认值会以纯文本提示文件的形式写入 ~/.config/opencode/dcp-prompts/defaults/。该目录中的一个 README.md 文件会解释每个提示以及如何创建覆盖。
要自定义行为,在覆盖目录下添加同名文件并以纯文本编辑即可。
要重置覆盖,从覆盖目录中删除对应文件。
默认情况下,以下工具始终受保护,不会被裁剪:
task、skill、todowrite、todoread、compress、batch、plan_enter、plan_exit、write、edit
commands 和 strategies 中的 protectedTools 数组会添加到此默认列表中。
对于 compress 工具,compress.protectedTools 确保特定工具的输出会被附加到压缩摘要中。默认包含 task、skill、todowrite 和 todoread。
LLM 提供商基于精确前缀匹配来缓存提示。当 DCP 裁剪内容时,会改变消息,从而从该点开始使缓存前缀失效。
权衡: 你会损失一些缓存命中,但能从减少的上下文大小中节省 token,并减少因过时上下文导致的幻觉。在大多数情况下,尤其是在长会话中,节省的开销超过了缓存未命中的代价。
Note
在测试中,使用 DCP 时缓存命中率约为 85%,不使用时约为 90%。
不受影响的情况:
- 按请求计费 — 如 GitHub Copilot 等按请求而非 token 计费的提供商。
- 统一 token 定价 — 如 Cerebras 等对缓存和未缓存 token 收取相同费率的提供商。
AGPL-3.0-or-later

{ "$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": [], }, }, }