Browser Harness — 自愈式浏览器控制(代码深度分析)
> 一句话版本:一个极简的 Python 浏览器控制工具,让 AI Agent 通过 Chrome DevTools Protocol 直接操控浏览器。最独特的设计:Agent 自己写自己缺的功能。缺 upload_file()?Agent 边做任务边写出来。2,768 stars,3 天前发布。
| 项目 | 信息 | ||
|---|---|---|---|
| 来源 | [github.com/browser-use/browser-harness](https://github.com/browser-use/browser-harness) | ||
| Stars | 2,768 | Forks 217 | |
| 语言 | Python | 许可证 | MIT |
| 创建 | 2026-04-17 | 最后推送 | 2026-04-20 |
| 代码量 | 806 行 Python(核心) | ||
| 母公司 | Browser Use(browser-use.com) |
核心理念:Bitter Lesson
作者 Gregor Zunic 写了篇博客《The Bitter Lesson of Agent Frameworks》,核心观点:
> "Agent 就是一个 for 循环。99% 的工作在模型里,不在你的代码里。框架是约束,不是帮助。"
Browser Harness 的设计哲学:
- 没有框架——没有 recipes、没有 rails、没有抽象层
- Agent 自己写缺失的工具——遇到需要但没有的功能,Agent 边做任务边写
- 一个 WebSocket 到 Chrome——中间什么都不加
架构
┌──────────────────────────────┐
│ Claude Code / Codex / etc │
│ exec(stdin Python) │
└──────────┬───────────────────┘
│ stdin (Python)
┌──────────▼───────────────────┐
│ run.py (44 行) │
│ ensure_daemon() → exec() │
└──────────┬───────────────────┘
│ Unix socket /tmp/bu-default.sock
┌──────────▼───────────────────┐
│ daemon.py (248 行) │
│ CDP WebSocket ↔ Unix Socket│
│ 事件缓冲 + 对话框管理 │
└──────────┬───────────────────┘
│ CDP WebSocket
┌──────────▼───────────────────┐
│ Chrome (remote debugging) │
│ 用户真实浏览器/会话 │
└──────────────────────────────┘
核心代码分析
helpers.py(216 行)— Agent 的工具箱
这是最关键的文件。Agent 可以读它、编辑它、扩展它。
CDP 通信层:
# 通过 Unix socket 发送 CDP 命令
def _send(req):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(SOCK)
s.sendall((json.dumps(req) + "\n").encode())
# ...接收响应
def cdp(method, session_id=None, **params):
"""裸 CDP 调用。cdp('Page.navigate', url='...')"""
return _send({"method": method, "params": params, "session_id": session_id})
9 个核心工具:
| 函数 | 功能 | 实现方式 |
|---|---|---|
| `goto(url)` | 导航 + 自动加载 domain-skills | CDP `Page.navigate` |
| `page_info()` | 获取 URL/标题/视口/滚动/页面尺寸 | JS `Runtime.evaluate` |
| `click(x, y)` | 鼠标点击(左/右/中,多击) | CDP `Input.dispatchMouseEvent` |
| `type_text(text)` | 输入文本 | CDP `Input.insertText` |
| `press_key(key)` | 按键(含修饰键组合) | CDP `Input.dispatchKeyEvent` |
| `scroll(x, y)` | 滚动 | CDP `Input.dispatchMouseEvent` (mouseWheel) |
| `screenshot(path)` | 截图(支持全页面) | CDP `Page.captureScreenshot` |
| `upload_file(selector, path)` | 文件上传 | CDP `DOM.setFileInputFiles` |
| `js(expression)` | 执行任意 JS(含 iframe) | CDP `Runtime.evaluate` |
标签页管理(5 个函数):
list_tabs()/current_tab()/switch_tab(target_id)/new_tab(url)/ensure_real_tab()- 切换标签页时在标题前加 🟢,让用户看到 Agent 控制的是哪个标签
关键设计:
def upload_file(selector, path):
"""Set files on a file input via CDP DOM.setFileInputFiles."""
doc = cdp("DOM.getDocument", depth=-1)
nid = cdp("DOM.querySelector", nodeId=doc["root"]["nodeId"], selector=selector)
cdp("DOM.setFileInputFiles", files=[path], nodeId=nid)
↑ 这个函数就是作者说的"Agent 自己写的"。最初 helpers.py 没有 upload_file(),Agent 在做任务时发现需要,自己编辑了这个文件加上了它。
daemon.py(248 行)— CDP ↔ Unix Socket 桥
Daemon 生命周期:
1. 读取 DevToolsActivePort 文件找到 Chrome 的 CDP WebSocket URL
2. 连接 WebSocket,附加到第一个真实页面
3. 启动 Unix socket server,等待 Python 命令
4. 转发 CDP 命令,缓冲事件
自动重连:
# session 过期时自动重新附加
if "Session with given id not found" in msg:
log(f"stale session {sid}, re-attaching")
if await self.attach_first_page():
return {"result": await self.cdp.send_raw(method, params, session_id=self.session)}
对话框管理:拦截 Page.javascriptDialogOpening,让 Agent 能处理 alert/confirm/prompt。
浏览器发现:自动扫描 Chrome、Edge、Chromium 的多个安装路径(macOS/Linux/Windows),找到 DevToolsActivePort。
run.py(44 行)— 入口
极简:
def main():
ensure_daemon() # 自动启动 daemon
exec(sys.stdin.read()) # 从 stdin 执行 Python(helpers 已预导入)
admin.py(298 行)— 管理功能
ensure_daemon()— 检查/启动 daemon 进程- 云端浏览器支持(
start_remote_daemon/stop_remote_daemon) - 本地 profile 列表和同步
Domain Skills 系统
domain-skills/
github/ scraping.md, repo-actions.md
linkedin/ (示例)
amazon/ (示例)
hackernews/ scraping.md
arxiv/ scraping.md
...
关键规则:Skills 是 Agent 自己写的,不是人写的。
> "Skills are written by the harness, not by you. Just run your task with the agent — when it figures something non-obvious out, it files the skill itself."
流程:Agent 做任务 → 发现某网站的交互模式有规律 → 自动生成 domain-skills 文件 → 下次做类似任务时自动加载。
与 OpenClaw 的对比
| 维度 | Browser Harness | OpenClaw Browser Tool |
|---|---|---|
| 协议 | 裸 CDP | CDP(封装层) |
| 接入方式 | MCP / stdin Python | 内置工具 |
| 自愈能力 | ✅ Agent 自己写工具 | ❌ 固定工具集 |
| Domain Skills | ✅ Agent 自动生成 | ❌ |
| 截图 | ✅ `screenshot()` | ✅ `browser screenshot` |
| 文件上传 | ✅ `upload_file()` | ❌ |
| iframe | ✅ `iframe_target()` | ✅ frame 参数 |
| 对话框处理 | ✅ 拦截 dialog | ✅ `browser dialog` |
| 标签管理 | ✅ 5 个函数 | ✅ tabs 工具 |
| 代码量 | 806 行 | OpenClaw 内部 |
| 定制 | Agent 直接改 helpers.py | 配置/插件 |
分析
优势:
- 🔥 极简 + 极强:806 行 Python 覆盖完整浏览器控制
- 🔥 自愈设计:Agent 自己写缺失的工具——这是真正的创新
- 🎯 Domain Skills 自动生成:做过的任务自动积累经验
- 🧹 零框架:没有抽象层,Agent 直接操作 CDP
- 🖥️ 连接用户真实浏览器:利用已有的登录态、cookie
- ☁️ 云端浏览器支持:免费 3 个并发,无需信用卡
风险:
- ⚠️ 安全隐患:Agent 能操作用户已登录的所有网站
- ⚠️ helpers.py 可被 Agent 随意修改:既是特性也是风险
- 🟡 只支持 Chrome/Chromium(通过 CDP)
- 🟡 3 天前发布:可能有不稳定的 edge case
- 🟡 云端服务依赖:远程浏览器需要 browser-use.com API key
与 Jay 的关联:
- OpenClaw 已有浏览器工具,但 Browser Harness 的"自愈"理念值得借鉴
- Domain Skills 自动生成:如果 OpenClaw 的 browser tool 也能积累网站交互经验,会大幅提升效率
- 云端浏览器:免费 3 并发,适合跑爬虫任务
- Jay 的 Mac M3 Air 可以直接用(连接本地 Chrome)
- 与 Open Computer Use 互补:Browser Harness 控制浏览器,Open Computer Use 控制桌面 App
从零开始:完整使用教程
第一步:开启 Chrome 远程调试
# 先完全退出 Chrome(Cmd+Q)
# 然后终端执行:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
Chrome 弹出提示 → 点 Allow。
第二步:安装
git clone https://github.com/browser-use/browser-harness.git
cd browser-harness
pip install uv
uv sync
第三步:交给 Claude Code
打开 Claude Code,输入:
帮我用 browser-harness 这个项目,打开 Hacker News 首页,截图保存到 /tmp/hn.png,然后告诉我前 5 条新闻的标题。
Claude Code 会自动:
1. 读 install.md,启动 daemon 连接 Chrome
2. 读 helpers.py,了解可用工具
3. 写 Python 代码并通过 run.py 执行:
goto("https://news.ycombinator.com")
wait_for_load()
screenshot("/tmp/hn.png")
titles = js("""
Array.from(document.querySelectorAll('.titleline > a'))
.slice(0, 5)
.map(a => a.textContent)
""")
4. 返回结果给你
自愈场景
如果 Claude Code 想滚动加载更多内容,发现 helpers.py 没有这个函数:
Claude Code: "需要滚动到底部"
↓
Claude Code: 编辑 helpers.py,加上:
def scroll_to_bottom():
for _ in range(10):
scroll(x=500, y=500, dy=-500)
wait(0.5)
↓
Claude Code: 调用 scroll_to_bottom()
↓
下次做类似任务,这个函数已经存在
全程数据流
Claude Code → 写 Python → run.py → Unix socket → daemon.py → CDP WebSocket → Chrome
↓
Claude Code ← 截图/数据 ← JSON 响应 ←──────────────────────────────────┘
你只需要做两件事:开启 Chrome 调试模式 + 告诉 Claude Code 你要什么。
评分
| 维度 | 评分 (1-10) | 说明 |
|---|---|---|
| 创新性 | 9 | Agent 自愈 + 自写工具 + 自动积累 Skills |
| 代码质量 | 8 | 806 行极简,架构清晰 |
| 实用性 | 8 | 直接可用,Claude Code 一行命令启动 |
| 成熟度 | 6 | 3 天前发布,2.7K stars 但需要更多实战 |
| 安全性 | 5 | Agent 可修改 helpers.py,操作已登录网站 |
| 与 Jay 的关联 | 8 | 补充 OpenClaw 浏览器能力,云端免费 |
| **总分** | **7.3** | 浏览器自动化的新范式:让 Agent 自己进化工具 |