它把网页压成一张编号元素表,让专用模型做"判断题"而不是"写作文"。官方演示里,苏黎世到伦敦的航班搜索 7.073 秒跑完;我在 Windows 上亲手部署复现,18 步花了 $0.003,也撞上一次教科书级的死循环。这篇文章把账算清,也把失败讲透。
docs/*measurement*.json)、我本机完整运行的 18 步日志、以及我对 TypeSafe API 的两次真实调用(附 token 用量)。文中所有对 GPT-4o 的对比均为列明假设的透明估算,不混作实测。过去两年,浏览器 Agent 的主流路线是"视觉大模型 + ReAct 循环":每走一步,给模型塞一张整页截图(或转成的无障碍树),模型输出一段思考和一个动作,执行后再截图、再思考。直觉上很通用,账单也很壮观。
token 消耗主要有三块:截图视觉 token(browser-use 官方文档给出的经验值是单张截图约 1,100 tokens,1080p 全页长截图 4,000–6,000)、DOM/无障碍树上下文(每步重复携带,通常数千到上万 token)、以及自回归输出(思考链加动作 JSON,按输出价计费,通常是输入价的数倍)。社区的经验锚点是:一个 10–15 步的中等任务,全程 8 万–15 万输入 token 很常见;一个真实的 31 步订票任务曾被记录到 459,840 输入 token。
按 GPT-4o 的公开单价(输入 $2.50/百万、输出 $10/百万)粗算,这类单次任务的成本在几美分到一美元之间。用来演示没问题,用来"每天早上自动跑 50 个表单"就是另一回事了。
Jev Ultrafast 是 Browser Use 组织 2026 年 9 月开源的参考实现(github.com/browser-use/jev-ultrafast),背后的判断模型由 TypeSafe AI 提供,模型名 System One / Jev,2026-09-15 以早期访问形式发布,公开报道称 TypeSafe 已获得 4,000 万美元融资;据 36 氪等媒体报道,项目开源数日 GitHub Star 即破 5,700。它的切入点非常明确:不跟大模型比谁更聪明,而是把"在网页上做一个动作"重新设计成便宜、确定、可批量调用的判断题。
核心管线只有四步,全部在源码里可以核对:
| 设计 | 做法 | 换来什么 |
|---|---|---|
| 一次调用拿全控件 | 注入页面的 snapshot.js 在单次浏览器往返里读取 HTML 与 ARIA 角色,输出带编号的元素表;节点身份用 WeakMap 维护,不靠脆弱的 CSS 选择器 | 观察成本从"每个动画帧轮询一次无障碍树"降到每步一次——这正是协议调用 1,092→101 的来源 |
| 投机式并行问题头 | 一次请求里同时回答多道有类型的问题:下一步做哪种操作(8 选 1)?如果是点击,点哪个编号?如果是选择,选哪个值?类似投机执行,最终只有被选中分支的结果会被消费 | 一轮往返拿到完整决策;问题是 Choice/Score 等结构化题型,返回校准概率而非自由文本 |
| 决策没有解码过程 | 选择头不逐 token 生成文本,TypeSafe 因此对输出免费,官方博客的措辞是"便宜到根本不值得计费"(too cheap to meter) | 输入 $0.042/百万 token、输出 $0;上下文窗口 32K |
模型的动作空间只有 8 种:CLICK、TYPE_TEXT、SELECT、SCROLL_UP、SCROLL_DOWN、WAIT、DONE、BLOCKED。执行前还有多层确定性护栏:动作前重新校验页面指纹(semantic 比对内容与结构,不比对像素)、点击前做命中测试与遮挡检查、可编辑 combobox 打字后最多等 200ms 让下拉建议出现。模型永远无法输出选择器、坐标或 JavaScript——它只能在给定编号里做选择。
api.typesafe.ai,输入框文字还会经过文本模型服务商(默认走 OpenRouter)。"数据不出本机"只对执行链路成立。处理敏感页面时,这一点必须纳入评估。先看定价(多个渠道交叉核实,OpenRouter、Vercel AI Gateway、ngrok 等同价上架):
| 项目 | Jev / System One | GPT-4o(公开价,对照) |
|---|---|---|
| 输入 | $0.042 / 百万 token(即 $42 / 十亿) | $2.50 / 百万 token |
| 输出 | 免费(选择头无解码过程) | $10 / 百万 token |
| 上下文 | 32K | 128K |
| 接口 | POST https://api.typesafe.ai/v1/systemone,模型 ID jev-1.13.0 / jev-latest | OpenAI 兼容接口 |
用仓库自带的 model.choose 构造真实请求体,我分别喂入"航班页初始状态(25 个元素)"和"运行中段状态(31 个元素、14 条历史)",两次返回如下:
| 调用 | 输入 / 输出 token | 延迟 | 决策 | 置信度 |
|---|---|---|---|---|
| 第 1 次(初始页) | 4,018 / 320 | 774ms | CLICK目标 12(票务类型) | 0.67 |
| 第 2 次(中段) | 4,366 / 320 | 1,804ms | CLICK目标 12(再次点同一处) | 0.59 |
两次调用合计成本约 $0.0004。注意:第二次调用在 API 层面就复现了死循环——同一状态下它稳定地再次选择同一个目标,置信度还下降了。这个细节第 7 节还会用到。
仓库 docs/ 附带了录制 run 的完整测量数据。7.073 秒那次航班任务共 17 次 Jev 请求,合计 90,558 输入 / 6,325 输出 token(平均每请求约 5,327 输入),加上两次文本模型调用的 $0.00006272,决策成本:
90,558 ÷ 1,000,000 × $0.042 ≈ $0.0038 # Jev 决策
+ $0.0000627 # 文本模型(mercury-2.5)
≈ $0.0039 / 任务
同文件里另外两组对照 run:优化分支三次分别 84,650 / 88,844 / 82,661 输入 token(16–18 次请求),旧循环分支三次 133,633 / 106,691 / 115,547(21–26 次请求)。
GPT-4o 那一栏是怎么算出来的(假设全部列明,欢迎挑刺):
结论:约 100 倍、两个数量级,而不是一个夸张的精确倍数。TypeSafe 官网自己的微任务对照(Jev $0.000081 / 0.114s 对比通用 LLM $0.013880 / 8.566s,约 171 倍;首页另有 444.6 倍的说法)是厂商口径,任务口径不同,这里只作旁证。
仓库文档给了少见诚实的一组性能实验:同一任务(苏黎世→伦敦)、同一 Chrome 配置文件、同一模型,交替运行旧的"动画帧轮询循环"与新的"一次性快照",各 3 次,且每次都用独立校验确认任务真的完成。
另外两个官方数据点:维基百科 Gödel 词条任务 2.798s,本地酒店筛选 fixture 1.896s;录制中 Jev 决策的中位延迟为 178ms。作为参照,我在深圳、跨太平洋网络下实测的每次决策延迟均值 659ms(区间 277–1,460ms),依然是亚秒级,但说明官方视频里的速度包含了网络就近的红利。
官方同时注明:符号检验 p=0.25,样本量很小,这是工程测量而不是统计学定论。这种克制在开源项目文档里不多见。
项目用 uv 管理依赖,uv sync 装 23 个包(含 browser-harness 0.1.13、cdp-use 1.4.5),Python 3.12。macOS 路径官方文档写得很顺,Windows 上我踩了四个实打实的坑,按踩中顺序记录:
browser.py 裸读注入脚本 snapshot.js,而该文件含弯引号(字节 0x92)。Windows 中文系统默认 GBK,读取即抛 UnicodeDecodeError。这是上游的跨平台 bug,解法是强制 UTF-8:
# PowerShell 当前会话
$env:PYTHONUTF8=1
# 设置后仓库测试全绿:pytest = 31 passed
demo.py 同样裸读 .env。用 PowerShell 5.1 的重定向写文件会带 UTF-8 BOM,配置行直接解析失败。用编辑器另存为"UTF-8 无 BOM",且 key 之外别放中文注释。最小配置:
TYPESAFE_API_KEY=sk-xxxx
TEXT_MODEL=nex-agi/nex-n2.5-mini:free
BU_CDP_URL=http://127.0.0.1:9223
日常 Chrome 会占住 127.0.0.1:9222 的 IPv4 端口,访问 /json/version 却返回 404(那不是调试实例)。daemon 的探测顺序是 9222→9223,环境变量优先级最高。正确做法是用独立用户目录起一个调试 Chrome 绑 9223:
& "C:\Program Files\Google\Chrome\Application\chrome.exe" `
--remote-debugging-port=9223 `
--user-data-dir="C:\Users\你\chrome-dev-profile"
我让 AI 助手在工具调用里后台拉起 daemon,调用一结束进程就被回收(PID 实测死亡),端到端 demo 始终连不上。必须在你自己的终端窗口里启动,服务常驻在 http://127.0.0.1:8766:
uv run --env-file .env jev
| 其他 Windows 现象 | 处置 |
|---|---|
约 50% 的 tick 出现 captureScreenshot 5 秒超时 | 动作实际已执行,可继续;但它会污染熔断状态(见第 7 节) |
| 默认文本模型 mercury-2.5 小样本探测返回空 content | 换成 OpenRouter 上的免费模型 nex-agi/nex-n2.5-mini:free,本稿所有运行均用它,文本调用 $0 |
环境:Windows 11、Chrome 152.0.7977.84、Python 3.12.14、uv 0.12.5、browser-harness 0.1.13、cdp-use 1.4.5。
任务:"Find the cheapest one-way flight from New York to London."(在 Google Flights 找纽约到伦敦的单程最便宜航班——注意,没有给日期。)
结果:18 次决策、3 次文本模型调用、总墙钟 231,318ms(约 3.9 分钟)、全程只有 1 次页面变化,最终状态停在 ready(既没 DONE 也没 BLOCKED)。
"Round trip"——把票务类型选项填进了城市输入框。小模型本身只负责"这个框该填什么字符串",上下文一旦被前面的混乱动作污染,它会一本正经地配合出错。这是整件事最值得写的部分。失败之后我没有急着重试,而是把官方成功 trace、项目提示词源码、我抓到的失败状态快照放在一起对了一遍。
官方测量文件记录的苏黎世→伦敦 trace 是这样的:输入 "Zurich" → CLICK 下拉建议 "Zürich, Switzerland"(目标 3);输入 "London" → CLICK "London, United Kingdom"(目标 3);然后点出发日期框、点日期、点 Done、点 Search(5.217s),7.073s 校验通过。
而且这不是模型临场发挥——提示词源码 questions.py 的 NEXT_ACTION 里白纸黑字写着:"A typed query still needs its matching autocomplete suggestion selected."(输入的查询还需要选中匹配的自动补全建议);日期选择器也写明了"CLICK 输入框、CLICK 日期、CLICK 确认"的顺序。
我保存了运行中段的完整状态 JSON(31 个可操作元素)。逐个检查后:里面只有标准控件(票务 combobox、出发/到达 combobox、日期 textbox、Search 按钮等),没有任何 listbox/option 角色的城市建议项;另一份探测快照里,出发地显示 "New York",目的地甚至是空的。也就是说,在模型做决策的那个瞬间,它想点下拉建议也点不到——编号表里没有这个编号。Google Flights 的下拉没有出现(或已消失):CDP 填字没有稳定触发/保留建议列表,200ms 的等待窗口没能兜住。
官方目标包含明确日期("on September 20, 2026"),填完两个城市后下一步毫无歧义:点日期框。我的目标没有日期,模型在"城市未生效 + 下一步该干嘛"的双重模糊下,倒向了提示词里另一条高优先级规则——"Search 按钮可见且必填字段就绪就立刻点它",于是开始连点搜索。槽位不全的自然语言目标,会显著放大策略的脆弱性。
agent.py 里其实有循环保护:最近 3 步全部 page_changed is False 且不是 WAIT,就置为 BLOCKED。但注意这个判断用的是严格等于 False。在我的运行里,约一半 tick 的截图环节 5 秒超时(日志中的 TICK ERR,穿插在第 9、11、13–15、17 步之后);这些 tick 的动作虽然执行了,动作后观察却失败,历史记录里的 page_changed 保持为空(None)而不是 False。于是"连续 3 个 False"永远凑不齐:连点序列被 ERR tick 反复打断,熔断一次都没有触发。这不是模型问题,是运行时可靠性问题,但代价由整个任务承担。
我把运行中段的页面状态和合成的 14 条历史重新发给 API(第 3 节的第 2 次调用):它再次返回 CLICK 目标 12,置信度从 0.67 降到 0.59。判断题模型的失败模式因此很清晰——不是天马行空,而是高确定性地重复同一个错误。好处是可复现、好调试;坏处是没有外层干预时它不会自己跳出局部最优。
| 官方明确支持 / 内置 | 明确不支持 / 边界 |
|---|---|
| 标准 HTML 控件(button / link / combobox / textbox / select)、滚动、表单填写、自动补全(200ms 等待)、遮挡与命中检查、页面指纹新鲜度校验 | Shadow DOM、iframe/frame、canvas、文件上传、新标签页/弹窗、嵌套滚动区域、复杂键盘组件(如自定义快捷键控件) |
| 运行预算:最多 60 个浏览器动作 / 120 次决策请求;候选元素上限 250 | DONE 不代表成功——官方反复强调必须独立校验结果(官方 6 轮 A/B 每轮都做了) |
Jev 代表的思路并不复杂:浏览器操作里绝大多数步骤不是开放推理题,而是"在这 25 个控件里选一个点"的判断题。把判断题从自回归大模型里拆出来,用专用的、带校准概率的模型批量作答,成本和延迟就同时掉一个数量级;真正需要语言能力的地方(往框里填什么字)才调用小模型,两次调用值 $0.00006。
我的这次失败没有推翻这个思路,反而印证了它的配套要求:判断模型越确定、越便宜,围绕它的运行时(观察可靠性、槽位补全、循环守护、结果校验)就越不能省。官方 7 秒的视频是真的,我 3.9 分钟的空转也是真的——它们是同一套系统在不同输入质量和运行环境下的两个合法输出。
对开发者来说,现在是值得花一个下午把它跑起来的时点:$5 额度足够跑上万次决策,协议开放、测量数据公开、失败也烧不掉一毛钱。只是上线前,请务必替它守好那几道护栏。