diff --git a/browser-harness/SKILL.md b/browser-harness/SKILL.md index 774344c..13e412d 100644 --- a/browser-harness/SKILL.md +++ b/browser-harness/SKILL.md @@ -17,6 +17,10 @@ Direct browser control via CDP. For task-specific edits, use `agent-workspace/ag `agent-browser` / `playwright-cli` 插件已置 `false`。 - ⛔ **不附着用户日常 Chrome**。下面「Local Chrome」一节说的"默认附着正在运行的 Chrome" 在本机**不适用** —— 那样会弹「允许远程调试?」去动用户自己的浏览器(2026-09-26 实际踩到)。 +- 🔴🔴 **一类任务只开一个标签页并复用,⛔ 禁止反复开**(2026-10-09 用户令)。 + 反复开页会把共享实例堆到**整机卡死**(端口不应答、进程不死,保活脚本也救不回 —— 见下面那条的实测读数)。 + 细则(什么叫"一类任务"、换路由/换视口/换页面各怎么办)**只写在下面那颗同名的 🔴🔴 子弹里**, + ⛔ 本处不复述 —— 但要记住它**优先于任何"顺手再开一个"的念头**。 ⇒ 必须起**独立实例**:`BU_CDP_URL=127.0.0.1:9223`(不要用用户 Chrome 默认的 9222)。 - 🔴 **先探测、能复用就复用**(2026-10-08 用户当场点破:「为什么要重新开浏览器,先检查之前是否开过浏览能否复用」)。 动手第一件事是查 `9223` 上**有没有已经在跑的实例**;有 ⇒ 直接连,⛔ 不要再起一个。 @@ -27,17 +31,22 @@ Direct browser control via CDP. For task-specific edits, use `agent-workspace/ag `curl --noproxy '*' -s http://127.0.0.1:9223/json/version` ⇒ 回 JSON 说明端口后面确实是 CDP。 确认在跑之后按下面第 2 条的 env 写法连上去,先 `list_tabs()` 摸清现有页, 自己需要的页用 `new_tab()` 开 —— ⛔ 不碰别人的页,也⛔ 不为自己方便关掉现有页。 -- 🔴 **一个页面只开一个标签,⛔ 不要反复开**(2026-10-08 用户令:「后续调试网页 一个页面开一个标签就行了不要反复开」)。 - 这条接在上一颗子弹后面:**先复用浏览器**是做对了,但**别在同一个浏览器里再反复开页**。 - 典型的错法就是调试一个原型:量一次 `new_tab(原型)` 一次,量完还忘了关 —— 一次会话下来 - 共享实例里就堆出一串**同一个页面**的标签(用户 2026-10-08 亲眼看到,才出的这条令)。 - 正确做法,按便宜的排: - - **同一个页面**(同一个 URL / 同一份原型)**从头到尾就那一个标签**。 - - 换路由 ⇒ 改 hash(`js("location.hash='#/x'")`)或 `goto_url()`,⛔ 不要 `new_tab()`。 - - 换视口 ⇒ `cdp("Emulation.setDeviceMetricsOverride", width=…, height=…)` 在**同一个标签**里改, +- 🔴🔴 **一类任务只开一个标签页并复用,⛔ 禁止反复开**(2026-10-08 用户令「后续调试网页 一个页面开一个标签就行了不要反复开」;2026-10-09 加严到**按任务算**:「一类任务只允许开一个标签页并复用,禁止反复开标签页」)。 + 这条接在上一颗子弹后面:**先复用浏览器**是做对了,但**别在同一个浏览器里反复开页**。 + ⚠️ **这不是"标签堆着难看"的问题 —— 它能把整机拖到卡死**(2026-10-09 实测):反复开页把共享实例堆爆后, + Chrome 会进入**端口不应答、进程却还活着**的僵死态,而保活脚本只看端口 ⇒ 查不出、也救不回。 + 当天现场读数:保活日志 `06:56 端口 9223 不应答(pid alive=True)`,直到 `07:06` 进程才退出;用户手动关掉全部会话。 + 典型错法:调试一个原型,量一次 `new_tab(原型)` 一次、量完忘了关 ⇒ 一次会话堆出一串同一个页面的标签。 + + **什么算「一类任务」**:同一件事的一整串动作 —— 同一个原型 / 同一轮站点调研 / 同一批数据抓取。 + 这类任务**从头到尾只用一个标签**: + - **同一个页面**(同一 URL / 同一份原型)⇒ 就那一个标签。 + - **换路由** ⇒ 改 hash(`js("location.hash='#/x'")`)或 `goto_url()`,⛔ 不要 `new_tab()`。 + - **换到同任务的另一个页面** ⇒ 也优先在**同一个标签**里 `goto_url()`,⛔ 不要为新页面开新标签。 + - **换视口** ⇒ `cdp("Emulation.setDeviceMetricsOverride", width=…, height=…)` 在**同一个标签**里改, ⛔ 不要为了量另一个宽度再开一个标签;量完 `cdp("Emulation.clearDeviceMetricsOverride")` 还原。 - - 要**并排对比两个不同页面**(比如参照物 vs 我方)⇒ 这时才开第二个,**用完立刻 `close_tab()`**。 - - 完全不需要页面时(只取一个数、截一张图)⇒ 复用**当前那个**标签,别再开。 + - **只有必须并排看两个页面时**(参照物 vs 我方)才开第二个,**用完立刻 `close_tab()`**。 + - **完全不需要页面时**(只取一个数、截一张图)⇒ 复用**当前那个**标签,别再开。 - 🔴 **收工前必须 `list_tabs()` 复核一遍,把自己开的一个不留**。共享实例是别人的工作现场, ⛔ 别留尾巴;反向也一样 —— ⛔ 别顺手关掉不是自己开的页。 - ✅ **动手前先 `list_tabs()`** 看清有哪些标签页,别盲点。(这条同时是上面那条的**收工复核**用的)