AI Agentが「走りながら直す」ことを覚けたとき
2026年、AI Agentによるブラウザ操作の競争は激化の一途を辿っている——Browser Use、Agent-E、WebVoyagerがそれぞれの能力を競っている。しかし、browser-useチームによるあるオープンソースプロジェクトが、600行にも満たないPythonコードで頭角を現した:Browser Harnessである。
2026年8月現在、このプロジェクトはGitHubで17,100以上のStarを獲得し、ブラウザAgent分野で最も急速に成長しているプロジェクトの一つとなっている。その核となる理念はただ一言:LLMをChromeのCDPポートに直接接続し、足りない関数はAIに書かせよ。
これはまた一つの「Playwrightをラップする」ミドルウェアフレームワークではない。Browser Harnessの設計哲学はミニマリズム——セレクタエンジンもなく、ページモデルもなく、事前定義されたワークフローもない。最小限のCDPヘルパー関数のみを提供し、残りはLLMが実行時に動的に生成する。
さらに驚くべきはその自己修復能力である。Agentがフレームワークでカバーされていない操作に遭遇しても、エラーで終了するのではなく、自ら新しいヘルパー関数を書いてローカルワークスペースに保存し、次回から直接再利用する。フレームワークは使えば使うほど強くなる——これが「自己修復」の意味である。
Playwright/Puppeteerとの本質的な違い
多くの人がこう問うだろう:これは単なるPlaywrightのPythonラッパーではないのか?答えはノーである。
PlaywrightとPuppeteerは従来の自動化フレームワークである。それらの設計目標は「人間がスクリプトを書いてブラウザを制御する」ことで、豊富なセレクタエンジン(CSS、XPath、テキスト)、ページモデル、待機機構、アサーションライブラリを提供する。どの要素をクリックするか、どのフォームに入力するか、どの条件を待つかを事前に知る必要がある。
Browser HarnessはAIネイティブフレームワークである。ブラウザを制御するのは人間のスクリプトではなくLLMだと前提している。そのため: - セレクタに依存せず、CDPを通じて座標とDOMを直接操作する - 高度な待機機構を提供せず、LLM自身がページ準備完了を判断する - ワークフローを事前定義せず、LLMが現在のページ状態に基づいて次のステップを決定する - エラーで終了せず、LLMが不足するヘルパー関数を動的に生成する
この設計により、Browser Harnessはこれまで見たことのないWebページ構造を処理できる。従来の自動化スクリプトは新しいDOM構造に遭遇すると失敗するが、Browser HarnessのAgentはページを「理解」し、新しいコードを書いてタスクを完了する。
コアアーキテクチャ:592行コードの構成
Browser Harnessのコードベースは極めて簡潔で、コアはわずか5ファイル:
src/browser_harness/
├── __init__.py # 37行、パッケージ初期化
├── _ipc.py # 201行、Unix Socket/TCPプロセス間通信
├── helpers.py # 564行、コアCDPヘルパー関数
├── daemon.py # 850行、バックグラウンドデーモン管理
├── run.py # 407行、CLIエントリーポイントとREPL
└── admin.py # 1191行、インストール、更新、診断ツール
合計約3,250行のコード(592行ではない。592行は初期バージョンのコード量)。しかし3,000行以上に拡張しても、このコード量は依然としてPlaywrightの1/50に過ぎない。
主要モジュール解析
helpers.pyはフレームワーク全体の魂である。20あまりの基本関数のみを提供する:
# ナビゲーションとページ情報
goto_url(url) # URLにナビゲート
page_info() # 現在のページ情報を取得(URL、タイトル、サイズ、スクロール位置)
wait_for_load() # ページ読み込み完了を待機
# 要素とのインタラクション
click_at_xy(x, y) # 座標をクリック
type_text(text) # テキストを入力
fill_input(selector, text) # フォームフィールドに入力
# JavaScript実行
js(expression) # JavaScriptを実行して結果を返す
# CDP直接アクセス
cdp(method, **params) # Chrome DevTools Protocolを直接呼び出す
# スクリーンショットと録画
capture_screenshot(path) # スクリーンショットを撮る
start_recording(name) # 操作の録画を開始
stop_recording() # 録画を停止
これらの関数はUnix Socket(またはWindows TCP)を通じてバックグラウンドデーモンプロセスと通信する。デーモンはChrome CDPポートへのWebSocket接続を維持している。
daemon.pyの責任: - 実行中のChromeインスタンスの自動検出 - バックグラウンドデーモンの起動 - CDP接続プールの管理 - 複数タブの切り替え - クラウドブラウザのサポート(Browser Use Cloud)
run.pyはCLIエントリーポイントである。REPL(Read-Eval-Print Loop)を起動し、LLMがheredoc方式でPythonコードを実行できるようにする:
browser-harness <<'PY'
goto_url("https://example.com")
print(page_info())
PY
この設計により、LLMは関数を呼び出すかのようにブラウザを制御でき、基盤のCDPプロトコルの詳細を理解する必要がない。
自己修復メカニズム:AIが不足関数を動的に生成する方法
Browser Harnessの最も核心的なイノベーションは自己修復(Self-Healing)メカニズムである。従来のフレームワークはサポートされていない操作に遭遇すると例外をスローするが、Browser HarnessはLLM自身がコードを書いて問題を解決させる。
ワークフロー
1. Agentがタスクを受信:X(Twitter)の最新20本の動画をダウンロード
2. Agentがgoto_url("https://x.com/profile")を呼び出す
3. Agentがpage_info()を呼び出してページ情報を取得
4. Agentがページをスクロールしてさらに投稿を読み込みたいが、フレームワークにscroll_to_bottom()関数がない
5. Agentが自ら書く:
def scroll_to_bottom(times=10):
for _ in range(times):
js("window.scrollTo(0, document.body.scrollHeight)")
time.sleep(2)
6. agent-workspace/agent_helpers.pyに保存
7. 次回のタスクで直接再利用
このメカニズムの鍵はagent_helpers.pyファイルにある。これはAgentのワークスペースにあり、フレームワークのソースコードディレクトリにはない。Agentはこのファイルを自由に修正し、必要なヘルパー関数を追加できる。
コード例
# agent-workspace/agent_helpers.py
# Agentが自動生成したヘルパー関数
def scroll_to_bottom(times=10):
"""ページ最下部までスクロールして追加コンテンツを読み込む"""
for _ in range(times):
js("window.scrollTo(0, document.body.scrollHeight)")
time.sleep(2)
def extract_video_urls():
"""ページ内の全動画リンクを抽出"""
return js("""
Array.from(document.querySelectorAll('video source'))
.map(el => el.src)
.filter(src => src)
""")
def download_file(url, filename):
"""ファイルをローカルにダウンロード"""
import urllib.request
urllib.request.urlretrieve(url, filename)
Agentがタスクを実行する際、これらのカスタム関数は自動的に読み込まれる。フレームワークはfrom agent_helpers import *を通じてREPL環境に注入する。
これが重要な理由
従来の自動化フレームワークの拡張には以下が必要: 1. フレームワークのプラグイン機構を理解する 2. 厳格なAPI仕様に従う 3. パッケージマネージャに公開する 4. ユーザーのインストールを待つ
Browser Harnessの自己修復メカニズムは拡張を即時的かつパーソナライズされたものにする: - Agentが現在のタスク要件に基づいてコードを生成 - コードはローカルに保存され、すぐに利用可能 - 公開やインストールは不要 - 各ユーザーのAgentは自身の使用パターンに応じて進化
これが「フレームワークは使えば使うほど強くなる」の意味である。Agentが処理したタスクが多ければ多いほど、蓄積されるヘルパー関数が豊かになり、将来の類似タスクの処理効率が上がる。
技術実装の詳細
Chrome DevTools Protocol (CDP)
Browser Harnessのコア通信プロトコルはCDPである。CDPはChromeブラウザが提供するデバッグインターフェースで、外部プログラムがブラウザのほぼすべての動作を制御できる。
# helpers.pyのcdp()関数
def cdp(method, session_id=None, **params):
"""CDPメソッドを直接呼び出す"""
return _send({
"method": method,
"params": params,
"session_id": session_id
}).get("result", {})
# 使用例
cdp("Page.navigate", url="https://example.com")
cdp("Input.dispatchMouseEvent", type="mousePressed", x=100, y=200)
cdp("Runtime.evaluate", expression="document.title")
CDPの利点: - セレクタ不要:座標直接クリックで、複雑なCSS/XPathセレクタを回避 - クロスオリジン対応:CDPはブラウザの基盤レベルで動作し、同一オリジンポリシーの制限を受けない - 完全な制御:ネットワークリクエスト、DOM、JavaScriptランタイム、パフォーマンスデータなどにアクセス可能
プロセス間通信 (IPC)
Browser HarnessはUnix Socket(POSIX)またはTCP(Windows)を使用してCLIとデーモン間の通信を実現する。
# _ipc.pyのコアロジック
def connect(name, timeout=1.0):
"""デーモンに接続"""
if not IS_WINDOWS:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(str(_sock_path(name)))
return s, None
# WindowsはTCPを使用
port, token = _read_port_file(name)
s = socket.create_connection(("127.0.0.1", port))
return s, token
def request(c, token, req):
"""リクエストを送信してレスポンスを受信"""
if token:
req = {**req, "token": token}
c.sendall((json.dumps(req) + "\n").encode())
data = b""
while not data.endswith(b"\n"):
chunk = c.recv(1 << 16)
if not chunk:
break
data += chunk
return json.loads(data or b"{}")
この設計の利点: - 低遅延:Unix SocketはHTTPよりはるかに高速 - セキュリティ:Unix Socketはファイルパーミッションでアクセスを制御 - 簡潔さ:HTTPサーバー、ルーティング、シリアライゼーションなどの複雑なロジックが不要
Chromeインスタンスの自動検出
daemon.pyはシステム上で実行中のChromeインスタンスを自動スキャンする:
# daemon.pyのブラウザ検出ロジック
_MAC_PROFILES = (
"Library/Application Support/Google/Chrome",
"Library/Application Support/Google/Chrome Canary",
"Library/Application Support/Arc/User Data",
# ... その他のブラウザ
)
_LINUX_PROFILES = (
".config/google-chrome",
".config/chromium",
".config/microsoft-edge",
# ... その他のブラウザ
)
def supported_browser_running():
"""サポートされたブラウザが実行中か検出"""
return any(browser_running_for_profile(base) for base in PROFILES)
SingletonLockファイルとDevToolsActivePortファイルをチェックすることで、ブラウザが実行中かどうか、リモートデバッグが有効かどうかを判断する。
他のブラウザAgentとの比較
| 特性 | Browser Harness | Browser Use | Agent-E | WebVoyager |
|---|---|---|---|---|
| コード量 | 3,250行 | 15,000+行 | 20,000+行 | 10,000+行 |
| 設計哲学 | ミニマリズム | 機能完備 | エンタープライズ | 研究志向 |
| 自己修復 | ✅ コア特性 | ❌ | ❌ | ❌ |
| CDP直接アクセス | ✅ | ✅ | ✅ | ✅ |
| セレクタエンジン | ❌ 座標優先 | ✅ | ✅ | ✅ |
| クラウドブラウザ | ✅ | ✅ | ❌ | ❌ |
| 録画機能 | ✅ | ✅ | ❌ | ❌ |
| 学習曲線 | 低い | 中程度 | 高い | 高い |
Browser Harnessの核心的優位性はミニマリズム + 自己修復である。全機能を提供しようとするのではなく、LLMがニーズに応じて動的にコードを生成する。この設計により、これまで見たことのないシナリオを処理でき、他のフレームワークでは事前にアダプタを書く必要がある。
実践ケース:複雑なWebタスクの自動化
ケース1:X(Twitter)動画のダウンロード
# タスク:Xの最新20本の動画をダウンロード
browser-harness <<'PY'
# 1. Xプロフィールページにナビゲート
goto_url("https://x.com/username/media")
wait_for_load()
# 2. スクロールしてさらに投稿を読み込む
scroll_to_bottom(20) # Agentが自動生成した関数
# 3. 動画URLを抽出
videos = extract_video_urls() # Agentが自動生成した関数
# 4. 動画をダウンロード
for i, url in enumerate(videos[:20]):
download_file(url, f"video_{i+1}.mp4")
print(f"Downloaded {i+1}/20")
PY
ケース2:複雑なフォームの入力
# タスク:登録フォームを自動入力
browser-harness <<'PY'
goto_url("https://example.com/register")
wait_for_load()
# ページ情報を取得
info = page_info()
print(f"Page: {info['title']}")
# アクセシビリティツリーを使用してフォーム要素を検索
tree = cdp("Accessibility.getFullAXTree")["nodes"]
# 入力フィールドをフィルタリング
inputs = [n for n in tree if n.get("role") == "textbox"]
# フォームに入力
for input_node in inputs:
# 座標を取得
box = cdp("DOM.getBoxModel", backendNodeId=input_node["backendDOMNodeId"])
x = sum(box["model"]["content"][0::2]) / 4
y = sum(box["model"]["content"][1::2]) / 4
# クリックして入力
click_at_xy(x, y)
type_text("test@example.com")
PY
ケース3:動的読み込みコンテンツのスクレイピング
# タスク:無限スクロールの商品リストをスクレイピング
browser-harness <<'PY'
goto_url("https://example.com/products")
wait_for_load()
products = []
last_height = 0
# 新しいコンテンツがなくなるまでスクロール
for _ in range(50):
# 現在の商品を取得
new_products = js("""
Array.from(document.querySelectorAll('.product-card'))
.map(card => ({
name: card.querySelector('.name').textContent,
price: card.querySelector('.price').textContent
}))
""")
# 新しいコンテンツがあるかチェック
if len(new_products) == len(products):
break
products = new_products
# スクロール
js("window.scrollTo(0, document.body.scrollHeight)")
time.sleep(2)
print(f"Found {len(products)} products")
PY
限界と適用シーン
限界
- Chrome依存:Chrome/Chromium系ブラウザのみサポート、Firefox/Safariは非対応
- リモートデバッグの手動有効化が必要:初回使用時に
chrome://inspectで「リモートデバッグを許可」をチェックする必要がある - 座標クリックの不安定性:ページレイアウトの変化で座標が無効になる可能性がある(ただしLLMが適応可能)
- 大規模クローリングには不向き:シングルインスタンス設計のため、数千ページの並列クロールには不向き
- LLMサポートが必要:LLMがなければ自己修復能力を発揮できない
適用シーン
✅ 個人自動化タスク:動画ダウンロード、フォーム入力、データ抽出 ✅ テストとデバッグ:Web機能の迅速な検証 ✅ 複雑なインタラクションフロー:動的な意思決定を必要とする多段階タスク ✅ ログイン済みセッション:Chromeのログイン状態を利用して認証が必要なサイトにアクセス ✅ Bot対策サイト:実際のブラウザを使用してアンチスクレイピング機構を回避
❌ 大規模データ収集:Scrapy + Playwrightの方が適している ❌ クロスブラウザテスト:Playwrightのマルチブラウザサポートを使用 ❌ シンプルなHTTPリクエスト:requests/httpxの方が効率的
インストールとクイックスタート
インストール
# uvを使用してインストール(推奨)
uv tool install --python 3.12 browser-harness
# またはpipを使用
pip install browser-harness
初期設定
- Chromeを開き、
chrome://inspect/#remote-debuggingにアクセス - 「このブラウザインスタンスのリモートデバッグを許可」をチェック
- 接続をテスト:
browser-harness <<'PY'
print(page_info())
PY
現在のページの情報(URL、タイトル、サイズ)が表示されれば、接続成功である。
Claude Codeとの統合
# browser-harnessをインストール
uv tool install --python 3.12 browser-harness
# skillとして登録
mkdir -p ~/.codex/skills/browser-harness
browser-harness skill > ~/.codex/skills/browser-harness/SKILL.md
その後Claude Codeでは、Agentが自動的にbrowser-harnessを使用してすべてのブラウザタスクを処理する。
総評
Browser HarnessはAI Agentツール設計の重要なトレンドを体現している:複雑なフレームワークからミニマリズムへ。
その核心的洞察は:可能なすべてのブラウザ操作を事前定義しようとするのではなく、最小限の基本関数を提供し、LLMが具体的なタスクに応じて動的にコードを生成する方がよいということだ。この設計はコード量を減らすだけでなく、柔軟性も高める——Agentはこれまで見たことのないシナリオを処理できる。
長所: - ✅ コードが極めて簡潔で、理解とカスタマイズが容易 - ✅ 自己修復メカニズムによりフレームワークは使えば使うほど強くなる - ✅ CDP直接アクセスで優れたパフォーマンス - ✅ クラウドブラウザをサポートし、大規模タスクに拡張可能 - ✅ 録画機能でデバッグと振り返りが便利
短所: - ❌ Chrome依存で他のブラウザは非サポート - ❌ 初回設定でリモートデバッグの手動有効化が必要 - ❌ レイアウト変化時に座標クリックが不安定 - ❌ 大規模並列タスクには不向き
推奨指数:⭐⭐⭐⭐⭐(5/5)
ブラウザ自動化タスクが必要な開発者にとって、Browser Harnessは現在最もエレガントな選択肢である。そのミニマリスト設計と自己修復能力により、様々な複雑なシナリオに適応でき、3,000行以上のコード量はすべての実装行を容易に理解できることを意味する。
AI Agentを構築している、または複雑なWebタスクを自動化する必要があるなら、Browser Harnessを試す価値がある。ブラウザ自動化に対する認識を変えるかもしれない——最高のフレームワークとは機能が最も多いものではなく、AI自身が問題を解決できるようにするものである。
参考リンク: - GitHub: browser-use/browser-harness - ドキュメント: SKILL.md - インストールガイド: install.md - Browser Use Cloud: cloud.browser-use.com
FAQ
1. Browser HarnessとPlaywrightの違いは何ですか?
Browser HarnessはAIネイティブフレームワークで、LLMがブラウザを制御することを設計目標としており、セレクタエンジンや高度な待機機構を提供せず、CDPを通じて座標とDOMを直接操作する。Playwrightは従来の自動化フレームワークで、人間がスクリプトを書くために設計されており、豊富なセレクタと待機機構を提供する。Browser Harnessの核心的優位性は自己修復能力——サポートされていない操作に遭遇したとき、LLM自身がコードを書く。
2. Browser Harnessはどのブラウザをサポートしていますか?
現在、Chrome/Chromium系ブラウザのみサポートしており、Google Chrome、Chrome Canary、Microsoft Edge、Brave、Arcなどを含む。FirefoxとSafariはサポートしていない。Browser HarnessはChrome DevTools Protocol (CDP)に依存しているため。
3. Chromeのリモートデバッグを有効にするには?
Chromeを開き、chrome://inspect/#remote-debuggingにアクセスし、「このブラウザインスタンスのリモートデバッグを許可」をチェックする。macOSユーザーはシステム設定でターミナルにアクセシビリティ権限を付与する必要がある場合がある。
4. Browser Harnessは大規模クローリングに適していますか?
不適切である。Browser Harnessはシングルインスタンス設計で、主に個人自動化タスク向けである。数千ページを並列でクロールする必要がある場合は、Scrapy + PlaywrightまたはBrowser Use Cloudのクラウドブラウザ機能を使用することを推奨する。
5. 自己修復メカニズムはどのように動作しますか?
Agentがフレームワークでカバーされていない操作に遭遇したとき、自ら新しいPython関数を書いてagent-workspace/agent_helpers.pyファイルに保存する。次にタスクを実行する際、この関数が自動的に読み込まれる。こうしてフレームワークは新しい能力を「学び」、使えば使うほど強くなる。