当 AI 代理需要操控浏览器时,原始 HTML 的冗余性是一个巨大的痛点。一个普通的电商页面可能包含数百 KB 的 DOM 结构,其中充斥着 JavaScript 脚本、隐藏样式和装饰性元素。如果直接将这些原始数据发送给大语言模型(LLM),不仅会迅速耗尽有限的上下文窗口,还会因为无关信息的干扰导致代理决策变慢、错误率上升。
设计一个高效的浏览器代理,不能仅仅依赖「更强的模型」,而必须从数据源头上做文章。本文将深入探讨一种基于「DOM 压缩」与「增量更新」的代理架构,目标是让代理以极低的 Token 消耗(通常可控制在全量的 10% 以下)感知页面状态,并仅针对变化区域做出反应。
1. 痛点分析:为什么全量 DOM 不可行?
传统的浏览器代理方案通常采用「快照轮询」模式:代理每隔几秒获取一次页面的完整 HTML 截图或结构树。这种做法存在三个核心问题。
上下文膨胀:一个包含导航栏、广告、脚本的复杂页面,其 DOM 节点数量往往超过 2000 个。HTML 标签本身的字符开销(<div class="...">)在转换为 Token 时效率极低,导致每次交互消耗数千 Token,业务成本居高不下。
信噪比失衡:LLM 并不需要知道页面的 CSS 样式细节或者 <script> 标签的内容,它需要的是「这里有一个可点击的购买按钮」或「显示价格的元素在这里」这样的结构化语义。原始 DOM 中 90% 的节点对于当前任务可能是完全无效的噪音。
状态盲区:即使有了全量 DOM,代理也难以感知「状态的变化」。例如,一个加载指示器从「加载中」变成了「完成」,在全量快照中这只是一个字符串的改变,代理如果不进行精细的文本对比,很难注意到这个关键的 UI 反馈。
2. 核心架构:压缩与增量双轨制
为了解决上述问题,我们设计了「压缩层 + 增量层」的双轨架构。这种设计在服务端维护一个精简的「虚拟 DOM 快照」,每次交互时只传输必要的语义变化。
2.1 第一轨:DOM 蒸馏(静态压缩)
在代理与页面交互之前,系统首先执行一次「蒸馏」操作,将原始 HTML 转换为一种轻量级的「结构化对象」。这一步的目标是去除所有非交互性元素,只保留语义骨架。
压缩策略:
- 节点剥离:移除
<script>,<style>,<svg>装饰性部分以及display: none的元素。 - 属性精简:仅保留
id,href,type,role,aria-label以及textContent。CSS 类名通常不包含语义,应默认过滤,除非作为关键定位符。 - 扁平化处理:将深层的 DOM 树扁平化,或者在保留层级信息的同时压缩 JSON 深度。例如,
{tag: "div", children: [...]}可以简化为更紧凑的表示形式。
经过这一步,一个 50KB 的页面可以被压缩到 2-5KB,Token 消耗下降约 90%。此时,LLM 看到的是一个干净的、可编程的结构树。
2.2 第二轨:增量 Diff(动态压缩)
仅仅有静态压缩还不够。当用户点击了一个按钮,页面发生了局部刷新(比如展开了一个下拉菜单),我们没有必要重新发送整个蒸馏后的 DOM。
增量算法流程:
- 快照对比:服务端维护上一帧的「蒸馏 DOM 树」。
- 差异计算:当新的页面事件(如点击、加载完成)触发时,重新抓取页面结构,计算与上一帧的差异(Diff)。这可以通过类似
jsondiffpatch的工具实现,或者使用简单的树遍历算法。 - 增量传输:只生成一个「变更集」(Change Set),包含「删除的节点 ID」、「新增的节点结构」以及「修改的属性 / 文本」。
这种模式将每次交互的 Token 消耗从数千降低到了数百甚至更少,使得高频交互(如表单填写、连续点击)变得经济可行。
3. 上下文感知的元素过滤
除了技术层面的压缩,我们还需要在「业务逻辑」层面引入过滤机制,即「Agent Context Mask」。
实现原理: 代理在执行任务时,通常有一个明确的短期目标(如「查找 iPhone 15 的价格」)。基于这个目标,系统可以动态调整过滤器的白名单 / 黑名单。
- 黑名单策略:如果任务不涉及页面底部的「相关推荐」,则自动将 DOM 中位于底部的节点权重降为 0,不参与语义摘要生成。
- 聚焦策略:当页面出现模态框(Modal)时,强制忽略背景层,只将模态框内部的 DOM 结构发送给 LLM。这解决了传统代理容易迷失在复杂层级中的常见 Bug。
这种「上下文感知」不仅节省了 Token,还显著提高了代理的准确率,因为它强制代理的注意力集中在当前任务相关的视觉区域。
4. 工程化落地:关键参数与配置
要在生产环境中实现上述架构,需要关注以下几个工程化参数。
4.1 压缩粒度控制
压缩并非越激进越好。过度 агрессивно 的压缩可能会丢失 LLM 定位元素所需的 CSS 选择器。建议保留每个交互元素的最近 3 层父级路径,以便 LLM 能推断出元素的相对位置。
4.2 Diff 频率与阈值
对于动态内容(如股票行情、体育比分),需要设置 Diff 触发的阈值。只有当文本变化超过一定比例(如 15%)或者出现新的交互节点时,才推送增量更新。这避免了高频刷新导致的「更新风暴」。
4.3 回滚与兜底
如果增量算法出现解析错误(例如,页面结构发生了完全的重排,导致 Diff 算法失效),系统必须具备快速回退到「全量快照模式」的能力。建议设置一个错误计数器,连续 3 次增量解析失败后,自动降级获取完整蒸馏 DOM。
5. 结论与演进方向
基于 DOM 压缩与增量更新算法的浏览器代理架构,是解决 AI 浏览器自动化「成本高、响应慢」瓶颈的关键路径。它通过「先蒸馏后 Diff」的两步走策略,将原本动辄数十万 Token 的消耗压缩到可控范围,同时通过上下文过滤进一步提升了信号密度。
未来的演进方向可以包括:
- 视觉锚点结合:不仅传输 DOM 结构,还可以叠加关键区域的截图 Base64 片段,供多模态模型辅助定位。
- 预测性预加载:结合 LLM 的意图预测(如检测到用户在看「结算」按钮),提前压缩并加载下一页的 DOM 结构,实现无感切换。
资料来源:本文核心架构灵感来源于 Incremental DOM 的设计理念以及 Gaffa 等 DOM 蒸馏工具的工程实践。