Playwright CLI 与 MCP:两种给 AI 看世界的方式
早些年写爬虫,人是主语,浏览器是工具,脚本是桥。如今轮到 AI 写爬虫,人退到了旁观席上,便多出一个问题:该让模型怎样“看见”一个网页。
Microsoft 先后给了两份答卷。2024 年的 Playwright MCP,把浏览器包成 Model Context Protocol 的一组工具,每次动作之后把可访问性树、截图字节一并塞回 LLM 的上下文。2026 年初的 Playwright CLI 则反其道而行——数据落盘,Agent 自己决定要读哪一页。同一家公司,同一个团队,先后两种哲学。像是先建了一座藏书楼要求来人过目不忘,过几年想通了,换成借阅处。
一句话结论
Claude Code、Cursor、Copilot 这类能碰到文件系统的 Agent,首选 Playwright CLI。token 消耗约为 MCP 的四分之一(典型任务 114k → 27k)。只有在 Claude Desktop 这类沙箱聊天界面里,才需要退回 Playwright MCP。
核心差异
| 维度 | Playwright MCP | Playwright CLI |
|---|---|---|
| 协议 | JSON-RPC(MCP 标准) | 普通 shell 命令 |
| 数据流 | 结果直接注入 LLM 上下文 | 写入磁盘,Agent 按需 Read |
| Token 成本 | 约 114k(典型任务) | 约 27k(同样任务) |
| 工具数量 | 21 个(受限于上下文预算) | 命令更多(无上下文顾虑) |
| 运行环境要求 | 任何支持 MCP 的宿主 | 必须有文件系统 + shell |
| 持久化状态 | 内存中会话 | 命名会话 -s=name + --persistent |
| 状态自省 | 每步返回完整 a11y 树 | Agent 主动 snapshot |
四倍 token 差从何而来
MCP 的前提假设是“LLM 看不到工具之外的世界”。于是每一次 click 之后,必须把最新页面状态原路奉还,模型才好决定下一步。一棵可访问性树常常几 KB 到几十 KB,十步操作便啃去几万 token。长会话里,这笔账像滚雪球。
CLI 的假设换了一条:Agent 本来就有 shell、有磁盘。playwright-cli snapshot -o page.yaml 只把数据写到 page.yaml,Agent 要看就 Read page.yaml,不看便无事发生。古人藏书于山中,用时取之,不用则束之高阁;CLI 的设计,大抵是这个意思。
命令能力速查(CLI)
| |
两个关键模式:-s=name 命名会话实现并行浏览器,-o file 把结果重定向到文件。
选型决策树
Agent 能访问文件系统和 shell 吗?
├─ 是 → Playwright CLI(主流)
│ ├─ Claude Code ✅
│ ├─ Cursor ✅
│ ├─ GitHub Copilot Agent ✅
│ └─ Codex/其他 CLI Agent ✅
└─ 否 → Playwright MCP(沙箱兜底)
├─ Claude Desktop ✅
└─ 纯 Chat UI ✅
分别用在哪里
Playwright CLI 的场景
- 写 E2E 测试:长会话、多步操作,token 压力最重的地方
- 开发期调试:截图/控制台/网络请求悉数落盘,可以反复 Read
- 生成 Playwright 测试代码:
playwright-cli codegen录制回放 - 批量脚本:shell pipeline 可以串起来
Playwright MCP 的场景
- Claude Desktop 里临时查网页:没有 shell,只好回到 MCP
- 探索性自动化:需要 Agent 每步都“看到”当前状态自我修正
- Self-healing 测试:依赖富语义的 a11y 树做失败重试
和 Chrome DevTools MCP 并行
三者不互斥,最优组合是各司其职:
- 开发期看页面状态 → Chrome DevTools MCP(性能 trace、真实 Chrome 登录态)
- 跑 E2E / 生成测试代码 → Playwright CLI
- 沙箱 Chat 里查页面 → Playwright MCP
Claude Code 集成方式
CLI 不走 claude mcp add 这条路。装完全局命令后,在对话里让 Claude 直接调 Bash 即可。配合项目 CLAUDE.md 里写好常用命令的指引,效果最好。
| |
然后在项目 CLAUDE.md 加一段约定:
| |
几个坑
- CLI 需要文件系统权限。sandbox 严格的 Agent 宿主未必可用,动手前先确认权限边界
- 会话名冲突。多项目并行时
-s=name要带项目前缀,否则串会话的后果是诡异的 --persistent会写到~/.cache/ms-playwright/。CI 环境记得清理,否则缓存会越积越厚- 不要和 MCP 混装。同项目里两套工具并存,Agent 会陷入选择困难,表现为在两种调用之间来回切换
迁移路径
从 Playwright MCP 迁到 CLI 的步骤:
npm install -g @playwright/cli@latest- 在
CLAUDE.md把browser_*工具说明替换成playwright-cli命令 - 移除
.mcp.json或~/.claude.json里的 playwright MCP 配置 - 跑几个典型任务对比 token 消耗,确认预期
尾声
MCP 不是被抛弃的旧工具,CLI 也不是什么跨时代的新发明。两者的分野只说明一件事:让模型看见世界的成本从来不是零。塞进上下文是一种办法,摊在磁盘上让它自取是另一种,前者适合无处借力的沙箱,后者适合有手有脚的编码 Agent。
工具选对了,token 便不至于流水一般漫出去。这一点在 Claude 的上下文窗口真正派上用场的地方——比如读一份庞大的代码库、追一个跨越十几个文件的 bug——最能看出分别。