Browser Use 创始人 Gregor Zunic 复盘了他们从 Browser Use 到 browser-harness 的架构演进,核心结论很反直觉。
从几千行到 600 行
Browser Use 早期版本:数千行 DOM indexer、element extractor、click wrapper。
这些是团队「替 LLM 做决定」的痕迹——团队认为模型需要这些辅助。结果是:每个辅助函数都是给 RL 训练过的模型强加的约束,模型得绕着这些抽象走。
核心洞察:LLM 已经被训练过 CDP 了
LLM 看过海量的 Page.navigate、DOM.querySelector、Runtime.evaluate。这些是 Chrome DevTools Protocol(CDP)的原生接口。
模型不需要你来翻译它本来就会用的东西。
真正的 harness 长这样
全部加起来 ~600 行:
- 13 行 — Python 入口,运行预加载了 helpers 的纯 Python
- 192 行 — CDP thin wrapper,Agent 自己会编辑它们
- 220 行 — CDP WebSocket 保活
- SKILL.md — 告诉 Agent 怎么用上述工具
给 Agent 自由会发生什么
当缺少 upload_file() 时:
Agent 读到 file input,grep 了一下,空白,然后直接用 DOM.setFileInputFiles 写了上传函数——就像修一个 missing import 一样。
当 12MB 文件触发 CDP websocket 10MB payload 上限时:
Agent 读了错误信息,自动切换到分块上传模式。
当 Azure admin portal 的 iframe 嵌套导致点击穿透失败时:
Agent 直接用 Input.dispatchMouseEvent 坐标级事件,走 compositor 层面通过。
这些都是 Agent 自己解决的,没有修改 harness。
惨痛教训(The Bitter Lesson)
你的 helpers 也是抽象层。删掉它们。让 agent 写它需要的东西。
Agent 不是从零写代码,它是在补那个缺失的函数——就像在任何代码库里修 missing import 一样自然。