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)
Stars2,768Forks 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 的设计哲学:

架构


┌──────────────────────────────┐
│   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-skillsCDP `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 个函数):

关键设计


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 行)— 管理功能

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 HarnessOpenClaw Browser Tool
协议裸 CDPCDP(封装层)
接入方式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配置/插件

分析

优势

风险

与 Jay 的关联

从零开始:完整使用教程

第一步:开启 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)说明
创新性9Agent 自愈 + 自写工具 + 自动积累 Skills
代码质量8806 行极简,架构清晰
实用性8直接可用,Claude Code 一行命令启动
成熟度63 天前发布,2.7K stars 但需要更多实战
安全性5Agent 可修改 helpers.py,操作已登录网站
与 Jay 的关联8补充 OpenClaw 浏览器能力,云端免费
**总分****7.3**浏览器自动化的新范式:让 Agent 自己进化工具