第 45 章:Computer Use 上下文管理
当前视口是证据。十一个已经过时的视口是负担——除非用户要求你比较全部十二个。
快速通道(5 分钟掌握核心)
- Computer Use 会同时增长两类历史:文本观察与图像
- 使用四项独立控制:单次观察上限、文本窗口、浏览器图像窗口、全局图像上限
- 按工具身份限定浏览器裁剪,让用户上传与批量视觉任务使用更宽松的预算
- 用明确的占位文本替换陈旧内容,同时保留
tool_use_id配对- 让过滤器幂等且可观测;裁剪 prompt 并不等于删除底层文件
公开源码快照:实现细节取自 Kocoro 公开
origin/main的4ec6772提交,复核日期为 2026-07-27。具体常量应以当前源码为准。
45.1 从 Agent 无法操作的十一个屏幕说起
Computer-use Agent 打开设置面板、截图、读取无障碍树、点击一个标签页,然后重复。十二次操作后,下一个模型请求包含:
12 screenshots
12 page / accessibility observations
12 assistant decisions
11 viewports that no longer exist
除最新一张之外,那十一张旧截图都很昂贵,而且通常已经没用。模型无法再点击那些旧画面,界面也早已变化。
但“通常”二字很关键。如果用户任务是“比较这十二张截图”,每张图都是任务对象。对浏览器导航非常合适的全局“只留一张图”,会毁掉批量视觉任务。
文本也有同一类错配。即使是最新观察,一份 DOM 转储也可能包含 80,000 个字符。保留三个这样的观察,并不能阻止一个超大页面主宰 prompt。
Computer-use 上下文不是一份预算,而是多类半衰期不同的载荷。
45.2 四种控制,对应四种失败
公开快照把四种控制分开:
| 控制 | 快照默认值 | 它负责的失败 |
|---|---|---|
| 单次观察文本上限 | 24,000 个 rune | 一个巨大页面或无障碍树转储 |
| 文本观察窗口 | 3 | 多步累积的旧页面状态 |
| 浏览器/GUI 截图窗口 | 1 条含图消息 | 过时视口主宰导航上下文 |
| 全局含图消息上限 | 50 | 浏览器任务之外失控的图像历史 |
数值属于工作负载选择,分离才是架构。
单项上限无法约束条目数量;滑动窗口无法约束一个异常大的条目;浏览器专属图像窗口无法保护批量图像任务;全局上限则不知道最新视口比六轮之前的用户上传更可操作。
每种控制都应有一个所有者、一项配置和一项公开边界测试。把它们合并成 max_context_items,只会得到一个谁来调整都会破坏其他工作负载的数字。
45.3 采集时限制大小,组装时处理老化
24,000 个 rune 的控制在浏览器或 GUI 工具结果第一次进入上下文时生效。它保留观察文本前部,并追加一枚能自我说明的标记:
[browser observation truncated: 81342 chars total]
标记本身包含在上限内,因此返回的观察文本不会悄悄超过配置最大值。按 rune 而不是字节计数,可以避免从中文、日文或 emoji 中间切断,也让“24,000 个字符”在不同语言中含义一致。
文本窗口稍后在每次组装请求时生效。它让三个最新 GUI 观察保持完整,把更早的字符串结果替换成单行存根:
[elided browser observation: browser_snapshot, was 23811 chars]
两种控制解决不同时间维度。采集时截断表示:“这个状态即使新鲜时也过大。”老化表示:“这个状态以前有用,现在已经不值得完整保留。”
这套针对特定来源的老化处理,运行在通用的上下文压力压缩之前。因此,第 37 章给浏览器工具设置的 Tier 2 下限,只约束通用压缩器:它阻止那套机制把仍可操作的页面快照压成元数据;本章的观察窗口则会更早淘汰已经失效的图形界面状态。
这正是第 36 章对单项结果大小与整轮总量的区分,只是应用到了观察,而不是普通工具输出。
45.4 浏览器图像不是用户图像
截图嵌在 tool_result 块内,但对话里的图像并非都来自浏览器。用户可能上传参考图,file_read 可能返回图表,视觉任务也可能有意携带几十张图。
因此,浏览器截图过滤器先识别 GUI 工具族的调用,再沿 tool_use_id 找到匹配结果。只有这些图像受“保留最新一张”窗口限制。用户上传与非 GUI 工具图像不受这一轮处理影响。
随后,全局过滤器对顶层与嵌套图像施加更宽松的 50 条含图消息上限。先运行范围窄的过滤器很重要:全局处理看到的是已经变薄的浏览器历史,可以把宽松预算留给真正需要它的工作负载。
规则也适用于图像之外:把激进预算限定给真正需要这种预算的生成方。廉价的全局分类,替代不了对数据来源的了解。
45.5 保留对话契约
直接删除截图块可能破坏 Provider 的消息契约。Assistant 的 tool_use 还在,但匹配的 tool_result 已经变形或消失。
所以过滤器保留结果块与 tool_use_id,只把陈旧载荷换成明确文本:
[previous screenshot removed to save context]
模型知道信息已被移除,Provider 仍看到合法的调用/结果配对,审计轨迹也能说明为什么后续决策没有旧像素可用。
文本过滤器遵循同一规则。它只改变结果内的字符串,不碰外围的轮次结构。这是第 37 章里的配对不变量在 GUI 观察上的特化。
静默删除是最糟选择。它节省 token,却让记录错误地暗示模型看过一份实际上已被移除的证据。
45.6 幂等性保护缓存
这些过滤器会在重复模型调用前运行。如果已经存根化的观察每轮都被改写成稍有不同的存根,前缀就会每轮变化,第 39 章所述的缓存也会永远在同一条消息处未命中。
文本存根有可识别前缀,所以后续处理会跳过;图像替代也是稳定的文本块。启用缓存调试遥测后,每次首次修改都会发出缓存压缩事件(obs_window、browser_img_strip 或全局 img_strip)及新旧哈希;没有变化的重访不发事件。
预期生命周期因此是:
full observation → one deterministic placeholder → byte-stable thereafter
这里的幂等性不只是代码整洁,也直接影响计费。
45.7 Prompt 保留不等于底层文件保留
四种控制操作的都是请求中的消息视图。它们本身不会删除截图文件、抹去完整审计事件,也不会撤销用户上传。
这些属于不同策略:
- Prompt 保留: 模型下一次迭代会收到什么
- 会话/审计保留: 运维人员之后可以重建什么
- 临时文件清理: 本地截图字节何时离开磁盘
- 用户素材所有权: 用户上传文件是否仍可使用
把它们绑在一起,“节省上下文”就可能变成“销毁证据”。保持分离,则可以从模型 prompt 中裁掉旧视口,同时保留调试错误点击所需的轨迹。
模型仍需要被告知损失,占位文本应说明删除了什么、为什么;运维需要遥测;存储需要自己的生命周期。一只裁剪函数不应假装同时拥有三者。
45.8 根据任务调优,而不是根据 token 焦虑
当前视口通常足够完成一次点击,但并非总是如此。表单可能只在导航后显示错误,比较流程可能需要前一张屏幕,画布任务也可能需要多步视觉连续性。
因此,请用真实操作序列调优:
- 跨多个页面的导航;
- 必须比较前后状态的模态框;
- 一批用户提供的图像;
- 巨大的多语言无障碍树;
- 对同一份历史重复过滤;
- 旧图已替换为存根后,从持久消息恢复。
同时测量任务成功率、模型调用次数、输入 token、缓存漂移与重复观察率。如果 Agent 不断重新获取同一张截图,窗口可能太紧,或占位文本删除了错误信号。如果成功率稳定而上下文大幅下降,预算才真正有效。
不要从一次干净的演示推导通用限制。Computer Use 里,界面变化总比直觉更快。
45.9 快照证据
| 观察 | 4ec6772 源码 |
|---|---|
| 四项默认值及各自背后的工作负载理由 | observation_window.go L11 |
| 单次观察上限按 rune 安全截断,并包含明确标记 | observation_window.go L84 |
| 文本窗口保留配对,并跳过已经存根化的结果 | observation_window.go L134 |
| 浏览器截图过滤器按 GUI 工具身份限定范围 | observation_window.go L212 |
| 全局图像过滤器处理顶层与嵌套图像 | loop.go L5911 |
| 浏览器专属、全局图像、文本窗口的执行顺序 | loop.go L3253 |
| GUI 结果进入上下文时应用更紧的上限 | loop.go L4742 |
| Daemon 分别接入四项控制 | runner.go L2737 |
这些内容描述的是一个有日期的实现与工作负载,不是普遍适用的观察上限。
45.10 常见陷阱
所有工作负载只有一个图像上限。 浏览器导航想要最新视口,批量视觉任务可能需要全部上传图像。
有窗口,没有单项上限。 一份巨大 DOM 转储仍会主宰 prompt。
有上限,没有窗口。 成千上万个分别合法的观察仍会累积。
把字节当字符。 多字节文本获得更少的有效上下文,还可能从一个 rune 中间被切断。
删除整个结果块。 破坏工具调用配对,还可能让 Provider 拒绝请求。
静默裁剪。 记录会暗示模型看过实际已经移除的证据。
占位文本非幂等。 每次组装都再次弄脏同一前缀,导致缓存反复失效。
裁剪 prompt 时删除底层文件。 上下文策略意外变成保留策略。
只根据一项任务调优。 很擅长点击表单的限制,可能彻底毁掉视觉比较。
本章要点
- Computer Use 有多种上下文生命周期。 文本、GUI 截图与用户图像的老化方式不同。
- 分别限制大小与数量。 一项超大观察与许多普通观察是不同故障。
- 按生成方限定激进裁剪。 浏览器历史可以很紧,而不会惩罚批量视觉任务。
- 保留配对,并披露损失。 用明确、稳定的占位文本替换载荷。
- Prompt 裁剪是一种视图,不是删除。 审计记录、文件与用户素材各有自己的生命周期所有者。
Part 10 至此闭环:上下文压缩、工具结果预算、缓存稳定性、运行中操控与时间纪律,最终都汇入第 28 章引入的高观察负载工作流。