「壊れたセレクター」という悪夢
フロントエンドがクラス名を.btn-submitから.btn-primary-v2に変更しただけで、深夜2時に自動化スクリプトのエラーで叩き起こされたことはありませんか?SalesforceやSAP Webのようなモダンなアプリケーションでは、DOM構造が頻繁に変わるため、XPathやCSSセレクターを維持し続けるのは終わりのない戦いです。
従来のツールには致命的な弱点があります。それは「盲目」であることです。これらは人間のようにインターフェースを見るのではなく、ソースコードと対話します。人間が「支払い」ボタンを見るとき、色や位置、文字で認識します。そのIDが#ext-gen-1024であるかどうかは気にしません。
この問題を根本的に解決するため、私はMicrosoftのOmniParserを採用しました。これは、AIエージェントがスクリーンショットを「見」てUIコンポーネントを理解し、HTMLコードを一行も触ることなくPlaywrightに操作を命じる方法です。
OmniParser:AIエージェントの「目」
OmniParserは単なるOCRではありません。これは、画面上のすべてのピクセルをコンピュータが理解できるデータへと構造化する、特化型のコンピュータビジョンモデルです。具体的には、以下の3つの主要なタスクを実行します:
- Detection(検出):アイコン、ボタン、入力フィールドを高精度で自動的に領域抽出します。
- Functional Semantics(機能的意味論):要素の意味を理解します(例:カートのアイコンを「ショッピングカート」として認識)。
- Coordinate Mapping(座標マッピング):Playwrightがクリックできる正確な座標(x, y)を抽出します。
GPT-4oのような強力なビジョンLLMと組み合わせる際、OmniParserは情報フィルタリングの役割を果たします。膨大な画像データを軽量なラベル(labels)に変換することで、複雑なダッシュボードを見てもAIが「混乱」するのを防ぎます。
システムの動作フロー
ハードコーディングする代わりに、私のエージェントは以下の思考ループに従って動作します:
- スクリーンショット撮影:Playwrightが現在の画面をキャプチャします。
- 解析:OmniParserが各ボタンに番号を振り、座標を抽出します。
- 意思決定:LLMが番号付きの画像を受け取り、ユーザーの要求と照らし合わせて操作すべき番号を選択します。
- 実行:Playwrightがその番号に対応する座標をクリックします。
実践的な導入ガイド
1. 環境構築
OmniParserは最適な処理速度を得るためにGPUを必要とします。PlaywrightスクリプトからAPI経由で呼び出せるよう、マイクロサービスとして実行することをお勧めします。
# リポジトリをクローンして環境を構築
git clone https://github.com/microsoft/OmniParser.git
cd OmniParser
pip install -r requirements.txt
実際には、OmniParserをDockerにパッケージ化し、GPU搭載サーバー(RTX 3060やA100など)にデプロイして、画像を1秒未満で処理できるようにしています。
2. Playwrightとコンピュータビジョンの連携
従来のセレクターの代わりに座標を使用してブラウザを制御する方法は以下の通りです:
from playwright.sync_api import sync_playwright
import requests
def get_ui_map(screenshot_path):
# OmniParser APIに画像を送信
with open(screenshot_path, "rb") as f:
response = requests.post("http://localhost:8000/parse", files={"file": f})
return response.json()
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://example-dashboard.com")
# スクリーンショットの撮影と解析
page.screenshot(path="screen.png")
elements = get_ui_map("screen.png")
# OmniParserが認識した「Export」ボタンの座標を取得
target = elements['Export_Button']
page.mouse.click(target['x'], target['y'])
print(f"座標 {target['x']}, {target['y']} をクリックしました")
3. ビジョンエージェントのためのプロンプティング手法
LLMに生の画像を送信しないでください。OmniParserによって番号付きの枠(bounding boxes)が描画された画像を送信してください。効果的なプロンプトの例は以下の通りです:「この画像の中で、『カートに入れる』ボタンは何番ですか?次のJSON形式で回答してください:{‘action’: ‘click’, ‘element_number’: X}」。
実プロジェクトから得られた教訓
私はこのシステムを導入して、50種類の異なるECサイトからデータをクロールしました。以下は重要な数値と留意点です:
- 安定性:UIの軽微な変更でスクリプトが停止することがなくなり、セレクターのメンテナンス時間が80%削減されました。
- レイテンシ(遅延):プロセス全体で1ステップあたり約3〜6秒かかります。これは柔軟性と引き換えのトレードオフであり、ミリ秒単位の速度が求められるタスクには向きません。
- Viewportに関する注意:Playwrightで
device_scale_factor: 1を設定する必要があります。そうしないと、画像上の座標とブラウザ上の実際の座標がずれてしまいます。 - コスト最適化:OmniParserの呼び出しは、ページが大きく変化した際や重要なアクションの後のみに限定します。
なぜこの手法が未来なのか?
DOMからの脱却は、自己学習能力を持つAIエージェントを構築する上で不可欠なステップです。私は、HTMLコードが非常に乱雑な2010年製の古い社内システムでエージェントを試したことがあります。結果は驚くべきものでした。従来のSeleniumスクリプトならデバッグに数時間かかるようなケースでも、エージェントは画像認識によって正しくボタンをクリックできました。
PlaywrightとOmniParserের組み合わせは、単なる新しい技術ではありません。それは、人間が見るのと同じように世界を見る方法をコンピュータに教えるという、パラダイムシフトなのです。
