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

模型: openai/gpt-5.4
生成日期: 2026-04-01
书名: Claude Code VS OpenCode:架构、设计与未来
章节: 第20章 — 上下文工程
Token用量: 约 6,600 input + 1,850 output

20.4 上下文窗口溢出恢复

更大的 context window 的确改变了 agent 设计的经济学,但它并没有消灭“溢出”这个问题。coding task 仍然会变长,工具输出仍然会堆积,记忆层仍然会叠加,探索过程仍然会制造大量局部噪音。所以,成熟系统已经不再把 context window overflow(上下文窗口溢出)当成罕见事故,而是把它视为一种正常运行状态,需要正式的恢复机制。

所谓 overflow recovery(溢出恢复),本质上就是:当原始 token 状态已经无法完整带入下一轮时,系统如何保住任务连续性。它不只是“做个摘要”,而是要在记忆压力下实现优雅退化。

OMO 有一个非常直观的例子:anthropic-context-window-limit-recovery hook。名字很具体,但背后的架构思想具有普遍性。它不等到会话直接崩掉,而是在检测到上下文上限问题时,主动进入恢复流程:保留 todo、重述任务锚点、压缩关键发现、恢复下一步行动姿态。这里最重要的不是 hook 名字,而是它体现出来的心态:溢出不是异常边缘情况,而是工作流事件。

Claude Code 则用更产品化的方式回答同样问题,即 auto-compact(自动压缩)。用户不一定会看到非常显式的“现在开始恢复”,但系统会主动折叠历史、保留有效记忆、继续推进任务。这比把溢出直接暴露为 hard failure(硬失败)要成熟得多。

OpenCode 给出的则是框架层启示:只有当 session、message、compaction 本身已经是正式架构概念,溢出恢复才能被系统化实现。否则系统连哪些状态该保、哪些状态可丢都说不清,更谈不上安全压缩。

这里最关键的区分,是 graceful degradation(优雅退化)hard failure(硬失败)

硬失败很好理解:上下文满了,任务中断,用户必须重新开局、手动重述目标、自己试图回忆系统刚才做到哪里。这是最糟的体验,因为它不仅浪费时间,还极容易丢掉一些用户自己都记不全的细微状态。

优雅退化则是相反的思路:系统优先丢弃低价值上下文,保留高价值状态。原始长历史变成摘要,局部探索细节变成结构化笔记,已完成分支被折叠,长期规则继续留存,当前任务重新锚定。用户感受到的是“系统变轻了,但没失忆”。

一个真正可靠的溢出恢复体系,至少需要五个部件。

第一,系统必须有 state tiers(状态分层)。持久规则、长期记忆、当前任务状态、原始聊天历史,不能被一视同仁地处理。

第二,系统要有 compaction triggers(压缩触发器)。不能总等到窗口彻底满了才被动处理。更好的系统会在接近上限前就启动压缩或清理。

第三,系统要有 structured preservation(结构化保留)。恢复时至少应该保存:当前目标、已完成步骤、关键发现、未决问题、重要文件、下一步计划。

第四,系统要有 resumability(可继续性)。恢复之后,agent 不只是“记得以前发生过什么”,而是真正知道“现在该继续做什么”。

第五,系统要有 observability(可观察性)。用户或开发者最好能知道:发生了压缩、保留了哪类状态、为什么系统现在还能继续。

Sub-agents 在这里也扮演重要角色。委派本身就是一种防止主上下文被局部细节淹没的手段。把探索、调研、验证等局部任务扔进独立子上下文,可以显著降低父上下文膨胀速度。也就是说,好的 orchestration(编排)不只是任务组织方式,也是在降低溢出概率。

另一个容易被忽视但非常关键的原则是:溢出恢复必须尽量保留 intent(意图),而不只是 facts(事实)。一个差的摘要也许保留了文件名、命令、结果,但如果它丢掉了“当前在试图证明什么”“为什么刚才否定了某条路径”“接下来为什么要走这一步”,那恢复后的 agent 仍然会像是断片。真正好的恢复,保留的不只是资料,还有方向感。

这也是为什么 structured notes 和 compaction 关系如此紧密。如果系统平时就把关键任务状态写成显式结构,那么溢出时就不是从混乱聊天里临时抢救信息,而是从已有状态对象中提取关键部分。需要推断的越少,恢复损失就越小。

随着上下文窗口越来越大,有些构建者会产生一种错觉:既然窗口很大,也许溢出工程可以先不做。这其实是危险判断。更大的窗口只是推迟了问题发生的时间,并没有改变其性质。甚至还可能让系统养成更懒散的上下文习惯,等到真的撞上边界时,累积的垃圾状态反而更多。

因此,更成熟的态度应该是:从一开始就按“必然会溢出”来设计。假设任务会很长,工具输出会很脏,历史会很厚,局部探索会很多,然后提前准备好压缩、恢复、再锚定的机制。这样系统在边界处才不会显得脆弱。

OMO 的显式恢复 hook 与 Claude Code 的自动压缩,代表了两种不同风格:前者更像把溢出处理成一个清楚可见的编排事件,后者更像把恢复打磨成用户几乎无感的产品能力。两种方式都比“等溢出后直接报错”要成熟得多。

归根结底,context window overflow recovery 并不是一个边缘附加功能,而是决定 agent 是否“有韧性”的关键部分。会在上下文边界处直接硬崩的系统,看起来总是不够工程化;能压缩、能恢复、能继续推进的系统,才真正像一个为长任务而生的工具。对 coding agent 来说,这种差别非常大,因为真正重要的工作,往往恰恰就是那些长、杂、会把上下文逼到边缘的工作。