Skip to content

视觉断言

当传统 UI 树(dump_ui / findElement)抓不到元素(Canvas、图片、游戏、WebView、自绘控件),或者你要判断的是"看起来对不对"而不是"有没有某个节点",用视觉断言。

Tapilot 提供两条路径:

  • assertVisual DSL action — Gemini 多模态模型读一张截图 + 你的 prompt,返回 pass/fail + 原因
  • analyze_screen MCP tool — 返回结构化分析(元素列表 / 文字块 / 异常标记)

DSL:assertVisual

yaml
- saveScreenshot: login-page
- assertVisual: "页面显示了登录表单(邮箱输入框、密码输入框、登录按钮)"

- assertVisual:
    prompt: "验证码倒计时显示为 59 秒"
    model: gemini-2.5-pro   # 可选,默认 gemini-2.5-flash

机制:

  1. 截图(优先用刚才 saveScreenshot 存的,否则即时截)
  2. 构造请求:{ image, prompt: "..." } 给 Gemini
  3. 要求 Gemini 返回 { pass: boolean, reason: string }
  4. pass: false 则 step 失败,reason 写进 run.md

适合 / 不适合

场景适合度
Canvas 渲染(游戏、地图、图表)✅ 主场
图片/广告内容判断
布局/样式是否对(颜色、对齐)
动画完成判断✅(配合 waitStable 更稳)
简单文字存在 / 按钮可点❌ 用 assert / assertVisible / assertClickable 更快更准
性能指标 / 元素数量❌ 用 metrics / assertCount

规则:能用传统断言就用传统,视觉断言贵(Gemini API 调用)+ 慢(~2-5 秒/次)+ 偶尔误判。仅视觉才能判断的情况才上。

MCP:analyze_screen

yaml
# MCP 调用伪代码
analyze_screen({
  serial: "<device>",
  hints: "找登录按钮、输入框、错误提示",
  focus: "interactive"  # elements | text | interactive | layout
})

返回 JSON:

json
{
  "elements": [
    { "type": "button", "label": "登录", "x": 540, "y": 1800, "confidence": 0.95 },
    { "type": "input", "placeholder": "邮箱", "x": 540, "y": 1200 }
  ],
  "text_blocks": [...],
  "anomalies": []
}

Claude 拿 JSON(~500 token)决定下一步,不需要自己看图。

其他 AI 视觉工具

Tool用途
ocr纯文字识别(Gemini OCR)
get_elements结构化元素列表(比 dump_ui 精简)
detect_anomaly专查 UI 异常(错位/空白/报错)
compare_screens前后两屏对比找差异
smart_tap描述元素让 AI 自己找坐标点(比 find_element 强)

配置

需要 Gemini API key:

bash
# 在仓库根目录 .env.local
GEMINI_API_KEY=your-key

或在桌面应用的「账号」页填。

价格和速度

Gemini 2.5 Flash:

  • 约 $0.075 / 百万输入 tokens,一张 screenshot ≈ 400-1000 token
  • 单次 assertVisual 调用 ~1500 token(含 prompt + 图)≈ $0.0001
  • 响应时间 1-3 秒

Gemini 2.5 Pro:

  • 贵 10x,但复杂场景(多元素/细节判断)更准
  • 响应 3-8 秒
  • 仅在 Flash 判断不稳时才切

典型用法

配合 waitStable 确保画面稳定

yaml
- tap: 加载
- waitStable: { timeoutMs: 10000 }  # 等画面不变
- assertVisual: "加载 spinner 已消失,内容区出现 3 张卡片"

失败时附带 reason

run.md 里会记录:

❌ step 5: assertVisual 失败 [gemini-2.5-flash]:'页面显示了登录表单'
    — 页面实际显示注册表单(有昵称字段),不是登录表单

方便人看原因,定位快。

Released under MIT License.