agent-browser skill 浏览器自动化
从"AI 在后台悄悄点浏览器"到"你亲眼看着 AI 操作浏览器"——一次完整实战记录。
背景
大模型驱动的编码助手(AI Agent)越来越多地需要"动手操作浏览器":帮用户查资料、填表单、抓数据、打开数据手册。但大多数时候,浏览器在后台无头运行,用户只能看到结果文字,看不到过程——体验就像隔着一堵墙。
本文记录两件事:
如何给 AI 安装并使用
agent-browser这个浏览器自动化 skill;如何把无头浏览器的画面实时投屏到前端,让用户亲眼看着 AI 操作。
实战场景:AI 打开立创商城,搜索 STM32F103C8T6,打开它的数据手册——并全程可视。
agent-browser 是什么
agent-browser 是 Vercel 官方出品的浏览器自动化 CLI(GitHub 40k+ star,skills 生态 648k+ 安装量)。核心特点:
基于 CDP(Chrome DevTools Protocol),不依赖 Playwright / Puppeteer;
通过可访问性树快照(accessibility-tree snapshot)给 AI 提供紧凑的
@eN元素引用,一次交互只需 200~400 token;浏览器跨命令保持运行,操作像"同一个会话";
支持无头 Chromium、真实 Chrome(带 profile)、云浏览器三种模式。
安装
三分钟上手:核心工作流
AI 操作浏览器的循环只有四步:
常用命令一览:
| 类别 | 命令 |
|---|---|
| 导航 | open back forward / reload |
| 读取 | snapshot get text @e1 get url / get title |
| 交互 | click fill type press Enter select / upload |
| 等待 | wait @e1 wait --text "..." wait --load networkidle |
| 提取 | get text get html eval <js> |
| 截图 | screenshot / screenshot --annotate(带编号标注,适配多模态模型) |
关键纪律:@eN 引用在页面变化后会失效,任何点击/导航后都必须重新快照。AI 自动化失败 90% 都是"等待没等对"或"用了过期的引用"。
实战:逛立创商城,查 STM32F103C8T6 数据手册
第一步:打开立创商城
页面标题正常返回,但随后就被弹回空白页——立创商城(国内站)部署了 WAF 反爬。
遭遇 WAF:JS 挑战 + 无头检测
用 HTTP 直连看服务端返回:
这是典型的 JS 挑战:服务器先返回一段混淆脚本,要求浏览器执行计算并种下 cookie 后重载,才会给真实内容。同时 WAF 检测自动化特征(navigator.webdriver、CDP 残留变量 cdc_* 等),命中就 location 跳转到 about:blank——这正是"页面打不开"的根因。
破局一:注入反检测脚本
agent-browser 支持 --init-script,在页面任何 JS 执行之前注入脚本:
页面 URL 稳定了,但 body 仍是空壳——WAF 的 JS 挑战对自动化环境依旧"不配合"。
破局二:绕过 SPA 空壳,直接拿数据
WAF 拦得住浏览器渲染,拦不住"以普通 HTTP 客户端直连":
页面居然完整返回(146KB),JSON-LD 结构化数据里直接解析出数据手册:
(注意:立创料号是 C8734,不是网上常传的 C8739。)
打开数据手册
PDF 自动下载到本地(C8734_单片机(MCU-MPU-SOC)_STM32F103C8T6_规格书_WJ115614.PDF),用系统 PDF 阅读器打开即可。
小结:真实网站的反爬是"组合拳"——无头检测、JS 挑战、SPA 壳。破局思路不是死磕渲染,而是多通道并行:浏览器走不通就直连抓数据,能拿到结果就是胜利。
进阶:把浏览器搬到前台——实时投屏
需求
AI 在后台操作浏览器,用户看不见。要让用户"亲眼看到"。
方案选型
| 方案 | 优点 | 缺点 |
|---|---|---|
--headed 有头窗口 | 最简单 | 在部分环境参数不生效(实测被忽略,仍是 headless) |
agent-browser 自带 stream(WebSocket 推帧) | 官方能力 | daemon 生命周期不稳定,端口易漂移,协议文档缺失 |
| 自建 CDP 截图流 + Web 播放器(本文方案) | 完全可控、稳定 | 需要 ~60 行代码 |
架构
三个关键决策:
用系统真实 Chrome +
--remote-debugging-port=9222,绕开 agent-browser 内置浏览器的 headless 问题,窗口真实弹出;agent-browser 用
--cdp 9222连接,AI 照常操作,但操作落在可见窗口里;截图用
Page.captureScreenshot轮询,而非Page.startScreencast——Chrome 147 实测 screencast 不推帧,captureScreenshot任何版本都稳定。
核心代码(viewer_server.js 节选)
// 连接 CDP → 找到真实页面 target → 附加会话 → 开启截图轮询
function attachTo(targetId) {
trackedSend('Target.attachToTarget', { targetId, flatten: true });
}
// attach 成功后:
trackedSend('Page.enable', {}, pageSessionId);
trackedSend('Page.captureScreenshot', { format: 'jpeg', quality: 55 }, pageSessionId);
// 收到截图响应 → 更新最新帧 → 250ms 后继续拍下一张
if (method === 'Page.captureScreenshot' && msg.result && msg.result.data) {
latestFrame = Buffer.from(msg.result.data, 'base64');
setTimeout(() => {
trackedSend('Page.captureScreenshot', { format: 'jpeg', quality: 55 }, pageSessionId);
}, 250);
}
前端播放器页面(约 40 行 HTML):一个 <img>,每 120ms 请求一次 /frame?t=<时间戳>,实现约 4~8 fps 的实时画面;帧接口返回最新 JPEG,带 Cache-Control: no-store 防止缓存。
效果
桌面弹出真实 Chrome 窗口,用户可直接看;
http://127.0.0.1:9333/播放器页面实时同步;agent-browser 每次导航/点击,两个画面同步更新(实测帧大小随页面内容变化,如必应首页 13KB → 125KB)。
踩坑清单(省得你再踩一遍)
agent-browser 的 daemon 在 CLI 命令间会退出 → 用 viewer 持续持有 CDP 连接,daemon 被"保活",CLI 通信也稳定了(此前频繁出现的
WaitDelay expired错误随之消失)。--headed可能被静默忽略(--headless=new仍在进程参数里)→ 放弃内置浏览器,改用系统 Chrome +--cdp。bash/shell 工具默认会杀掉子进程 → 启动 Chrome 这类 GUI 进程要保留后台进程(detached),否则窗口一闪就没。
立创商城 WAF:203 + JS 挑战 + 无头跳转 → 反检测脚本 + 直连解析 JSON-LD。
Chrome 147 screencast 不推帧 → 换
captureScreenshot轮询。响应消息没有
method字段 → 调试 CDP 时用msgId → method的 pending map,别用msg.method判断响应。
结束语
从"装一个 skill"到"AI 真的替你逛了趟商城、查了份数据手册、还把全过程实时投屏给你看",核心收获是:Agent 工具链的默认能力往往不够"可观测",但 CDP 这条通路,加上几十行胶水代码,就能把 AI 的每个动作都变成你眼前看得见的画面。
技术要点:
浏览器自动化:
agent-browser(open → snapshot → act → re-snapshot)反爬对抗:
--init-script反检测 + 多通道直连实时投屏:系统 Chrome + CDP
captureScreenshot轮询 + Web 播放器
相关文件:
init_undetect.js—— 反自动化检测注入脚本viewer_server.js—— CDP 截图流 + Web 播放器服务


评论