🤖

Gemini Computer Useを社内システム等のWeb操作自動化で使えるようにサンプル実装を改造してみた

に公開

概要

LLMエージェント系の進化は色々早いですが、少し前Compute Useというブラウザ操作をLLMにやらせる手法が出てきてからかなり一般的になったと思います。
Geminiも(少し遅かった気がしますが)APIでComputer Useを提供しており、Python等をつかったAPIベースでComputer Use特化モデルが使えるようになってます。

僕の仕事の一つに大企業系のDXコンサルみたいなものがあり、大企業の社内システムの自動化等に関わることが多いのですが、
「これが進化していけば社内システムとかをRPAで自動化している業務がかなり楽になるなーとか」とずっと考えていました。
RPAやSeleniumで自動化するとWebサイトの構成が変わるごとにメンテしたりする必要がありますが、これは自然言語でスクショ見て勝手にやり方考えるのでかなり柔軟。いいじゃんってなってました

これが出る前に、Gemini + Playwright MCPで精度を試したことがあるのですが、入力系とかだいぶ酷く、あんまり実用に足るものじゃないなーと思っていたのですが、Compute Useで試したところかなり複雑な指示でも可能になっています。
また、MCPサーバーを起動するのにNodeが必要ですが、大企業で自動化したいPCに様々なソフトウェアをインストールするのは現実的ではありません。Pythonのみで完結させ、pyinstallerなどでexe化して配布したいといった要望がありました。

しかもGemini Pro2.5の料金らしくGemini Flash2.5と比べたら少し高いですが、とんでもない量のブラウザ操作をしなければ普通に安い。

リファレンス実装もあるし使ってみたのですが、リファレンス実装だと少し足りないところがあったので最小で使えるコードに変えました。

リファレンス実装で足りなかったところ

既存ブラウザに繋ぐ

Playwrightにはconnect_over_cdp関数でdebugging_portオプションを有効にして起動したブラウザに接続して操作する選択肢が存在するのですが、リファレンス実装は流石にplaywright installでブラウザをインストールして使う前提になっていました。ただそれだと大企業の社内では結構使えない会社が多い・・・というわけでremote_debugging_portを指定したらconnect_over_cdpするように改造しました。

構造化出力

実際かなり重要なのはこれで、社内システムで自動化するときとかも色々社内システムを操作して情報を集めなければいけないというのがあります。しかし、返ってくるのがテキストだと毎日違う出力がされてしまうという状況になってしまうため、構造化出力が必須です。ですが、構造化出力機能はCompute Useと並行で使えないっぽい。なのでちょっと改造してresponse_schemaを引数でもらえるようにした上で、自作のfunction_callingを定義して最後操作結果を response_schemaで定義した型で引数に入れて実行するよう指示する形式にしました。こうすれば最後エージェントが終わったと判断したら結果を構造化して関数呼び出ししてくれます。

トークン上限

こわいのが、自動化している時にcompute useがバグって無限ループしてしまうという問題。同じサイトにアクセスし続けてスクショ撮りつづけるとかやられてとんでもないAPI料金になるのだけは避けたいです。そのため、max_input_tokenとmax_output_tokenを設定できるようにしてそれを超えたら中断するような仕組みに変更しました。

できた成果物

https://github.com/sonken625/structured-output-gemini-compute-use

実際に使ってみた。

以下の感じでmain.pyを改造して使います。

    query = "googleで東京の天気を検索して何度か教えて"
    api_key = os.getenv("GEMINI_API_KEY")
    

    class WeatherInfo(BaseModel):
        """天気情報のスキーマ"""

        location: str
        temperature: Optional[str] = None
        weather_condition: Optional[str] = None
        additional_info: Optional[str] = None

    # 例3: トークン制限と構造化出力を両方使用
    result = run_agent(
        query=query,
        api_key=api_key,
        max_input_tokens=15000,
        max_output_tokens=10000,
        # remote_debugging_port=9222,
        response_schema=WeatherInfo,
    )

    print("Final Result:", result)

いい感じ

性能実験してみた

余談ですが性能を試すため、僕がLeague Of Legendと呼ばれるゲームをやっているので
「lolalytics(LoLの統計サイト)からジャックス vs イラオイのページ探して最初のコアアイテムがどれがいいのか教えて」という極めて曖昧かつなんの説明もない専門用語だらけの指示で実験してたのですが、この統計サイトは人間が見てもかなり複雑でよくわからない物にも関わらず、10ステップくらいで100%の確率で成功してました。
ただ辿り着く方法が毎回違ったのでそうやっていけんのみたいなものも結構あって面白かったです。

Discussion