本节摘要:本节讲视觉流派的表示与定位机制,以及它在该用的地方用、不该用的地方省的成本观。管道:页面截图喂给多模态模型,模型按指令识别目标元素并给出位置(边界框或坐标),客户端把模型坐标换算成页面坐标后驱动点击——换算环节有缩放比与视口两处坑。唯一解清单:Canvas 与 WebGL 内容、图片按钮、无语义标记的自绘控件、以及结构化表示被框架层屏蔽的场景——正好是第 4.1 节快照读不出的那份欠账。成本对比:图像输入的 token 成本是等价语义快照的数倍,延迟与费用同阶上升,因此工程口径是结构化优先、视觉兜底。桥接:Set-of-Mark 给截图编号(或在图上标注候选),让模型「看图选号」,把视觉的通用性与结构化的精确引用结合起来——《深入理解 AI Agent》第 9 章对 SoM 有原理阐述,本节只讲工程用法。
视觉定位的每一步动作都走这条管道:
指令「点击右上角的购物车图标」 │ ▼ ① 截图:客户端抓取页面(或区域)的位图 ▼ ② 识别:多模态模型看图,输出目标的位置(边界框或中心点) ▼ ③ 换算:模型坐标系 → 页面坐标系(除以缩放比、加滚动偏移) ▼ ④ 点击:驱动浏览器在换算后的坐标上执行动作 │ ▼ 产物:动作执行结果 + 带标注的截图(排障金矿)
原理层面,② 是「视觉定位(Grounding)」问题——模型要把语言指称映射到图像区域,这是《深入理解 AI Agent》第 9 章 Computer Use 一节的核心议题之一,本书不重讲。工程层面最脆的是③:模型输出的坐标基于它看到的图,图与页面之间隔着缩放比(截图分辨率与 CSS 像素的比例,高 DPI 屏与缩放设置都会撬动它)和视口(全页截图与可视区截图的坐标系不同)。防坑三招:固定视口尺寸(第 2.3 节的会话选项在此复用);显式传缩放比给换算代码,不猜;点击前把目标滚动进视口再截一次图,缩短坐标旅行距离。
拿一组示意数字把换算坑算明白:视口 1280 乘 800 的 CSS 像素、设备像素比 2,则截图是 2560 乘 1600 的位图;模型在图上指出目标中心在 (2048, 1200),换算回页面坐标要先除以像素比得到 (1024, 600)——若页面已向下滚动 300 像素,真实页面坐标还要加回滚动量 (1024, 900)。任何一步搞错,点击就会偏移到隔壁元素上,而且不报错:
# coord_math.txt —— 坐标换算算例(示意数字) 模型输出(图上坐标): (2048, 1200) ← 基于 2560x1600 的截图 除以像素比 2 : (1024, 600) ← 回到视口 CSS 坐标 加滚动偏移 300 : (1024, 900) ← 页面绝对坐标 漏掉任何一步 : 偏移半个到一整个元素,且无报错
视觉定位的失败形态也自成一格:偏一点——目标框住了按钮的边缘,点击落到按钮外;撞类似——图标长得像的两个元素点错。这决定了视觉动作的验证比结构化动作更不可省(第 6 章的验证策略对坐标点击有专门一档)。
第 4.1 节列过快照读不出的四类内容,这里从「任务」角度重列,并补一类:
| 场景 | 结构化表示里长什么样 | 视觉能看到什么 |
|---|---|---|
| Canvas / WebGL 图表与画布 | 一块无内部结构的画布角色 | 每个数据点、图例、按钮 |
| 图片按钮(无替代文本) | 无名图形节点 | 图标形状与位置 |
| 无语义标记的自绘控件 | 裸容器 | 控件外观与可点击区域 |
| 邮件类 HTML(语义残缺) | 结构混乱的节点堆 | 版面与视觉分组 |
| 框架层屏蔽 DOM 的封装环境 | 拿不到树,只有画面 | 一切 |
最后一行值得展开:某些自动化目标运行在受限容器或远程画面流里,客户端根本拿不到 DOM——结构化路线的入场券(能读到页面结构)不存在,视觉是物理意义上的唯一通道。前四行的公共解法仍是「补语义标记」优先(能改页面就改页面,第 4.1 节立场),视觉路线用于「改不了页面」的世界。
这份清单还有一个常被忽略的推论:视觉是唯一解,不等于整页只有视觉一个工具。在 Canvas 密集的页面里,图表区域必须走视觉,但同页的导航、表单、弹窗往往仍然语义完整——整页一刀切地全视觉,等于用最贵的通道跑最便宜的段落。正确姿势是分域混合:页面哪里欠账,哪里才用眼睛——第 5.3 节的 Skyvern 与本节第五张路由表,都是这个推论的落地。
三笔账(第 4.1 节对照表的视觉扩展版):
| 维度 | 无障碍快照 | 截图 |
|---|---|---|
| 输入成本 | 文本按字符计,低 | 图像按块计,等价信息的数倍 |
| 延迟 | 低 | 视觉编码加模型推理,每步高出一截 |
| 定位精度 | ref 精确到元素 | 坐标近似到区域,有偏移风险 |
| 覆盖面 | 仅语义内容 | 一切可见内容(含 Canvas、图片) |
| 可调试性 | 纯文本可 diff | 标注截图可回放(更直观但更占存储) |
成本差的量级感受:一次「看页面」用快照可能是几百到几千 token 的文本,用截图则常见数千到上万——叠加每步模型调用,多步任务的差距按乘法放大。延迟侧同样有笔可拆(示意量级):
| 延迟构成 | 结构化路线 | 视觉路线 |
|---|---|---|
| 页面状态获取 | 树序列化,几十毫秒 | 截图编码,几十毫秒 |
| 模型输入处理 | 文本,快 | 图像编码,慢一档 |
| 模型推理 | 较快 | 较慢(视觉理解更重) |
| 步间往返 | 串行累加 | 串行累加 |
单步差几百毫秒到一两秒,十步任务的体感差就是数秒到十几秒——对交互式工具可忍,对批量任务与用户体验敏感的流程就是硬伤。所以工程口径是明确的:同一个任务,结构化路线能做就用结构化,视觉留给结构化做不了的部分。反例也真实存在:某些任务里页面语义极差而视觉信息极富(海报式页面、设计稿、图表 Dashboard),此时视觉反而是「便宜」的——因为结构化路线根本做不成,成本无穷大。选型序见第 5 章支柱页的判定图,一句话版:先问快照,再问 act,最后问眼睛。
视觉路线的偏移与撞类似问题,有一个漂亮的半结构化解法:先在截图上把候选元素标出来(编号、框线),再让模型「看图选号」——这就是 Set-of-Mark(SoM)思路。模型不再输出坐标,而是输出「选 3 号」,编号到区域的映射由客户端持有,换算环节的坑被绕开。
纯视觉:指令 ──▶ 模型看整图 ──▶ 坐标(易偏移) ──▶ 点击 SoM: 截图 ──▶ 客户端标注候选(框+编号)──▶ 模型选号 ──▶ 客户端按号取区域 ──▶ 点击 ↑ 这一步是确定性代码,不是模型
《深入理解 AI Agent》第 9 章把 SoM 讲成「与其在像素里猜,不如把候选摆出来让模型挑」,并指出 browser-use 的编号点击是其在 Web 上的结构化实现。注意这个精妙的对应关系:browser-use 的编号清单是 SoM 的 DOM 版(候选来自无障碍树,编号发给模型时是文本),截图标注版 SoM 的候选来自视觉分析(编号画在图上)——两个流派在「让模型做选择题而不是问答题」这一点上殊途同归。工程上的混合定位也由此自然生长:候选发现用结构化通道(便宜、准确),视觉确认用截图(防同名、防遮挡),Skyvern 的视觉加 DOM 混合正是这个思路的产品化(第 5.3 节)。
真实系统很少纯视觉或纯结构化,常见三种混合形态:
| 形态 | 机制 | 代表 |
|---|---|---|
| 结构化发现加视觉确认 | 候选来自快照,截图辅助消歧 | Skyvern(第 5.3 节) |
| 视觉发现加结构化执行 | 模型看图选号,执行走元素引用 | SoM 类标注方案 |
| 分域路由 | 页面区域按可读性分流两个通道 | 自建系统常见 |
混合定位的第一条设计守则:通道切换发生在区域边界,不发生在动作中间——同一个动作别一半用快照一半用截图,两套坐标系混在一步里,排障时连「它到底在哪套坐标里找的」都说清不了。第二条守则:每个视觉步骤的标注截图必须留档(第 5.2 节的报告机制),因为视觉步骤的「现场」无法像文本那样事后重建——不留图,失败就永远说不清。
给自建系统的建议:把「用哪个通道」做成每步骤的显式配置而不是全局开关——同一个任务里,「填表单」走结构化(便宜)、「点图表上的某个点」走视觉(唯一解),第 3 章判定树的分段思想在这里原样复用,只是分支多了一层。一张路由配置的长相(示意):
| 步骤 | 页面区域 | 通道 | 理由 |
|---|---|---|---|
| 登录 | 表单区 | 结构化 | 语义完整,ref 稳定 |
| 选日期 | 日历组件 | 结构化 | 按钮有角色有名 |
| 圈选图表区间 | 数据画布 | 视觉 | Canvas 无语义 |
| 确认弹窗 | 弹窗层 | 结构化加视觉兜底 | 偶发遮挡,双保险 |
配置表本身也值得进版本管理:它是第 3.3 节缓存与固化思想的延伸——通道选择也是可固化、可回退的决策,页面改版时先改这张表,而不是改代码。团队评审时拿这张表过一遍,每行问一句「这个通道选得有证据吗」,选型就从玄学变成了工程。
给第一次做视觉接入的团队四条起步建议:
原理就位,下一节进入实战:Midscene 把视觉定位包装成三件套 API(ai、aiQuery、aiAssert),让测试代码里直接写自然语言——我们在靶场上完整走一遍,看看模型眼里的「买牛奶按钮」长什么样。