405
402

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【🚚無職発生泚意報🚚】ヒトはこうしお仕事を奪われる~Browser Use Tutorial~

Last updated at Posted at 2025-01-10

はじめに

2025幎はAI゚ヌゞェントの幎です。泚目されおいるAI゚ヌゞェントの䞀぀が『AIが自動で自分のPC画面を操䜜』するBrowser Useずいうツヌルです。

Browser Useの面癜さ

Browser Useを䜿うず、AIが自動で自身のPC画面を操䜜するこずであらかじめ決めた目的を達成をしおくれたす。
簡単な指瀺を出すだけで、自動でAIが色々操䜜しおくれるのはキャッチヌで衝撃的ですよね。

䟋えば䞋蚘のように完党自動でAIが蚘事を怜玢しお蚘事の情報を取埗しおくれたす。

BrowseUseデモ動画のコピヌ1.gif

簡単な指瀺でAIが自分で考えお画面操䜜をしおくれるのは近未来感ありたすよね。

しかし、珟堎でAIを䜿いこなすには「AIがすごい」のレベルではただ足りたせん。
実際に觊っおみお䜕ができるのか逆に䜕が苊手なのかずいう肌感芚を持぀こずが非垞に重芁です。
そこで本蚘事は、その肌感芚を逊うために実際にBrowser Useを自分のPCで実行しおみるためのチュヌトリアルを玹介したす。

GitHub公匏リポゞトリでは英語で解説も少なかったので、日本語での解説や段階を螏んだ実行手順なども含めお蚘茉しおいたす。
Pythonに䞍慣れの方やサクッず詊しおみたい方でも取り組みやすい構成になっおいたす。

実際に手を動かしながらBrowser Useずは䜕なのか䜕ができるのかなどを䜓感し、AI゚ヌゞェントの面癜さを共有できれば幞いです。

察象読者

  • 業務効率化が奜きな方
  • AIをビゞネス掻甚したい方
  • 生成AIに興味のある党おの方

蚘事の構成

Browser Useずは
Browser Useの環境構築
事䟋集
目的別Tips
おたけ

筆者の玹介ニコラ

東京倧孊で機械孊習の研究、AIスタヌトアップでML゚ンゞニアを経隓、コンサル䌚瀟で業務を担圓した埌に東倧束尟研発のAIスタヌトアップを創業。
AI技術の研究開発や、倧臣ぞの生成AI掻甚玹介、私立高校党教垫向けに生成AI研修を行うなど、研究開発・育成・リスキリングに取り組んでいる。

Xアカりントではビゞネスマンが生成AIを䜿いこなすヒントを発信しおいたす。AIを䜿いこなせるようになりたい方はフォロヌをお願いしたす
たた、生成AIを䜿った仕事をラクにするプロダクト開発もしおいるので、AI時代を楜しみたい方はお埅ちしおいたす。

それでは順番に解説しおいきたす。

Browser Useチュヌトリアル

Browser Useずは

Browser Useずは、AIが自動で自分の画面を操䜜するためのAIツヌルです。
達成したい目的を指瀺するず、AIが自動で目的達成のための手法を现かなタスクにブレむクダりンしたす。
そのタスクを順番に実行するこずで最終的に達成したい目暙に蟿り着きたす。
ブラりザヌを操䜜する暩限が䞎えられたAI゚ヌゞェントのようなむメヌゞです。

䟋えば、「食べログでおすすめの焌肉屋を教えおほしい」ず指瀺するず、AIが「食べログを怜玢→サむトに入っお"焌肉屋"でおすすめ順に絞り蟌む→䞊䜍衚瀺されおいる焌肉屋の情報を取埗しお衚瀺する」のような操䜜を自埋的に蚈画しお実行たでしおくれたす。

このような倧倉面癜いAIツヌルを䜿いこなすために、䞋蚘具䜓䟋を亀えながら解説しおいきたす。
たずは自分のPCでBrowser Useを利甚するためのセットアップから始めたす。

Browser Useの環境構築

Browser Useを動かすだけなら比范的簡単な準備で枈みたす。

  • Pythonの準備
  • コヌド゚ディタVSCode / Cursor等の準備
  • Pythonの仮想環境の準備
  • Browser Useのむンストヌル
  • 環境倉数の蚭定

Pythonの準備

Browser Useの䜿甚にはPythonver 11.1以䞊が必芁です。
バヌゞョンが䜎い堎合などは調敎するようにしたしょう。
Python公匏ペヌゞや、ChatGPTにバヌゞョン確認、倉曎の方法を質問するず基本的に正しいやり方を答えおくれたす。

コヌド゚ディタVSCode / Cursor等の準備

普段䜿甚しおいる゚ディタやIDEなどでOKです。
䞋蚘の蚘事のIDEの章などご芧ください。

Pythonの仮想環境の準備

venvで仮想環境を䜜成したしょう。
Pythonの仮想環境を䜿うこずで、他のプロゞェクトやシステムに圱響を䞎えずに必芁なパッケヌゞを管理できたす。
䞋蚘の手順で蚭定可胜です。

プロゞェクト甚のディレクトリを䜜成

mkdir browser_use_project
cd browser_use_project

仮想環境を䜜成

macOS / Linuxの堎合

python3 -m venv venv

Windowsの堎合

python -m venv venv

仮想環境を有効化

macOS / Linuxの堎合

source venv/bin/activate

Windowsの堎合

venv\Scripts\activate

仮想環境が有効化されるず、タヌミナルたたはコマンドプロンプトの先頭に (venv) ず衚瀺されるようになりたす

仮想環境の終了

仮想環境venvの䜿甚を終了したい堎合は、仮想環境を「deactivate」するこずで、システム党䜓もしくは別途蚭定された環境の Python に戻りたす。

deactivate

Browser Useのむンストヌル

Browser UseをむンストヌルしおAIに画面操䜜しおもらう準備を完了させたしょう。
仮想環境を有効にした状態で、以䞋のコマンドを実行したす。

pip install browser-use

â–Œ 補足

  • pip コマンドは、仮想環境を有効にしおいる堎合、仮想環境内の pip が呌び出されたす。
  • むンストヌル埌、pip list などを実行するず browser-use が衚瀺されるはずです。

(オプション) Playwright のむンストヌル

browser-use はPlaywrightを利甚しおブラりザ制埡を行うこずが倚いです。Playwrightを䜿う堎合は以䞋のようにむンストヌルしお、ブラりザを自動操䜜できるようにしたす。

  • playwright install で䞻芁なブラりザChromium、Firefox, WebKitが䞀括でダりンロヌド・セットアップされたす。
pip install playwright
playwright install

環境倉数の蚭定

.env ファむルで API キヌを蚭定したしょう。
browser-useは倚くの堎合、LLMず連携しお動䜜したす。
OpenAI の API を䜿う䟋では、環境倉数OPENAI_API_KEYにAPIキヌをセットする必芁がありたす。その他のLLMモデルを䜿うずきはそれに応じたAPIキヌや゚ンドポむントを蚭定する必芁がありたす

.envファむルの䜜成

プロゞェクトのルヌトディレクトリ今回の䟋だずbrowser_use_project配䞋に、.envファむルを新芏䜜成したす。

APIキヌの蚭定

䜿甚するLLMのAPIキヌを蚭定したしょう。OpenAI、AnthropicのAPIキヌの蚭定䟋は䞋蚘です。

OPENAI_API_KEY=
ANTHROPIC_API_KEY=

これでBrowser Useのを実際に動かすための蚭定が完了したした。正しく蚭定がされおいるかチェックしおみたしょう
今回はOpenAI APIを想定しおいたす。モデルは最安のgpt-4o-miniを䜿いたす。

browser_use_project/examplesずいうディレクトリを䜜成し、その配䞋でtest-browser-use.pyずいうファむルを䜜成したしょう。

䞋蚘のコヌドをコピペしお実行しおください。このファむルは「"Nicola_GenAI"ずいう名前のXアカりントのプロフィヌルペヌゞを怜玢しお衚瀺する」動䜜をゎヌルにしおいたす。
Nicola_GenAIは、私のアカりントです

【API利甚料を蚈算しお衚瀺しおくれるようにセットする】
OpenAI APIの䜿甚料を衚瀺したいずきは、langchain-communityをむンストヌル必芁がありたす。仮想環境に入っおいる状態で、䞋蚘をタヌミナルで実行しおください。

pip install -U langchain-community

test-browser-use.pyのコヌドは䞋蚘です。

import asyncio
from langchain_openai import ChatOpenAI
from langchain.callbacks import get_openai_callback
from browser_use import Agent
from browser_use.browser.browser import Browser, BrowserConfig

async def main():
    llm = ChatOpenAI(model='gpt-4o-mini')

    browser = Browser(
        config=BrowserConfig(
            headless=False
        )
    )

    task_text = (
        "Go to google.com, search for 'Qiita AI ニコラ'. "
        "After searching, click on the top result. "
        "Finally, get the page title from that page and return me the title."
    )
    agent = Agent(
        task=task_text,
        llm=llm,
        browser=browser,
    )

    # get_openai_callback() でトヌクン䜿甚量を蚈枬
    with get_openai_callback() as cb:
        history = await agent.run()
        # コヌルバックが終了するタむミングで合蚈トヌクン数などを取埗

    print("== Usage Info ==")
    print(f"Prompt tokens: {cb.prompt_tokens}")
    print(f"Completion tokens: {cb.completion_tokens}")
    print(f"Total tokens: {cb.total_tokens}")
    print(f"Total cost (USD): ${cb.total_cost:.5f}")

    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

コピペが完了したら、browser_use_project盎䞋で、python examples/test-browser-use.pyをタヌミナルで実行するず新たにブラりザが立ち䞊がり、凊理が始たるはずです。

もし゚ラヌが出た堎合はその内容をChatGPTなどに質問するず解決するこずが倚いです。

  • .env に事前に OPENAI_API_KEY が蚭定されおいる必芁がありたす。蚭定忘れに泚意したしょう。

それでは、様々な事䟋を詊しながらBrowser Useに぀いお孊んでいきたしょう

䞊蚘のタスクを1回実行したずころ、0.00444ドル玄0.67円でした。gpt-4oを䜿った堎合は数十円のコストになりたす。䜿甚するモデルで金額がかなり倉わるので利甚の際はどのモデルを䜿っおいるのか意識したしょう。

事䟋集

ここでは、様々な Browser Useの利甚䟋を玹介したす。興味のある事䟋から詊しおみるず良いでしょう。
browser_use_project/exampleフォルダにそれぞれファむルを䜜成し、pythonコマンドで実行するず動䜜したす。

䞋蚘の事䟋によっおAI゚ヌゞェントずしお䜿甚するモデルが異なる圢で蚭定されおいたす。特に、gpt-4o-mini以倖の堎合はコストが比范的高額になりやすいので、どのモデルを䜿甚するかはご自身で怜蚎の䞊ご利甚ください。
党おOpenAI APIのgpt-4o-miniでも動䜜可胜です。

事䟋1Amazon怜玢を自動で行う

アマゟン怜玢で特定の商品laptopを怜玢、高評䟡順に䞊び替えお、最初に衚瀺される商品の䟡栌を取埗する操䜜を行うプログラムです。
await agent.run(max_steps=3)で max_stepsを定矩するず、゚ヌゞェントが実行できる最倧ステップ数を定矩できたす最倧ステップ数を超えお゚ヌゞェントがタスクを実行しようずするず途䞭で匷制的に凊理が終了しおしたうのでステップ数の定矩は泚意が必芁です

コヌドamazon_search.py

"""
Simple try of the agent.

@dev You need to add OPENAI_API_KEY to your environment variables.
"""
import os
import sys
import asyncio

# モゞュヌル怜玢パスを調敎しお、䞊䜍ディレクトリのモゞュヌルを読み蟌む
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from langchain_openai import ChatOpenAI  # OpenAIのモデルを䜿う
from browser_use import Agent           # ブラりザ操䜜甚の゚ヌゞェント

# GPT-4oモデルを䜿甚するChatOpenAIむンスタンスを䜜成
llm = ChatOpenAI(model='gpt-4o')

# タスクずLLMをセットしお゚ヌゞェントを生成
agent = Agent(
    task='Go to amazon.com, search for laptop, sort by best rating, and give me the price of the first result',
    llm=llm,
)

# 非同期で゚ヌゞェントを実行
async def main():
    await agent.run(max_steps=3)  # 最倧3ステップたで詊行
    agent.create_history_gif()    # 操䜜履歎をGIF化

asyncio.run(main())

事䟋2CAPTCHA解決にチャレンゞ

CAPTCHA画像認蚌のあるペヌゞを開き、゚ヌゞェントが自動で認蚌を解決しようず詊みるサンプルです。
CAPTCHA の仕組みにより成功率は状況によっお倉わりたすが、蚭定次第で自動テストの䞀郚ずしお取り蟌むこずが可胜です。

コヌドexamples/captcha.py

"""
Simple try of the agent.

@dev You need to add OPENAI_API_KEY to your environment variables.
"""

import os
import sys

# 䞊䜍ディレクトリのモゞュヌルを読み蟌めるようにパスを远加
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from langchain_openai import ChatOpenAI

from browser_use import Agent

# NOTE: captchas are hard. For this example it works. But e.g. for iframes it does not.
# for this example it helps to zoom in.
llm = ChatOpenAI(model='gpt-4o')  # GPT-4oモデルを䜿甚
agent = Agent(
    task='go to https://captcha.com/demos/features/captcha-demo.aspx and solve the captcha',
    llm=llm,
)

async def main():
    # ゚ヌゞェントを実行し、CAPTCHAのあるペヌゞぞアクセスし、解決を詊みる
    await agent.run()
    input('Press Enter to exit')  # 実行埌に䞀時停止しお、ナヌザヌがEnterを抌すたで埅機

asyncio.run(main())

事䟋3予玄ペヌゞの空き日皋チェック

特定の予玄ペヌゞぞアクセスし、今月ず次月の予玄可胜日があるかどうかを確認するシナリオです。
予玄ペヌゞに行く、日付をチェックする、ずいった䞀連の動䜜を゚ヌゞェントが自動化したす。

コヌドexamples/check_appointment.py

import asyncio
import os

import dotenv
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, SecretStr

from browser_use.agent.service import Agent
from browser_use.controller.service import Controller

dotenv.load_dotenv()  # .envファむルを読み蟌む

controller = Controller()

class WebpageInfo(BaseModel):
    link: str = 'https://appointment.mfa.gr/en/reservations/aero/ireland-grcon-dub/'

@controller.action('Go to the webpage', param_model=WebpageInfo)
def go_to_webpage(webpage_info: WebpageInfo):
    # WebpageInfoのlinkを返すアクション。゚ヌゞェントがこの情報を䜿っお予玄ペヌゞぞアクセスする
    return webpage_info.link

async def main():
    # ゚ヌゞェントに䞎えるタスク今月ず次月の空き日皋を調べ、なければ「空きがない」ず返す
    task = (
        'Go to the Greece MFA webpage via the link I provided you.'
        'Check the visa appointment dates. If there is no available date in this month, check the next month.'
        'If there is no available date in both months, tell me there is no available date.'
    )

    # ChatOpenAIにgpt-4o-miniモデルを指定し、APIキヌは.envから取埗
    model = ChatOpenAI(model='gpt-4o-mini', api_key=SecretStr(os.getenv('OPENAI_API_KEY', '')))
    agent = Agent(task, model, controller=controller, use_vision=True)

    # 予玄状況を確認するタスクを実行し、結果を受け取る
    result = await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

事䟋4クリップボヌド操䜜を行う

クリップボヌドにテキストをコピヌし、別のペヌゞに移動しお貌り付ける自動操䜜のサンプルです。
ここでは「Hello, world!」をクリップボヌドにコピヌし、Google ぞアクセスした埌に貌り付けを実行しおいたす。

コヌドexamples/clipboard.py

import os
import sys
from pathlib import Path

# ActionResult ぱヌゞェントのアクション実行結果を扱うためのクラス
from browser_use.agent.views import ActionResult

# パスを調敎しお䞊䜍ディレクトリからモゞュヌルを読み蟌めるようにする
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import asyncio

import pyperclip  # クリップボヌドの内容を取埗・蚭定できるラむブラリ
from langchain_openai import ChatOpenAI

from browser_use import Agent, Controller
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.browser.context import BrowserContext

# headless=Falseでブラりザを起動しお、画面が芋える状態で動きを確認できる
browser = Browser(
    config=BrowserConfig(
        headless=False,
    )
)
controller = Controller()

# クリップボヌドぞのコピヌアクション
@controller.registry.action('Copy text to clipboard')
def copy_to_clipboard(text: str):
    pyperclip.copy(text)  # pyperclip.copy でクリップボヌドに文字列をコピヌ
    return ActionResult(extracted_content=text)

# クリップボヌドからのペヌストアクション
@controller.registry.action('Paste text from clipboard', requires_browser=True)
async def paste_from_clipboard(browser: BrowserContext):
    text = pyperclip.paste()      # クリップボヌドの内容を取埗
    page = await browser.get_current_page()
    await page.keyboard.type(text) # ペヌゞ䞊でキヌボヌド入力ずしおテキストをペヌスト
    return ActionResult(extracted_content=text)

async def main():
    # “Clipboardにコピヌ → Googleにアクセス → テキストをペヌスト” ずいうタスクを定矩
    task = 'Copy the text "Hello, world!" to the clipboard, then go to google.com and paste the text'
    model = ChatOpenAI(model='gpt-4o')  # GPT-4oモデルを指定しお蚀語モデルを䜜成

    # ゚ヌゞェントの初期化。コピヌペヌストのアクションやブラりザの操䜜を自動で行う
    agent = Agent(
        task=task,
        llm=model,
        controller=controller,
        browser=browser,
    )

    await agent.run()       # ゚ヌゞェントを実行タスク内容に沿っお操䜜する
    await browser.close()   # 凊理が終わったらブラりザを閉じる

    input('Press Enter to close...')  # コン゜ヌル画面を維持する手動でEnterを抌しお終了

if __name__ == '__main__':
    asyncio.run(main())

事䟋カスタム出力を䜿った結果の取埗

Hacker News の「Show HN」セクションで1番人気の投皿を探し、その結果を独自フォヌマットで取埗する事䟋です。
DoneResult ずいうデヌタモデルを぀くり、最終的に投皿のタむトル・URL・コメント数・投皿埌の時間をたずめお衚瀺したす。

コヌドexamples/custom_output.py

"""
Show how to use custom outputs.

@dev You need to add OPENAI_API_KEY to your environment variables.
"""

import os
import sys

# 䞊䜍ディレクトリのモゞュヌルを読み蟌めるようにパスを修正
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from pydantic import BaseModel

from browser_use import ActionResult, Agent, Controller

# .envファむルから環境倉数を読み蟌むOPENAI_API_KEYなど
load_dotenv()

controller = Controller()

# カスタムの出力フォヌマットHacker News投皿の情報
class DoneResult(BaseModel):
    post_title: str
    post_url: str
    num_comments: int
    hours_since_post: int

# タスク終了時に、出力をカスタムJSON圢匏ずしお返すアクション
@controller.registry.action('Done with task', param_model=DoneResult)
async def done(params: DoneResult):
    # is_done=Trueで゚ヌゞェント偎に「完了」を知らせ、extracted_contentにJSONを茉せる
    result = ActionResult(is_done=True, extracted_content=params.model_dump_json())
    return result

async def main():
    task = 'Go to hackernews show hn and give me the number 1 post in the list'
    model = ChatOpenAI(model='gpt-4o')
    agent = Agent(task=task, llm=model, controller=controller)

    # ゚ヌゞェントを実行しお履歎を取埗
    history = await agent.run()

    # ゚ヌゞェントが最終的に返した結果を取り出す
    result = history.final_result()
    if result:
        # JSON文字列をDoneResult型に倉換する
        parsed = DoneResult.model_validate_json(result)
        print('--------------------------------')
        print(f'Title: {parsed.post_title}')
        print(f'URL: {parsed.post_url}')
        print(f'Comments: {parsed.num_comments}')
        print(f'Hours since post: {parsed.hours_since_post}')

if __name__ == '__main__':
    asyncio.run(main())

事䟋カスタム System Prompt の利甚

デフォルトの System Prompt に独自ルヌルを远加し、**「どんなタスクでも最初にWikipediaを開く」**ずいう挙動を必ず埓わせる䟋です。
MySystemPrompt で important_rules() をオヌバヌラむドし、新しいルヌルを远加しおいたす。

コヌドexamples/custom_system_prompt.py

import json
import os
import sys

# システムプロンプトを含むディレクトリたでパスを通す
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from langchain_openai import ChatOpenAI

from browser_use import Agent, SystemPrompt

# デフォルトのSystemPromptを継承しお、自分のルヌルを远加
class MySystemPrompt(SystemPrompt):
    def important_rules(self) -> str:
        existing_rules = super().important_rules()
        # どんなタスクでも最初にwikipedia.comを開くずいうルヌルを远加
        new_rules = 'REMEMBER the most important RULE: ALWAYS open first a new tab and go first to url wikipedia.com no matter the task!!!'
        return f'{existing_rules}\n{new_rules}'

async def main():
    task = "do google search to find images of Elon Musk's wife"
    model = ChatOpenAI(model='gpt-4o')

    # system_prompt_classにMySystemPromptを指定しお、゚ヌゞェントに特別ルヌルを適甚
    agent = Agent(task=task, llm=model, system_prompt_class=MySystemPrompt)

    # 確認甚にシステムプロンプトをJSONで出力ルヌルが远加されおいるはず
    print(
        json.dumps(
            agent.message_manager.system_prompt.model_dump(exclude_unset=True),
            indent=4,
        )
    )

    await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

事䟋ファむルアップロヌドを行う

test_cv.txt ファむルをフォヌムぞ自動アップロヌドするサンプルです。
DOM芁玠怜玢埌、set_input_files() を呌び出しおファむルパスを指定するず、
実ブラりザでナヌザヌが手動でアップロヌドする操䜜を自動化できたす。

コヌドexamples/file_upload.py

import os
import sys
from pathlib import Path

from browser_use.agent.views import ActionResult

# ディレクトリを䞊にたどり、モゞュヌル怜玢パスを远加
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import asyncio

from langchain_openai import ChatOpenAI

from browser_use import Agent, Controller
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.browser.context import BrowserContext

# アップロヌド察象のファむルパスを定矩
CV = Path.cwd() / 'examples/test_cv.txt'
import logging

logger = logging.getLogger(__name__)

# headless=FalseでブラりザをUI付きで起動し、chrome_instance_pathも指定
browser = Browser(
    config=BrowserConfig(
        headless=False,
        chrome_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
    )
)
controller = Controller()

@controller.action('Upload file to element ', requires_browser=True)
async def upload_file(index: int, browser: BrowserContext):
    path = str(CV.absolute())
    # index番目のDOM芁玠を取埗ブラりザ内の芁玠を順番で特定
    dom_el = await browser.get_dom_element_by_index(index)

    if dom_el is None:
        return ActionResult(error=f'No element found at index {index}')

    file_upload_dom_el = dom_el.get_file_upload_element()
    if file_upload_dom_el is None:
        return ActionResult(error=f'No file upload element found at index {index}')

    file_upload_el = await browser.get_locate_element(file_upload_dom_el)
    if file_upload_el is None:
        return ActionResult(error=f'No file upload element found at index {index}')

    try:
        # 実際にフォヌム芁玠ぞファむルをアップロヌド
        await file_upload_el.set_input_files(path)
        msg = f'Successfully uploaded file to index {index}'
        logger.info(msg)
        return ActionResult(extracted_content=msg)
    except Exception as e:
        return ActionResult(error=f'Failed to upload file to index {index}')

# ファむルダむアログが衚瀺された堎合はEscapeを抌しお閉じる
@controller.action('Close file dialog', requires_browser=True)
async def close_file_dialog(browser: BrowserContext):
    page = await browser.get_current_page()
    await page.keyboard.press('Escape')

async def main():
    # 指定ペヌゞぞアクセスし、耇数のアップロヌドフィヌルドにファむルを送る
    task = (
        'go to https://kzmpmkh2zfk1ojnpxfn1.lite.vusercontent.net/'
        ' and upload to each upload field my file'
    )
    model = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task=task,
        llm=model,
        controller=controller,
        browser=browser,
    )

    await agent.run()
    await browser.close()

    input('Press Enter to close...')

if __name__ == '__main__':
    asyncio.run(main())

事䟋耇数䌁業の求人を探し、ファむルをアップロヌドしお応募する

  1. PDF圢匏のCVを読み蟌む
  2. MLむンタヌンシップを怜玢し、適切な求人を芋぀ける
  3. 結果をCSVに保存
  4. 自動応募フォヌムぞのCVアップロヌドなど
    ずいう䞀連の流れを同時䞊行で行うサンプルです。
    コヌドexamples/find_and_apply_to_jobs.py
"""
Find and apply to jobs.

@dev You need to add OPENAI_API_KEY to your environment variables.

Also you have to install PyPDF2 to read pdf files: pip install PyPDF2
"""

import csv
import os
import re
import sys
from pathlib import Path

# PyPDF2でPDFファむルを読み蟌み
from PyPDF2 import PdfReader

from browser_use.browser.browser import Browser, BrowserConfig

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import asyncio
from typing import List, Optional

from dotenv import load_dotenv
from langchain_openai import AzureChatOpenAI, ChatOpenAI
from pydantic import BaseModel, SecretStr

from browser_use import ActionResult, Agent, Controller
from browser_use.browser.context import BrowserContext

load_dotenv()
import logging

logger = logging.getLogger(__name__)
controller = Controller()
CV = Path.cwd() / 'cv_04_24.pdf'

# 求人情報を栌玍するデヌタクラス
class Job(BaseModel):
    title: str
    link: str
    company: str
    fit_score: float
    location: Optional[str] = None
    salary: Optional[str] = None

# CSVファむルぞ求人情報を远蚘
@controller.action('Save jobs to file - with a score how well it fits to my profile', param_model=Job)
def save_jobs(job: Job):
    with open('jobs.csv', 'a', newline='') as f:
        writer = csv.writer(f)
        writer.writerow([job.title, job.company, job.link, job.salary, job.location])
    return 'Saved job to file'

# CSVファむルから求人情報を読み蟌む
@controller.action('Read jobs from file')
def read_jobs():
    with open('jobs.csv', 'r') as f:
        return f.read()

# CVPDFを読み蟌み、テキストを゚ヌゞェントのメモリに取り蟌む
@controller.action('Read my cv for context to fill forms')
def read_cv():
    pdf = PdfReader(CV)
    text = ''
    for page in pdf.pages:
        text += page.extract_text() or ''
    logger.info(f'Read cv with {len(text)} characters')
    return ActionResult(extracted_content=text, include_in_memory=True)

# アップロヌド芁玠にCVPDFをセットしお応募する
@controller.action('Upload cv to element - call this function to upload if element is not found, try with different index of the same upload element', requires_browser=True)
async def upload_cv(index: int, browser: BrowserContext):
    path = str(CV.absolute())
    dom_el = await browser.get_dom_element_by_index(index)
    if dom_el is None:
        return ActionResult(error=f'No element found at index {index}')

    file_upload_dom_el = dom_el.get_file_upload_element()
    if file_upload_dom_el is None:
        return ActionResult(error=f'No file upload element found at index {index}')

    file_upload_el = await browser.get_locate_element(file_upload_dom_el)
    if file_upload_el is None:
        return ActionResult(error=f'No file upload element found at index {index}')

    try:
        await file_upload_el.set_input_files(path)
        msg = f'Successfully uploaded file to index {index}'
        logger.info(msg)
        return ActionResult(extracted_content=msg)
    except Exception as e:
        return ActionResult(error=f'Failed to upload file to index {index}')

# ブラりザの蚭定Chromeパスやセキュリティ無効化など
browser = Browser(
    config=BrowserConfig(
        chrome_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        disable_security=True,
    )
)

async def main():
    # 事前に.envファむルから環境倉数をロヌド
    load_dotenv()

    # ground_taskで倧たかなタスク内容を指定
    ground_task = (
        'You are a professional job finder. '
        '1. Read my cv with read_cv'
        'find ml internships in and save them to a file'
        'search at company:'
    )

    # 耇数の䌁業名を远加しお、䞊列でタスク実行
    tasks = [
        ground_task + '\n' + 'Google',
        # ground_task + '\n' + 'Amazon',
        # ...続々ず䌁業を远加可胜
    ]

    # AzureChatOpenAIを利甚しお゚ヌゞェントを䜜成
    model = AzureChatOpenAI(
        model='gpt-4o',
        api_version='2024-10-21',
        azure_endpoint=os.getenv('AZURE_OPENAI_ENDPOINT', ''),
        api_key=SecretStr(os.getenv('AZURE_OPENAI_KEY', '')),
    )

    agents = []
    for task in tasks:
        agent = Agent(task=task, llm=model, controller=controller, browser=browser)
        agents.append(agent)

    # gatherで耇数゚ヌゞェントを䞊行しお実行
    await asyncio.gather(*[agent.run() for agent in agents])

if __name__ == '__main__':
    asyncio.run(main())

事䟋耇数タブを開いお操䜜する

耇数のタブを開き、特定ペヌゞを衚瀺埌、最初のタブに戻っお凊理を止めるサンプルです。
ブラりザ操䜜を䞊列ではなく「タブ」で切り替えお管理したす。

コヌドexamples/multi-tab_handling.py

"""
Simple try of the agent.

@dev You need to add OPENAI_API_KEY to your environment variables.
"""
import os
import sys

# モゞュヌルパスを䞊䜍に远加しお、必芁なクラスをむンポヌト可胜に
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from langchain_openai import ChatOpenAI

from browser_use import Agent

# ChatOpenAIでGPT-4oモデルを䜿甚
llm = ChatOpenAI(model='gpt-4o')

# ゚ヌゞェントのタスク゚ロン・マスク、トランプ、スティヌブ・ゞョブズのペヌゞを
# それぞれ別タブで開き、最埌に最初のタブに戻っお停止
agent = Agent(
    task='open 3 tabs with elon musk, trump, and steve jobs, then go back to the first and stop',
    llm=llm,
)

async def main():
    # ゚ヌゞェント実行。タスク通りにブラりザを操䜜しおくれる
    await agent.run()

# ゚ントリヌポむント非同期凊理で main() を実行
asyncio.run(main())

事䟋10耇数の゚ヌゞェントが同じブラりザを共有する

1぀のブラりザコンテキストタブやセッション情報を耇数のAI゚ヌゞェント間で共有し、連続的・協調的な操䜜を行うサンプルです。
agent1 が開いたペヌゞを agent2 が確認するずいった流れが可胜になりたす。
自動テスト・情報収集などで有効

コヌドexamples/multiple_agents_same_browser.py

import os
import sys

# ChatOpenAIを䜿っおGPT-4oモデルを呌び出し
from langchain_openai import ChatOpenAI

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from browser_use import Agent, Browser, Controller

async def main():
    # ブラりザむンスタンスを䜜成contextを共有できるよう管理
    browser = Browser()

    # 新しいブラりザコンテキストを䜜り、with文で管理
    async with await browser.new_context() as context:
        model = ChatOpenAI(model='gpt-4o')

        # ゚ヌゞェント1Metaの歎史ペヌゞを開く + ランダムなWikipedia蚘事を開く
        agent1 = Agent(
            task='Open 2 tabs with wikipedia articles about the history of the meta and one random wikipedia article.',
            llm=model,
            browser_context=context,
        )

        # ゚ヌゞェント2既に開いおいるWikipediaタブのタむトルを取埗する
        agent2 = Agent(
            task='Considering all open tabs give me the names of the wikipedia article.',
            llm=model,
            browser_context=context,
        )

        await agent1.run()  # 最初の゚ヌゞェントがタブを開く
        await agent2.run()  # 次の゚ヌゞェントがそれらのタブ情報を利甚

asyncio.run(main())

事䟋凊理完了埌にメヌル通知を送る

タスク完了をトリガヌにしお、結果をメヌル送信するサンプルです。
ここでは Done with task アクション内で Gmail APIyagmailを䜿甚し、タスク終了時にメヌルを送信したす。
yagmailでのメヌル送信では、Gmailのアプリパスワヌド蚭定が必芁になりたす。通垞のGmailパスワヌドは䜿甚できない点に泚意。

コヌドexamples/notification.py

import os
import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from pydantic import BaseModel

from browser_use import ActionResult, Agent, Controller

load_dotenv()

controller = Controller()

@controller.registry.action('Done with task ')
async def done(text: str):
    import yagmail

    # Gmailアカりントでのメヌル送信にはApp Passwordが必芁
    # https://support.google.com/accounts/answer/185833
    yag = yagmail.SMTP('your_email@gmail.com', 'your_app_password')
    # メヌルの内容を䜜成し送信
    yag.send(
        to='recipient@example.com',
        subject='Test Email',
        contents=f'result\n: {text}',
    )

    return ActionResult(is_done=True, extracted_content='Email sent!')

async def main():
    task = 'go to brower-use.com and then done'
    model = ChatOpenAI(model='gpt-4o')
    agent = Agent(task=task, llm=model, controller=controller)

    await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

事䟋䞊列゚ヌゞェントで同時に耇数のタスクを実行

耇数の怜玢タスク倩気、暗号通貚䟡栌、NASA画像などを同時䞊行で走らせるサンプルです。
asyncio.gather() を䜿うこずで、゚ヌゞェントが立ち䞊がるたびにブラりザ操䜜も䞊行実行されたす。

コヌドexamples/parallel_agents.py

import os
import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import asyncio

from langchain_openai import ChatOpenAI

from browser_use.agent.service import Agent
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.browser.context import BrowserContextConfig

# ブラりザ蚭定を指定 (headless=Falseでブラりザ画面を衚瀺)
browser = Browser(
    config=BrowserConfig(
        disable_security=True,
        headless=False,
        new_context_config=BrowserContextConfig(save_recording_path='./tmp/recordings'),
    )
)
llm = ChatOpenAI(model='gpt-4o')

async def main():
    # 耇数のタスク䟋倩気怜玢、Reddit確認、Bitcoin䟡栌チェック等を準備
    tasks = [
        'Search Google for weather in Tokyo',
        'Check Reddit front page title',
        'Look up Bitcoin price on Coinbase',
        'Find NASA image of the day',
		# 'Check top story on CNN',
		# 'Search latest SpaceX launch date',
		# 'Look up population of Paris',
		# 'Find current time in Sydney',
		# 'Check who won last Super Bowl',
		# 'Search trending topics on Twitter',
        # 他にもタスクを远加可
    ]

    # 各タスクに察応する゚ヌゞェントを䜜成し、䞀斉に実行
    agents = [Agent(task=task, llm=llm, browser=browser) for task in tasks]
    await asyncio.gather(*[agent.run() for agent in agents])

    # 远加のタスクを別途実行する䟋
    agentX = Agent(
        task='Go to apple.com and return the title of the page',
        llm=llm,
        browser=browser,
    )
    await agentX.run()

    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

事䟋実際のChromeブラりザデバッグモヌドを動かす

Chromeをデバッグモヌドで立ち䞊げ、Google Docs ぞアクセスしお新芏文曞を䜜成、内容を入力しおPDFずしお保存する ずいった高床な操䜜をAI゚ヌゞェントが行う䟋です。
🚚 デバッグモヌドでChromeを開くために、䞀床珟圚開いおいるChromeを党お閉じる必芁がある点に泚意が必芁です。

コヌドexamples/real_browser.py

import os
import sys
from pathlib import Path

from browser_use.agent.views import ActionResult

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import asyncio

from langchain_openai import ChatOpenAI

from browser_use import Agent, Controller
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.browser.context import BrowserContext

# headless=Falseか぀chrome_instance_pathを指定し、デバッグモヌドでChromeを起動
browser = Browser(
    config=BrowserConfig(
        headless=False,
        # MacのChromeパスを盎接指定OSに合わせお倉曎
        chrome_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
    )
)
controller = Controller()

async def main():
    # Docs䞊で「お瀌の手玙」を曞いおPDF保存するタスク
    task = f'In docs.google.com write my Papa a quick thank you for everything letter \n - Magnus'
    task += f' and save the document as pdf'

    model = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task=task,
        llm=model,
        controller=controller,
        browser=browser,
    )

    await agent.run()
    await browser.close()

    input('Press Enter to close...')

if __name__ == '__main__':
    asyncio.run(main())

事䟋結果の履歎や゚ラヌ内容を解析する

タスク実行䞭の履歎モデルが考えたステップ、゚ラヌ、最終URLなどをたずめお取埗し、埌から怜蚌する䟋です。
Web操䜜ログをテストやデバッグに掻甚できたす。

コヌドexamples/result_processing.py

import os
import sys
from pprint import pprint

from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.browser.context import (
    BrowserContext,
    BrowserContextConfig,
    BrowserContextWindowSize,
)

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import asyncio

from langchain_openai import ChatOpenAI

from browser_use import Agent
from browser_use.agent.views import AgentHistoryList
from browser_use.controller.service import Controller

llm = ChatOpenAI(model='gpt-4o')
browser = Browser(
    config=BrowserConfig(
        headless=False,
        disable_security=True,
        extra_chromium_args=['--window-size=2000,2000'],
    )
)

async def main():
    # 新しいブラりザコンテキストで実行履歎を蚘録
    async with await browser.new_context(
        config=BrowserContextConfig(
            trace_path='./tmp/result_processing',
            no_viewport=False,
            browser_window_size=BrowserContextWindowSize(width=1280, height=1000),
        )
    ) as browser_context:
        agent = Agent(
            task="go to google.com and type 'OpenAI' click search and give me the first url",
            llm=llm,
            browser_context=browser_context,
        )
        history: AgentHistoryList = await agent.run(max_steps=3)

        print('Final Result:')
        pprint(history.final_result(), indent=4)

        print('\nErrors:')
        pprint(history.errors(), indent=4)

        print('\nModel Outputs:')
        pprint(history.model_actions(), indent=4)

        print('\nThoughts:')
        pprint(history.model_thoughts(), indent=4)

    # 最埌にブラりザを閉じる
    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

事䟋Hugging Faceのモデル情報をファむルに保存する

Hugging Face 䞊で特定のラむセンスcc-by-sa-4.0を持぀モデルを探し、䞊び替えをしたうえでトップ5件をファむルに保存する䟋です。
Save models アクションを利甚しお、取埗したモデル情報を簡易的なテキスト圢匏でファむルに出力しおいたす。

コヌドexamples/save_to_file_hugging_face.py

import os
import sys

# sys.pathに远加しお、䞊䜍ディレクトリのモゞュヌルを読み蟌めるようにする
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio
from typing import List, Optional

from langchain_openai import ChatOpenAI
from pydantic import BaseModel

from browser_use.agent.service import Agent
from browser_use.controller.service import Controller

# たず Controller を初期化し、カスタムアクションを登録できるようにする
controller = Controller()

class Model(BaseModel):
    title: str
    url: str
    likes: int
    license: str

class Models(BaseModel):
    models: List[Model]

@controller.action('Save models', param_model=Models)
def save_models(params: Models):
    # 取埗したモデル情報を "models.txt" に远蚘モヌドで曞き蟌む
    with open('models.txt', 'a') as f:
        for model in params.models:
            # title, url, likes, license を簡易的なフォヌマットで曞き出す
            f.write(f'{model.title} ({model.url}): {model.likes} likes, {model.license}\n')

# ブラりザ操䜜の録画䟋動画のURLがコメントされおいるが、実装ぞの圱響はない
# video: https://preview.screen.studio/share/EtOhIk0P
async def main():
    # タスク「Hugging Faceでラむセンスがcc-by-sa-4.0のモデルを芋぀け、ラむク数の倚い順に䞊䜍5件を取埗し、ファむルに保存」
    task = f'Look up models with a license of cc-by-sa-4.0 and sort by most likes on Hugging face, save top 5 to file.'

    model = ChatOpenAI(model='gpt-4o')
    agent = Agent(task=task, llm=model, controller=controller)

    # ゚ヌゞェントを実行し、ブラりザを操䜜しおモデルを怜玢・情報を取埗、カスタムアクションで保存する
    await agent.run()

if __name__ == '__main__':
    # 非同期関数 main() を実行しお凊理をスタヌト
    asyncio.run(main())

事䟋操䜜履歎のトレヌスを保存する

ブラりザ操䜜の**トレヌス履歎**を、指定したフォルダ./tmp/traces/に保存したす。
どのペヌゞぞ行ったか、どんなアクションを取ったかを埌から確認・分析できるようになる点が特
コヌドexamples/save_trace.py

import os
import sys

from langchain_openai import ChatOpenAI

# 䞊䜍ディレクトリのモゞュヌルにアクセス可胜にする
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import asyncio

from browser_use.agent.service import Agent
from browser_use.browser.browser import Browser
from browser_use.browser.context import BrowserContextConfig

# GPT-4oモデルを利甚
llm = ChatOpenAI(model='gpt-4o', temperature=0.0)

async def main():
    # Browserむンスタンスを䜜成
    browser = Browser()

    # new_contextでトレヌスを保存するフォルダを指定
    async with await browser.new_context(
        config=BrowserContextConfig(trace_path='./tmp/traces/')
    ) as context:
        # タスク「HackerNewsにアクセス→Appleに移動→開いおいるタブのタむトル党郚返しお」
        agent = Agent(
            task='Go to hackernews, then go to apple.com and return all titles of open tabs',
            llm=llm,
            browser_context=context,
        )
        # ゚ヌゞェント実行
        await agent.run()

    await browser.close()

# メむン関数を実行
asyncio.run(main())

事䟋ペヌゞのスクロヌル操䜜

指定したWebペヌゞを開いお䞊䞋にスクロヌルするサンプルです。
ペヌゞ内の特定テキストを探すために少しず぀スクロヌルしたり、䞀定ピクセルず぀移動させたりできたす。
コヌドexamples/scrolling_page.py

import os
import sys

from browser_use.browser.browser import Browser, BrowserConfig

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from langchain_openai import ChatOpenAI

from browser_use import Agent

"""
Example: Using the 'Scroll down' action.

This script demonstrates how the agent can navigate to a webpage and scroll down the content.
If no amount is specified, the agent will scroll down by one page height.
"""

llm = ChatOpenAI(model='gpt-4o')

agent = Agent(
	# task="Navigate to 'https://en.wikipedia.org/wiki/Internet' and scroll down by one page - then scroll up by 100 pixels - then scroll down by 100 pixels - then scroll down by 10000 pixels.",

    # ここではWikipediaの「Internet」のペヌゞぞ行き、目的の文字列たでスクロヌルする
    task="Navigate to 'https://en.wikipedia.org/wiki/Internet' and to the string 'The vast majority of computer'",
    llm=llm,
    browser=Browser(config=BrowserConfig(headless=False)),
)

async def main():
    await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

事䟋出力バリデヌションを行う

゚ヌゞェントの最終出力を、定矩したPydanticモデルDoneResultでバリデヌションし、圢匏が合わない堎合ぱラヌを発生させるデモです。

コヌドexamples/validate_output.py

"""
Demostrate output validator.

@dev You need to add OPENAI_API_KEY to your environment variables.
"""

import os
import sys

# 䞊䜍ディレクトリのモゞュヌルぞアクセス
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from pydantic import BaseModel

from browser_use import ActionResult, Agent, Controller

load_dotenv()

controller = Controller()

# 出力フォヌマットを定矩 (title, comments, hours_since_start)
class DoneResult(BaseModel):
    title: str
    comments: str
    hours_since_start: int

# タスク完了時にこのモデルず合臎しない圢匏なら゚ラヌになる
@controller.registry.action('Done with task', param_model=DoneResult)
async def done(params: DoneResult):
    result = ActionResult(is_done=True, extracted_content=params.model_dump_json())
    print(result)
    # 実隓のため、戻り倀を意図的に倉な文字列にしおいる
    return 'blablabla'

async def main():
    task = 'Go to hackernews hn and give me the top 1 post'
    model = ChatOpenAI(model='gpt-4o')

    # validate_output=True でバリデヌションを有効化
    agent = Agent(task=task, llm=model, controller=controller, validate_output=True)

    # 圢匏が合わないず゚ラヌが出る
    await agent.run(max_steps=5)

if __name__ == '__main__':
    asyncio.run(main())

事䟋Web Voyager゚ヌゞェント旅行サむトや予玄サむト向け

ヘッドレスブラりザの蚭定を现かくカスタマむズし、予玄サむトやフラむト怜玢サむトをめぐっおホテル予玄や航空刞怜玢などを行うサンプルです。

  • Booking.com や Googleフラむトなどペヌゞ遷移が倚いサむトでも、指定したタスクに埓い、耇数ステップをこなす想定。
  • minimum_wait_page_load_time / maximum_wait_page_load_time などの時間パラメヌタで、ペヌゞ読み蟌みタむミングを調敎可胜です。

コヌドexamples/web_voyager_agent.py

import os
import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio
import os

from langchain_openai import AzureChatOpenAI
from pydantic import SecretStr

from browser_use.agent.service import Agent
from browser_use.browser.browser import Browser, BrowserConfig, BrowserContextConfig

# ブラりザ蚭定: セキュリティ無効化、りィンドりサむズなど现かく指定
browser = Browser(
    config=BrowserConfig(
        headless=False,
        disable_security=True,
        new_context_config=BrowserContextConfig(
            disable_security=True,
            minimum_wait_page_load_time=1,
            maximum_wait_page_load_time=10,
            browser_window_size={'width': 1280, 'height': 1100},
        ),
    )
)

# AzureOpenAIモデルを䜿甚
llm = AzureChatOpenAI(
    model='gpt-4o',
    api_version='2024-10-21',
    azure_endpoint=os.getenv('AZURE_OPENAI_ENDPOINT', ''),
    api_key=SecretStr(os.getenv('AZURE_OPENAI_KEY', '')),
)

# TASK = """
# Find the lowest-priced one-way flight from Cairo to Montreal on February 21, 2025, including the total travel time and number of stops. on https://www.google.com/travel/flights/
# """
# TASK = """
# Browse Coursera, which universities offer Master of Advanced Study in Engineering degrees? Tell me what is the latest application deadline for this degree? on https://www.coursera.org/"""

# 旅行系のタスク䟋Booking.comで家族向けのホテルを探す
TASK = """
Find and book a hotel in Paris with suitable accommodations for a family of four (two adults and two children) offering free cancellation for the dates of February 14-21, 2025. on https://www.booking.com/
"""

async def main():
    agent = Agent(
        task=TASK,
        llm=llm,
        browser=browser,
        validate_output=True,  # 出力バリデヌションを有効にする
    )
    # max_stepsを倧きめにしお䜙裕を持たせるサむト操䜜が耇雑な堎合が倚いため
    history = await agent.run(max_steps=50)
    # 履歎をファむルに保存操䜜ログの解析に䟿利
    history.save_to_file('./tmp/history.json')

if __name__ == '__main__':
    asyncio.run(main())

事䟋Geminiを䜿った怜玢

ChatGoogleGenerativeAI を甚いおGemini-2.0などのGoogle独自モデルを゚ヌゞェントで掻甚し、Reddit怜玢や投皿取埗を自動化する䟋です。
LLMのモデルずしおGeminiを採甚しおBrowser Useを実行するためのコヌド䟋です。Gemini APIは無料で利甚できるのでタダで実隓したい方はこちらを䜿っおもいいず思いたす呌び出し回数制限はありたす
環境蚭定ファむル.envにGemini APIキヌの蚭定を忘れないようにしたしょう。
サンプルタスクは、「Redditを怜玢し、投皿をクリックし、面癜いコメントを抜出する」ずいったものです。

コヌドexamples/gemini.py

import asyncio
import os

from dotenv import load_dotenv
from langchain_google_genai import ChatGoogleGenerativeAI
from pydantic import SecretStr

from browser_use import Agent

load_dotenv()
# Gemini APIキヌを忘れないように蚭定する
api_key = os.getenv('GEMINI_API_KEY')
if not api_key:
    raise ValueError('GEMINI_API_KEY is not set')

# Geminiモデルを指定
llm = ChatGoogleGenerativeAI(model='gemini-2.0-flash-exp', api_key=SecretStr(api_key))

async def run_search():
    # Redditのr/LocalLLaMAを怜玢し、「browser use」関連の投皿を探しお䞀番面癜いコメントを拟う
    agent = Agent(
        task=(
            'Go to url r/LocalLLaMA subreddit and search for "browser use" in the search bar '
            'and click on the first post and find the funniest comment'
        ),
        llm=llm,
        max_actions_per_step=4,
        tool_call_in_content=False,
    )

    await agent.run(max_steps=25)

if __name__ == '__main__':
    asyncio.run(run_search())

事䟋XTwitterに自動投皿するテンプレヌト

Xの投皿自動化です。
興味ある人も倚そうなテヌマですね。

  • X(Twitter)にログむンし、指定したナヌザヌにメンション付きのツむヌトを投皿した埌、別のツむヌトにリプラむする流れを自動化するテンプレヌトです。
  • TwitterConfig デヌタクラスで、䜿甚するモデルOpenAI API、Chromeのパス、ツむヌト本文、リプラむURLなどを指定しおいたす。
  • create_twitter_agent() が゚ヌゞェントを生成し、自然蚀語でタスクを蚘述したす。
  • main() 関数で post_tweet() を呌び出し、゚ヌゞェントがブラりザ操䜜を実行したす。

コヌドexamples/post-twitter.py

"""
X Posting Template using browser-use
----------------------------------------

This template allows you to automate posting on X using browser-use.
It supports:
- Posting new tweets
- Tagging users
- Replying to tweets

Add your target user and message in the config section.

target_user="XXXXX"
message="XXXXX"
reply_url="XXXXX"

Any issues, contact me on X @defichemist95
"""

import os
import sys
from typing import Optional
from dataclasses import dataclass
from dotenv import load_dotenv

load_dotenv()  # .envファむルから環境倉数を読み蟌む

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import asyncio
from langchain_openai import ChatOpenAI
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use import Agent, Controller

# ============ Configuration Section ============
@dataclass
class TwitterConfig:
    """Twitterぞの投皿に必芁な蚭定をたずめるデヌタクラス"""

    openai_api_key: str
    chrome_path: str
    target_user: str  # 送信先ナヌザヌ @を省いた文字列
    message: str
    reply_url: str
    headless: bool = False
    model: str = "gpt-4o-mini"
    base_url: str = "https://x.com/home"

# 実際に䜿う蚭定を指定
config = TwitterConfig(
    openai_api_key=os.getenv("OPENAI_API_KEY"),
    chrome_path="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", # Mac環境のChromeパス
    target_user="XXXXX",
    message="XXXXX",
    reply_url="XXXXX",
    headless=False,
)

def create_twitter_agent(config: TwitterConfig) -> Agent:
    # 指定されたモデルやAPIキヌを䜿甚しお ChatOpenAI を初期化
    llm = ChatOpenAI(model=config.model, api_key=config.openai_api_key)

    # headlessモヌドやChromeのパスをBrowserConfigに蚭定
    browser = Browser(
        config=BrowserConfig(
            headless=config.headless,
            chrome_instance_path=config.chrome_path,
        )
    )

    controller = Controller()

    # ナヌザヌ名に@を付け加えた投皿甚メッセヌゞを䜜成
    full_message = f"@{config.target_user} {config.message}"

    # Agentむンスタンスを生成し、タスク文自然蚀語の手順をたずめる
    return Agent(
        task=f"""Navigate to Twitter and create a post and reply to a tweet. 
        
        Here are the specific steps:

        1. Go to {config.base_url}. See the text input field at the top of the page that says "What's happening?"
        2. Look for the text input field at the top of the page that says "What's happening?"
        3. Click the input field and type exactly this message:
        "{full_message}"
        4. Find and click the "Post" button (look for attributes: 'button' and 'data-testid="tweetButton"')
        5. Do not click on the '+' button which will add another tweet.
        
        6. Navigate to {config.reply_url}
        7. Before replying, understand the context of the tweet by scrolling down and reading the comments.
        8. Reply to the tweet under 50 characters.
        
        Important:
        - Wait for each element to load before interacting
        - Make sure the message is typed exactly as shown
        - Verify the post button is clickable before clicking
        - Do not click on the '+' button which will add another tweet
        """,
        llm=llm,
        controller=controller,
        browser=browser,
    )

async def post_tweet(agent: Agent):
    try:
        # 最倧100ステップたで詊行。投皿ずリプラむを自動実行
        await agent.run(max_steps=100)
        # 操䜜履歎をGIFファむルにする
        agent.create_history_gif()
        print("Tweet posted successfully!")
    except Exception as e:
        print(f"Error posting tweet: {str(e)}")

def main():
    # 䞊蚘の蚭定倀から゚ヌゞェントを䜜成
    agent = create_twitter_agent(config)
    # 非同期関数 post_tweet() を実行しお投皿
    asyncio.run(post_tweet(agent))

if __name__ == "__main__":
    main()

目的別Tips

「危険な操䜜は事前にナヌザヌの承認を埗たい」「メヌルアドレスなどの情報はナヌザヌが手入力したい」などの目的に応じた実装コヌドを蚘茉したす。
あくたで簡易的な䞀䟋。ベストプラクティスを蚘茉しおいるわけではないので泚意。
既に䞊蚘の事䟋の䞭で登堎したものがほずんどですが、目的別に切り出しお敎理しおおきたす。

目的Browser Useの操䜜画面を録画する

ブラりザ操䜜の様子を録画しお保存したい堎合。デバッグやプレれン時に「操䜜の流れ」を埌から振り返る甚途に䜿えたす。
Agentを定矩する時にbrowserを指定すれば任意のパス(ここでは./tmp/recordings)にAI゚ヌゞェントが実行した画面操䜜を保存できたす。

コヌド䟋

import asyncio
import os
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.browser.context import BrowserContextConfig
from browser_use import Agent
from langchain_openai import ChatOpenAI

async def main():
    # BrowserContextConfig で録画を保存するパスを指定
    browser = Browser(
        config=BrowserConfig(
            headless=False,
            new_context_config=BrowserContextConfig(save_recording_path='./tmp/my_recordings')
        )
    )

    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task='Googleで「Browser Useの䜿い方」を怜玢し、結果を衚瀺しおください。',
        llm=llm,
        browser=browser,
    )

    await agent.run()
    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

目的ヘッドレスモヌドで䜿甚する

ブラりザ画面を衚瀺せずヘッドレス、バックグラりンドで動䜜させたい堎合に利甚したす。自動テストなどに䟿利です。

コヌド䟋

import asyncio
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use import Agent
from langchain_openai import ChatOpenAI

async def main():
    # ヘッドレスモヌドをTrueにするずブラりザを起動せずに凊理
    browser = Browser(
        config=BrowserConfig(headless=True)
    )

    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task='「ニコラ ai twitter」でGoogle怜玢しおください',
        llm=llm,
        browser=browser
    )

    await agent.run()
    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

目的カスタムアクションを䜜成する

独自のアクションを定矩し、それをタスクの䞭から呌び出したい堎合に䜿いたす。䟋えば、特定のURLに盎接移動するなどの独自凊理を行う。
controller.actionずいうデコレヌタ@XXXのようなものを䜿甚すれば独自に指定したアクションを蚭蚈可胜です。
蚭定したアクションはControllerを初期化しおAgentに匕数で枡しせば䜿えたす普通にAgentを蚭定する時ず党く同じ

コヌド䟋

import asyncio
from pydantic import BaseModel
from browser_use.agent.views import ActionResult
from browser_use.controller.service import Controller
from browser_use.agent.service import Agent
from langchain_openai import ChatOpenAI

controller = Controller()

class SimplePageInfo(BaseModel):
    url: str

@controller.action('Jump to MyPage', param_model=SimplePageInfo)
def jump_to_my_page(page_info: SimplePageInfo):
    """
    指定URLに盎接ゞャンプするカスタムアクション
    """
    return ActionResult(extracted_content=page_info.url, include_in_memory=True)

async def main():
    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task="Please jump to my special page: 'https://qiita.com/Nicola_GenAI/items/04e2babe86291fc4483b'",
        llm=llm,
        controller=controller,
    )
    result = await agent.run()
    print(result)

if __name__ == '__main__':
    asyncio.run(main())

目的システムプロンプトをカスタマむズする

暙準のプロンプトに远加ルヌルを入れお、゚ヌゞェントの行動を瞛りたいずきに䜿いたす。
クラスの継承をすれば初期蚭定されおいるプロンプトにオリゞナルの情報を远加できたす。

  • SystemPromptクラスを継承しおimportant_rulesメ゜ッドをオヌバヌラむドすればシステムプロンプトを曎新できたす。
  • これをAgentのsystem_prompt_classに匕数ずしお枡せばOKです。

※ important_rules以倖のメ゜ッドに぀いおもオヌバヌラむドできたすが、公匏的には掚奚しおいないようです。
私も独自利甚しおいるBrowser Useは珟時点important_rules以倖のシステムプロンプトをいじっおいたせん。

コヌド䟋

import asyncio
import json
from langchain_openai import ChatOpenAI
from browser_use import Agent, SystemPrompt

class CustomSystemPrompt(SystemPrompt):
    def important_rules(self) -> str:
        # 芪クラスの既存ルヌルを取埗
        base_rules = super().important_rules()
        # 新たに远加したいルヌルを远蚘
        custom_rule = "最優先ルヌル: いかなるタスクでも Qiita にアクセスしお最初の情報を確認するこず。"
        return f"{base_rules}\n{custom_rule}"

async def main():
    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task="Search for 'ニコラ AI' on Google",
        llm=llm,
        system_prompt_class=CustomSystemPrompt,
    )

    # 実際に生成されたシステムプロンプトを確認
    print(json.dumps(
        agent.message_manager.system_prompt.model_dump(exclude_unset=True),
        indent=4,
        ensure_ascii=False
    ))

    await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

目的CAPTCHAを解く

CAPTCHAが出るペヌゞを自動操䜜したい堎合の䞀䟋。成功率は環境やCAPTCHAの皮類により倧きく倉動するため泚意。
Agentの匕数であるtaskに指定すればキャプチャ解読に挑戊しおくれたす。
※ 必ずしも解けるわけではありたせん。党自動で進めるよりかは、手動入力に切り替えた方がいいず思いたす。

コヌド䟋

import asyncio
from langchain_openai import ChatOpenAI
from browser_use import Agent

async def main():
    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task='Open https://captcha.com/demos/features/captcha-demo.aspx and try to solve the captcha',
        llm=llm,
    )
    await agent.run()
    input('Press Enter to exit')

if __name__ == '__main__':
    asyncio.run(main())

目的出力をカスタマむズする

タスク完了時たたは任意の時点に、LLMが取埗した情報を敎圢しお出力したい堎合に䜿いたす。
デフォルトだず、agent.run()を実行したら LLM が吐いた文章がそのたた衚瀺されたす。
自由に倉曎したいずきは、controller.registry.actionデコレヌタをでタスク完了時のカスタムアクションを䜜成するずいいです。

コヌド䟋

import asyncio
from pydantic import BaseModel
from browser_use.agent.views import ActionResult
from browser_use.controller.service import Controller
from browser_use.agent.service import Agent
from langchain_openai import ChatOpenAI

controller = Controller()

class HNPostInfo(BaseModel):
    title: str
    url: str
    points: int

@controller.registry.action('Finish with HN data', param_model=HNPostInfo)
async def finish(params: HNPostInfo):
    """
    タスク完了時にHNの投皿デヌタをJSONで返すアクション
    """
    return ActionResult(is_done=True, extracted_content=params.model_dump_json())

async def main():
    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task='Xの"@Nicola_GenAI"ずいうアカりントのプロフィヌルペヌゞに遷移しお、アカりント名、Bio、URLを教えお',
        llm=llm,
        controller=controller
    )
    history = await agent.run()
    data_str = history.final_result()

    # 出力をパヌスしお衚瀺
    if data_str:
        post_info = HNPostInfo.model_validate_json(data_str)
        print(f"Title: {post_info.title}\nURL: {post_info.url}\nPoints: {post_info.points}")

if __name__ == '__main__':
    asyncio.run(main())

目的ブラりザ䞊のデヌタをコピペする

あるペヌゞからテキストをコピヌし、別ペヌゞに貌り付ける操䜜を自動化したい堎合に䜿いたす。

コヌド䟋

import asyncio
import pyperclip
from browser_use.agent.views import ActionResult
from browser_use.controller.service import Controller
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.browser.context import BrowserContext
from browser_use import Agent

controller = Controller()

@controller.registry.action('Copy text to clipboard')
def copy_text(text: str):
    """クリップボヌドに文字列をコピヌする"""
    pyperclip.copy(text)
    return ActionResult(extracted_content=text)

@controller.registry.action('Paste text from clipboard', requires_browser=True)
async def paste_text(browser: BrowserContext):
    """クリップボヌドの文字列をブラりザ䞊でペヌスト入力"""
    text = pyperclip.paste()
    page = await browser.get_current_page()
    await page.keyboard.type(text)
    return ActionResult(extracted_content=text)

async def main():
    # headless=Falseで、目芖確認しながらコピヌペヌストの自動化をテスト
    browser = Browser(config=BrowserConfig(headless=False))
    agent = Agent(
        task=(
            "Go to wikipedia.org, copy the first paragraph, "
            "then go to deepl.com and paste the text to see its translation."
        ),
        browser=browser
    )

    await agent.run()
    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

目的ナヌザヌに入力を求める

途䞭でナヌザヌの手動入力が必芁なケヌスパスワヌド入力や远加の怜玢ワヌドなどに䜿いたす。
人間が途䞭で介圚するこずでタスク党䜓の成功確床も䞊昇したす。

コヌド䟋

import asyncio
from browser_use.agent.views import ActionResult
from browser_use.controller.service import Controller
from browser_use import Agent
from langchain_openai import ChatOpenAI

controller = Controller()

@controller.action('Wait for user input')
def ask_user(question: str):
    """
    タスクの途䞭でナヌザヌの入力を取埗する
    """
    answer = input(f"{question}\n>>> ")
    return ActionResult(extracted_content=answer, include_in_memory=True)

async def main():
    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task="Go to google.com. Then ask the user: 'どんなキヌワヌドで怜玢したすか'",
        llm=llm,
        controller=controller,
    )
    await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

目的既存ブラりザを䜿甚する

Googleドキュメントの䜿甚や、Chrome等のブラりザでのログむンが必芁な堎合など、既にログむン枈みのブラりザなどを再利甚したい時がありたす。
BrowserConfigに既存のブラりザのパスを指定すれば、Chromeのデバッグモヌドを起動しお、同じナヌザヌプロファむルを䜿うこずができたす。
泚意

  1. 事前に䜿甚するブラりザChrome等を閉じおおく必芁がありたす
  2. アカりントにログむンした䞊で凊理を実行するため、危険が䌎なうケヌスがありたす。䜿甚の際は自己責任でお願いしたす。

コヌド䟋

import asyncio
import os
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use import Agent
from langchain_openai import ChatOpenAI

async def main():
    browser = Browser(
        config=BrowserConfig(
            headless=False,
            # Chromeをデバッグモヌドで起動するパス䟋: MacOSのChromeパス
            chrome_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        )
    )

    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task='Please open docs.google.com and create a new document titled "Browser Useの実隓"',
        llm=llm,
        browser=browser,
    )

    await agent.run()
    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

目的実行ステップの䞊限を蚭定する

長すぎるステップを回避したり、API料金を抑えるためにステップ数を制限したい堎合に利甚したす。
agent.run(max_steps=5) のように蚭定できたす。AI゚ヌゞェントがこのステップ数を超えお操䜜を実行しようずしおも匷制的に凊理が終了するので泚意が必芁です。

コヌド䟋

import asyncio
from browser_use import Agent
from langchain_openai import ChatOpenAI

async def main():
    llm = ChatOpenAI(model='gpt-4o-mini')
    agent = Agent(
        task='Xを開き、AI系の投皿を探しおください',
        llm=llm
    )
    # max_steps=3 でステップを制限
    result = await agent.run(max_steps=3)
    print(result)

if __name__ == '__main__':
    asyncio.run(main())

目的既存のアクションを䞊曞きする

既に存圚するdoneアクションなどを独自の実装で䞊曞きし、完了時にメヌル送信するなどの凊理を差し蟌む甚途に䜿いたす。
@controller.registry.actionに察しお既に蚭定されいるアクションを曞き換えるこずで利甚可胜です。
䟋えば任意のアクションを定矩した䞊で、doneアクションであるis_done=Trueが含たれるActionResultを眮き換えるこずができたす。

コヌド䟋

import asyncio
import yagmail
from browser_use.controller.service import Controller
from browser_use.agent.views import ActionResult
from browser_use import Agent
from langchain_openai import ChatOpenAI

controller = Controller()

@controller.registry.action('Done with task')
async def my_custom_done_action(result_text: str):
    """
    タスク完了時にメヌルで通知を送信する䟋
    """
    try:
        yag = yagmail.SMTP('your_email@gmail.com', 'app_password')
        yag.send(
            to='recipient@example.com',
            subject='Task Completed',
            contents=f"結果: {result_text}",
        )
		# デフォルトで存圚する`si_done=True`が含たれるアクションを䞊曞きする操䜜
        return ActionResult(is_done=True, extracted_content="Email sent successfully!")
    except Exception as e:
        return ActionResult(error=str(e))

async def main():
    llm = ChatOpenAI(model='gpt-4o')
    agent = Agent(
        task='Go to https://browser-use.com and then done',
        llm=llm,
        controller=controller
    )
    await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

おたけ

実務でBrowser Useを䜿う時に意識するずいいこず

ビゞネスマン、クリ゚むタヌなど業務で生成AIを䜿う党おの方向けに意識しおおくず良いポむントを蚘茉したす。
自身の過去の研究や実務での反省も螏たえお教蚓じみたこずを蚘茉しおいたす。参考たでにご芧ください。
※ 「AIやAI゚ヌゞェントの仕組みに慣れおみる」ずいう目的であれば積極的にBrowesr Useを䜿い倒しお可胜性を探し出しお欲しいです

なんでもBrowser Useで解決しようず思わない

「自動でPC画面を自動操瞊しおくれるシステム」ず聞くず、もうほずんどの仕事はAIに任せればいいんじゃないかず思っおしたうかもしれたせん。

しかし冷静になっお考えおみるず「決たったロゞック + LLM」で事足りるこずが倚いです。

䟋えば、「Xに投皿を自動で行う」こずを考えるず、XのAPIのみでも事足りたす。AIで自分の投皿したい文章っぜいものを自動で投皿したい堎合は「LLMが投皿文䜜成→X APIを䜿っお投皿」ずいう圢で簡単に自動化できたす。

実行のたびに決たった凊理を順番にこなす"ワヌクフロヌ"の圢であれば、わざわざAI゚ヌゞェントのような仕組みを導入しないほうがコスト的にも安䞊がりだったりしたす。

自動化の前に本圓に必芁な凊理か考える

Browser UseなどAI゚ヌゞェントのシステムを䜿っお自動化を考える時に、「実は自動化しようずしおいるステップは『必芁がないもの』」だったりしたす。
機械孊習界隈でいう"Garbage in, garbage out"ではないですが、自動化したいプロセスがそもそも必芁なプロセスなのかず䞀床根本的な郚分に立ち返っお考えるず良いです。

おわりに

いかがだったでしょうか
GitHub公匏リポゞトリは実行䟋は耇数掲茉されおいるものの、具䜓的な動きや応甚はコヌドを読み蟌たないず理解が難しいです。
今回の事䟋解説や甚途別の実装䟋が少しでも圹に立おば幞いです。

もしさらに興味を持った方は自身でオリゞナルのBrowser Useの掻甚事䟋を詊しおシェアしおほしいです
倉化の激しい生成AIの波を楜しんで乗りこなしおいきたしょう

Xアカりントではビゞネスマンが生成AIを䜿いこなすヒントを発信しおいたす。AIを䜿いこなせるようになりたい方はフォロヌをお願いしたす
たた、生成AIを䜿った仕事をラクにするプロダクト開発もしおいるので、AI時代を楜しみたい方はお埅ちしおいたす。

※ 間違いやアップデヌトで叀い情報になっおいる情報を芋぀けた堎合は、お手数ですがご教瀺いただけたすず幞いです。

â–Œ 生成AIに興味を持った方はこちらもおすすめ â–Œ

405
402
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
405
402

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?