Files
docs/browser-harness-guide.md

14 KiB
Raw Permalink Blame History

Browser Harness 使用指南:连接 AI 与真实浏览器

官方仓库:browser-use/browser-harness

组织:Browser Use

设计哲学:最薄、最小、最强的 Agent 浏览器控制层


一、项目背景

Browser Harness 是一个极薄的 CDPChrome DevTools Protocol)桥接层,让 AI 编程助手(Claude Code、Codex、Hermes Agent 等)直接操控你的真实浏览器。它不做任何高层抽象 — 就是一条 WebSocket 连到 Chrome,中间什么都没有。

核心理念来自 The Bitter Lesson of Agent Harnesses

"Agent 需要的不是一个全功能的浏览器自动化框架,而是一根足够细的管道 — 能传递点击和截图就够了。"

与传统工具的区别

特性 Browser Harness Playwright / Puppeteer Selenium
代码量 ~1000 行(4 个文件) 数十万行 数十万行
浏览器 连接你的真实 Chrome 启动独立浏览器 启动独立浏览器
登录态 直接用你的 Cookie / Session 需要手动注入或重新登录 需要手动注入或重新登录
扩展/书签 全部可用
AI Agent 编辑 Agent 可直接改 helper 代码 不能 不能
跨 iframe / Shadow DOM 坐标点击天然穿透 需要切换 context 需要切换 context

架构(~1000 行代码)

Chrome / Browser Use Cloud → CDP WebSocket → daemon(长驻进程)→ IPC → browser-harness CLI

四个核心文件:

文件 作用
run.py CLI 入口,负责解析命令、启动 daemon、执行 Python 片段
daemon.py 长驻中间层进程,管理 CDP 连接生命周期
helpers.py CDP 封装 + 核心浏览器原语(截图、点击、导航、JS 执行)
admin.py daemon 生命周期管理、诊断、更新、云浏览器管理

Agent 只能编辑 agent-workspace/ 下的内容:

  • agent_helpers.py — 任务特定的辅助函数
  • domain-skills/ — 可复用的站点技能(社区贡献)

二、安装

前置要求

  • Python >= 3.11
  • uv(推荐,Python 包管理器)或 pip
  • Chrome / Chromium 浏览器
  • Git

推荐安装方式(uv tool,全局可用)

# 1. 克隆到持久目录(推荐 ~/Developer/,不要放 /tmp
git clone https://github.com/browser-use/browser-harness
cd browser-harness

# 2. 用 uv tool 安装为可编辑的全局命令
uv tool install -e .

# 3. 验证
command -v browser-harness
# 输出: /home/user/.local/bin/browser-harness

为什么用 -eeditable)? Agent 在运行时会往 agent-workspace/agent_helpers.py 中写自定义 helper,editable 安装保证下次调用 browser-harness 立即使用新代码,无需重新安装。

备选安装方式(pip

git clone https://github.com/browser-use/browser-harness
cd browser-harness
pip install -e .

平台支持

平台 状态 备注
Linux 完全支持 Socket: /tmp/bu-<NAME>.sock
macOS 完全支持 Socket: /tmp/bu-<NAME>.sock
Windows 支持 IPC 使用 TCP loopback + port file

各平台安装注意事项

macOS

# Chrome 路径
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
# 一键打开 chrome://inspect 页面
osascript -e 'tell application "Google Chrome" to activate' \
          -e 'tell application "Google Chrome" to open location "chrome://inspect/#remote-debugging"'

Windows

# Chrome 路径
"C:\Program Files\Google\Chrome\Application\chrome.exe"
# 安装后确保 %USERPROFILE%\.local\bin 在 PATH 中

Linux

# Chrome 通常已通过包管理器安装
google-chrome
# 非标准安装路径
/usr/bin/google-chrome
/opt/google/chrome/chrome

注册为 Agent 的全局 Skill(可选)

安装后,让 AI Agent 在任何项目中都能使用 Browser Harness

Claude Code — 在 ~/.claude/CLAUDE.md 中添加:

@~/Developer/browser-harness/SKILL.md

Codex — 创建符号链接:

mkdir -p ~/.codex/skills/browser-harness
ln -sf ~/Developer/browser-harness/SKILL.md ~/.codex/skills/browser-harness/SKILL.md

三、浏览器连接

Browser Harness 连接浏览器有两种方式:

Way 1chrome://inspect 复选框(推荐日常使用)

连接到你的真实 Chrome,继承所有登录态、扩展、书签。

  1. 在 Chrome 地址栏输入 chrome://inspect/#remote-debugging
  2. 勾选 "Allow remote debugging for this browser instance"
  3. 此设置是每个 Profile 一次性的,勾选后该 Profile 的每次启动都默认开启

Chrome 144+ 首次连接时会弹出 "Allow remote debugging?" 确认框,点击 Allow 即可。

优点:直接用你的真实浏览器,Cookie、Session、扩展全部生效。 缺点:偶尔需要手动点击 Allow 弹窗。

Way 2:命令行启动(推荐自动化/无头场景)

启动独立的 Chrome 实例,无弹窗,适合无人值守。

# Linux / macOS
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-bh

# macOS(完整路径)
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=/tmp/chrome-bh

# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" ^
  --remote-debugging-port=9222 ^
  --user-data-dir=%TEMP%\chrome-bh

重要--user-data-dir 必须指向非默认 Profile 目录。指向默认目录(如 ~/.config/google-chrome)时,Chrome 136+ 会静默忽略 --remote-debugging-port 参数。

告诉 Harness 连接哪个端口:

# 环境变量方式
export BU_CDP_URL=http://127.0.0.1:9222
browser-harness <<'PY'
print(page_info())
PY

# 或者内联
BU_CDP_URL=http://127.0.0.1:9222 browser-harness <<'PY'
print(page_info())
PY

Headless 模式(E10 等企业系统自动化专用)

启动独立 headless Chrome

google-chrome --headless=new \
  --remote-debugging-port=9223 \
  --user-data-dir=/tmp/bh-e10 \
  --no-first-run --no-default-browser-check \
  --window-size=1920,1080

然后所有 browser-harness 命令加上端口前缀:

export BU_CDP_URL=http://127.0.0.1:9223 && browser-harness <<'PY'
new_tab("https://example.com/login")
wait_for_load()
PY

⚠️ 关键exportbrowser-harness 必须在同一行。daemon 是独立进程,不会继承后续 shell 的环境变量。


四、基本使用

第一个命令

browser-harness <<'PY'
print(page_info())
PY

输出当前标签页的 URL 和标题。

导航

browser-harness <<'PY'
# 打开新标签页(首选方式,不会覆盖用户当前标签)
new_tab("https://github.com")
wait_for_load()

# 获取页面信息
print(page_info())
PY

new_tab() vs goto_url():第一次导航总是用 new_tab()goto_url() 会在用户当前活跃标签页中导航,可能覆盖用户正在看的内容。

截图(最核心的反馈方式)

browser-harness <<'PY'
capture_screenshot("/tmp/page.png")
PY

截图是验证操作结果的首选方式 — 比 DOM 检查更快、更直观。

坐标点击(穿透 iframe / Shadow DOM

browser-harness <<'PY'
# 用截图找到目标坐标后直接点击
click_at_xy(500, 300)
wait_for_load()
capture_screenshot("/tmp/after_click.png")
PY

坐标点击经由 Chrome 浏览器的合成器层(compositor level)派发 Input.dispatchMouseEvent,天然穿透 iframe、Shadow DOM 和跨域边界。不需要切换 context。

工作流capture_screenshot() → 看图找坐标 → click_at_xy(x, y)capture_screenshot() 验证。这是 Browser Harness 推荐的操作模式,而非 Playwright 风格的 "先定位再点击"。

JS 执行(DOM 读取和复杂逻辑)

browser-harness <<'PY'
# 读取页面内容
content = js("document.body.innerText")
print(content[:500])

# 提取结构化数据
import json
links = json.loads(js('''
var all = document.querySelectorAll("a");
var result = [];
for (var i = 0; i < all.length; i++) {
    if (all[i].href) result.push({text: all[i].textContent.trim(), href: all[i].href});
}
return JSON.stringify(result);
'''))
for l in links:
    print(l["text"], "->", l["href"])
PY

表单填充(native setter 方式)

React/Vue 等框架的受控组件不接受直接的 .value = "..." 赋值。需要使用原生 setter + 事件派发:

browser-harness <<'PY'
# 注入通用 fillInput 函数
js('''
var ns = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
window.__fi = function(selector, value) {
    var el = document.querySelector(selector);
    el.focus();
    ns.call(el, value);
    el.dispatchEvent(new Event("input", { bubbles: true }));
    el.dispatchEvent(new Event("change", { bubbles: true }));
    el.dispatchEvent(new Event("blur", { bubbles: true }));
};
''')

js('window.__fi("#username", "myuser")')
js('window.__fi("#password", "mypass")')
PY

原始 CDP 调用

需要 helpers.py 没有封装的功能时,直接调 CDP 协议:

browser-harness <<'PY'
# 清空浏览器缓存
cdp("Network.clearBrowserCache")
# 设置 Cookie
cdp("Network.setCookie", {"name": "token", "value": "abc123", "domain": "example.com"})
PY

五、核心 Helpers 速查

浏览器启动时自动导入的 helpers:

Helper 功能
new_tab(url) 打开新标签页并导航
goto_url(url) 在当前标签页导航(谨慎使用)
wait_for_load() 等待页面加载完成
capture_screenshot(path) 截图保存为 PNG需要传 path 参数
click_at_xy(x, y) 坐标点击(穿透所有层级)
js(code) 在页面中执行 JavaScript 并返回结果
page_info() 返回当前 URL 和标题
switch_tab(target) 切换到指定标签页
cdp(method, params) 直接调用 CDP 协议方法
http_get(url) 并发 HTTP GET(适合批量请求静态页面)
ensure_real_tab() 确保当前连接的是真实标签页(排除 Chrome 内部页)

六、Interaction Skills(交互技能)

interaction-skills/ 目录下包含可复用的交互模式文档:

技能 内容
screenshots.md 截图策略
tabs.md 标签页管理
dialogs.md 弹窗处理(alert/confirm/prompt
dropdowns.md 下拉框交互
iframes.md iframe 内操作
cross-origin-iframes.md 跨域 iframe 处理
shadow-dom.md Shadow DOM 穿透
uploads.md 文件上传
downloads.md 文件下载
drag-and-drop.md 拖拽操作
scrolling.md 页面滚动
cookies.md Cookie 管理
network-requests.md 网络请求拦截
print-as-pdf.md 网页转 PDF
viewport.md 视口调整

七、Cloud 浏览器(Browser Use Cloud

Browser Use 提供免费云浏览器(3 个并发浏览器,无需绑卡):

# 设置 API Key
export BROWSER_USE_API_KEY="your-key"

# 启动远程 daemon
browser-harness <<'PY'
start_remote_daemon("work")
PY

# 使用
BU_NAME=work browser-harness <<'PY'
new_tab("https://example.com")
print(page_info())
PY

云浏览器特性

  • Stealth 模式(绕过反爬检测)
  • 代理支持(proxyCountryCode="de"
  • Profile 持久化(profileName="my-work" — 登录态保持)
  • 本地 Profile 同步(sync_local_profile("MyChromeProfile") 上传 Cookie

八、Agent 自进化:写好 Helper,下次直接用

Browser Harness 的设计允许 Agent 在执行过程中自我改进。当遇到 helpers.py 没有的功能时:

# 在 agent-workspace/agent_helpers.py 中添加
def fill_form_selectors(fields: dict):
    """填表:fields = {'#username': 'john', '#password': '***'}"""
    ns = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value").set
    for selector, value in fields.items():
        el = document.querySelector(selector)
        el.focus()
        ns.call(el, value)
        el.dispatchEvent(new Event("input", {"bubbles": true}))

下次调用 browser-harness 时(因为是 -e editable 安装),新 helper 自动可用。


九、日常维护

# 诊断当前状态
browser-harness --doctor

# 更新到最新版(每天检查一次,有更新时自动提示)
browser-harness --update -y

# 重启 daemon
browser-harness <<'PY'
restart_daemon()
PY

十、故障排查

Daemon 不响应

# 清理残留的 daemon
pkill -f browser_harness.daemon
rm -f /tmp/bu-*.sock /tmp/bu-*.pid

# 重新启动
browser-harness <<'PY'
restart_daemon()
PY

Chrome 远程调试未开启

browser-harness --doctor
# 看 "chrome running" 和 "daemon alive" 两行
  • chrome FAILChrome 没运行。Way 1 让用户打开 ChromeWay 2 自己启动。
  • chrome ok, daemon FAIL:Chrome 运行了但远程调试没开。去 chrome://inspect/#remote-debugging 勾选复选框。

macOS:一键打开 chrome://inspect

osascript -e 'tell application "Google Chrome" to activate' \
          -e 'tell application "Google Chrome" to open location "chrome://inspect/#remote-debugging"'

Windows:环境变量设置

# PowerShell
$env:BU_CDP_URL = "http://127.0.0.1:9222"

# CMD
set BU_CDP_URL=http://127.0.0.1:9222

环境变量陷阱

export BU_CDP_URL=... 然后下一行 browser-harness 不会生效。daemon 是独立进程,不继承后续 shell 环境变量。必须:

# ✓ 正确
export BU_CDP_URL=http://127.0.0.1:9222 && browser-harness <<'PY'
...
PY

# ✗ 错误
export BU_CDP_URL=http://127.0.0.1:9222
browser-harness <<'PY'   # daemon 拿不到 BU_CDP_URL
...
PY

十一、相关资源


最后更新:2026-06-01 基于 Browser Harness v0.1.0