不是模拟环境。它驱动你电脑上真实的 Edge/Chrome,打开真实网页,看真实页面, 点真实按钮,然后把每一步的画面实时推给你看。
git clone https://github.com/xiaoyaoqilan/browser-agent.git
cd browser-agent
npm install # 只装 playwright-core
cp config.example.json config.json
# 编辑 config.json,把 apiKey 换成你自己的
node run.js "在百度搜索 Playwright" --url https://www.baidu.com --mode dry --steps 4 # 先不接模型验证链路browser-agent/
├── browser.js 浏览器控制:启动 Edge/Chrome、提取可操作元素、执行动作、截图
├── llm.js 模型接入层:openai / anthropic / ollama 三种协议,统一支持图片输入
├── agent.js 决策循环:观察 → 模型决策 → 执行 → 再观察
├── run.js 命令行入口
├── serve.js Web 控制台(实时画面 + 思维流)
├── selftest.js 端到端自检(不需要任何模型密钥)
└── config.json 模型配置
# 1. 不接模型,先验证浏览器链路(不需要任何配置)
node run.js "在百度搜索 Playwright" --url https://www.baidu.com --mode dry --steps 4
# 2. 填好 config.json 里的 apiKey,然后:
node run.js "在百度搜索 Playwright 教程,返回第一条结果的标题和链接" --url https://www.baidu.com
# 3. 或者打开可视化控制台
node serve.js # 访问 http://127.0.0.1:8890VLM 接入没有什么神秘的东西:就是在发消息时,把当前页面的截图转成 base64,
和文字一起塞进消息体。三种协议的图片格式略有不同,llm.js 已经全部处理好了:
| 协议 | 图片格式 | 接口 |
|---|---|---|
| openai(及一切兼容中转) | {type:"image_url", image_url:{url:"data:image/jpeg;base64,..."}} |
/v1/chat/completions |
| anthropic | {type:"image", source:{type:"base64", media_type:"image/jpeg", data:"..."}} |
/v1/messages |
| ollama(本地) | 消息里的 images: ["<base64>"] 字段 |
/api/chat |
光给截图,模型很难说清楚"点哪里"。所以 VLM 模式下会先给页面上每个可操作元素
压一个红色小编号,再截图。截图上显示 7,元素列表里就是 e7,模型直接回答
{"op":"click","id":"e7"} 就能点中。文字元素列表 + 视觉截图双通道,
比纯视觉坐标点击稳得多。
路线 A:云端多模态 API(最省事)
{
"provider": "openai",
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"apiKey": "sk-...",
"model": "qwen-vl-max",
"visionModel": "qwen-vl-max"
}支持图片输入的常见模型:Qwen-VL 系列(通义)、GLM-4V(智谱)、GPT-4o / GPT-4o-mini (OpenAI)、Claude 3.5+(走 anthropic 协议)、豆包视觉版。DeepSeek 的纯文本模型 不能看图,但 DOM 模式不需要看图。
路线 B:本地 Ollama(数据不出机器)
ollama pull qwen2.5vl:7b # 7B 就够驱动浏览器{ "provider": "ollama", "baseUrl": "http://127.0.0.1:11434", "model": "qwen2.5vl:7b" }路线 C:本地 vLLM 部署(追求吞吐)
vllm serve Qwen/Qwen2.5-VL-7B-Instruct --port 8000{ "provider": "openai", "baseUrl": "http://127.0.0.1:8000/v1", "model": "Qwen/Qwen2.5-VL-7B-Instruct" }路线 D:公司 / 内网网关
把 baseUrl 换成你的网关地址(openai 兼容协议),填好 apiKey 即可。
注意:网关上的模型必须是多模态的才能跑 VLM 模式;纯文本模型走 DOM 模式。
node run.js --list # 列出接口上可用的模型
node run.js --probe # 发一张 1x1 图片,测当前模型是否支持视觉
node diagnose.js # 网关体检:不知道地址怎么填、报 405/401 就跑这个
node selftest.js --vision # 不需要密钥的端到端自检
node selftest.js --vision --refuse-image # 验证模型拒图后能否自动降级自检会验证:截图真的发出去了、base64 数据非空、系统提示词正确、 浏览器真的完成了动作、最终 URL 正确。
| DOM 模式(默认) | VLM 模式(--vision) | |
|---|---|---|
| 需要的模型 | 任意文本模型 | 多模态模型 |
| 每步开销 | 约 1-2K token | 约 1-2K token + 一张 300KB 截图 |
| 擅长 | 常规网页操作,又快又稳 | 验证码、canvas 画布、复杂视觉布局、图片语义 |
| 弱点 | 看不到纯视觉内容 | 慢、贵,编号依赖 DOM |
日常任务用 DOM 模式,遇到"必须看图才能懂"的页面再切 VLM。
node run.js "任务" [--url 网址] [--mode dom|vision|dry] [--steps 25]
[--show] [--model 名字] [--config 路径]
node run.js --list | --probe
--show弹出真实浏览器窗口,亲眼看着它点--mode dry内置启发式,不接模型,验证链路用
click / type / select / press / scroll / goto / back / wait / extract / done
模型每步输出一个 JSON 动作,解析层做了容错(代码块包裹、单引号、纯数字 id 都能救回来)。
selftest.js与selftest.js --vision全部通过(2026-09-10)- 真实百度:打开 → 输入 → 回车 → 停在结果页,截图 336KB base64 确认送达模型侧
- 修复过的坑:DOM 更新后旧元素编号残留导致重复 id(每次观察前先清标记)、 OpenAI 协议下 system 提示词未随请求发出(两种协议统一改为首条 system 消息)、 同名 id 命中隐藏元素(选择器改为遍历取第一个可见元素)