多模态Agent的上下文预算,为什么一遇到截图就漂移?

Agent 连续处理截图时,模型窗口可能没有变化,压缩账本却低估了视觉历史。本文解释图片如何变成任务状态、漏算怎样改变压缩后的保留边界、为什么长上下文不能自动修好这件事,以及日志必须记录哪些图片成本、裁剪结果和实际请求大小,才能判断多模态 Agent 究竟留下了什么。

你让 Agent 对着网页改 UI:看截图,调整 CSS,再截图确认。循环跑到第五张、第七张时,图片已经不只是附件,而是 Agent 判断“页面现在长什么样”的任务状态。

长任务不可能永远保留全部历史。Agent 必须把较早的内容压缩成摘要,再决定哪些原始消息、工具结果和图片值得留下。如果做这项决定的账本漏算图片,界面显示的“剩余空间”就不再代表真正保留的内容。

这才是“截图让上下文预算漂移”的含义:变化的不是模型窗口,而是 Agent 对自己保留了多少视觉历史的判断。

截图不是附件,它会变成 Agent 的任务状态

一张报错图只用于解释一次错误,丢掉以后影响有限。UI Agent 的截图不同:上一张图记录修改前的状态,下一张图用于确认按钮、间距和颜色是否变化。图片之间有时间顺序,旁边的文字还会标明 before.pngafter.png 或具体文件路径。

当 Agent 压缩历史时,它面对的不是“删掉几张无关图片”,而是“还能不能保留做出下一步判断所需的视觉状态”。图片与标签被拆开,或者新截图被裁掉、旧文字反而留下,任务状态都会变得残缺。

Codex 的图片输入文档已经把报错截图、UI、架构图和前后状态列为典型输入。视觉能力进入开发循环以后,图片也必须成为上下文管理的一等公民。

“上下文不够了”可能发生在三个不同环节

模型上下文上限、触发压缩的阈值和压缩后历史保留预算是三套不同数字

图 1:本文讨论的是第三个环节——压缩完成后,原始图片究竟占掉多少保留空间。

  • 模型上下文窗口:一次请求最多能装多少输入与输出。
  • 压缩触发点:会话长到什么程度时,Agent 开始把旧历史压缩成摘要。
  • 压缩后保留预算:摘要之外,还允许带回多少原始消息、工具结果和图片。

这三项会互相影响,但不是同一个数字。模型支持 128K、200K 或 1M 上下文,不代表 Agent 一定知道压缩后保留的图片占了多少空间。窗口可以完全没变,错误发生在第三项的记账过程。

文本进了账本,图片却没有

Codex 的一份修复 PR暴露了一个非常具体的缺口:远程压缩的保留消息预算计算了文本,却没有计算普通消息里的图片。图片很多时,实际保留的内容可能超过账面预算所代表的大小。

这就是“上下文管理还停留在文本时代”的具体形态:系统已经能把图片交给模型,负责裁剪历史的预算表却仍主要沿用文本路径。图片出现在会话里,却没有进入决定“该保留多少”的同一份账本。

旧逻辑只计算文本,新逻辑同时加入图片估算成本的前后对比

图 2:问题不是图片估算能否做到绝对精确,而是旧路径把普通图片记成了 0;修复后才按图片尺寸估算成本。

文本在这段代码里同样使用近似 token 计算,因此不能简单概括成“文本精确、图片不精确”。真正的差别是:**文本至少进入了账本,图片当时没有。**图片越多,账面余额与实际多模态输入之间就可能离得越远。

少记一张图,压缩器就可能选错保留边界

压缩器从较新的消息向前挑内容,每保留一项就扣减预算。图片没有成本时,它会继续向前保留;账本说“还能装”,实际组装出的多模态历史却已经更大。

公开证据确认的结果到这里为止:**图片较多的历史可能保留超过预算所代表的上下文。**它没有证明 Agent 一定会重复点击、提前失忆或过早压缩。

但对工程排查来说,账本失真已经足够麻烦。下一轮请求为什么比预期更重、压缩以后为什么还保留这么多图片、界面显示的剩余比例为什么和请求体对不上,都无法只靠“模型窗口有多大”解释。

7 张图片如何把 64K 保留预算顶穿

Codex 0.149.1 提供了一个可以核对的案例。官方集成测试放入 7 张 original detail 图片,每张按 10,000 个 estimated patch tokens 计算,再触发远程压缩。

7 张图的估算已经达到 70,000,高于代码中的 64,000 保留预算,还没有计算旁边的文字。

Codex 官方集成测试中七张图片各按一万估算 token 计入六万四千保留预算

图 3:这是官方仓库里的边界测试,不是所有截图都固定消耗 10,000 token,也不是 SandBase 自行跑出的 benchmark。

图片预算状态重复压缩后的预期
保持默认图片继续被保留
明确关闭图片继续被保留
明确开启按预算裁掉较老图片

修复包含三个动作:把保留图片按现有尺寸估算计入预算;把图片与相邻标签作为一个整体裁剪;边界图片放不下时,不再用更老的消息填补剩余空间。三者解决的都是同一件事——让压缩器保留一段语义完整、成本可计算的视觉历史。

这份测试验证的是下一轮请求里还剩哪些图片,不是模型回答质量。对应开关 compaction_image_budget 在源码中仍是 UnderDevelopment,默认值为 false。因此只能确认 0.149.1 包含实现,不能据此断言所有托管会话已经默认启用。

多模态 Agent 的日志至少要回答四个问题

如果团队只记录“还剩 42% 上下文”,这类问题几乎无法定位。一次可排查的压缩事件至少要回答:

  • 压缩发生前,历史里有多少文字、工具结果和图片?
  • 每张图片使用什么 detail、尺寸和估算成本?
  • 压缩以后,哪些图片被保留,哪些被裁掉?
  • 预算扣减值与下一轮实际请求大小相差多少?

这些不是 Codex 当前承诺提供的四个固定字段,而是多模态 Agent 需要具备的观测能力。排查 Codex 这条路径时,还要记录实际版本、是否使用 remote compaction v2,以及图片预算开关状态。

会看图之后,竞争转向如何管理视觉历史

这不等于 Claude Code 或其他视觉 Agent 已经确认存在同一个 Bug。更准确的判断是:任何把截图当作任务状态、又会压缩长期历史的 Agent,都需要回答同一个问题——图片成本是否进入了决定保留边界的预算。

文本、图片、工具返回和网页状态会争用同一份工作记忆。模型窗口再长,如果图片仍是预算系统里的二等公民,Agent 就无法可靠解释自己究竟保留了什么。如果正在比较不同上下文长度和多模态能力的模型,可以在 SandBase 模型目录 查看当前可用选项;但更换模型只能改变窗口大小与视觉能力,不能代替 Agent 自己的图片预算和压缩逻辑。

关于“窗口很长”和“任务能稳定跑很久”为什么不是一回事,可以继续看百万上下文模型在 Agent 任务里的实际差别

多模态 Agent 要走向可靠,光把图“喂进去”还不够,必须把图像纳入和文本同一套、精确的预算计量体系。

Codex 0.149.1 修的是这一单 bug,但它提醒的是整个方向——视觉上下文的管理,是下一阶段 Agent 可靠性的分水岭。

Sources