
OpenHands 应对 Claude 3.7 上下文窗口限制3 档修复路径与 Token 预算自查清单【免费下载链接】OpenHands OpenHands: AI-Driven Development项目地址: https://gitcode.com/GitHub_Trending/ope/OpenHands长任务跑到一半对话突然断在一半模型端返回输入加 max_tokens 超过了上下文上限或者干脆抛出一条历史消息总长超出窗口上限的异常。这是我们撞上的 Claude 3.7 上下文窗口限制现场——OpenHands 对这个问题的处理值得拆一遍。整条链路由配置开关、异常驱动的自动截断、可插拔的压缩器三层拼成本文按先算账、再给 3 档修复路径的顺序讲清楚最后附一份自查清单。一、先把这笔 Token 账算明白上下文窗口本质是一张固定面额的额度卡每轮请求都会把三部分拼在一起扣款扣爆了就是上面那个报错。预算项说明典型量级Claude 3.7窗口按 200k 计历史消息全部轮次每轮都要重发越聊越贵150k长对话的主要消耗本轮输入你的新消息 附带的文件、工具结果数百数千预留输出max_tokens留给模型这次要生成的内容数千数万两个反直觉的点其一历史消息是每轮全量重发它的成本随轮数线性上涨其二预留输出会挤压可用额度——所以哪怕输入只有 195k只要输出预留到 6k同样会撞墙。想通这一点后面所有策略的取舍就都顺理成章了。二、档 1改 3 行配置结论90% 的该开没开问题改配置就能收场。核心开关在配置模板里[agent] enable_history_truncation true # 默认值 true历史截断默认开启 condenser NoOpCondenserConfig # 默认值不做任何压缩仅按需截断enable_history_truncation历史截断的总开关。我们团队的翻车记录里超过一半是内部模板把它显式写成了false把默认保护关了而没人察觉。condenser压缩策略槽位。默认NoOpCondenserConfig意为不压缩——此时系统只会硬砍消息来腾地方换成带摘要能力的压缩器历史才能被改写而不是删除。改完重启会话即可不用动代码。三、档 2看懂内置的截断与压缩链路结论OpenHands 的触发方式是异常驱动的——不预测、不轮询报错来了才动手。链路拆成三段识别模型侧报错文案如 input length andmax_tokensexceed context limit或历史消息总长超出窗口上限的ConversationError被后端的字符串匹配捕获。处置enable_history_truncation true时触发截断重写历史再重发请求若压缩器是 NoOp就按策略直接砍掉最旧消息截断关闭或重写后仍超限异常原样上抛给上层。恢复重试成功会话继续用户侧通常无感只在日志里留下一条已截断并重试。前端还留了一个主动口用量面板里的水位组件实时显示当前占用百分比数据来自会话指标的per_turn_token / context_window超过告警阈值后压缩上下文按钮会升级成醒目主按钮点击即调用/api/conversations/{id}/condense端点完成后提示释放了多少 token。相当于在被动截断之外多了一个提前手动踩刹车的时机。四、档 3自定义压缩器怎么写结论内置策略不够用时扩展点就一个——实现压缩器接口再把配置里的condenser指向它。接口级示意class ClaudeOptimizedCondenser(AbstractCondenser): def condense(self, history): # 针对 Claude 3.7保留最近几轮原文 # 早期轮次压成摘要代码块只留签名 return self.keep_recent_summarize_older(history)接口本身很薄基类定义压缩入口与配置项你的实现只需要回答哪些轮次保留原文、哪些进摘要、摘要多长。对 Claude 3.7 比较务实的取舍是——最近几轮逐字保留当前任务上下文最敏感更早的轮次各压成一段摘要历史里的代码块只保留函数签名与关键行注释与重复样板整段丢弃。五、选型表什么任务规模开哪档任务规模建议组合常见误配及后果短问答、单文件改动档 1 默认值即可无中等多轮任务档 1截断开启 非 NoOp 压缩器enable_history_truncation false报错直接打断会话长文档分析、跨文件重构档 2依赖自动截断并在水位过半时手动压缩预留输出开太大输入没满就撞墙且生成被截断超长自动化任务档 3自定义压缩器 任务拆分成子任务只做硬截断不做摘要早期关键决策被整轮丢弃后续行为漂移六、5 条快速自查模板里enable_history_truncation是不是truecondenser当前挂的哪个策略两者默认值分别是true和NoOpCondenserConfig。抓一次日志超限报错文案之后有没有紧跟截断并重试的记录没有说明链路被配置断掉了。水位组件超过 80% 时先手动点一次压缩别等被动截断替你决定丢哪些轮次。长任务拆成子任务分别开会话别指望单条会话扛全程。持续盯压缩频率和任务完成率的组合压缩越来越频繁而完成率不涨就是该上档 3 自定义压缩器的信号。源码位置项目可从https://gitcode.com/GitHub_Trending/ope/OpenHands获取配置定义openhands/core/config/agent_config.py异常定义openhands/core/exceptions.py触发与重试逻辑openhands/controller/agent_controller.py压缩器基类与实现openhands/memory/condenser/前端水位与手动压缩src/hooks/use-context-window-usage.ts、src/components/features/conversation/usage-panel/compact-context-button.tsx【免费下载链接】OpenHands OpenHands: AI-Driven Development项目地址: https://gitcode.com/GitHub_Trending/ope/OpenHands创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考