Claude Media
Claude APIのBrowser Useツール実装 — navigateとread_pageを呼ぶ

Claude APIのBrowser Useツール実装 — navigateとread_pageを呼ぶ

Claude APIのBrowser Useは、tools配列にbrowser_toolset_20260801を足し、返るtool_useを自前のブラウザで実行します。navigateとread_pageの呼び方、ref参照、エラー処理。

Browser Useツールとは

Claude APIでBrowser Useを使うには、tools配列にbrowser_toolset_20260801を1つ足し、返ってくるtool_useを自分のブラウザ自動化で実行して結果を返します。

Computer useとの違いや31個のツールの全体像はClaude APIのBrowser use tool解説にあります。ここではnavigateとread_pageを呼ぶ実装コードを扱います。

Browser Useツールは、Claudeにブラウザの操作を許可するAnthropic定義のクライアントツールセットです。宣言するとnavigateやread_pageを含む27個のメンバーツールがデフォルトで使えます。オプションの4個を有効にすると合計31個です。

navigateはURLを開く、または履歴を戻る・進む・再読み込みするための呼び出しです。read_pageはページの構造をアクセシビリティツリーとして文字列で返し、各要素に[ref_1]のような参照タグを付けます。Claudeはこの参照を次のクリックや入力の対象として指定できます。

ブラウザを動かすのは自分のアプリケーションです。Anthropicはtool_useブロックを返すだけで、実行は一切しません。SDKのクラスを継承して実行側を書く方法はClaude SDKのbrowser toolsetにあります。

デスクトップ全体の操作が必要なタスクにはComputer Useツールが向きます。Browser Useが対象にするのは、ブラウザ内で完結するタスクと、JavaScriptでコンテンツを構築するページです。ページを読むだけなら、APIが代わりに実行するWeb fetchツールやWeb searchツールの方が軽く済みます。

対応モデルとプラットフォーム

Browser Useツールが使えるのは次の9モデルです。

  • claude-fable-5-1
  • claude-mythos-5-1
  • claude-fable-5
  • claude-mythos-5
  • claude-opus-5-5
  • claude-opus-5
  • claude-sonnet-5-5
  • claude-sonnet-5
  • claude-opus-4-8

Opus 4.7以前やSonnet 4.6は対象外です。

項目対応状況
Claude API対応状況対応
Google Cloud(Vertex AI)対応状況対応
Claude Platform on AWS対応状況非対応
Amazon Bedrock対応状況非対応
Microsoft Foundry対応状況非対応
ZDR(ゼロデータ保持)対応状況対象(Covered Modelsを除く)
Claude Managed Agents対応状況非対応

対応モデルの範囲はComputer Useツールの新ツールセットと同じです。一方、Computer UseはAWS・Bedrock・Microsoft Foundryでbetaとして提供されており、Browser Useとは面ごとの対応が異なります。ただしこれらの面で使えるのは旧版のツールだけです。

最初の往復で何が返るか

実装の骨格は、Claudeがtool_useを返し、アプリケーションが実行してtool_resultを返す往復です。最小構成のリクエストは次のとおりです。

curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 2048,
    "tools": [{"type": "browser_toolset_20260801"}],
    "messages": [
      {"role": "user", "content": "example.com/docsを開いて要点を教えて"}
    ]
  }'
手順

Browser Useの1ターンの流れ

  1. 1

    Claudeがメンバー呼び出しを返す

    stop_reason: "tool_use"で終わり、navigateとread_pageのtool_useブロックが並びます。各ブロックには"toolset_name": "browser"が付き、inputにはそのメンバーのパラメーターだけが入ります。

  2. 2

    実行は出現順に、1つずつ

    response.contentのブロックをすべて拾い、前から順に実行します。後の呼び出しは前の結果に依存することが多いためです。

  3. 3

    結果を1つのuserメッセージで返す

    ブロックごとにtool_resultを作り、tool_use_idで対応させてtoolset_nameも付け直します。どれか1つでも答えないと次のリクエストは拒否されます。

  4. 4

    Claudeがテキストで答えるまで繰り返す

    結果を読んで追加の操作が要れば、再びメンバー呼び出しが返り、手順2に戻ります。

navigateの結果にはタブの状態を示すbrowser_stateブロックが付き、read_pageの結果は全要素に参照が付いたテキストになります。

{
  "type": "tool_result",
  "tool_use_id": "toolu_01NRLabsLyVHZPKxbKvkfSMn",
  "toolset_name": "browser",
  "content": [
    { "type": "text", "text": "Navigated to https://example.com/docs" },
    {
      "type": "browser_state",
      "tabs": [
        { "tab_id": "tab-1", "title": "Documentation", "url": "https://example.com/docs", "active": true }
      ]
    }
  ]
}
{
  "type": "tool_result",
  "tool_use_id": "toolu_01UvHU5cDyTZ2vXKf5wCkPqR",
  "toolset_name": "browser",
  "content": [
    {
      "type": "text",
      "text": "link \"Documentation\" [ref_1]\nlink \"Getting started\" [ref_2]\ntextbox \"Search docs\" [ref_3]"
    }
  ]
}

次のターンでClaudeはref_2をleft_clickの対象にでき、スクリーンショットからリンクの座標を探す手間がなくなります。

参照で操作するか、座標で操作するか

クリックやホバーのtargetには2つの形があります。要素の参照を渡す{"type": "ref", "ref": "ref_2"}と、ビューポートのピクセル座標を渡す{"type": "coordinate", "x": ..., "y": ...}です。Claudeはページが何を公開しているかで両者を使い分けます。

くらべる

参照と座標の使いどころ

アクセシビリティツリーがあるページ

参照(ref)

レイアウトのずれやリフローに強く、ポインターで狙いにくいコントロールも操作できます。read_pageかfindの出力から得ます。

ツリーに載らない内容

座標(coordinate)

canvas描画の画面、埋め込み動画、リモートデスクトップ、仮想化リスト、クロスオリジンiframe内の要素が当てはまります。screenshotとzoomを見て座標でクリックします。

座標はスクリーンショットと同じビューポートのピクセル空間で、左上が原点です。ツールセットは表示サイズを宣言しないので、Claudeはスクリーンショットから大きさを推定します。返す画像のサイズは毎回そろえてください。zoomで拡大した画像を見たあとも、Claudeが出す座標はビューポート全体のピクセルです。

読み取りメンバーの使い分け

メンバー向いている場面特徴
read_page向いている場面ページ全体の操作対象を把握したいとき特徴filterとdepthでスコープを絞れる
find向いている場面「検索ボックス」のような自然言語で要素を探すとき特徴最大20件をread_pageと同じ形式で返す
get_page_text向いている場面記事やドキュメントの本文を読みたいとき特徴本文中心の可視テキストをそのまま返す

read_pageのfilterは3種類です。省略すると表示中の全要素、interactiveは表示中の操作可能要素だけ、allはビューポート外の要素も含みます。depthは木の深さの上限で最小1・既定15、refを指定すると特定要素配下のサブツリーだけを読めます。出力は50,000文字で打ち切られ、その旨をテキストに添える決まりです。Claudeはそれを見てdepthやrefで範囲を絞り直します。

大きなページでは、スクリーンショットよりread_pageの方が入力トークンを抑えられることが多く、すぐ使える参照も手に入ります。レイアウトや画像そのものを見たいときだけscreenshotとzoomに切り替えます。

参照の対応表とnavigateのexecutor

参照を採番して対応表を持つのはexecutor側の仕事です。参照は発行元のタブに紐づき、そのタブが遷移するかDOMが大きく変わるまで有効です。APIには古い参照を検出する手段がないため、未知の参照が来たらエラー結果を返してClaudeに読み直させます。

navigateの入力には、URLのほかに"back"・"forward"・"reload"が来ます。スキームのないURLはhttps://として扱い、httpとhttps以外はエラー結果で拒否します。次の実装で、この仕様と参照の対応表をまとめて確認しました(Python 3.12.2)。

import re
from urllib.parse import urlparse
 
HISTORY = {"back", "forward", "reload"}
# コロンの直後がポート番号だけなら host:port とみなし、スキームとは数えない
HAS_SCHEME = re.compile(r"^[A-Za-z][A-Za-z0-9+.-]*:(?!\d+(?:[/?#]|$))")
 
 
class BrowserToolError(Exception):
    pass
 
 
def resolve_url(raw):
    url = re.sub(r"[\t\r\n]", "", raw.strip())  # スキーム内のタブ・改行は無視される
    if url in HISTORY:
        return url
    if not HAS_SCHEME.match(url):
        url = f"https://{url}"
    parsed = urlparse(url)
    if parsed.scheme.lower() not in ("http", "https"):
        raise BrowserToolError("Navigation refused. Only http and https URLs are allowed.")
    return parsed.geturl()
 
 
class RefTable:
    """タブごとの ref -> ノードの対応表。遷移するまで採番し直さない。"""
 
    def __init__(self):
        self.nodes, self.next_id = {}, 1
 
    def issue(self, node):
        ref = f"ref_{self.next_id}"
        self.next_id += 1
        self.nodes[ref] = node
        return ref
 
    def lookup(self, ref):
        if ref not in self.nodes:
            raise BrowserToolError(
                f"{ref} is stale or not found on the current page. "
                "Re-read the page to get fresh references."
            )
        return self.nodes[ref]
 
    def reset(self):  # 遷移またはDOMの大幅な変化のとき呼ぶ
        self.nodes.clear()
'example.com/docs' -> https://example.com/docs
'JavaScript:alert(1)' -> ERROR: Navigation refused. Only http and https URLs are allowed.
'  javascript:alert(1)' -> ERROR: Navigation refused. Only http and https URLs are allowed.
'java\tscript:alert(1)' -> ERROR: Navigation refused. Only http and https URLs are allowed.
'file:///etc/passwd' -> ERROR: Navigation refused. Only http and https URLs are allowed.
'data:text/html,hi' -> ERROR: Navigation refused. Only http and https URLs are allowed.
'example.com:8080/x' -> https://example.com:8080/x
'reload' -> reload
ref_1 is stale or not found on the current page. Re-read the page to get fresh references.

大文字のJavaScript:も先頭の空白もタブ混じりの綴りも、パーサーを通すと同じjavascriptとして拒否されます。文字列の前方一致だと、この3つはどれもすり抜けます。

もう1つ、スキームの有無を"://" in urlで判定する書き方には落とし穴があります。同じPythonでjavascript:alert(1)を通すと、://を含まないためhttps://javascript:alert(1)に化けました。ホスト名がjavascript、ポートがalert(1)の不正なURLですが、拒否されるはずの入力が拒否されないままpage.gotoに届きます。localhost:3000やexample.com:8080のようなhost:portもスキーム付きと誤読されやすいので、上の正規表現はコロンの直後がポート番号だけの場合を別扱いにしています。

PythonやTypeScriptでエージェントループごと組む場合は、Python SDKの非同期実行とtool_runner実装やTypeScript SDKのStreaming・Tool実装が土台になります。ストリーミングでは各メンバーのinputが1つの完全なinput_json_deltaとして届くため、ターンの完了を待ってからバッチを実行します。

複数の呼び出しとタブ状態

1ターンに複数のメンバー呼び出しが含まれるものがバッチアクションです。出現順に実行し、最初の失敗で止めます。残りのブロックはすべてis_error: trueで、テキストはNot executed: an earlier action in this turn failed.と決まっています。クリックして入力してEnterを押す、といった具体例はBrowser useツールのバッチアクションにあります。

タブの状態が変わった結果にはbrowser_stateブロックを添えます。

  • tabsは呼び出し後に開いている全タブの一覧で、空でなければactive: trueが必ず1つ
  • state_changesは新規タブやダウンロードの報告で、報告がなければフィールドごと省き、空配列は拒否される
  • 1つの結果につき最大1ブロックで、is_error: trueの結果には付けられない
  • tab_idはexecutorが採番し、tab_id・title・urlはそれぞれ4,096文字以内、tabsは100件、state_changesは200件まで

new_tab・switch_tab・close_tab・list_tabsは、成功時のcontentがbrowser_stateブロック1つだけです。Claudeが読む文言はAPIがtabsから生成します。それ以外のメンバーでテキストとbrowser_stateを一緒に返すと、APIがTab Contextというフッターをテキストの末尾に足します。重複した状態は2回目以降は描画されないので、状態を毎回添えてもコストはかかりません。

ダウンロードはstate_changesで報告します。種類はdownload_started・download_completed・download_failedの3つで、executorが採番したdownload_idで結果をまたいで対応づけます。開始と完了が同じ呼び出しの間に起きたときは、download_completedだけを報告します。pathは、同じ環境の別ツール(bashツールやfile_upload)がそのファイルを読める場合だけ入れます。タブの組み立てはbrowser_stateでタブ管理を実装するガイドに詳しくあります。

返したエラーはClaudeが読んで直す

失敗は通常のエラー結果で返します。is_error: trueにして、何が起きたかを書いたテキストを入れ、toolset_nameを付け直し、browser_stateは付けません。Error: navigation failedだけでは手がかりになりません。Error: Navigation to https://example.com/status timed out after 30 seconds. The page may be unavailable.のように原因まで書くと、Claudeが次の手を選べます。

メンバーを無効にしていても、Claudeがその名前を呼ぶ可能性は残ります。その場合も呼び出しを捨てず、Error: javascript_exec is not enabled in this environment.のようなエラー結果で答えます。

形式の誤りはAPIが弾きます。結果の側で起きやすいものを挙げます。

送ったものAPIの反応
toolset_nameのない、または違う値のtool_resultAPIの反応invalid_request_errorで拒否
前のターンのメンバー呼び出しに対応するtool_resultがないAPIの反応同上(全呼び出しに答える必要がある)
text・image・browser_state以外のブロックAPIの反応同上
is_error: trueの結果についたbrowser_stateAPIの反応同上
モデルの上限を超える画像、またはリクエストに20枚超の画像がある場合のより厳しい上限を超える画像APIの反応同上(APIは画像を縮小しない)

画像は返す前に自分でリサイズし、Claudeが返してきた座標はリサイズ倍率の逆数で元に戻してからブラウザへ送ります。

任意の4メンバーを有効にする前に

javascript_exec・file_upload・read_console・read_networkはデフォルトで無効です。有効にするにはconfigsで個別に指定します。

{
  "type": "browser_toolset_20260801",
  "configs": {
    "read_console": { "enabled": true },
    "read_network": { "enabled": true }
  }
}

逆に、executorが実装していないメンバーは"enabled": falseでClaudeの定義から外せます。configsのキーはメンバー名だけ、値はenabledとdefer_loadingだけを受け付けます。それ以外を書くとリクエストが拒否されます。

任意メンバー

有効にするときに実装側で必要なこと

  • file_upload

    ファイル入力要素に直接ファイルを設定します。targetは参照のみで、pathsかdocument_idsのどちらか、または両方を渡します。パスは悪意あるページに書き換えられうるため、シンボリックリンクと..を解決したうえで、アップロード専用ディレクトリ以外を受け付けない実装にします。ダウンロード先と共用すると、ページが落としたファイルがそのままアップロード対象になります。

  • javascript_exec

    Claudeが書いた式をページの文脈で実行し、最後の式の値をテキストで返します。return文ではなく式です。ページの権限(Cookie・ストレージ・同一オリジンのリクエスト)で動くため、有効にするのは資格情報を持たないセッションだけにし、Claudeが書いたコードはログに残します。

  • read_console / read_network

    コンソールのエントリとネットワークのリクエストを、前回の読み取り以降の分だけ1行1件で返します。アタッチ前の記録は取れないので、空の結果は通信がなかった証拠になりません。URLにトークンが載ることがあるため、資格情報らしい値は伏せ、長い行は切り詰めて返します。

セキュリティ考慮事項

Browser Useツールは開かれたWeb全体を対象にするため、標準的なAPI機能にはないリスクを伴います。ページが返す文字列はすべて未検証の入力として設計します。ドキュメントが挙げる対策は6点です。

対策

導入前の6つの対策

  1. 1

    専用の環境で動かす

    ブラウザとexecutorは、最小権限の専用コンテナかVMで、認証情報を持たないまっさらなプロファイルを使います。

  2. 2

    到達先を絞る

    ネットワーク層でドメイン許可リストを強制し、リダイレクト後のnavigateハンドラでも再確認します。タスクに不要ならループバックやプライベート帯も遮断します。

  3. 3

    ページ由来の文字列を信用しない

    タブのタイトルやURL、ダウンロードのurl・path・errorを未検証データとして扱います。ページの読み取りは生のDOMでなく描画結果から作ります。

  4. 4

    navigateでスキームを検証する

    履歴キーワードを受け付け、スキームなしはhttps://にし、パーサーでhttpとhttps以外を拒否します。APIはClaudeが開くURLを一切フィルターしません。

  5. 5

    危険なメンバーは必要なときだけ

    javascript_execとfile_uploadは無効のままにします。

  6. 6

    重大な操作は人間が確認する

    購入・アカウント変更・メッセージ送信・規約への同意が対象です。1ターンに複数の呼び出しが入りうるので、確認はexecutor内で呼び出しごとに行います。

Anthropicはプロンプトインジェクションに抵抗するようモデルを学習させたうえで、ページ内容やスクリーンショットを自動でスキャンする分類器を追加しています。疑わしい指示を検知すると、実行前に指示の出所を確認するようClaudeを誘導する仕組みです。人間の確認を挟めないユースケースでこの保護が合わない場合は、サポート経由でオプトアウトを依頼できます。それでも上の対策は省けません。

ブラウザが訪れるサイトからは、executorのネットワーク上の素性が見えます。ページの内容がAPIに届くのは、tool_resultとして返したものだけです。実装全体の隔離設計はBrowser useツールのセキュリティ対策6原則にまとめています。

ブラウザ操作は何十往復にもなり、read_pageやget_page_textの長いテキストが古いターンに残り続けます。tool result clearingの設定を併用すると、コンテキストウィンドウの圧迫を抑えられます。

Computer Useと併用するとき

レイテンシー、ビジョン精度、プロンプトインジェクションのリスクはComputer Useと共通です。アクションの遅延設定や検証、ログ記録といった実装指針もブラウザのexecutorにそのまま当てはまります。

Browser UseはComputer Useと同じ要求に同時に宣言することもできます。座標系が別なので(ビューポートのピクセルとデスクトップのスクリーンショットのピクセル)、screenshotやkeyのように名前が同じメンバーはtoolset_nameで見分けます。自作ツールがnavigateという名前を持っていても、同じ仕組みで衝突しません。ただし、browserという名前のツールは他に置けず、ブラウザのツールセットは1リクエストに1つだけです。

料金とデータ保持

課金は通常のツール使用料金と同じ体系です。browser_toolset_20260801をデフォルト構成で宣言すると、メンバー定義とツール使用のシステムプロンプト分として、約6,600の入力トークンが加算されます。モデル別の内訳は次のとおりです。

モデル加算トークン数(概算)
Claude Fable 5 / Mythos 5 / Opus 5 / Opus 4.8加算トークン数(概算)約6,610
Claude Sonnet 5加算トークン数(概算)約6,670

オプションの4メンバーをすべて有効にすると約880トークンが加わり、configsでメンバーを無効にすれば減ります。正確な値はレスポンスのusageに毎回返り、事前の見積もりはトークンカウントAPIでできます。

スクリーンショットやzoom画像は画像入力として、read_pageやget_page_textのテキストは通常の入力トークンとして、それぞれ別途課金されます。ブラウザセッション、ダウンロード、アップロードしたファイルは自分の環境に残ります。返したスクリーンショット、ページのテキスト、タブ状態はリクエストの一部で、標準の保持ポリシー(ZDR契約があればその内容)に従います。

まとめ

実装の分かれ目は、スキームの検証をURLパーサーで行うことと、参照を遷移するまで採番し直さないことの2点です。それ以外の失敗は、原因まで書いたエラー結果で返せば、Claudeが読み直して先へ進めます。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. platform.claude.com/docs/en/agents-and-tools/tool-use/browser-use-tool
  2. platform.claude.com/docs/en/agents-and-tools/tool-use/computer-use-tool
この記事を共有:XはてブLinkedIn