agent 执行的每一个浏览器、命令、文件与桌面操作,都以 computerId 显式指名目标机器。这不是 UI 约定:工具层内部强制执行,没有有效且已授权目标的调用即失败。工具绝不回落到本地机器、「活跃」计算机或任何其他机器。
三个正交维度
决定工作在哪里运行,涉及三个互相独立的决策。任何一个都不蕴含另一个:
| 维度 | 选择 | 它不意味着什么 |
|---|---|---|
| agent runtime 所在位置 | 本地或云端 | 不决定每次工具调用触碰哪台机器。 |
| 工具执行目标 | 必填的 computerId |
不是 IP 地址、用户 ID、会话 ID 或代理客户端 ID。 |
| 网络 egress | 直连,或选定的客户端代理 | 不搬移 runtime,也不授予对客户端机器的控制。 |
浏览器可以跑在 A 机上、经 B 机的网络出网——这是两个彼此独立、分别授权的选择。不需要隧道时,默认 direct egress 仍遵循执行机器自身的路由。一旦选定了客户端代理,egress 选择即失败即关闭(fail-closed):隧道不可达时调用失败,而不是静默回落到 direct;切换 egress 是显式的生命周期变更,不是留着旧隧道继续用的 UI 开关。
每次调用发生什么
OS 级工具(shell、文件读/写/列/删、浏览器导航/快照/标签页、桌面动作)在模型看到它们之前,先被一层 middleware 包装。包装层强制目标纪律:
- 缺少
computerId→ 显式报错并指名该操作。这一层拒绝猜测目标,底层工具不会被调用。 computerId: "local"→ 调用直达本地实现,无路由开销。- 任何其他
computerId→ 路由器解析计算机,检查它存在且在线,校验所有权,然后派发给匹配的 provider(Docker、Windows,或已登记机器的设备 daemon)。工具层另行核实该计算机声明了此工具所需的能力——在无桌面控制的机器上执行桌面动作会以能力错误失败。
路由决策
computerId |
路径 | 开销 |
|---|---|---|
"local" |
直达本地 provider | 无 |
| UUID(docker/windows/enrolled) | 注册表 → 在线检查 → 能力检查 → provider | 约 5 ms(已登记机器另加网络 RTT) |
| 空 / 缺失 | 以指名工具的错误拒绝 | 无 |
调用在以下情况显式失败:
computerId缺失或为空;- 计算机不存在、已销毁/已吊销,或处于离线状态;
- 该计算机的类型没有注册 provider;
- 发起调用的账号不拥有该计算机;
- 或该计算机不具备此工具所需的能力。
每一种都是附带原因的类型化错误——能力缺失错误同时携带所需能力集与实际可用能力集。其中没有任何一种会换一台机器重试。
两层授权
目标被重新授权两次:调用被路由时在控制面授权一次;设备 daemon 收到方法时在目标节点再授权一次。模型给出的参数从不被单独信任——daemon 会为请求的方法核对声明的能力,并显式拒绝超出能力的操作。
句柄与所属计算机绑定
会话、标签页、终端等资源句柄与创建它们的计算机绑定。来自 A 机的句柄在 B 机上无法解析;tabId 会校验确实属于配合使用的那个会话,跨任务使用句柄会被拒绝。句柄不是走到哪都能用的 bearer token。
审计
浏览器工具调用在执行前先审计。每次调用发出一条结构化记录,写明工具族、动作、目标 computerId 以及涉及的会话/标签页句柄,带毫秒级时间戳:
{ "tool": "browser", "action": "navigate", "computerId": "…", "sessionId": "…", "tabId": "…", "at": 1760000000000 }
记录进入审计 sink——默认是 stderr 上的一行结构化日志——sink 可插拔,部署可以把工具审计接进自己的日志收集处。
范围
computerId 授权面只覆盖 OS 级工具:文件操作、浏览器操作、命令执行与原生桌面动作。MCP 服务器与插件市场的工具不绑定 computerId——它们是你自行安装并信任的扩展,不是 agent 驱动的机器操作。
关于计算机本身——托管创建(provisioning)、enroll 登记与生命周期——见云电脑。浏览器会话与标签页管理构建在这套路由之上,见浏览器会话。