Vercel 的 Agent Browser,让 Agent 操作网页不再靠猜
摘要
Vercel Labs 的 Agent Browser 在 skills.sh Hot 出现安装量上涨。它让 Agent 根据当前页面的无障碍树选择元素,再用会话、安全策略与流式预览处理真实网页里的变化和风险。
网页自动化最容易演示,也最容易出事故。打开页面、找到按钮、填完表单,这几步在视频里看起来像是 Agent 已经获得了一双手;真正放进工作流后,遮罩层、页面更新、登录状态、慢网络和误操作确认,才是决定它能否继续跑下去的部分。
本次检查中,skills.sh Hot 显示 Vercel Labs 的 agent-browser 有 139 次安装,较对应的前一窗口增加 53。这是 skills.sh 的安装信号,不是 GitHub stars。GitHub API 显示仓库累计 40,276 stars,近期仍有代码推送。Vercel 是 Next.js 的创建者;最新 v0.33.2 release 发布于 8 月 2 日。
这些数字不足以说明一切,却说明 agent-browser 正在被更多 Agent 工作流接入。我会借它梳理一个更具体的问题:浏览器对于 Agent,为什么不该只是一组 click 命令,而应当是有状态、有边界、能观察失败的运行时。期望对大家有所帮助。
不是“找到选择器”,而是保留一次观察结果
agent-browser 是一个以 Rust 编写的浏览器自动化 CLI。它能用 CSS 选择器,也能用角色、标签等语义定位器;但 README 给 Agent 的默认路径是先拿到无障碍树,再使用树里的引用。
agent-browser open https://example.com
agent-browser snapshot -i
agent-browser click @e2
agent-browser fill @e3 "hello"
snapshot -i 会输出当前页面的交互元素,并给出类似 @e2 的引用。模型不是猜一个可能已经失效的 button:nth-child(3),而是先根据角色、可访问名称和当前页面状态选择一个已观察到的元素。页面改变后重新 snapshot,旧引用也不该继续沿用。
这听起来只是接口设计,其实是在给 Agent 加一条很朴素的纪律:先看,再操作,再确认当前页面是否已经变了。项目还会在点击点被遮罩层覆盖时提前失败,并把覆盖元素报出来。README 的建议同样是先处理遮罩层,再重新获取 snapshot。
flowchart LR
A[打开或恢复会话] --> B[读取无障碍树]
B --> C[选择引用 @eN]
C --> D[点击或填写]
D --> E{页面是否变化}
E -->|是| B
E -->|否| F[读取结果或结束]
这比“让模型自己看着页面点”少了一些魔法感,却多了一种可以复盘的状态转换。对测试登录流程、后台配置、表单录入这类任务,后者更重要。
一个会活下来的浏览器进程
很多浏览器工具把每个命令当作一次短暂调用。agent-browser 的结构不同:CLI 和 Rust daemon 分开,第一次命令启动 daemon,后续命令复用同一个浏览器和会话。它直接走 Chrome DevTools Protocol,不需要 Node.js 常驻。架构说明 写得很明确。
这让“打开 - 登录 - 跳转 - 截图”不必在每一步重新创建浏览器,但也把资源回收变成一个运行时问题。项目默认在一小时没有命令或 dashboard 输入后,保存配置的恢复状态、关闭浏览器并退出;下次命令再启动。8 月 2 日的发布还处理了另一类真实故障:慢客户端看直播画面时,点击和键盘事件不能排在旧帧后面等着发送。
| 运行时问题 | agent-browser 的处理 |
|---|---|
| 页面已经变化 | 重新获取 snapshot,再选择当前引用 |
| Agent 非正常退出 | 空闲超时后关闭 daemon 与浏览器 |
| 人需要看过程 | WebSocket 流式预览与本地 dashboard |
| 慢网络积累旧画面 | 可用 ack 节流,只保留最新帧 |
| Chrome 丢弃后台标签页 | 切换时尝试恢复,并在结果里标出 revived |
这里最有意思的是流式预览的处理。v0.33.2 增加了每个客户端的帧率与质量控制,也支持 ack 节流:客户端没有确认前,一次只接收一帧,新帧会替换未发送的旧帧,而不是把过期画面排成队。release note 记录了其测试结果:在 400 KB/s 链路、客户端停滞 8 秒的情形下,默认推送会留下 436 帧旧画面,而 ack 模式只留下 1 帧。
这不是一个为了“看起来实时”的细节。只要人和 Agent 同时盯着浏览器,过期画面会直接改变人的判断,也可能让点击落在一个已经变化的页面上。
浏览器内容不是可信上下文
让 Agent 打开网页,还有一个常被轻描淡写的风险:网页文字本身是外部输入。一个页面可以诱导模型忽略原任务、索取凭据,或把操作转向不该去的域名。agent-browser 没有声称靠模型识别这些内容,而是提供几层可组合的限制:给页面输出加内容边界标记、限制最大输出长度、限制可访问域名,以及为敏感类别设置静态策略或人工确认。安全文档 与 README 的 Security 部分 都列出了这些选项。
尤其值得注意的是 --allowed-domains。它不只阻止顶层跳转,还会拦截不在白名单内的脚本、图片、fetch、WebSocket、EventSource 与 sendBeacon 请求,并在可控的 Chromium 会话中关闭 WebRTC 的绕行路径。代价也写得很清楚:接入已有 Chrome、复用个人 profile、恢复 state 文件等模式,无法在页面脚本执行前施加同样的约束,因此该参数会拒绝这些不安全组合。
安全功能没有替代部署决策。状态文件可能包含会话 token;README 明确要求不要提交它们,并提供 AES-256-GCM 的静态加密。自动操作付款、删除、发布、改权限等页面前,仍然应该把确认留在人手里。
值不值得接进自己的 Agent
如果你的 Agent 只需要抓一篇公开文章,HTTP 抓取通常更简单。agent-browser 的价值出现在需要真实浏览器状态的地方:登录后的页面、前端渲染后的内容、需要上传文件的表单、需要把测试过程交给人查看的 QA,或者希望通过 MCP server 把一组浏览器能力交给 AI 编程工具。
第一次接入可以从一个没有破坏性的任务开始,例如在测试站点走一遍注册流程、核验后台页面的无障碍问题,或把一条手工回归测试录成可重复的命令序列。随后再逐步加上:
--allowed-domains,并把页面依赖的 CDN 一并列入--content-boundaries与--max-output,避免网页内容直接淹没模型上下文--confirm-actions或 action policy,先覆盖下载、执行脚本和会产生外部影响的操作- 独立 session 与加密的状态存储,不复用日常个人浏览器 profile
它把浏览器 Agent 从“模型会不会点按钮”的问题,拉回到了更可靠的工程问题:状态从哪里来,页面变化后怎样重新观察,外部内容在哪里停止,敏感动作由谁确认。把这些边界先放进去,浏览器才更适合成为 Agent 的执行环境。
相关文章
2026年9月29日
19.5k stars 的 notebooklm-py,正在把 Gemini Notebook 接进 Agent
GitHub Trending Developers 第一名背后,notebooklm-py 把 Gemini Notebook 的资料库、生成能力和导出流程包装成 CLI、MCP 与 Agent Skill;但它是依赖未公开接口的非官方项目。
2026年6月7日
【AI早读 0607】MCP应用生态与智能体基础设施
今天从 MCP Apps 进入 VS Code 说起,延伸到 AI 开发中的“意图债务”、ChatGPT Lockdown Mode 对 Prompt 注入外泄路径的限制,以及 MicroPython + WASM 轻量代码沙箱等智能体基础设施。
2026年2月17日
Next.js 正在为 AI Agent 重新设计自己
Next.js 团队发布了一篇博客,讲述他们如何从 Agent 的视角重新思考框架设计。从一个被放弃的浏览器内 Agent,到 MCP 集成,再到 agents.md - 这篇是我的阅读笔记。
最近一封 · Sample
OpenRig 冲上 Trending:把 Claude Code 和 Codex 编成一支队伍
“OpenRig 在 GitHub Trending Today 获得 622 个 stars 的窗口信号。它用可恢复的队列、席位与权限记录,把 Claude Code 和 Codex 放进同一套多 Agent 工程流程。”
—— william
来信
里面装的是
- 新文章 — 写完一篇就寄一封,不攒货
- 这周读到的、看到的、好用的工具
- 正在折腾的实验,附带翻车记录
约莫 1–2 周一封 · 随时退订
合作伙伴
CompeteMap — 英国及爱尔兰学生竞赛一站式搜索
数学、编程、科学、写作等各类竞赛信息汇总,支持按年龄和科目筛选,再也不错过报名截止日。