---
name: capybrowser
description: 当用户希望接入百智云云浏览器、完成网页任务、复用登录状态或主动查询当前能力与使用说明时，遵循此执行流程。先核对当前服务与能力边界，更新信息按需处理。
---

# 云浏览器 · Agent 执行流程

你的职责是替用户完成接入和使用，在原对话里交付实际结果。不要只返回教程或让用户代做工具选择、档案创建等可由你完成的准备。

## 与用户交流的方式

先用一句话介绍云端网页操作与登录状态复用的能力。已有明确任务时直接围绕目标行动；目标不清楚时，通过简短提问了解“先试示例”还是“完成自己的任务”。问用户想得到什么，不让用户替你完成技术设计。

有结构化提问工具时可给两个简单选项；收到回答后自然确认一句再行动。不重复已有答案、不把所有后续分支一次列出。前端简单不代表 Agent 对话不能提问或解释；每一步应让用户清楚正在发生什么、会得到什么。

只在第一次实际用到时解释概念：运行是一次启动的浏览器；档案是可跨次加载的登录与网站状态。解释一两句，然后继续执行，用户追问再深入。只有服务实际提供可供用户打开的链接时，才能说明其用途；观看链接只针对已有运行，不是通用公开旁观入口。

## 1. 先确认服务和环境

首次任务先读取[最短接入说明](./installation.md)，确认服务地址、页面操作能力和执行合同。复杂情形再查[详细参考](./browser-reference.md)，不要把两份文档都当作首次必读。当前 Agent 无法访问文档所示服务地址，或健康与鉴权响应异常时，简短说明这项阻塞，不调用前端演示接口、不安装无效依赖、不生成模拟成功结果。

先用无鉴权、无计费的 `GET /version` 记录服务构建版本与 API 合同版本，再验证身份。验证后用只读的 `GET /openapi/v1/pricing` 或 `browser_pricing` 获取当前价格；这一步不创建运行或收费。用户可在原对话里说“这次用指定线路”或“以后我的浏览器都用指定线路”：本次选择先查询 `GET /openapi/v1/browser/egress-lines` 或 `browser_list_egress_lines`，创建时传 `egress_line_id`；长期偏好用 `PATCH /openapi/v1/browser/profiles/:id` 或 `browser_update_profile_egress` 保存。未指定就沿用 Profile 偏好或默认云出口。MCP `initialize.serverInfo.version` 应与服务构建版本一致；版本不同不等于合同不兼容，也不能证明某个历史问题已修复。详细路径、限制和 FAQ 以[详细参考](./browser-reference.md)为准。

服务正式可用后，检查已有工具、配置与项目约定；能复用就复用，只补缺失项。技术选择由你根据兼容性与现有环境完成。不要先问用户选语言、协议、一次性模式还是档案。

只在新逻辑任务开始、收费创建之前按客户端独立缓存比较可选 `agent_guide.revision`；首次只建基线，修订变化才按需读取同源 `GET /version?view=agent-guide`，同修订安静，失败不阻断任务。已有任务的恢复/控制/结束/结算不插检查。MCP 初始化说明提供同一修订和资源 `capybrowser://service/agent-guide`；可主动用 `resources/read` 查询完整能力，服务不推送文档更新。机器信号不代表模型或用户已读，默认不播报；仅在与用户当前需求有关时介绍相应功能。功能支持与当前用户/环境是否配置可用分开核对，不能推断其他环境已上线。具体有界检查、缓存与同源规则见[按需发现说明](./agent-updates.md)。

若客户端已配置云浏览器 MCP，可用同名 `browser_*` 工具完成运行、档案、人工处理、下载及用量查询；它们与 HTTP OpenAPI 共用同一权限和费用合同。用 `browser_create_session` 时传稳定的 `idempotency_key`，不要因为切换 MCP/HTTP 就重新创建。页面本身仍需从 `browser_control` 取得 CDP 地址后用兼容客户端操作；MCP 连接成功或运行创建成功都不是网页任务完成。

HTTP 普通成功响应从 `data` 取业务对象。MCP `tools/call` 即使得到 HTTP 200，也要检查 `result.isError`；普通工具解析 `result.content[].text` 中的 JSON，下载内容则读取 resource 块的 base64 `blob`。下载保存到本机后核对长度与 SHA-256。分页参数传整数；`browser_usage_summary` 的 `since`、`until` 都传 RFC3339 时间，且 `since < until`。

目标或项目范围不清楚时可以澄清；缺少工具执行能力、文档不可达、凭据未配置或缺少必要授权时，提出能解除当前阻塞的具体请求。已经获得的授权不重复询问，具体安装与写入遵守执行环境规则。

## 2. 验证使用资格，再开始

按接入参考中已发布的方法验证权限与限额。平台确认网关已为本应用启用个人中心 Key 鉴权时可使用平台 Key，应用内 Key 是兼容备用；两者都只作为 Bearer 凭据配置，不手动设置 `X-Baizhiyun-*` 身份头。仅有密钥文本或用户点击过复制，不代表验证通过。不要输出敏感凭据；也不要凭空要求项目 ID、档案 ID 或额外模型服务密钥。

验证失败先区分原因：服务不可达、凭据无效、权限不足、积分不足或并发占满。依据实际响应处理，不把所有错误都解释成“密钥不对”。

未认证的管理请求可返回 401；已认证后的资源不存在与不可见统一为 JSON 404；未知路径或一次性 CDP 链接失效也可能表现为 404/握手失败。结合发生阶段、响应类型和 Session 状态判断，不解析 Go/nginx 默认错误正文，也不泄露其他用户资源是否存在。

## 3. 按目标完成第一次使用

用户没有明确任务时，问一次“先试一个小例子，还是直接完成自己的任务？”用户已选过或明确任务时跳过该提问。

- **试个例子**：选择无需登录、无副作用的公开页面，先说明实际目标，再读取标题或正文；不要硬编码未经确认的网站或虚构结果。
- **自己的任务**：确认目标和必要网站信息，然后执行。只有确有需要时先做最小连通性检查，不强行追加教学演示。
- **接入现有项目**：用户提到项目时，检查语言、包管理、已有自动化代码和凭据配置方式；范围不清楚才确认。遵从项目约定，不盲目创建新工程。

开始前说明预期结果，执行中按需解释新概念。例如“我会在云端打开公开页面，读取标题和正文，再整理结果”。服务实际返回可供用户打开的链接时才说明用途后提供；没有链接时用实际结果、截图或关键节点说明过程。

- 首次公开网页样例不关联档案。申请限时运行（未指定 `max_seconds` 时为 900 秒；新运行可按任务设置 1–7000 秒），记录完整运行标识，等到明确就绪，再进行页面操作。到达公开 `expires_at` 时停止操作并开始结束运行。
- 判断页面状态后执行下一步，避免依赖固定等待。依据实际看到的内容生成结果，不把预期示例文本当作抓取结果。
- 在实际进展变化时简短反馈。只有确实收到可供用户打开的链接，才按其真实用途提供；不要把一次性 CDP 控制地址当作观看链接。
- 没有进展时按合同超时或错误进入恢复流程，不无限等待、不无依据循环重试。

首次体验以尽快取得真实结果为目标，不承诺固定时长。

服务请求桌面启动窗口，但不要承诺固定 CSS 布局视口。页面就绪后，在同一 Target 分别测量 `screen`、`outer`、`inner`/`visualViewport` 和 CDP window bounds。设备 emulation 与真实窗口 resize 是两层状态；clear emulation 恢复当前真实窗口对应的视口，不抹掉主动 resize。`configured_environment=null` 只表示没有完整版本化模板，不等于没应用启动尺寸，也不会清除旧档语言、时区或登录内容。

任务涉及网页下载时，点击下载后轮询当前 Session 的制品列表。只使用条目的 `id`、`filename`、`state`、`size_bytes`、`sha256`、`error_code`：仅在 `item.state === "ready"` 时，把 `item.id` 填入内容 URL 的 `:download_id`，不读取 `status` 或 `download_id` 条目字段。通过客户端库的大小写不敏感 Header 接口读取 `Content-Length` 与 `X-Content-SHA256`，保存后核对长度和 SHA-256；0 字节、长度或摘要不符、响应中断都不是成功。

## 4. 遇到问题时继续承担处理

| 实际情况             | 下一步                                                                 |
| -------------------- | ---------------------------------------------------------------------- |
| 调用结果不确定       | 先查询已知运行；依据幂等合同重试，不直接新建第二个浏览器               |
| `control_busy` | HTTP `409` 不会撤销手中仍有效的旧 `cdp_url`。地址丢失时先 GET 原 Session；仅当 `control_grant.phase=awaiting_first_connection`、未到期且无人工操作，用原凭据调用 `browser_recover_control`（HTTP `/control/recover`），传当前 `control_grant.id` 为 `expected_grant_id`。旧服务的 `control_phase=awaiting_first_connection` / `retry_after_seconds` 只是等待信息。详见[接入参考](./browser-reference.md#丢失未使用控制链接时恢复)。 |
| `control_grant_changed` / 换发响应不明 | 先 GET 同一 Session；若当前未使用链接仍丢失，才用当前新引用显式恢复一次；`claimed` 或人工操作中停止换发，不抢占。禁止自动循环、删除重建或重放网页写操作。 |
| `control_recovery_unavailable` / `control_recovery_forbidden` | 前者表示原链接已过期或首次连接已开始，查当前状态走普通恢复路径；后者要求签发原链接的同一身份和凭据，不换 Key 强行恢复。 |
| 依赖缺失或版本不兼容 | 参照已发布兼容性和项目约定修复，复用已有环境                           |
| 积分或并发限制       | 说明具体限制与必要动作，不反复申请运行，也不结束无关运行               |
| 页面加载或操作失败   | 检查当前页面和错误，做有依据的修正；仍失败则返回实际原因并清理本次资源 |
| 必须本人登录或授权   | 提供对应运行的处理链接，按下一节交接                                   |
| 状态保存或释放未确认 | 保留运行标识与待核对状态，按合同查询或重试清理，不宣称已完成释放       |

先观察并修正原因，再对同一操作最多重试一次；创建结果不确定时必须复用原 Idempotency-Key。仍失败就报告并清理，不能无限循环。默认完整加载失败且确认任务只需要文本时，可说明限制后尝试一次阻断 image/media/font 的受限加载；表单、布局、截图或视觉任务不得使用，最终报告必须标注“受限加载”。

## 5. 状态与人工处理按需使用

原有 `browser_begin_handoff` / `POST /handoff` 可以继续直接使用，无需先建观看链接、增加参数或更换客户端。观看只是可选入口；旧入口的多页面选择行为保持原合同，不能假定会自动选择 Agent 正在使用的任意标签页。

用户要求观看当前运行时，若服务提供 `browser_create_view_link`，对**同一个已就绪 Session**签发 `scope=view` 链接并把返回的 `page_url` 交给用户；只有用户明确希望必要时亲自操作，才用 `scope=view_takeover`。使用稳定的 `idempotency_key`，签发结果不明时复用原键核对，不新建 Session 或盲目换发。链接由首次领取的浏览器使用，可用 `browser_revoke_view_link` 按 `grant_id` 撤销。签发和观看不会打断 Agent；只有用户在观看页明确确认后才进入人工接管。交还后重新取得原 Session 控制并检查页面状态，再继续任务。不要把 CDP 控制链接当观看页链接，也不要把页面显示的旧帧视为已经更新。详细权限和期限见[接入参考](./browser-reference.md#实时观看与主动接管)。

主动接管会断开原 CDP 控制连接；这不能直接判定任务失败或对原 Session 执行 `DELETE`。先用原 Session ID 查询 `human_action_status` 和运行状态。若 `human_action_status=in_progress`，停止网页写操作、自动重连抢占和自动清理，保留原 Session 身份及待核对的写操作；确认交还或人工期限结束后，再为原 Session 申请控制、重新观察页面。状态不明时有界重查并报告未知，不推断已交还或继续执行，也不重放结果不明的写操作。此处只约束使用本 Skill 的 Agent，不能保证自动暂停其他第三方 Agent。

只有任务确实需要保留或复用状态时，才选择或创建有权限的档案。临时运行无需档案，创建档案也不等于启动浏览器。同一档案占用中时不能覆盖或并发使用。主动结束或到达公开 `expires_at` 后，查询原运行直至保存和释放结果明确；到期后的收尾不增加运行费用，也不允许继续页面操作。保存失败时保留已有可信旧快照；没有旧快照时标记 `recovery_required`。

`POST /control` 返回的 `expires_at` 只表示控制链接最晚首次建连时间，固定为 5 分钟并受 Session 到期时间限制；成功建立的连接持续到客户端断开、Session 公开到期或被服务撤销。同一链接不能并发连接第二次。未使用链接过期或连接异常断开时，先查询原 Session；确认未处于人工操作且仍 ready，才申请新控制链接并重新观察页面，不询问用户、不新建 Session、不重复收启动费。结果不明的网页写操作不得自动重放。

需要本人处理时，暂停自动操作，在原对话里直接提供该运行的处理链接与一句具体原因，例如“这个网站需要你登录，请打开这个浏览器窗口完成登录”。不要让用户自己查运行列表，也不要求用户理解控制权协议。

用户完成后，按合同确认交接、恢复控制并重新观察页面，然后继续原任务。`POST /handoff` 返回 `human_action.url` 和 `human_action.expires_at`，此时到期时间表示最晚首次进入；Agent 安全保留链接。首次进入成功后，Session 查询中的 `human_action.expires_at` 表示人工操作截止时间，原首次进入期限不会中断已开始的操作；人工操作截止时间由服务配置决定，且不晚于 Session 的 `expires_at`。查询 Session 不重发链接，`url` 为 null，无有效需求时整个 `human_action` 为 null。等待进入或人工操作到期只撤销人工控制并交回 Agent，不结束原运行；仍需人工处理时重新生成链接。若原运行已超时释放，如实说明，按保存结果决定能否继续；不能假装原浏览器还在。

人工画面空白不必然是断线：区分真实空白页/仍在加载、站点阻断、尚无首帧与连接失效，不自动导航覆盖原页面。断线或人工结束后都在原 Session 重新申请控制、重新观察页面；不重复创建，不重放结果不明的写操作。

未过期的链接不可用且原 Session 仍为 `human_action_pending` 时，可换发一次新链接或取消等待，旧链接立即失效；若用户已开始操作，Agent 不得自动换发、取消或抢占。只有用户在原 Agent 对话中明确要求撤销时才调用 revoke：应用内鉴权必须继续使用发起当前人工处理时绑定且仍有效的那一把 API Key，同一用户的其他应用 Key 不可替代；平台可信网关鉴权则使用当前已认证的平台身份，客户端不得自行填写网关身份头。只读身份验证通过不等于该资源操作一定获准。服务端不能验证自然语言意图，因此不要根据故障或超时自行推断授权；控制台手动撤销仍可作为备用。换发后仍不可用时排查实际页面或网关原因，不无限重试。撤销或正常交还后在原 Session 重新申请控制、观察同一页面，不新建运行或重放结果不明的写操作。

`GET /openapi/v1/browser/sessions/:id` 的 `human_action_status` 可区分 `waiting`、`in_progress`、`completed`、`cancelled`、`expired`、`revoked`；`none` 表示没有可判定的结果。结束结果保留到下一次人工处理开始。不要只凭 `control_state=agent` 猜测用户是否交还、取消或被撤销。

## 6. 返回结果，确认释放

视口覆盖本身不能解释状态保存失败，保存前不必清除覆盖。先核对原 Session 最终 `save_status`；`saved` 后再用 Profile 的 `current_version` 和 `last_saved_session_id` 关联提交结果。后续 Session 可继续推进 latest，不能用后来指向变化否定早先已保存事实。`snapshot_sha256` 只标识快照，不要求每次变化，也不证明网站仍免登录。保存失败、快照恢复失败、网站要求重新认证是三个不同结论；失败时保留旧 Profile 和可信旧版本，不自动删除，不猜底层根因。

正常与异常路径都要结束自己创建的运行并确认资源已释放；在停止前先取回需要的下载。人工正在操作时暂缓自动结束，保留清理责任，待交还或运行到期确认后再按原任务收尾。若当前 Agent 只是连接用户提供、由其他流程拥有的 Session，不自动结束，除非用户明确把结束责任交给当前 Agent。清理本身失败时保留信息供后续核对。将业务任务结果、档案保存、资源释放和费用结算作为分别验证的事实。

最终在原对话中简短提供：

- **结果**：实际得到的信息或完成的动作；未完成则指出具体失败点。
- **过程说明**：服务实际返回可打开的链接时说明用途后提供；没有则给出实际结果、截图或关键节点。人工处理链接只在确有本人操作时提供。
- **释放状态与费用**：`status=released` 才能确认浏览器已关闭且不再计费；仍待核对则明确说明。只按 `billing.status` 报告费用：`settled` 时用 `billing.actual_charge_centipoints` 换算实际费用，不能用估算代替；`waived` 为未扣费，`reserved` 为积分已预留，`preparing` 为预留准备中，`settling` 为结算中，`review_required` 为待核对。仅运行中且尚未结算时可按 `billing.estimated_charge_centipoints` 报告预计费用。金额为精确整数，100 centipoints = 1 积分；未知金额为 null，零为确定的零。

排障只按需记录服务版本、Session/request ID、时间、终态、保存/释放/billing 证据；不要输出 API Key、Cookie、CDP 或人工控制链接。当前运行、控制、下载和 Profile 限制及排障清单见[详细参考](./browser-reference.md#短-faq-与排障)。

首次示例成功后，可以自然问“想用它试试你自己的哪个任务？”已有实际任务则围绕结果继续；不要自动启动新工程、安装或再次重复起步菜单。告诉用户后续直接在原 Agent 对话中提任务即可。

用户留在原来的 Agent 中提出任务；云浏览器只提供浏览器运行与状态管理能力。不要把控制台扩展为内置 Agent 或任务编排平台。

成功和失败都可展示 Session ID。成功时说任务结果、浏览器已关闭且不再计费、实际费用；失败时自然说明原因和下一步。请求 ID 只在排障时展示，不原样复述后端字段名。
