Browser UseでPythonのエージェントを作るには、モデル、新しい Browser セッション、答えを確かめられるタスクを Agent に渡します。この例ではローカルHTMLから見出しと番号を読み取ります。Pydanticで形式を確認し、Pythonでページの値と照合します。
以前のバージョンでは、モデルが生成した操作が検証を通らず止まったという GitHubの報告があります。以下はクイックスタートと出力形式のドキュメントに沿った例です。APIはドキュメントと照合しました。実行による通しの検証は行っていません。
要点
セッション、タスク、検証をアプリ側で管理するなら、Browser UseのPythonライブラリを使います。
最初はローカルHTMLを、アカウントにログインしていないセッションで開きます。
ブラウザーとモデルの実行場所は別々に選べます。
ChatBrowserUseはローカルのChromiumを使っていてもホスト型のモデルを呼びます。history.is_successful()はエージェント自身の判定です。結果はページと別途照合します。最初のテストページにはフォーム、アカウント、アップロードを入れません。
ブラウザーとモデルの実行場所を決める
モデルが操作を選び、ブラウザーが実行します。Pythonは両者をつなぎます。ブラウザーエージェント、決められた手順のPlaywright、ウェブ検索のどれが必要かを、この役割の違いから判断できます。
| 構成 | ブラウザーの実行場所 | 選ぶ場面 |
|---|---|---|
| Pythonライブラリとローカルブラウザー | スクリプトを実行する端末 | ローカルのテストページを読み、Pythonで検証する |
| Pythonライブラリとリモートブラウザー | スクリプトから接続できるリモートセッション | リモート環境が必要で、その環境から対象ページに届く |
| Browser Use Cloudのホスト型エージェント | 管理された環境 | ホスト型APIを使い、その環境から届くURLを渡せる |
この例では最初の構成を使います。クイックスタートに従い、BROWSER_USE_API_KEY を環境変数またはローカルの .env に設定します。鍵をリポジトリに含めないでください。uv を入れた環境で新しいプロジェクトを作ります。
uv init --python 3.12
uv add browser-use
uvx browser-use install最後のコマンドでChromiumを準備します。環境を再現するにはロックファイルを残します。対応モデルの一覧には ChatOllama もあります。モデルを変えるときはテストページと期待値を固定し、ブラウザー操作と出力を確認します。Cloudのクイックスタートには別の認証とセッション設定があります。
RedditのQA担当者の投稿では、顧客データを社内に置くために自前で動くモデルを求めています。同じ条件ならローカルモデルを選びます。この例で送るのは架空のテストデータだけです。
答えが分かっているテストページを作る
HTMLを fixture/index.html に保存します。番号は架空で、フォームや認証情報はありません。別のターミナルでサーバーを起動します。公開する範囲は fixture ディレクトリだけです。
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Inventory fixture</title>
<main>
<h1>Inventory Check</h1>
<p>Reference code: BU-741</p>
</main>
</html>uv run python -m http.server 8765 --bind 127.0.0.1 --directory fixture127.0.0.1 はブラウザーを実行する端末を指します。リモートブラウザーなら、そのリモート端末自身に接続します。この例では両方を同じ端末で動かします。接続できるか確かめるときは、まずページを手動で開きます。
エージェントを実行して2つの項目を照合する
プロジェクトの直下に check_page.py を保存します。ブラウザー設定で許可ドメインを、Agentの設定で出力形式を確認できます。タスクにはURLを渡します。期待値は照合コードにだけ書き、モデルにはページから読み取らせます。
import asyncio
from tempfile import TemporaryDirectory
from browser_use import Agent, Browser, ChatBrowserUse
from pydantic import BaseModel
URL = "http://127.0.0.1:8765/"
class PageCheck(BaseModel):
heading: str
reference: str
async def main():
with TemporaryDirectory(prefix="browser-use-fixture-") as profile:
browser = Browser(
headless=True,
user_data_dir=profile,
allowed_domains=["127.0.0.1"],
accept_downloads=False,
)
try:
agent = Agent(
task=(
f"Open {URL} and read its visible heading and reference code. "
"Return only those two values. Do not interact with any form."
),
browser=browser,
llm=ChatBrowserUse(),
output_model_schema=PageCheck,
)
history = await agent.run(max_steps=5)
result = history.structured_output
expected = PageCheck(heading="Inventory Check", reference="BU-741")
if result != expected:
raise RuntimeError("The output does not match the fixture.")
print(result.model_dump_json())
finally:
await browser.stop()
if __name__ == "__main__":
asyncio.run(main())uv run python check_page.py期待する見出しは Inventory Check、番号は BU-741 です。不一致ならステップ上限を増やす前に履歴を確認します。上限を増やしても同じ操作が繰り返し失敗することがあります。
ページへのアクセスと出力、副作用を別々に確認する

実行時に / へのリクエストがあったか、まずサーバーログで調べます。次に history.urls()、history.errors()、ターミナルの出力を照合します。出力形式のガイドでは、終了、エージェントの成功判定、外部からの検証を分けています。
日常使うプロファイルとテスト用のセッションを分けます。既存ブラウザーに接続すると、エージェントがアクセスできるセッションやCookieが変わります。許可リストが制限するのはナビゲーションです。実サービスでは読み取り権限をサーバー側で設定し、テストアカウントを使います。詳しくはエージェントのセキュリティリスクを参照してください。
最初に失敗した段階から調べる
| 症状 | 先に見る箇所 | 次の確認 |
|---|---|---|
| ブラウザーは起動するがリクエストが届かない | 実行場所、ローカルアドレス、ポート、許可ドメイン | Chromiumと同じ環境からページを開く |
| モデル提供元がリクエストを拒否する | 鍵、接続先、アダプター、モデルの利用権限 | ブラウザー設定を変える前に提供元のエラーを読む |
| 履歴に操作の検証エラーがある | モデルのアダプターとBrowser Useのバージョン | 公式文書にあるアダプターで同じテストを実行する |
| 形式は正しいが値が違う | ページの状態とモデルが転記した値 | 項目ごとにHTMLとログを照合する |
別のリモートCDPの報告では、ブラウザープロトコルの呼び出しが止まった事例が記録されています。操作の検証とは異なる段階です。どちらも特定バージョンの報告なので、手元のエラーを起点に調べてください。
レコード作成やメッセージ送信を伴うタスクがタイムアウトしたときは、再実行の前に対象システムを確認します。今回の読み取り用ページなら、もう一度アクセスしてログを照合できます。
Python連携が向く場面
後続の処理が型付きのデータを受け取り、値を検証するならPythonが向いています。URL、セレクター、手順が固定ならブラウザースクリプトで十分です。テキストを一度確認するだけなら、ページを開いて読めます。TabbitとBrowser Useの比較とエージェント型ブラウザーの解説では、ブラウザー画面とコード連携の用途の違いを説明しています。
最初の実行では、リクエストが届き、2つの値が一致したところまで確認します。ブラウザー、モデル、対象ページを変えるときは、ひとつずつ切り替えて同じ確認を繰り返します。
よくある質問
PythonライブラリにBrowser UseのAPIキーは必要ですか?
この例のChatBrowserUseにはキーが必要です。他のアダプターは別の設定を使い、ローカルのOllamaにはこのキーが不要です。
ローカルのOllamaモデルを使えますか?
公式ドキュメントにChatOllamaが掲載されています。選んだモデルでブラウザー操作を生成でき、指定した形式で結果を返せるかを確認してください。
最初のタスクを読み取り専用にするには?
アカウントや書き込み先がないテストページと独立したセッションを使います。実際のアプリではサーバー側でも読み取り権限を設定します。
リモートブラウザーでlocalhostを開けないのはなぜですか?
そのアドレスはブラウザーを実行しているホストを指します。この例では同じ端末で両方を動かすか、リモート環境から届くテスト用URLを用意します。
history.is_successful()は何を示しますか?
エージェント自身の成功判定です。対象ページの状態と返された値を個別に確認してから完了と判断します。
structured_outputが空なら何を確認しますか?
履歴でナビゲーション、モデル提供元、操作のエラーを調べます。スキーマやステップ数を変更する前に、output_model_schemaが設定され、処理が完了したかを確認してください。