WWW.YOUINFO.SITE
标签聚合 ACP

/tag/ACP

LinuxDo 最新话题 · 2026-06-08 22:46:53+08:00 · tech

本帖使用社区开源推广,符合推广要求。我申明并遵循社区要求的以下内容: 我的帖子已经打上 开源推广 标签: 是 我的开源项目完整开源,无未开源部分: 是 我的开源项目已链接认可 LINUX DO 社区: 是 我帖子内的项目介绍,AI生成、润色内容部分已截图发出: 是 以上选择我承诺是永久有效的,接受社区和佬友监督: 是 以下为项目介绍正文内容,AI生成、润色内容已使用截图方式发出 github.com GitHub - ApliNi/IpacPanel: 一个轻量好用且专业的终端程序管理面板 一个轻量好用且专业的终端程序管理面板 历时 4 个月开发的最新力作, 终端程序管理面板. 对于单台主机管理大量终端程序, 苦于找不到一个合适好用的面板, 于是开发了这个软件. 它与 MCSManager 类似, 但在使用体验和性能上做了大量改进. 已在自己的生产服务器上测试了两个月的时间, 运行稳定, 达到预期. 原生开发, 无前后端框架, 轻量稳定, 操作流畅, 没有圆角. 支持不停机更新, 内置 vscode 同款文本编辑器和中文等宽字体. 目前正在 windows 和 linux 平台积极维护. 欢迎提出建议和需求 (。・̀ᴗ-)✧ 3 个帖子 - 2 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-06-04 10:34:54+08:00 · tech

基础准备 1、本地安装好ClaudeCode。 2、idea安装好AI Assistant(或者使用高版本的idea,自带AI Assistant)。 环境配置 1、在 C:\Users\【你的用户名】\.claude\settings.json添加如下配置(env配置根据自己选择的中转站来配置),推荐使用ccswitch更加方便。 { "hasCompletedOnboarding": true, "env": { "ANTHROPIC_BASE_URL": "https://***", "ANTHROPIC_AUTH_TOKEN": "sk-cbfX7poXE5mjLl**************", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" } } 2、idea添加ACP配置 点击AI Assistant对话框右上角的option按钮(三个竖直的点) 选择Add customer Agent,进入acp.json配置界面 添加以下acp.json配置; 重启IDEA后生效; { "default_mcp_settings":{}, "agent_servers": { "Claude Code Local": { "command": "npx.cmd", "args": [ "@agentclientprotocol/claude-agent-acp" ], "env": { "ACP_PERMISSION_MODE": "bypassPermissions" }, "use_idea_mcp": true, "use_custom_mcp": true } } } 3、切换到Claude Code Local,即可使用本地Claude Code配置,在idea的AI Assistant实现vibe coding。 1 个帖子 - 1 位参与者 阅读完整话题

V2EX - 技术 · 2026-05-28 12:44:26+08:00 · tech

ricky@archlinux ~> sudo dmesg | grep -i i2c [sudo] password for ricky: [ 0.211745] ACPI BIOS Error (bug): Could not resolve symbol [_SB.PC00.I2C3.TPD0], AE_NOT_FOUND (20251212/dswload2-162) [ 0.211891] ACPI BIOS Error (bug): Could not resolve symbol [_SB.PC00.I2C4.TPL1], AE_NOT_FOUND (20251212/dswload2-162) [ 0.212028] ACPI BIOS Error (bug): Could not resolve symbol [_SB.PC00.I2C5.TPL1], AE_NOT_FOUND (20251212/dswload2-162) [ 0.237528] ACPI: _SB_.PC00.I2C3.PXTC: New power resource [ 0.238649] ACPI: _SB_.PC00.I2C4.PTPL: New power resource [ 0.239054] ACPI: _SB_.PC00.I2C5.PTPL: New power resource [ 1.207616] Modules linked in: i915(+) i2c_algo_bit drm_buddy ttm nvme intel_gtt nvme_core intel_lpss_pci serio_raw video nvme_keyring spi_intel_pci drm_display_helper nvme_auth intel_lpss hkdf spi_intel idma64 wmi cec intel_vsec [ 3.815849] i2c_dev: i2c /dev entries driver [ 4.195336] input: FTSC1000:00 2808:5662 as /devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-0/i2c-FTSC1000:00/0018:2808:5662.0008/input/input18 [ 4.195401] input: FTSC1000:00 2808:5662 UNKNOWN as /devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-0/i2c-FTSC1000:00/0018:2808:5662.0008/input/input20 [ 4.195467] hid-multitouch 0018:2808:5662.0008: input,hidraw7: I2C HID v1.00 Device [FTSC1000:00 2808:5662] on i2c-FTSC1000:00 [ 4.203661] input: TOPS0102:00 35CC:0104 Consumer Control as /devices/pci0000:00/0000:00:15.1/i2c_designware.1/i2c-1/i2c-TOPS0102:00/0018:35CC:0104.0009/input/input22 [ 4.205224] input: TOPS0102:00 35CC:0104 Touchpad as /devices/pci0000:00/0000:00:15.1/i2c_designware.1/i2c-1i2c-TOPS0102:00/0018:35CC:0104.0009/input/input23 [ 4.205278] hid-multitouch 0018:35CC:0104.0009: input,hidraw8: I2C HID v1.00 Mouse [TOPS0102:00 35CC:0104] on i2c-TOPS0102:00 libinput list-devices 识别为两个设备 Device: TOPS0102:00 35CC:0104 Consumer Control Kernel: /dev/input/event12 Id: i2c:35cc:0104 Group: 5 Seat: seat0, default Capabilities: keyboard pointer Tap-to-click: n/a Tap-and-drag: n/a Tap button map: n/a Tap drag lock: n/a Left-handed: n/a Nat.scrolling: disabled Middle emulation: n/a Calibration: n/a Scroll methods: none Scroll button: n/a Scroll button lock: n/a Click methods: none Clickfinger button map: n/a Disable-w-typing: n/a Disable-w-trackpointing: n/a Accel profiles: n/a Rotation: 0.0 Area rectangle: n/a Device: TOPS0102:00 35CC:0104 Touchpad Kernel: /dev/input/event13 Id: i2c:35cc:0104 Group: 5 Seat: seat0, default Size: 130x92mm Capabilities: pointer gesture Tap-to-click: disabled Tap-and-drag: enabled Tap button map: left/right/middle Tap drag lock: disabled Left-handed: disabled Nat.scrolling: disabled Middle emulation: disabled Calibration: n/a Scroll methods: *two-finger edge Scroll button: n/a Scroll button lock: n/a Click methods: *button-areas clickfinger Clickfinger button map: left/right/middle Disable-w-typing: enabled Disable-w-trackpointing: enabled Accel profiles: flat *adaptive custom Rotation: n/a Area rectangle: n/a 尝试过修改启动内核参数 i2c_hid.reset_suspended=1 还有 ignore dmi ,都没用 偶尔冷启动能用手势,重启就没了,监听输入设备事件就只有左键触发,没有手势

LinuxDo 最新话题 · 2026-05-26 16:26:24+08:00 · tech

想在idea中用codex,试了试发现idea的agent里面的codex要登录,自己装了zed的codx acp,发现配置是跟着系统里面的走的,想在idea里面可以设置url和key,这样可以很容易的分发给别人,类似.codebuddy配置那样。 看了看codex-acp的仓库也没有详细的文档,就研究了下怎么配置。 { "default_mcp_settings": { "use_idea_mcp": true, "use_custom_mcp": true }, "agent_servers": { "codex-acp-custom": { "command": "npx.cmd", "args": [ "-y", "@zed-industries/codex-acp", "-c", "model_provider='custom'", "-c", "model='gpt-5.3-codex'", "-c", "model_providers.custom.wire_api='responses'", "-c", "model_providers.custom.name='custom'", "-c", "model_providers.custom.base_url='https://xxxxxxxxxxx/v1'", "-c", "model_providers.custom.env_key='OPENAI_API_KEY'" ], "env": { "OPENAI_API_KEY": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } } } 发现问题的关键是要加上 “-c”, “model_providers.custom.env_key=‘OPENAI_API_KEY’” 然后key配置在env中, 确定是走的 acp.json中,在key中故意多一个字符会显示一个当前中转地址的报错 另外这个agent的acp有时候要关掉重新打开才会重新加载配置 2 个帖子 - 1 位参与者 阅读完整话题

V2EX - 技术 · 2026-05-20 17:27:14+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 17:27:14+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 17:27:14+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 17:21:03+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 14:51:10+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 14:51:10+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 14:51:10+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 13:34:38+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。

V2EX - 技术 · 2026-05-20 13:17:47+08:00 · tech

潜水 10 年:) 可以先把话撂在这里,acp 这个插件出现其他上下文压缩方式就可以谢幕了,甚至尝试继续扩大模型上下文的行为也变得无意义。 先说说上下文压缩插件 acp 是啥,这是一个 opencode 中的插件。为什么需要上下文压缩?用过 AI coding 的都知道,模型上下文都是有限的,哪怕你有 100w 上下文也无济于事,面对旷日持久的大项目也捉襟见肘(尤其是可怜的 glm5.1 啊啊啊)。 所以 gpt 和你聊天实际上是假聊天,你和他每次说的消息,包括他的输出,都作为上下文,每次都全部发给 gpt 处理,久而久之你们就攒满几十万甚至 100w 上下文,就要删去一些。 作为程序员,显而易见想到的方式就是把上下文提炼总结,替换掉原会话冗余的上下文。现在大部分上下文压缩都是这么做的,只不过有一些做的很粗糙(大部分),有的很精细(比如 claude 多级级联),有一些还甚至想出做向量存储相关性搜索等等。 不过最终面临的问题还是压缩效果不好的问题。 想法很简单,实现很简单:模型自己决定要不要压缩,怎么压缩 说起来一肚子气,本来这个插件是要提给原作者 dcp 的,我修了几十个 bug ,增加了类似 jvm 的垃圾回收算法,结果他看都不看全给我关了!!! 废话不多说先看看效果:最近上下文几乎都没有超过 50%! 模型 GLM-5.1 ( 204K context window ),ACP 阈值 55%。 指标 修复前 (5/14 - 5/19) 修复后 (5/19 - 5/20) 采样数 2,749 362 峰值 context 74.2% 45.3% 平均 context 35.9% 25.3% context <40% 的占比 64.5% 87.0% context >55% 的次数 130 次 (4.7%) 0 次 (0%) 主:修复前之前还有,再之前会话超过几百条就上下文丢干净了。 这是最近几天这个会话的 token 指标 数值 总 Input Tokens 35,232,595 (约 3520 万) 总 Output Tokens 616,525 (约 62 万) 总 Tokens (输入+输出) 约 35,849,120 (约 3585 万) 消息总数 3,762 条 会话时长 约 6 天( 5/14 - 5/20 ) 模型 GLM-5.1 ( 204,800 token 上下文窗口) ACP 压缩阈值 55%( 112,640 tokens ) 原理:把上下文压缩当做一个 skill 是的,就这么简单。你不需要像 claude 一样搞多级压缩(都是人工定死的,哪有模型灵活?)也不需要搞外部 api 专门压缩(外部 api 才不了解你需要哪些信息)。也不需要专门训练模型,只需要交给模型一个 skill ,他自己决定什么时候调用即可。 重点说明一些基本特性: 每条消息模型都可以压缩,或者解压缩(这很重要) 模型可以把连续 N 条消息压缩成 1 条消息。 模型可以删除消息。 模型可以修改消息。 系统做什么? 在模型启动的时候告诉模型可以压缩 在上下文 45%的时候提示模型应该压缩 在上下文 55%的时候提示模型必须压缩 仅此而已。 最后说说我改了啥?和原生 dcp 有啥区别 原始 DCP 有个致命问题:上下文状态全靠 msgId 列表追踪,但这些 ID 不持久化,一重启就丢,35 个压缩块全部作废,559K 字符的摘要变成废纸,3175 条原始消息全部涌回上下文,GLM-5.1 直接返回 model_context_window_exceeded 。 我从头重写了核心架构,主要改了这些: 1. 独立 Block 架构 — 不再有巨型摘要 DCP 原始设计有个脑残的地方:每次压缩会把旧 block 的摘要 内联展开 到新 block 中。打个比方,就像你每次整理抽屉,都把之前所有整理记录的完整版塞进新记录里。经过 23 次压缩后,最新 block 的摘要膨胀到 90K 字符 — 整个会话历史的递归摘要。这个巨型摘要无法再压缩(它本身就是摘要),占据了上下文的大部分空间,会话卡在 70% context 无法继续。 ACP 改成独立 Block 架构:每个 block 独立存在,摘要只覆盖自己的范围。多个 active block 在上下文中同时存在。不再自动嵌套, (bN) 引用保留为文本标签。模型需要显式用 bN 作为 boundary 才会消费旧 block 。 2. 压缩块状态机(类似 JVM 分代 GC ) 每个压缩块有 young → old 代的概念。新压缩的块是 young generation ,经历多次压缩周期后晋升为 old generation 。Old generation 的摘要会被 GC 自动截断(保留头部 + 尾部引用标记),防止老摘要无限膨胀吃掉上下文。 JVM GC ACP 触发条件 Young Gen 新创建的压缩块 每次压缩产生 Minor GC 合并最近的 young 块 55% 阈值触发 Old Gen 存活超过 N 次压缩周期的块 survivedCount ≥ 5 自动晋升 Major GC 截断 old-gen 块摘要 超过阈值自动执行 Age-based deactivation 超龄块自动停用 age > 15 实测效果:126 个 active blocks ( 63K tokens 死重)→ GC 自动清理到 10 个。 3. 34 个 Bug 修复 fork 以来修了 34 个 bug ( 4 CRITICAL ,15 HIGH )。每个都是真实踩到的坑,不是坐着想出来的: 最离谱的几个: 状态不持久化 :重启后所有压缩块丢失,几千条原始消息涌回上下文,API 直接返回 model_context_window_exceeded ,会话当场暴毙。这是 DCP 最大的坑,我反复踩了 N 次。 prune summary 静默丢失 :遇到一种边界情况,原始消息被删了但摘要没注入进去 — 也就是 数据直接丢了 ,不是压缩质量不好,是真的没了。 每轮 20-50 秒延迟 :DCP 的 Logger 在 debug=false 时仍然执行 new Error() + Error.prepareStackTrace 来获取调用栈,每次 50-100ms 。syncToolCache 对每个 tool call 调一次 logger ,500 个 tool × 100ms = 50 秒。用户以为模型在思考,实际上是 DCP 在那做无用的堆栈追踪。( PS:大概原生 dcp 上下文没这么大过,所以不会复现这个 bug 吧哈哈) 阈值计算错误 :DCP 用 inputBudget (= context limit - output limit = 73K )代替 context limit ( 204K )算百分比,导致 36% 就触发 CRITICAL WARNING ,模型疯狂压缩一个根本没满的上下文。 压缩完模型罢工 :compress 工具返回后,模型说"压缩完成,接下来你想做什么?"然后停下来。正在执行的多步任务被直接中断。 前缀缓存被打破 :DCP 把动态数据注入到对话中间的锚定消息里,GLM-5.1 的 cache 是前缀匹配,锚定消息内容每轮变化 → 后面所有内容都变成 cache miss ,命中率从 99% 持续下降到 82%。 npm 静默覆盖 :opencode 自动安装 npm 原版 DCP ,原版缺少我的 bug fix ,加载会话时清空所有压缩块,1866 条消息未压缩直接发送。(好吧,这个不是 bug ,现在我改名了,再也不会有这个困扰了) 完整的 bug 列表太多了就不贴了,感兴趣的看 GitHub 。 增加了 300 个测试 凸(艹皿艹 ),原来 dcp bug 那么多,总计 15 个测试只有 5 个能跑,让 glm5.1 帮我写了 300 个基准测试, 竞品对比 ACP DCP 原版 Morph opencode 内置 压缩方式 模型自己决定 模型自己决定 外部专用压缩 API 被动全量摘要 额外 LLM 调用 无 idle 分析可选(费 token ) 需要 API Key 1 次摘要调用 触发时机 45% 建议,55% 必须 可配置 70% 95%(基本已经来不及了) PS:实际上 glm5.1 本身就是压缩大师了:)。 安装 opencode plugin opencode-acp@latest --global 或者 { "plugin": ["opencode-acp@latest"] } 配置文件 acp.jsonc : { "maxContextLimit": "55%", // 触发压缩的阈值 "gc": { "enabled": true, "interval": 300 // 每 5 分钟 GC 检查一次 } } 链接 GitHub: https://github.com/ranxianglei/opencode-acp npm: https://www.npmjs.com/package/opencode-acp 吐槽归吐槽,DCP 原作者的设计思路我是认可的(好吧,这句话是模型给我加的,原作者思路是对的,只不过并没有发挥到登峰造极) — 让模型自己决定压缩,而不是搞一堆规则和外部 API 。只是在工程实现上踩了太多坑,我花了几周把这些坑都填上了。 如果你也在用 opencode 做大项目,试试看。 几周 session 不用重开。 遇到 bug 就提 github 吧,我自己高频用,应该还会发现很多 bug 。你发现了在 issue 说,直接提 pr 即可。