跳到正文

快照与 ref

ref 属于产生它的那次快照。这一页讲它的构成、重新识别方式和失效后的动作。

snapshot 把一棵可访问性树读成 JSON,并给其中每个智能体能操作的元素分配一个 ref。 智能体之后所有的动作都指向这个 ref。

ref 的构成

@s8f3k2p9:e8
└─┬─────┘ └┬─┘
  │        └ 元素在这次快照里的序号
  └ snapshot_id

id 两段缺一不可。只写 @e8 会被拒绝并返回 INVALID_ARGS——脱离快照的序号没有含义, 下一次快照里的 e8 很可能完全是另一个元素。

ref 指向什么

一个 ref 背后是这次快照里那个节点的读数:角色、名字、可用动作,以及它是从哪棵子树里来的。

{
  "role": "treeitem",
  "name": "Documents",
  "ref_id": "@s8f3k2p9:e8",
  "available_actions": ["Click"]
}

available_actions 是选择动作的依据。对不在列表里的动作发起请求,会被平台拒绝。

ref 如何被重新识别

动作执行前,agent-desktop 会从存储的条目重新识别这个 ref。从 2.6 起,Windows、Linux, 以及 macOS 上无法取得元素地址的 ref,采用同一套证据规则:

  • 快照必须完整读取过它的窗口,并证明捕获时恰好有一个元素匹配它的完整谓词: 角色加上记录的稳定字段(native id、稳定 name、稳定 description)。
  • 解析时在当前窗口重新计数这个谓词,只接受恰好一个匹配。
  • 骨架、深度截断和 --root 下钻都只是同一次完整窗口观察的浅层呈现,它们的 ref 仍然按整个窗口计数。
  • 值(value)和位置(bounds)永远不参与身份判断。

如果快照需要完整读取窗口才能证明 ref,但没能读完,data.identity_unproven 为 true。 这不影响 complete 对当前呈现树的描述,但这批 ref 都会以 identity_not_unique 失败; 用更大的 --timeout-ms 重拍。

macOS 上带元素地址的 ref 走另一条路:地址失效,或进程、角色、标识符不再匹配时, 直接返回 retained_object_stale,不执行搜索,避免落到相似元素上。

什么时候失效

界面是活的。产生 ref 的那次快照对应的界面状态一旦被替换,ref 就不再安全。

情形 结果 该怎么做
只写了序号,没带快照 id INVALID_ARGS 用完整的 @snapshot:序号
元素消失,或 macOS 的元素地址失效 STALE_REF(details.kind 为 saved_ref_absent / retained_object_stale) 重新快照,改用新快照里的 ref
捕获之后出现了完全相同的元素 AMBIGUOUS_TARGET(saved_ref_ambiguous) 换一个在窗口内唯一的控件;重新快照会同时拒绝两个双胞胎
捕获时没有证明 ref 唯一,或窗口没能在超时内读完 AMBIGUOUS_TARGET(identity_not_unique) 换唯一控件;只是超时则用更大的 --timeout-ms 重拍
用 --app 选目标时应用有多个窗口 AMBIGUOUS_TARGET,error.details 列出候选窗口 id 用 --window-id 指定其中一个

最后一行的多窗口歧义是目标选择层面的问题,和 ref 身份歧义不是一回事。遇到 AMBIGUOUS_TARGET 先读 details.kind,不要一律用 --window-id。

上述 ref 身份失败都带 details.retryable: false,并且是 not_delivered。 它们的 disposition.retry 仍然是 safe,因为什么都没发送;但重复同一个 ref 会得到同样的拒绝。 唯一的例外是 resolution_identity_unknown:实时字段读不到导致身份计数未完成,它会以 TIMEOUT 报告,可以重试。

正确的用法

一次动作之后必然跟一次读取。这不是保守,是因为动作成功只说明请求被接受了, 不说明界面按你的预期变了。

agent-desktop snapshot --app Finder -i              # 读,拿到 snapshot_id
agent-desktop click @s8f3k2p9:e8                    # 用这次读到的 ref 动作
agent-desktop snapshot --app Finder -i              # 再读,核对结果

需要「等到某个值变成什么」时,用 wait 而不是反复快照:

agent-desktop wait --element @s8f3k2p9:e6 --predicate value --value 7

下一步

输入关键词搜索…

↑↓ 导航↵ 选择Esc 关闭