feat(web-access): 收尾约定——汇报前先确认页面仍在,且不再无条件关会话

两条都来自真机缺陷。

一、汇报前先确认

Agent 导航成功后直接汇报「 已打开,页面已可在内置浏览器面板中查看」,而会话早已因
BROWSER_RESOURCE_QUOTA_EXCEEDED:cpuPercentPerSession 被终止(重 JS 站点很容易命中),
用户看到的是一片空白。它拿的是上一次成功的结果,中间没有任何工具调用,因而无从知道
页面已经没了。

补一次 BrowserSnapshot 即可暴露:会话若已终止,工具返回 BROWSER_TOOL_SESSION_TERMINATED
并说明原因(该错误语义见主仓库 #2348)。此时如实说明会话中断,再决定重试、换轻量页面
还是交回用户——不得把先前的成功当作现状。

二、不要无条件 close_session

原流程第 7 步写死「任务收尾 close_session」。真机发生过:Agent 用两分钟做完演示随即关闭
会话,用户回头去看只剩空白面板——它做的事没错,只是没留给用户任何查看的机会。内置浏览器
要展示给用户,靠的是工作台呈现该会话;会话一关就什么都没有了。

改为按「用户还需不需要看」判断:演示/交互类保留并告知页面位置,纯抓取才关闭,用户明说
关掉就关。拿不准时保留——留着最多占一点资源,关早了用户得从头再来。

双语同步,en-US 为 human-locked 翻译,已手工同步并对齐 source_hash。version 3.2.0 → 3.3.0。
validate-i18n 与 translate --check 均通过。
This commit is contained in:
2026-08-28 21:57:40 +08:00
parent 2891f9dc06
commit e5d653222c
2 changed files with 66 additions and 9 deletions

View File

@@ -15,7 +15,7 @@ description: >-
新闻、网址、URL、找一下、搜一下、查一下、小红书、B站、微博、飞书、Twitter、
推特、X、知乎、公众号、已登录、登录状态。
license: Complete terms in LICENSE.txt
version: 3.2.0
version: 3.3.0
type: procedural
risk_level: low
status: enabled
@@ -41,7 +41,7 @@ provides:
- LocalBookmarks
metadata:
author: desirecore
updated_at: '2026-08-21'
updated_at: '2026-08-28'
i18n:
default_locale: en-US
source_locale: zh-CN
@@ -53,14 +53,14 @@ metadata:
short_desc: 联网搜索、网页抓取、内置受管浏览器登录态访问与取文、研究调研工作流
description: 联网访问工具包——搜索公开页面、Jina 优化抓取、内置受管浏览器完成登录态访问与取文,以及用户点名时接管他自己的 Chrome。
body: ./SKILL.zh-CN.md
source_hash: sha256:4d3bc4221b2d6b09
source_hash: sha256:3988a0abf7573385
translated_by: human
en-US:
name: Web Access
short_desc: Web search, page fetching, logged-in access via the governed built-in browser, research workflows
description: A web-access toolkit — search public pages, fetch heavy pages via Jina Reader, reach and read logged-in sites through the governed built-in browser, and drive the user's own Chrome over CDP on request.
body: ./SKILL.md
source_hash: sha256:4d3bc4221b2d6b09
source_hash: sha256:3988a0abf7573385
translated_by: human
market:
icon: >-
@@ -354,7 +354,36 @@ The full command surface, capability tiers, and boundaries are in [references/br
4. `BrowserSnapshot(semantic)` for interactive-element `ref` handles (cross-origin iframe elements are in the same tree with globally sequential refs)
5. Interact via `input.*` (humanized trajectories) or `page.element` (bulk form writes); wait for results via `page.wait` or inline wait blocks
6. Read body text via `BrowserSnapshot(text)` or `BrowserAct(page.extract-text)`; pull API data via the fetch.browser recipe
7. `BrowserManage(close_session)` when done
7. Wrap up: **confirm first, then decide whether to close** — see "Wrapping up: before you report, before you close" below
### Wrapping up: before you report, before you close
**1. Before reporting a browser result to the user, take one more snapshot to confirm the page is still there.**
Never report based on an earlier successful navigation. The session may have been terminated since —
most often by the resource quota guard (`BROWSER_RESOURCE_QUOTA_EXCEEDED`), which heavy JS sites hit
easily. This happened in the field: the agent navigated successfully, reported "✅ opened, the page is
visible in the built-in browser panel", while the session had already crashed and the user was staring
at a blank panel.
One `BrowserSnapshot` (`text` or `visual`) before reporting surfaces this: if the session is gone, the
tool returns `BROWSER_TOOL_SESSION_TERMINATED` with the reason. When that happens, **tell the user the
session was interrupted**, then decide whether to retry, switch to a lighter page, or hand it back —
never present the earlier success as the current state.
**2. Do not close the session unconditionally. The test is whether the user still needs to look at it.**
| Task nature | Wrap-up |
|---|---|
| Demo / interactive / user wants to see the result | **Keep the session** and tell them where the page is, so they can take over |
| Pure data extraction, text already retrieved | Close it and free the resources |
| User explicitly said "close it when done" | Close it |
Showing the built-in browser to the user depends on the workbench presenting that session; close it and
there is nothing left to show. This happened in the field: the agent finished a two-minute demo and
immediately called `close_session`, leaving the user with an empty panel — nothing it did was wrong, it
just left no chance to look. **When in doubt, keep it**: keeping costs a little resource, closing too
early costs the user the whole run.
Multi-step sequences (navigate→snapshot→click→wait→extract) can be done in one `BrowserScript` run, skipping the per-action IPC round trips.
@@ -427,7 +456,8 @@ Notes:
← body text read out directly; if too long, pass back the returned nextCursor to continue
7. Need to confirm rendering → BrowserSnapshot({ mode: 'visual' }) (pixels readable in place)
8. SitePatternRead({ domain: 'xiaohongshu.com' }) ← read accumulated experience
9. At task end → BrowserManage({ action: 'close_session', sessionId })
9. Before reporting → one more BrowserSnapshot to confirm the page is still there (the session may have been quota-terminated)
10. At task end → if the user still wants to look, **keep the session** and say where the page is; close only for pure extraction
10. If you find a new pitfall → SitePatternWrite({ domain, scope: 'agent', mode: 'merge', content })
```

View File

@@ -264,10 +264,36 @@ See [references/jina-reader.md](references/jina-reader.md) for advanced endpoint
4. `BrowserSnapshot(semantic)` 拿可交互元素 `ref`(跨源 iframe 的元素也在同一棵树里ref 全局连续编号)
5. 交互用 `input.*`(拟真轨迹)或 `page.element`(表单批量写);等结果用 `page.wait` 或内联 wait 块
6. 取正文用 `BrowserSnapshot(text)``BrowserAct(page.extract-text)`;取接口数据用 fetch.browser 配方
7. 任务收尾 `BrowserManage(close_session)`
7. 收尾:**先确认、再决定关不关**,见下方「收尾:汇报之前与关闭之前」
多动作连续编排(导航→快照→点击→等待→取文)可用 `BrowserScript` 一段脚本完成,省去逐动作 IPC 往返。
### 收尾:汇报之前与关闭之前
**一、向用户汇报浏览器结果之前,先用一次快照确认页面仍在。**
不要拿上一次成功的导航结果直接汇报。会话可能在那之后被系统终止——最常见的是页面持续占用
过多资源触发配额保护(`BROWSER_RESOURCE_QUOTA_EXCEEDED`),重 JS 站点很容易命中。真机发生过:
Agent 导航成功后直接汇报「✅ 已打开,页面已可在内置浏览器面板中查看」,而会话早已 crashed
用户看到的是一片空白。
汇报前补一次 `BrowserSnapshot``text``visual` 均可)即可暴露这类情况:会话若已终止,
工具会返回 `BROWSER_TOOL_SESSION_TERMINATED` 并说明原因。此时**如实告诉用户会话中断了**
再决定是重试、换更轻量的页面,还是交由用户处理——绝不能把先前的成功当作现状。
**二、不要无条件 `close_session`。判据是「用户还需不需要看」。**
| 任务性质 | 收尾 |
|---|---|
| 演示 / 交互 / 用户要看结果 | **保留会话**,并告诉用户页面停在哪、可以直接接管 |
| 纯数据抓取,正文已取回 | 关闭,释放资源 |
| 用户明确说「用完关掉」 | 关闭 |
内置浏览器的画面要展示给用户,靠的是工作台把会话呈现出来;会话一关,用户就什么都看不到了。
真机发生过Agent 用两分钟做完演示随即 `close_session`,用户回头去看只剩空白面板——它做的事
没错,只是没留给用户任何查看的机会。拿不准时**保留**:留着最多占一点资源,关早了用户就得
从头再来一遍。
## L3 速查v3.0
### 读页面:按需求选通道
@@ -336,8 +362,9 @@ BrowserAct:
← 正文直接读出;太长就传上一页返回的 nextCursor 续读
7. 需要确认渲染效果 → BrowserSnapshot({ mode: 'visual' })(像素直接可看)
8. SitePatternRead({ domain: 'xiaohongshu.com' }) ← 读累积经验
9. 任务结束 → BrowserManage({ action: 'close_session', sessionId })
10. 如发现新陷阱 → SitePatternWrite({ domain, scope: 'agent', mode: 'merge', content })
9. 汇报前 → 再来一次 BrowserSnapshot 确认页面仍在(会话可能已被配额终止)
10. 任务结束 → 用户还要看就**保留会话**并告知页面位置;纯抓取才 close_session
11. 如发现新陷阱 → SitePatternWrite({ domain, scope: 'agent', mode: 'merge', content })
```
## 站点经验积累