# 把屏幕翻译成 LLM 能读的文本：Agent-View 的桌面感知层设计

> 作者: Lazybones | 日期: 2026-10-22

# 把屏幕翻译成 LLM 能读的文本：Agent-View 的桌面感知层设计

> 大多数桌面智能体的做法是“每一步截一张图，喂给多模态模型”。这当然能跑，但慢、贵，而且很难调试。Agent-View 换了一个方向：把屏幕先翻译成文本大模型能直接读的标记，只有文本不够用时才调用视觉模型。

## 问题：桌面是像素，LLM 读的是 token

让 LLM 操作桌面，本质上是让它回答一个问题：

> 在当前界面里，为了完成目标，下一步应该点哪里、输入什么？

多模态模型可以直接看截图回答。但这条路径有三个现实问题：

1. **慢**：每一步都要上传截图、跑视觉编码，交互延迟高；
2. **贵**：一整张 1080p 截图的 token 成本，远高于几十行结构化文本；
3. **难调**：模型说“点右上角的按钮”，但右上角有三个按钮，失败后很难定位是感知错了还是决策错了。

Agent-View 的假设是：**桌面上的大部分可操作信息，其实已经以文本形式存在**——按钮有标签、输入框有占位符、菜单有文字、UIA 有控件树。把这些信息抽取出来，用稳定的 ID 和坐标组织成文本，纯文本模型就能完成大部分操作。视觉模型只在“必须理解图像内容”时介入，比如识别一张没有文字的海报、判断弹窗的图标含义。

## 四层架构

代码按职责分成四层，每层可以独立替换：

| 层 | 模块 | 职责 |
|---|---|---|
| 感知层 | `perception/` | 截图、OCR、UI 元素检测、窗口信息、UIA 控件 |
| 表示层 | `representation/` | 元素 ID 注册、生成文本标记、解析 LLM 引用 |
| 执行层 | `action/` | 鼠标、键盘、剪贴板、启动应用、DPI 换算、重试 |
| Agent 层 | `agent/` + `cli.py` | 工具注册、smolagents CodeAgent 编排 |

在这四层之外，还有三个横向模块：`grounding/` 负责把引用解析成坐标，`memory/` 负责轨迹与经验，`planning/` 负责把复杂任务拆成子任务。

数据流很短：

```text
截图 + OCR + 检测 + UIA
        ↓
带 ID 的文本 markup
        ↓
LLM 选择工具 / 输出动作
        ↓
Grounding：ID / 文本 / 坐标 → 物理像素
        ↓
执行 + 前后截图验证
```

## 表示层：先给元素一个稳定的名字

表示层做两件事：给每个元素分配 ID，然后把元素列表序列化成文本。

ID 的规则是确定的：先按从上到下、从左到右排序，再按类型加前缀。按钮是 `btn_1`、输入框是 `input_1`、文本是 `txt_1`。同一份布局，两次感知应该得到同一组 ID；这样 LLM 在下一步引用 `btn_3` 时，指的还是同一个按钮。

序列化后的 markup 大致是这样：

```text
[btn_1] button "发布" at (120,300,60,28)
[input_1] input "标题" at (100,200,400,32)
[chk_1] checkbox "记住我" [unchecked] at (50,350,80,20)
[txt_1] text "推荐" at (50,150,40,20)
```

每一行包含四类信息：ID、类型、可读文本、屏幕坐标。UIA 能读到的状态也会被注入，比如 `[checked]`、`[value=...]`、`[disabled]`。这样 LLM 不需要“看”截图，也能知道当前复选框是选中还是未选中。

这层看起来只是格式化，但它决定了后面所有环节的稳定性：

- ID 稳定，LLM 的引用才有意义；
- 坐标和文本同时存在，Grounding 才有多个解析路径；
- 结构化的行可以被程序审计，而不是只能靠模型“感觉”。

## 感知层：五源融合，而不是一张截图

感知层不是简单地“截屏 + OCR”，而是把五个来源合并：

1. **视觉元素检测**：默认 OpenCV 启发式（零模型依赖），可选 OmniParser（YOLO 图标检测 + Florence-2 描述）；
2. **OCR**：`auto` 模式按顺序探测服务化 OCR → 旧 MCP OCR → GPU PaddleOCR → CPU EasyOCR → Tesseract → CPU PaddleOCR，取首个可用；
3. **Windows UIA 控件树**：按钮、输入框、复选框、单选框、滚动条、标题栏按钮等，带原生状态；
4. **二维码检测**：作为 `type=qrcode` 元素注入；
5. **容器轮廓**：在后台线程补充面板、对话框、列表的边界。

多源结果按 IoU 去重，UIA 控件的置信度最高（0.99），因为它来自操作系统而不是像素猜测。图标和标签会做绑定：一个没有文字的图标按钮，如果能和旁边的 OCR 文本对齐，就会被合并成一个带标签的元素。

这里有一个重要的工程取舍：**默认路径必须零模型依赖。** OpenCV 检测器和轻量 OCR 开箱即用，不需要下载几百 MB 权重；只有需要更高精度时才切到 OmniParser + Florence-2。这让项目在普通笔记本上也能跑起来，而不是先配一台带 GPU 的机器。

## Grounding：让多个专家竞争，而不是固定优先级

LLM 输出“点击 btn_3”之后，执行层需要把它变成真实坐标。这一步叫 Grounding。Agent-View 没有采用“先 ID、再文本、最后视觉”的固定优先级，而是让七位专家竞争：

| 专家 | 依据 | 典型置信度 |
|---|---|---|
| Explicit | LLM 直接给出 ID 或坐标 | 1.0 |
| Text | 按可见文本匹配 | 0.9 / 0.6 |
| UIA | UIA 控件树 | 0.95 / 0.7 |
| VisionDetector | 图标/图像描述 | 0.7 / 0.5 |
| PlaywrightDom | 浏览器 DOM | 0.85 |
| VisionLLM | 通用多模态定位 | 0.7 |
| UI-TARS | 本地 UI-TARS-1.5 视觉 grounding | 0.85 |

路由器按适用性排序，先跑非视觉专家；第一个置信度超过阈值（默认 0.6）的结果直接返回；全部低于阈值时，才升级到视觉专家。这样既避免了“每次都调用视觉模型”的成本，也避免了“文本匹配失败就放弃”的脆弱。

这个设计的关键不是专家数量，而是**短路条件**：大部分点击都能被 Explicit、Text 或 UIA 以高置信度解决，视觉模型只处理真正的长尾。

## 动作之后要验证，卡住要能回到安全点

点击和输入不是“发出去就完了”。执行层会在动作前后各截一张图，比较变化，向 LLM 报告三种结果：

- `changed`：界面发生了变化；
- `unchanged`：看起来没变，可能点错了，也可能本来就没有视觉反馈；
- `unverified`：截图失败或无法比较。

如果连续 `unchanged` 达到阈值（默认 2 次），系统会提示回到最近的 checkpoint 重新决策。这就是恢复机制：不是让模型在错误状态里越陷越深，而是回到一个已知的安全点。

这套机制对桌面自动化尤其重要。网页可以靠 DOM 判断状态，桌面应用没有统一的 DOM；一次误点可能打开一个模态对话框，把后续所有步骤都带偏。前后截图对比不是万能的，但它是最便宜、最通用的验证信号。

## 记忆：让第二次做同一件事更快

记忆层记录成功任务的完整轨迹：任务描述、每一步的动作、坐标、结果。下一次遇到相似任务时，`recall` 会把历史轨迹、可复用技能和避坑提示返回给 LLM。

召回策略有三种：

- `recent`：最近 N 条；
- `similarity`：字符 bigram Jaccard；
- `info_theoretic`：信息论打分，对中文更友好（默认）。

任务结束后，反思引擎会总结成功/失败原因和标签；同类成功轨迹达到阈值（默认 3 条）后，抽象成 `ExperienceSkill`；失败教训保存为 `AntiPattern`。这让系统有机会“越做越快”，而不是每次从零开始。

不过，记忆也有边界：它只能复用“见过的路径”，不能保证在新界面上有效。所以记忆是加速器，不是正确性保证；最终还是要靠动作验证和 Grounding 兜底。

## 成本：文本优先，视觉按需

把上面的设计合起来，成本结构就很清楚：

- 默认输入是 markup，不是截图；
- 视觉模型只在 `look` 工具被 LLM 主动调用时使用，或者 Grounding 的非视觉专家全部失败时升级；
- 记忆复用减少重复推理的轮次；
- 分层规划让 Worker 只关注当前子任务，避免长上下文。

在系统设计文档里，评估口径是：网页任务总耗时控制在 3 分钟以内、单任务 5 次运行成功率 ≥80%、Token 消耗相比纯视觉方案降低 50% 以上。**这些是设计目标，不是本文宣称的实测结果。** 真正要验证，需要在固定机器、固定网络、固定账号状态下跑基准，且把成功判据写死。

## 工程约束：Windows 优先，DPI 是硬骨头

目前完整验证的平台是 Windows 10/11。原因很实际：UIA、DPI 换算、窗口管理都依赖 Windows 的实现；纯视觉路径设计上跨平台，但 UIA 带来的高置信度元素在别的平台上没有直接替代。

DPI 是桌面自动化里最容易翻车的地方。截图是物理像素，鼠标 API 用的是逻辑坐标；多显示器、不同缩放比例下，两者不是简单的一个系数。执行层在点击前会按当前显示器做物理→逻辑换算，UIA 操作则优先走 Invoke/Toggle/Value 模式，失败再回退鼠标。

危险操作默认逐次确认：PowerShell 工具默认关闭，文件删除、注册表写入等动作需要用户确认。这不是“模型能力”的一部分，而是产品边界。

## 小结

Agent-View 的核心不是某个模型，而是一条**表示管线**：

1. 把屏幕拆成元素，给每个元素一个稳定的 ID；
2. 把元素序列化成 LLM 能读的文本，坐标和状态都不丢；
3. 把 LLM 的引用通过多专家 Grounding 解析回像素；
4. 用动作验证、恢复、记忆和规划把长任务串起来。

这条路线的价值在于可解释：当一步失败时，你可以问“是感知漏了元素、表示错了 ID、Grounding 选错了专家，还是决策本身错了”。相比“再截一张图问问模型”，这种可分解的结构更容易定位问题。

代码和设计文档在 [Agent-View](https://github.com/LiaoZiqi-GZFLS/Agent-View)。它目前是一个 Windows 优先的 SDK，不是开箱即用的产品；但感知层、表示层和 Grounding 的分层，对其他平台的桌面智能体同样适用。