我让 Playwright MCP 打开一个页面,它当场回我:“Browser is already in use … use
--isolatedto run multiple instances of the same browser”。这不是 bug,是设计。这句报错里藏着”给 Agent 用的浏览器”这类产品从 Selenium 到 ego-lite 的所有分歧。
Playwright、Puppeteer、browser-use、Stagehand、Skyvern、Browserbase、Steel、Anthropic Computer Use、ego-lite——十来款产品都在解决”让程序控制浏览器”这件事,但你会发现它们的 tagline 完全不一样:Playwright 说自己是 “fast reliable e2e testing”、browser-use 说 “make websites accessible for AI agents”、Browserbase 说 “give your agents access to the whole web”、ego-lite 说 “Agents work in their own isolated space, reusing the user’s login state”。
把这些 tagline 排到一起,能看出一条隐藏的时间线——每一代产品,都在补上前一代没承认的一个事实。这篇是这条时间线的一张地图。
名词速查
| 术语 | 一句话解释 |
|---|---|
| DOM 选择器 | #id、.class、CSS selector——直接指着 HTML 里的节点。写测试的默认原语。 |
| 无障碍树(accessibility tree) | 浏览器为屏幕阅读器构建的语义树。每个节点带 role(按钮/输入框/链接)+ name(可见文本)。比 DOM 干净、比 HTML 小一个数量级。 |
| CDP(Chrome DevTools Protocol) | Chromium 内建的调试协议。DOM、网络、Runtime、Emulation 都在这里,一切上层浏览器自动化都是它的皮。 |
| Task space | ego-lite 造出来的词:一个隔离的浏览标签页集合,继承用户登录态,但和用户当前的标签页互不打扰。 |
| Handoff | 控制权移交。同一个 task space 里,agent 或 user 必须有明确的独占方,中间显式交接。 |
| MCP server | Anthropic 定义的工具协议。Playwright MCP 是把 Playwright 包成一个 MCP server,让 Claude/Codex 通过标准工具调用来驱动浏览器。之前写过 Agent 工程决策地图 有更长版解释。 |
一、根本约束:浏览器有两个用户,产品差异都来自这里
一句话根本约束——
浏览器最初为人写、Agent 是这个系统的第二用户。这一堆产品的定位差,就是每家对「怎么伺候第二用户」的答复。
这句可反驳。反事实:如果人从来没用过浏览器、Agent 是它的原生用户,那这套产品树整体消失——一切都会走结构化 API,没有 DOM、没有 CSS、没有截图,没有”锁冲突”这种事。事实是这个星球上先有了 Web 页面和登录态,然后才出现能”读页面/想动作/执行”的机器;每一款产品都在这个既定事实上做取舍。
这条约束的价值在于它是可反事实测试的。凡是宣称”我的浏览器 agent 更好”的产品,都可以问一句:你在”人也是这浏览器的用户”这一点上,做了什么让步或坚持?——答不出来的产品,通常只是把上一代重新包装。
二、六个决策点决定分裂方向
我从两篇姊妹文里提炼过 Browser Agent 的控制栈和 ego-lite 的 runtime 假设,这里从产品层总结出六个能真正区分定位的决策点:
- 主用户是谁:脚本的第一目标读者,是开发者(写测试的人)还是 Agent(LLM)。
- 页面观察原语:DOM 选择器 / 无障碍树 / 像素——决定了 token 消耗、稳定性、能不能应付 canvas 类应用。
- 状态归属:全新隔离会话 vs 复用用户登录态——决定了 SSO/OAuth/captcha 由谁处理。
- 运行位置:本地 / 云端 / 模型内——决定了并发规模与延迟基线。
- 决策回路:脚本预写 / LLM 逐步决策 / 模型直驱像素——决定了每步谁在做判断。
- 共存策略:独占浏览器 / 隔离进程 / 云端 fleet / task-space handoff——决定了”人也想用浏览器”时怎么办。
三、十一款产品对着这六个点,站位一目了然
| 产品 | 主用户 | 观察原语 | 状态 | 运行位置 | 回路 | 共存策略 |
|---|---|---|---|---|---|---|
| Selenium(2004) | 开发者 | DOM 选择器 | 全新会话 | 本地/自托管 | 脚本 | 独占浏览器 |
| Puppeteer(Google, 2017) | 开发者 | DOM + CDP | 全新会话 | 本地 | 脚本 | 独占 |
| Playwright(Microsoft, 2020) | 开发者 | Locator + ax-tree | 全新会话 | 本地 | 脚本 | 独占 profile |
| Playwright MCP | Agent | ax-tree(无 vision) | 全新会话 | 本地/MCP | LLM 逐步 | profile 锁独占 |
| browser-use(112k★) | Agent | Playwright 之上 DOM+screenshot | 全新会话 | 本地/云 | LLM 逐步 | 独占 |
| Stagehand(Browserbase) | Agent | act/observe/extract | 全新会话 | 云为主 | LLM 逐步 | 独占(云 session) |
| Skyvern | Agent(业务人) | Vision LLM + workflow | 全新会话 | 云 | LLM + CV | 独占 |
| Browserbase(基础设施) | Agent fleet | 交给 SDK | 云端 fleet | 云(35M+ 会话/月) | 上游决定 | 无冲突(远程) |
| Steel.dev(基础设施) | Agent fleet | 交给 SDK | 云端 fleet | 云/自托管 Docker | 上游决定 | 无冲突(远程) |
| Anthropic Computer Use(2024-10, Claude 3.5 Sonnet) | 模型自己 | 像素 + 虚拟键鼠 | VM 隔离 | 用户机器 + VM | 模型直驱 | VM 沙盒 |
| ego-lite / ego-browser | 人 + Agent 并存 | ax + screenshot + CDP | 复用用户登录 | 本地(Chromium 分发) | LLM 逐步 | task space + handoff |
★ 数字来自 browser-use 仓库首页 2026-09-04 徽章。
三点值得单独指出来:
Playwright MCP 那格标注了”profile 锁独占”——它并不是没有 Agent 意识,而是继承了 Chromium 一个物理事实:一个 user_data_dir 同一时刻只能被一个 Chromium 进程打开。你正在用的 Chrome 就会挡住 Playwright MCP 想复用同一个 profile 的所有尝试;官方留的口子是 --isolated,代价是丢失所有登录态。
Anthropic Computer Use 那格标注了”模型直驱”——之前的产品是 Agent 每一步先决策再调工具,工具再操作浏览器;Computer Use 把这层拆掉了,模型直接对着截图输出鼠标坐标和虚拟键盘按键。这不是”更方便”,是”承认像素是这个星球上最通用的界面协议”。
ego-lite 那格里”人 + Agent 并存”是一个别人不敢占的位置——绝大多数产品的默认假设是”人和 agent 不同时用浏览器”(要么另开一个隔离进程、要么远程放在云上)。ego-lite 把”共存”作为一等公民,代价是要专门造一个 Chromium 分发和 task-space/handoff 这套抽象。
四、五代演进:每一代补一个前一代没承认的事实
把上面表格按时间摊开,会看到一条清晰的演进链——每一代都在承认前代刻意回避的某个事实。
第一代(2004–2020):“Agent?没听说过。”
Selenium 2004 年出生,用 WebDriver 协议远程控制浏览器;Puppeteer 2017 年跟着 Chrome DevTools Protocol 出来;Playwright 2020 年扩展到 Chromium/Firefox/WebKit 三家渲染引擎。这一代的主用户是写测试的人:他们要的是稳定的 selector、快的等待策略、可复制的 CI 环境。Agent 这一端在这一代产品里根本不存在——page.click('button.primary') 假设了一个人已经知道 CSS 选择器长什么样。
这一代的技术遗产至今是整个行业的底座:browser-use 底层跑的是 Playwright,Stagehand 是 Playwright 的皮,Playwright MCP 更是官方产物。这条链有多深,看今天的产品用什么打底就知道。
第二代(2023–2024):“Agent 存在了,但可以套在 Playwright 上”
browser-use 明确写着 “Playwright-based”;Stagehand 是 Browserbase 家在 Playwright 之上做的 SDK,暴露 act / observe / extract 三个针对 LLM 优化的原语;Playwright MCP 是把 Playwright 的定位器和 accessibility snapshot 包成 MCP 工具。
这一代的核心承认:LLM 是新的调用方,它读页面的方式和人不一样。人看得懂截图但吐 CSS selector 累,LLM 读结构化文本快但对像素很贵。所以这一代产品的贡献是把”页面表示”从 DOM 换成 accessibility tree——role/name 语义化后,一个页面从几百 KB HTML 压缩到几 KB 文本,LLM 一眼看完能决策。
这一代没解决的事:登录态还是要你手动构造(用户 profile 或 storageState),因为 Playwright 的默认哲学是”每个测试用干净会话”。用户的日常浏览器和 agent 的 Playwright 浏览器还是两回事。
第三代(2024-10):“像素才是最原始的通用接口”
2024 年 10 月,Anthropic 发布 Claude 3.5 Sonnet 的 Computer Use 能力,同期 arXiv 2411.10323 发了一篇”Dawn of GUI Agent”记录这个案例研究。技术路线简单粗暴——模型直接看截图,直接输出 click(x, y)、type("hello")、key("Enter")。
这一代的核心承认:结构化界面(DOM/无障碍树)在实际生产网站上有严重覆盖不足。arXiv 2511.19477 “Building Browser Agents”(Aram Vardanyan, 2025)把这点写得很直白——很多生产网站的无障碍属性并不完整(不是开发者不愿做,是要额外投入),而 Google Sheets、Figma、Canva 这类基于 HTML5 canvas 的应用根本不把可交互元素暴露给 DOM 或 accessibility API。
这一代的代价:像素比结构化文本贵得多——图片 token 大、决策延迟高、每步都要重新截图,且很容易被”像人一样点”的成本压垮。arXiv 2511.19477 的实测数字:混合 ax-tree + 选择性 vision 的架构,在 WebGames 上做到约 85% 成功率;单纯依赖某一种通道的架构约 50%;人类基线 95.7%。这篇论文的核心主张:模型能力已经不是瓶颈,架构选择才是。
第四代(并行发展):“Agent 用的浏览器需要一个 fleet”
Browserbase 和 Steel.dev 走的是另一个方向——承认 agent 是一个 fleet,不是一个人。它们提供云端浏览器基础设施:Browserbase 官网自称”每月跑 35M+ 浏览器会话,服务 10000+ 客户”;Steel.dev 主打亚秒级启动、24 小时会话、可 Docker 自托管,开源。
这一代真正在解决的问题不是”怎么点按钮”,而是:Agent 并发跑 100 个任务时,怎么统一处理 CAPTCHA、指纹、代理、录像、会话回放。这些都是运维问题,不是自动化问题——它们把 Playwright/Puppeteer/Selenium 都当成客户端 SDK,自己在中间提供云。
第五代(2026):“人和 Agent 要用同一个浏览器”
ego-lite 是我看到的第一个把这条明确当产品定位的方案。它的 SKILL.md 里明白写着——每个 task space 是隔离的浏览标签页集合,但默认继承用户当前的登录态,所以 agent 可以直接操作那些”必须登录后才有意义”的页面,而不干扰用户正在看的其他标签页。
它还专门定义了 handOffTaskSpace / takeOverTaskSpace / claimTaskSpace 一整套控制权移交语义——一个 task space 同一时刻只能被 agent 或 user 独占,需要用户接管(登录、captcha、手动确认)时 agent 显式移交,用户完成后必须显式移交回来才能继续。它把”共存”从工程 workaround 抬到了协议层。
这代产品还没形成气候(我目前只观察到 ego-lite 一家把这套明确产品化),但只要”agent 越来越多、但人还是要用浏览器”这个事实不变,就总会有人来占这个位置。
五、亲手实验:三种表示的字节账 + 一次真实翻车
给读者两个数字账。
账一:同一个页面,三种表示的字节数
我用 ego-browser 在本机打开维基百科 “Web browser” 页面(en.wikipedia.org/wiki/Web_browser),分别取三种表示:
| 表示 | 字符数 | 相对原始 HTML |
|---|---|---|
完整 HTML(document.documentElement.outerHTML) | 526,061 | 100% |
ego-lite snapshotText()(无障碍树 + refs) | 326,683 | 62% |
纯 innerText(丢结构) | 20,359 | 3.9% |
复现命令(在装了 ego-browser 的机器上):
ego-browser nodejs <<'EOF'
await useOrCreateTaskSpace('bench')
await openOrReuseTab('https://en.wikipedia.org/wiki/Web_browser', { wait: true, timeout: 30 })
const snap = await snapshotText()
cliLog('snapshot=' + snap.length)
cliLog('raw_html=' + (await js('document.documentElement.outerHTML')).length)
cliLog('inner_text=' + (await js('document.body.innerText')).length)
EOF
这个数字说明为什么第二代产品都跑去做无障碍树——完整 HTML 直接把主流模型的 context window 撑破(同期 arXiv 2508.04412 “Beyond Pixels: DOM Downsampling” 报告过一个数字:42% 的原始 DOM 快照超过模型上下文窗口;他们的 D2Snap 算法做完 downsampling 后,平均上下文占用降到 16.5%)。纯 innerText 便宜但没法用——你能读到”Learn more”但不知道它是哪个链接、点了会跳到哪里。ego-lite 的 snapshotText 是 role/name/locator 三件套的中间路线,是当前”给 LLM 看的页面”里最主流的形态。
账二:同一个 example.com 页面
| 表示 | 字符数 |
|---|---|
原始 HTML(curl example.com) | 559 |
ego-lite snapshotText() | 303 |
小页面上无障碍树的压缩比不明显(例子简单本来 role/name 就少),差距要到 wiki 这种真实页面才显著——这个反差本身就是”实测”的价值:不要相信任何在 example.com 上跑出来的压缩比数字。
账三(翻车):Playwright MCP 的 profile 锁冲突
我准备做 Playwright MCP 侧的对照实验时,直接撞到锁:
Error: Browser is already in use for
<home>/Library/Caches/ms-playwright-mcp/mcp-chrome-bea7d78,
use --isolated to run multiple instances of the same browser
这不是 Playwright MCP 的锅——Chromium 的 user_data_dir 就是同时只能被一个进程独占的,一切在同一 profile 上并发的尝试都会撞上这堵墙。可选项只有两个:一是加 --isolated(每次开全新会话,丢失 profile 里的一切登录态、扩展、书签),二是等前一个进程退出。
在 ego-lite 里同一个物理浏览器实例可以有多个 task space 同时活着——这就是它多花力气造分发的回报:profile 锁的独占约束被抬到 task space 层,浏览器进程反而是共享的。
六、崩点:把某个约束抽掉,最先崩在哪里
这是”根本约束”的可反驳性测试——每个决策点抽掉,先崩在哪里、崩多少量级。
- 抽掉”人也用浏览器”(第五代的核心假设):产品树塌回第四代,Browserbase 类云基础设施是唯一形态。先崩的是 SSO/OAuth/2FA 场景——你得为每个 agent 手动构造 storageState、维护多个凭据轮换、每周处理 captcha。规模从 1 → 100 时,这个成本按并发数线性爆炸。ego-lite 的路径的价值就在这里:复用一次人已经登录好的态。
- 抽掉”agent 也用浏览器”(第二代之前):产品树塌回第一代——你会得到今天的 Playwright / Puppeteer / Selenium,服务测试和 RPA,不服务 LLM。先崩的是 LLM 决策成本——你要为每一个交互写好选择器和等待,模型只是被叫来给一个”要不要点这个按钮”的意见。
- 抽掉”结构化观察”(第三代的路径):产品树塌向 Anthropic Computer Use。先崩的是图片 token 成本和时延——每步都要重截图,一次典型交互要 5-10 张图(每张相当于几千文本 token),一个多步任务的总成本按截图张数近乎线性放大。arXiv 2511.19477 里的 85% vs 50% 差距,也可以反过来读:纯像素路径省一步观察成本,但架构缺少 fallback 时命中率掉一半。
七、共同祖先:屏幕爬取的老争论,只是换了消费者
如果站远一点看,这场分歧从 2004 年 Selenium 出生那天就存在——屏幕爬取(screen scraping) vs 结构化集成(API integration)。二十年前的分歧结论是:能走 API 就走 API,实在不行才用屏幕爬取,因为屏幕爬取太脆。
LLM 的到来没有改变分歧本身,只改变了”结构化”的性价比:
- 二十年前,“结构化”意味着让服务方给你 API,成本主要在跨组织谈判;
- 今天,“结构化”意味着让模型从无障碍树/DOM 快照读出结构,成本主要在上下文 token。
这就是为什么这一代产品几乎无一例外都在优化”页面表示的压缩比”(Playwright MCP 用 ax-tree、Stagehand 用 observe/extract、browser-use 做 DOM downsampling)。爬屏的老争论没变,变的只是它进入了每个消费者都能负担的价格区间。
小结
一句话根本约束:浏览器最初为人写、Agent 是它的第二用户;所有产品的定位差都是对”怎么伺候第二用户”的一次答复。
崩点速查:抽掉”人也用” → SSO/OAuth 每 agent 手动构造成本按并发线性爆;抽掉”agent 也用” → 塌回第一代测试工具;抽掉”结构化观察” → 图片 token 与时延近乎线性放大。
三条选型建议:
- 只跑测试或 RPA、无 LLM 决策 → 直接 Playwright,不要绕。
- LLM 每步决策、并发规模 > 单机 → Browserbase / Steel 云端 fleet 起手,Stagehand/browser-use 做客户端 SDK。
- 需要真人登录态、agent 与人共用同一台电脑 → ego-lite 这条路,代价是要接受一个非主流 Chromium 分发。
Playwright MCP 特别提示一句:它在同一个 profile 上和用户桌面浏览器互斥,如果你想 agent 和自己同时用浏览器,Playwright MCP 不是这个方案;但如果你的场景是”agent 独占一台机器/一个 profile 跑长任务”,它依然是 token 最省的选择之一(无 vision)。
下一步(5 分钟)
想验证本文观点是否适用于你的场景,最便宜的做法是拿你最常用的那个业务页面——不是 example.com、不是 wiki,是你 agent 真正要操作的那个页面——跑一遍上面的三行 ego-browser 脚本,把 raw_html / snapshot / inner_text 三个数字记下来。
如果比例接近我这里(62% / 3.9%),第二代产品的选型逻辑对你成立;如果 snapshot 大到远超模型上下文,你要么去 Browserbase 这种云端方案(把浏览器 session 生命周期从模型上下文里分离),要么去 Anthropic Computer Use 这种像素路径(截图 token 成本可控但每步不便宜)。选型之前先测这一个数字,胜过读三篇选型综述。
参考来源
工程实践:
- Playwright 官网 — Microsoft,2020 起
- Playwright MCP — 官方 MCP server
- Puppeteer — Google, 2017 起
- browser-use — Python,Playwright-based,112k★
- Stagehand — Browserbase 出品的 agent SDK
- Skyvern — LLM + 计算机视觉
- Browserbase — 云端浏览器 fleet
- Steel.dev — 开源云端浏览器
- Anthropic Computer Use 发布公告(2024-10)
- ego-lite — dual-space 浏览器
arXiv 论文:
- Vardanyan A. “Building Browser Agents: Architecture, Security, and Practical Solutions.” arXiv:2511.19477(2025)— WebGames 85% vs 50% 混合架构结果
- Schiepanski T M, Piël N. “Beyond Pixels: Exploring DOM Downsampling for LLM-Based Web Agents.” arXiv:2508.04412(2025)— D2Snap 算法,42% 原始 DOM 超上下文
- Hu S, Ouyang M, Gao D, Shou M Z. “The Dawn of GUI Agent: A Preliminary Case Study with Claude 3.5 Computer Use.” arXiv:2411.10323(2024)
站内相关:
- Agent 如何控制浏览器:从 HTTP、DOM、CDP 到视觉与混合自动化 — 控制通道与页面表示的详细拆解
- Ego Lite 的关键不是会点网页,而是把浏览器变成 Agent 的共享运行时 — ego-lite 源码/产品笔记
- Agent 工程决策地图 — 更上一层的选型框架