目次を表示する

browser-use完全解説

第2章 アーキテクチャ ── エージェントループの解剖

第2章 アーキテクチャ ── エージェントループの解剖


全体像

browser-useの内部構造を理解するには、「LLMとブラウザの間にあるもの」を一層ずつ剥がして見る必要がある。

graph TD
    subgraph BU["browser-use スタック"]
        TASK["タスク指示(自然言語)"]
        AGENT["エージェントコア<br/>(ループ管理・状態追跡)"]
        LLM["LLMインテグレーション層<br/>(ChatBrowserUse / Claude / GPT-4 / Gemini)"]
        PERCEIVE["知覚層<br/>(Screenshot + Accessibility Tree + DOM)"]
        PW["Playwrightアダプター<br/>(click / type / scroll / navigate)"]
        BROWSER["ブラウザ<br/>(ローカルChromium / クラウドブラウザ)"]
    end

    TASK --> AGENT
    AGENT --> LLM
    LLM --> PERCEIVE
    PERCEIVE --> AGENT
    AGENT --> PW
    PW --> BROWSER
    BROWSER --> PERCEIVE

エージェントコアが全体のループを管理し、LLMとブラウザの間を仲介する。LLMは「何をするか」を決め、Playwrightアダプターが「実際にする」。


エージェントループ:Observe → Think → Act → Repeat

browser-useの動作原理は「Observe → Think → Act → Repeat」の繰り返しだ。

flowchart TD
    START["タスク開始<br/>(自然言語指示)"]
    OBS["① Observe<br/>ページのスクリーンショット<br/>+ Accessibility Tree<br/>+ 現在のURL・タイトル"]
    THINK["② Think<br/>LLMが現在状態を分析し<br/>次のアクションを決定"]
    ACT["③ Act<br/>click / type / scroll / navigate<br/>などを実行"]
    CHECK["④ Check<br/>タスク完了か?<br/>エラーが起きたか?"]
    DONE["タスク完了・結果返却"]

    START --> OBS
    OBS --> THINK
    THINK --> ACT
    ACT --> CHECK
    CHECK -- 継続 --> OBS
    CHECK -- 完了 --> DONE
    CHECK -- エラー回復 --> OBS

各ステップを詳しく見る。


① Observe:ページをどう「見るか」

これがbrowser-useの技術的核心だ。「ページを見る」にはいくつかの方法があり、browser-useはそれらを組み合わせる。

スクリーンショット(視覚情報)

ブラウザの現在状態を画像として撮影し、マルチモーダルLLMに渡す。人間が「画面を見る」のと同じだ。

強み:Canvas要素・カスタムレンダリング・CSSビジュアル・画像内テキストを認識できる。HTMLでは表現されない視覚的情報を把握できる。

弱み:座標依存(ピクセル位置でクリックするため、レイアウト変更に弱い)。推論コストが高い。

Accessibility Tree(意味情報)

ブラウザが内部的に保持するアクセシビリティツリーをテキストとして取得する。役割(role)・ラベル・状態・インタラクション可能かどうかがコンパクトに表現される。

# Accessibility Tree の例(一部)

main[role=main]
  heading[level=1] "browser-use/browser-use"
  link[href=/browser-use/browser-use/stargazers] "81.2k stars"
  link[href=/browser-use/browser-use/forks] "8.7k forks"
  button[expanded=false] "Star"

強み:構造化・コンパクト・クリック対象の特定が安定している。DOM変更に対してスクリーンショットより堅牢。

弱み:視覚的なレイアウト・位置関係・スタイル情報は含まれない。

DOM(構造情報)

生のHTMLではなく、整形・フィルタリングされたDOM表現。

browser-useは三つの表現を状況に応じて組み合わせる。通常時はAccessibility Tree + スクリーンショット、DOM要素の特定が難しいときはDOMを追加参照する。これにより「スクリーンショットだけ」でも「DOMだけ」でもない、ハイブリッドな高精度な認識が実現される。

graph LR
    PAGE["Webページ"]
    SS["スクリーンショット<br/>視覚情報・Canvas・画像"]
    AT["Accessibility Tree<br/>意味情報・構造・クリック対象"]
    DOM["DOM<br/>HTML構造・属性・テキスト"]
    LLM["LLM<br/>(統合して判断)"]

    PAGE --> SS
    PAGE --> AT
    PAGE --> DOM
    SS --> LLM
    AT --> LLM
    DOM --> LLM

② Think:LLMが判断する

LLMへのプロンプトには以下の情報が含まれる。

LLMへの入力(1ステップあたり)

1. タスク指示(ユーザーが最初に与えた自然言語)
2. 現在のページ状態(スクリーンショット + Accessibility Tree)
3. これまでに実行したアクション履歴
4. 利用可能なアクション一覧(click, type, scroll, navigate, ...)
5. AGENTS.md / システムプロンプト(カスタマイズがある場合)

LLMへの要求:
- 現在の状態を分析し
- タスクを完了するために次に取るべき最善のアクションを1つ選び
- 構造化された形式(JSON)で返す

LLMは思考過程とともに次のアクションをJSON形式で出力する。

{
  "thought": "検索ボックスが見えている。タスクに必要なリポジトリ名を入力する",
  "action": {
    "type": "click",
    "element_ref": "search-box-ref-14"
  }
}

③ Act:Playwrightが実行する

LLMが出力したアクション指示をPlaywrightのAPIに変換して実行する。

LLMのアクション指示Playwrightのコール
click(element_ref=...)page.click(selector)
type(text=...)page.fill(selector, text)
scroll(direction=down, amount=3)page.evaluate("window.scrollBy(0, 300)")
navigate(url=...)page.goto(url)
screenshot()page.screenshot()
extract_content()DOM読み取り

④ Check:エラー回復とタスク完了判定

各アクションの後、エージェントは状態をチェックする。

タスク完了の判定:LLMが「タスクが完了した」と判断するか、明示的な完了条件(max_stepsに達した、期待する情報が取得できたなど)に達したとき。

エラー回復(Self-Healing):browser-useの重要機能の一つだ。アクションが失敗した場合(要素が見つからない、タイムアウト、予期しないポップアップなど)、エラー情報をLLMに渡して別のアプローチを試みる。

エラー回復の例

実行:button[label="閉じる"] をクリック
結果:要素が見つからない(Timeout)

→ エラー情報をLLMに渡す
LLMが再判断:「モーダルダイアログが閉じボタンの代わりにESCキーで閉じるかもしれない」
→ keyboard.press("Escape") を実行
→ 成功

メモリと状態管理

browser-useはタスク実行中の状態を複数の形で管理する。

状態管理の種類

エージェント実行中メモリ:
  - アクション履歴(今まで何をしたか)
  - 収集済み情報(スクレイピングしたデータ等)
  - エラー履歴(何が失敗したか)

セッション間の継続性:
  - ブラウザプロファイル(Cookieやログイン状態の保持)
  - ワークフロー記録(成功したアクションシーケンスの保存)

ブラウザプロファイルの再利用:既存のChromeプロファイルを引き継ぐことで、Googleやnotionなど既にログイン済みのサービスにもエージェントが直接アクセスできる。認証フローを自動化する必要がなくなる。


パフォーマンスとコストの現実

エージェントループは「1ステップ = 1回のLLM呼び出し」だ。

コスト試算(参考)

平均タスク所要時間:約62秒(BU 2.0)
平均ステップ数:5〜15ステップ

1ステップあたりのLLMコスト:
  GPT-4o    約$0.01〜0.05
  Claude 3  約$0.01〜0.03

1タスクあたり:$0.05〜$0.50程度

高ボリューム(月1万タスク):$500〜$5,000/月

このコスト構造は「決定論的なPlaywrightスクリプトと比べて桁違いに高い」という評価に直結している。Playwrightでできる単純な繰り返し作業をbrowser-useでやるのは非合理。browser-useが正当化されるのは「ページ構造が変わっても動く必要がある」「手動でスクリプトを書けないほど複雑な判断が必要」なケースだ。


二モードの設定

browser-useには二つの動作モードがある。

# モード1:ローカルブラウザ(OSS)
from browser_use import Browser, BrowserConfig

browser = Browser(config=BrowserConfig(
    headless=False,  # ブラウザウィンドウを表示
))

# モード2:クラウドブラウザ(Browser Use Cloud)
browser = Browser(config=BrowserConfig(
    cdp_url="wss://connect.browseruse.com/...",  # クラウドブラウザに接続
))
# または
browser = Browser(config=BrowserConfig(use_cloud=True))

次章でこの二モードの違いと使い分けを詳しく扱う。