Gemini のコンピュータ使用ツールを使用すると、グラフィカル ユーザー インターフェース(GUI)を操作してタスクを自動化するブラウザ、モバイル、デスクトップの制御エージェントを構築できます。コンピュータの使用が有効になっている場合、モデルはスクリーンショットを使用して画面を観察し、マウスのクリック、スクロール、キーボード入力などの特定の UI アクションを生成して動作します。
Gemini は、いくつかの高度なコンピュータ使用機能をサポートしています。
- マルチ環境のサポート: ブラウザ、モバイル、デスクトップ環境用のエージェントを構築します。
- インテントを使用した効率的なアクション: アクションには、各ステップの背後にあるモデルの推論を説明する
intentフィールドが含まれています。 - 構成可能な安全ポリシー: 組み込みのポリシー カテゴリとオーバーライドを使用して、安全動作を微調整します。
- プロンプト インジェクションの検出: スクリーンショットのスキャンを有効にして、隠れた敵対的な指示を検出します。
コンピュータ使用を活用して、次のことができるエージェントを構築できます。
- ウェブサイトやデスクトップ アプリケーションでのデータ入力やフォームへの記入など、繰り返し発生する作業を自動化します。
- ウェブ、モバイル、デスクトップのユーザーフローの自動テストを実行します。
- ウェブサイトやアプリケーションを操作して調査を収集する(商品情報、価格、レビューの比較など)。
- アプリケーション間で複数のステップからなる一連のアクションを実行して、ユーザーを支援します。
このガイドの内容は、次のとおりです。
- コンピュータ使用の仕組み
- コンピュータの使用を有効にする方法
- 環境の設定、リクエストの送信、レスポンスの受信、エージェント ループの構築を行う方法
- サポートされている環境とカスタム関数
- サポートされているコンピュータ アクション
- 安全性とセキュリティのサポート
- 料金
関数呼び出しと同様に、クライアントサイドのアプリケーション コードを記述して、コンピュータ使用関数呼び出しを受信し、対応するアクションを実行する必要があります。
このガイドは、Google Gen AI SDK for Python を使用しており、Playwright API に精通していることを前提としています。
GitHub でコンピュータ使用のリファレンス実装を確認できます。
サポートされているモデル
コンピュータの使用は、次のモデルでサポートされています。
クリックしてサポートされているモデルを開く
コンピュータ使用の仕組み
テキスト レスポンスを生成する代わりに、コンピュータ使用は、マウスのクリックなどの特定の UI アクションを実行するタイミングを判断し、これらのアクションを実行するために必要なパラメータを返します。クライアントサイドのアプリケーション コードを記述して、コンピュータ使用 function_call を受け取り、対応するアクションを実行する必要があります。
コンピュータ使用のインタラクションは、エージェント ループ プロセスに従います。
モデルにリクエストを送信する
- API リクエストに、コンピュータ使用(および必要に応じて別のツール)を追加します。
- ユーザーのリクエストと、GUI の現在の状態を表すスクリーンショットを含むプロンプトをモデルに送信します。
モデル レスポンスを受信する
- モデルはユーザーのリクエストとスクリーンショットを分析し、UI アクションを表す
function_call(「座標(x,y)をクリック」、「テキスト text を入力」など)を含むレスポンスを生成します。モデルで使用できるすべてのアクションの一覧については、サポートされているアクションをご覧ください。 - API レスポンスには、モデルの提案されたアクションをチェックした内部安全システムからの
safety_decisionが含まれる場合もあります。このsafety_decisionは、アクションを次のように分類します。- 通常または許可: アクションは安全であると見なされます。これは、
safety_decisionが存在しないことでも表されます。 - 確認が必要: モデルがリスクの高い操作(「Cookie バナーに同意する」をクリックするなど)を実行しようとしています。
- 通常または許可: アクションは安全であると見なされます。これは、
- モデルはユーザーのリクエストとスクリーンショットを分析し、UI アクションを表す
受信したアクションを実行する
- クライアントサイドのコードは
function_callと、付随するsafety_decisionを受け取ります。 safety_decisionが「通常または許可」を示している場合(またはsafety_decisionが存在しない場合)、クライアントサイドのコードはターゲット環境(ウェブブラウザなど)で指定されたfunction_callを実行できます。safety_decisionが「確認が必要」を示している場合、アプリケーションはfunction_callを実行する前にエンドユーザーに確認を求める必要があります。ユーザーが承認した場合は、アクションの実行に進みます。ユーザーが拒否した場合は、アクションを実行しないでください。
- クライアントサイドのコードは
新しい環境の状態をキャプチャする
- アクションが実行されると、クライアントは GUI の新しいスクリーンショットと現在の URL をキャプチャし、
function_responseの一部としてモデルに送信します。 - アクションが安全システムによってブロックされた場合や、ユーザーによって拒否された場合、アプリはモデルに別の形式のフィードバックを送信するか、インタラクションを終了することがあります。
- アクションが実行されると、クライアントは GUI の新しいスクリーンショットと現在の URL をキャプチャし、
更新された状態で新しいリクエストがモデルに送信されます。ステップ 2 からプロセスが繰り返されます。モデルは、新しいスクリーンショット(提供されている場合)と進行中の目標を使用して、次のアクションを提案します。このループは、タスクが完了するか、エラーが発生するか、プロセスが終了するまで続きます(たとえば、レスポンスが安全フィルタまたはユーザーの決定によってブロックされた場合など)。
次の図は、コンピュータ使用の仕組みを示しています。

コンピュータの使用を有効にする
コンピュータ使用を有効にするには、アプリケーションがサポートされているモデルのいずれかを使用していることを確認し、有効なツールのリストにコンピュータ使用を追加します。
Python
from google import genai from google.genai import types from google.genai.types import Content, Part client = genai.Client( enterprise=True, project="PROJECT_ID", location="global", ) # Add computer use to the list of tools generate_content_config = types.GenerateContentConfig( tools=[ types.Tool( computer_use=types.ComputerUse( environment=types.Environment.ENVIRONMENT_BROWSER, ) ), ] ) contents = [ Content( role="user", parts=[ Part(text="Go to google.com and search for 'weather in New York'"), ], ) ] response = client.models.generate_content( model="gemini-3.8-flash", contents=contents, config=generate_content_config, ) print(response)
Node.js
import { GoogleGenAI, Environment } from '@google/genai'; const ai = new GoogleGenAI({ enterprise: true, project: 'PROJECT_ID', location: 'global', }); const response = await ai.models.generateContent({ model: 'gemini-3.8-flash', contents: "Go to google.com and search for 'weather in New York'", config: { tools: [ { computerUse: { environment: Environment.ENVIRONMENT_BROWSER, }, }, ], }, }); console.log(response);
REST API
curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash:generateContent" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -d '{ "contents": [ { "role": "user", "parts": [ { "text": "Go to google.com and search for '\''weather in New York'\''" } ] } ], "tools": [ { "computer_use": { "environment": "ENVIRONMENT_BROWSER" } } ] }'
実行環境を設定する
コンピュータ ユース ツールを使用して構築する前に、以下を設定します。
- 安全な実行環境: サンドボックス化された仮想マシン(VM)またはコンテナ(Docker など)でエージェントを実行して、ホストシステムから分離します。
- クライアントサイドのアクション ハンドラ: マウスクリック、キーボード ストローク、スクリーンショットのキャプチャを実行するクライアント ロジックを実装します。
まず、SDK とブラウザの依存関係をインストールしてから、環境を構成します。
pip install --upgrade google-genai playwright termcolor playwright install chromium export GOOGLE_CLOUD_PROJECT="PROJECT_ID" export GOOGLE_CLOUD_LOCATION="global" export GOOGLE_GENAI_USE_ENTERPRISE=True
次に、正規化された座標(0 ~ 1000)が正確にスケーリングされるように、明示的なビューポート寸法で Playwright ブラウザ インスタンスを初期化します。
from playwright.sync_api import sync_playwright SCREEN_WIDTH = 1440 SCREEN_HEIGHT = 900 playwright = sync_playwright().start() browser = playwright.chromium.launch(headless=False) context = browser.new_context( viewport={"width": SCREEN_WIDTH, "height": SCREEN_HEIGHT} ) page = context.new_page() page.goto("https://www.google.com")
リクエストを送信する
コンピュータ使用ツールを構成したら、ユーザーの目標と GUI の最初のスクリーンショットを含むプロンプトをモデルに送信します。
必要に応じて、次の情報を追加することもできます。
- 除外するアクション: サポートされている UI アクションのリストに、モデルに実行させたくないアクションがある場合は、
excluded_predefined_functionsでこれらのアクションを指定します。 - ユーザー定義関数: コンピュータの使用に加えて、カスタムのユーザー定義関数を含めることもできます。
次のサンプルコードは、コンピュータの使用を有効にして、モデルにリクエストを送信します。
Python
from google import genai from google.genai import types from google.genai.types import Content, Part client = genai.Client() # Specify predefined functions to exclude (optional) excluded_functions = ["drag_and_drop"] # Configuration for computer use with browser environment generate_content_config = genai.types.GenerateContentConfig( tools=[ # 1. Computer Use tool with browser environment types.Tool( computer_use=types.ComputerUse( environment=types.Environment.ENVIRONMENT_BROWSER, # Optional: Exclude specific predefined functions excluded_predefined_functions=excluded_functions ) ), # 2. Optional: Custom user-defined functions (need to defined above) # types.Tool( # function_declarations=custom_functions # ) ], ) # Create the content with user message contents: list[Content] = [ Content( role="user", parts=[ Part(text="Search for highly rated smart fridges with touchscreen, 2 doors, around 25 cu ft, priced below 4000 dollars on Google Shopping. Create a bulleted list of the 3 cheapest options in the format of name, description, price in an easy-to-read layout."), # Optional: include a screenshot of the initial state # Part.from_bytes( # data=screenshot_image_bytes, # mime_type='image/png', # ), ], ) ] # Generate content with the configured settings response = client.models.generate_content( model='gemini-3.8-flash', contents=contents, config=generate_content_config, ) # Print the response output print(response.text)
カスタム ユーザー定義関数を含めて、モデルの機能を拡張することもできます。ブラウザ固有のアクションを除外しながら、open_app、long_press_at、go_home などのアクションを追加してモバイル ユースケースのコンピュータの使用状況を構成する方法については、Gemini 3.5 Flash 以降とモバイルまたはデスクトップのユースケースをご覧ください。
レスポンスの受信
モデルは、タスクを完了するために UI アクションまたはユーザー定義関数が必要であると判断した場合、1 つ以上の FunctionCalls を返します。アプリのコードで、これらのアクションを解析して実行し、結果を収集する必要があります。コンピュータ使用は並列関数呼び出しをサポートしています。つまり、モデルは 1 回のターンで複数の独立したアクションを返すことができます。
Gemini 3.5 Flash 以降のモデルでは、各アクションに intent 引数が含まれており、そのステップの背後にあるモデルの推論が説明されています。
{ "content": { "parts": [ { "function_call": { "name": "type", "args": { "x": 450, "y": 320, "text": "smart fridge touchscreen 2 doors 25 cu ft under $4000", "press_enter": true, "intent": "Type the search query into the Google search box and submit." } } } ] } }
アクションによっては、API レスポンスで関数呼び出し引数内に safety_decision が返されることもあります。
{ "content": { "parts": [ { "function_call": { "name": "click", "args": { "x": 60, "y": 100, "intent": "Click the 'I'm not a robot' verification checkbox.", "safety_decision": { "explanation": "I have encountered a CAPTCHA challenge that requires interaction. I need you to complete the challenge by clicking the 'I'm not a robot' checkbox and any subsequent verification steps.", "decision": "require_confirmation" } } } } ] } }
受信したアクションを実行する
レスポンスを受け取ったら、function_call を解析し、正規化された 0 ~ 1000 のグリッドから実際のビューポートのピクセル寸法に座標をスケーリングして、アクションを実行します。
import time
from typing import Any, Dict, List, Tuple
import termcolor
def denormalize_x(x: int, screen_width: int) -> int:
"""Convert normalized x coordinate (0-1000) to actual pixel coordinate."""
return int(x / 1000 * screen_width)
def denormalize_y(y: int, screen_height: int) -> int:
"""Convert normalized y coordinate (0-1000) to actual pixel coordinate."""
return int(y / 1000 * screen_height)
def get_safety_confirmation(safety_decision: Dict[str, Any]) -> str:
"""Prompt user for confirmation when safety check is triggered."""
termcolor.cprint("Safety service requires explicit confirmation!", color="red")
print(safety_decision.get("explanation", ""))
decision = ""
while decision.lower() not in ("y", "n", "ye", "yes", "no"):
decision = input("Do you wish to proceed? [Y]es/[N]o\n")
if decision.lower() in ("n", "no"):
return "TERMINATE"
return "CONTINUE"
def execute_function_calls(
response, page, screen_width: int, screen_height: int
) -> List[Tuple[str, Dict[str, Any]]]:
"""Extract and execute modern and legacy function calls from Gemini response."""
candidate = response.candidates[0]
function_calls = []
thoughts = []
for part in candidate.content.parts:
if hasattr(part, "function_call") and part.function_call:
function_calls.append(part.function_call)
elif hasattr(part, "text") and part.text:
thoughts.append(part.text)
if thoughts:
print(f"Model Reasoning: {' '.join(thoughts)}")
results: List[Tuple[str, Dict[str, Any]]] = []
for function_call in function_calls:
fname = function_call.name
args = function_call.args or {}
action_result: Dict[str, Any] = {}
print(f" -> Executing: {fname} (Intent: {args.get('intent', 'N/A')})")
# Check for safety decision before executing
if "safety_decision" in args:
decision = get_safety_confirmation(args["safety_decision"])
if decision == "TERMINATE":
print("Terminating agent loop")
break
action_result["safety_acknowledgement"] = "true"
try:
if fname in ("open_web_browser", "open_app", "take_screenshot"):
pass
elif fname in (
"click",
"click_at",
"double_click",
"triple_click",
"middle_click",
"right_click",
"mouse_down",
"mouse_up",
"move",
"hover_at",
):
actual_x = denormalize_x(args["x"], screen_width)
actual_y = denormalize_y(args["y"], screen_height)
if fname in ("click", "click_at"):
page.mouse.click(actual_x, actual_y)
elif fname == "double_click":
page.mouse.dblclick(actual_x, actual_y)
elif fname == "triple_click":
page.mouse.click(actual_x, actual_y, click_count=3)
elif fname == "middle_click":
page.mouse.click(actual_x, actual_y, button="middle")
elif fname == "right_click":
page.mouse.click(actual_x, actual_y, button="right")
elif fname == "mouse_down":
page.mouse.move(actual_x, actual_y)
page.mouse.down()
elif fname == "mouse_up":
page.mouse.move(actual_x, actual_y)
page.mouse.up()
elif fname in ("move", "hover_at"):
page.mouse.move(actual_x, actual_y)
elif fname in ("type", "type_text_at"):
actual_x = denormalize_x(args["x"], screen_width) if "x" in args else None
actual_y = denormalize_y(args["y"], screen_height) if "y" in args else None
text = args["text"]
press_enter = args.get("press_enter", False)
clear_before_typing = args.get("clear_before_typing", True)
if actual_x is not None and actual_y is not None:
page.mouse.click(actual_x, actual_y)
time.sleep(0.1)
if clear_before_typing:
page.keyboard.press("ControlOrMeta+A")
page.keyboard.press("Backspace")
page.keyboard.type(text)
if press_enter:
page.keyboard.press("Enter")
elif fname in ("scroll", "scroll_at", "scroll_document"):
if "x" in args and "y" in args:
page.mouse.move(denormalize_x(args["x"], screen_width), denormalize_y(args["y"], screen_height))
direction = args.get("direction", "down")
magnitude = args.get("magnitude_in_pixels", args.get("magnitude", 300))
dx, dy = 0, 0
if direction == "down":
dy = magnitude
elif direction == "up":
dy = -magnitude
elif direction == "right":
dx = magnitude
elif direction == "left":
dx = -magnitude
page.mouse.wheel(dx, dy)
elif fname == "drag_and_drop":
start_x = denormalize_x(args.get("start_x", args.get("x", 0)), screen_width)
start_y = denormalize_y(args.get("start_y", args.get("y", 0)), screen_height)
end_x = denormalize_x(args.get("end_x", args.get("destination_x", 0)), screen_width)
end_y = denormalize_y(args.get("end_y", args.get("destination_y", 0)), screen_height)
page.mouse.move(start_x, start_y)
page.mouse.down()
page.mouse.move(end_x, end_y)
page.mouse.up()
elif fname == "press_key":
page.keyboard.press(args["key"])
elif fname == "key_down":
page.keyboard.down(args["key"])
elif fname == "key_up":
page.keyboard.up(args["key"])
elif fname == "hotkey":
page.keyboard.press("+".join(args.get("keys", [])))
elif fname == "key_combination":
page.keyboard.press(args["keys"])
elif fname == "navigate":
page.goto(args["url"])
elif fname == "search":
page.goto("https://www.google.com")
elif fname == "go_back":
page.go_back()
elif fname == "go_forward":
page.go_forward()
elif fname in ("wait", "wait_5_seconds"):
time.sleep(5 if fname == "wait_5_seconds" else args.get("seconds", 1))
else:
action_result["warning"] = f"unhandled_function: {fname}"
page.wait_for_load_state(timeout=5000)
time.sleep(1)
except Exception as e:
print(f"Error executing {fname}: {e}")
action_result["error"] = str(e)
results.append((fname, action_result))
return results
返された safety_decision が require_confirmation の場合は、アクションの実行に進む前に、ユーザーに確認を求める必要があります。利用規約に基づき、人間による確認のリクエストを回避することは許可されていません。
新しい状態をキャプチャする
アクションを実行したら、各アクションの結果と更新されたスクリーンショットを FunctionResponse にパッケージ化してモデルに返します。
from google.genai import types from google.genai.types import Content, FunctionResponse, Part def get_function_responses( page, results: List[Tuple[str, Dict[str, Any]]] ) -> Content: """Capture screenshot and URL and package them as FunctionResponses.""" screenshot = page.screenshot(type="png") current_url = page.url function_response_parts = [] for name, action_result in results: function_response_parts.append( Part( function_response=FunctionResponse( name=name, response={ "url": current_url, **action_result, }, parts=[ types.FunctionResponsePart( inline_data=types.FunctionResponseBlob( mime_type="image/png", data=screenshot, ) ) ], ) ) ) return Content( role="user", parts=function_response_parts, )
エージェント ループを作成する
これらのステップを、モデルと実行環境の間で継続的に反復処理するエンドツーエンドのループにまとめます。
Python
from google import genai from google.genai import types from google.genai.types import Content, Part from playwright.sync_api import sync_playwright def has_function_calls(response) -> bool: """Check if model response contains any function calls.""" candidate = response.candidates[0] return any( hasattr(part, "function_call") and part.function_call for part in candidate.content.parts ) def main(): client = genai.Client( enterprise=True, project="PROJECT_ID", location="global", ) generate_content_config = types.GenerateContentConfig( tools=[ types.Tool( computer_use=types.ComputerUse( environment=types.Environment.ENVIRONMENT_BROWSER, enable_prompt_injection_detection=True, ) ) ], ) screen_width, screen_height = 1440, 900 with sync_playwright() as p: browser = p.chromium.launch(headless=False) context = browser.new_context( viewport={"width": screen_width, "height": screen_height} ) page = context.new_page() page.goto("https://www.google.com") initial_screenshot = page.screenshot(type="png") contents: list[Content] = [ Content( role="user", parts=[ Part(text="Search for flights from San Francisco to Honolulu departing June 30 and returning July 6."), Part.from_bytes(data=initial_screenshot, mime_type="image/png"), ], ) ] # Agent loop: iterate until model provides a final text response for iteration in range(10): print(f"\n--- Iteration {iteration + 1} ---") response = client.models.generate_content( model="gemini-3.8-flash", contents=contents, config=generate_content_config, ) contents.append(response.candidates[0].content) if not has_function_calls(response): print(f"FINAL RESPONSE:\n{response.text}") break results = execute_function_calls(response, page, screen_width, screen_height) if not results: break user_feedback_content = get_function_responses(page, results) contents.append(user_feedback_content) browser.close() if __name__ == "__main__": main()
Gemini 3.5 Flash 以降、モバイルまたはパソコンのユースケース
パソコンの使用では、モバイル(ENVIRONMENT_MOBILE)、デスクトップ(ENVIRONMENT_DESKTOP)、ブラウザ(ENVIRONMENT_BROWSER)の環境を設定できます。デフォルトは ENVIRONMENT_BROWSER です。
次の例は、Gemini 3.5 Flash 以降でコンピュータを使用するための実行環境を構成する方法を示しています。
REST API
リクエストのデータを使用する前に、次のように置き換えます。
- PROJECT_ID: プロジェクト ID。
HTTP メソッドと URL:
POST https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.5-flash:generateContent
リクエストの本文(JSON):
{
"contents": [
{
"role": "user",
"parts": {
"text": "find me a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th. start by navigating directly to flights.google.com"
}
}
],
"generation_config": {
"candidateCount": 1
},
"tools": [
{
"computer_use": {
"environment": "ENVIRONMENT_BROWSER"
}
}
]
}
リクエストを送信するには、次のいずれかのオプションを展開します。
成功したことを示すステータス コード(2xx)と空のレスポンスが返されます。
Python
次の例では、python-genai バージョン 2.7.0 以降が必要です。
from google import genai
from google.genai.types import (
Part,
GenerateContentConfig,
Content,
Tool,
ComputerUse,
Environment,
ThinkingConfig,
)
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.6-flash",
contents=[
Content(
role="user",
parts=[
Part(text="find me a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th"),
],
)
],
config=GenerateContentConfig(
temperature=1,
top_p=0.95,
top_k=40,
max_output_tokens=8192,
tools=[
Tool(
computer_use=ComputerUse(
environment=Environment.ENVIRONMENT_MOBILE
),
),
],
thinking_config=ThinkingConfig(
include_thoughts=True
),
)
)
カスタムのユーザー定義関数
computer_use とカスタム ユーザー定義関数(function_declarations)を組み合わせることで、モデルの機能を拡張できます。たとえば、人間参加型(HITL)シナリオでは、excluded_predefined_functions を使用して特定の事前定義アクションを除外し、カスタム yield_to_user 関数を登録して、2FA プロンプトやあいまいな画面に遭遇したときにエージェントが制御を人間に戻すようにできます。
Python
from google import genai from google.genai import types from google.genai.types import Content, Part client = genai.Client() def yield_to_user(reason: str) -> dict[str, str]: """Yields control back to the user for assistance or verification when an automated action is unsafe or ambiguous. Args: reason: The reason why the agent is yielding control to the human. """ return {"status": "yielded", "reason": reason} generate_content_config = types.GenerateContentConfig( tools=[ types.Tool( computer_use=types.ComputerUse( environment=types.Environment.ENVIRONMENT_BROWSER, excluded_predefined_functions=["drag_and_drop"], ) ), types.Tool( function_declarations=[ types.FunctionDeclaration.from_callable( client=client, callable=yield_to_user ) ] ), ] ) response = client.models.generate_content( model="gemini-3.8-flash", contents=[ Content( role="user", parts=[ Part( text="Click the submit button. If you need a second-factor authentication code, ask me." ), ], ) ], config=generate_content_config, ) print(response)
サポートされているアクション
コンピュータ使用ツールを使用すると、モデルは FunctionCall を使用して次のアクションをリクエストできます。クライアントサイドのコードで、これらのアクションの実行ロジックを実装する必要があります。例については、リファレンス実装をご覧ください。次の表に、ブラウザ環境でサポートされているアクションを示します。Gemini 3 Flash と Gemini 3.5 Flash 以降のモデルでは、FunctionCall 名セットが異なります。
Gemini 3.5 Flash 以降
Gemini 3.5 Flash: 選択した環境に応じて、異なる関数呼び出しのセットにアクセスできます。ブラウザ環境
| コマンド名 | 説明 | 引数(関数呼び出し内) |
|---|---|---|
click |
指定された座標を左クリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
double_click |
指定された座標をダブルクリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
triple_click |
指定された座標をトリプルクリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
middle_click |
指定された座標を中央クリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
right_click |
指定した座標を右クリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
mouse_down |
座標でマウスボタンを長押しします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
mouse_up |
座標でマウスボタンを離します。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
move |
カーソルを指定した位置に移動します。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
type |
テキストを入力します(必要に応じて、最初に x、y をクリックします)。 |
y: int(0 ~ 999、省略可)x: int(0 ~ 999、省略可)text: strpress_enter: bool(省略可、デフォルトは false)intent: str
|
drag_and_drop |
(start_x, start_y) から (end_x, end_y) にアイテムをドラッグします。 |
start_y: int(0 ~ 999)start_x: int(0 ~ 999)end_y: int(0 ~ 999)end_x: int(0 ~ 999)intent: str
|
wait |
指定された秒数だけ待機します。 |
seconds: int(省略可、デフォルトは 1)intent: str
|
press_key |
指定されたキーを押して離します。 |
key: strintent: str
|
key_down |
指定されたキーを長押しします。 |
key: strintent: str
|
key_up |
指定されたキーを解放します。 |
key: strintent: str
|
hotkey |
指定されたキーの組み合わせを押します。 |
keys: List[str]intent: str
|
take_screenshot |
現在の画面のスクリーンショットを返します。 | intent: str |
scroll |
指定した座標で、指定したピクセル距離だけ上下左右にスクロールします。 |
y: int(0 ~ 999)x: int(0 ~ 999)direction: str(up、down、left、right)magnitude_in_pixels: int(0 ~ 999、省略可、デフォルトは 300)intent: str
|
open_web_browser |
ウェブブラウザを開きます。 | intent: str |
navigate |
ブラウザを指定された URL に直接移動します。 |
url: strintent: str
|
go_back |
ブラウザの履歴の前のウェブページに戻ります。 | intent: str |
go_forward |
ブラウザの閲覧履歴の次のウェブページに移動します。 | intent: str |
モバイル環境
| コマンド名 | 説明 | 引数(関数呼び出し内) |
|---|---|---|
open_app |
名前でアプリケーションを開きます。 | intent: str |
click |
座標を左クリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
list_apps |
デバイスで利用可能なアプリを一覧表示し、その名前とパッケージ名を返します。 | intent: str |
wait |
指定された秒数だけ待機します。 |
intent: strseconds: int(省略可、デフォルトは 1)
|
go_back |
ブラウザの履歴の前のウェブページに戻ります。 | intent: str |
type |
テキストを入力します。 |
text: strintent: strpress_enter: bool(省略可、デフォルトは false)
|
drag_and_drop |
start_y と start_x から end_y と end_x にアイテムをドラッグします。 |
start_y: int(0 ~ 999)start_x: int(0 ~ 999)end_y: int(0 ~ 999)end_x: int(0 ~ 999)intent: str
|
long_press |
画面上の特定の y(0 ~ 999)、x(0 ~ 999)座標を長押しします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: strseconds: int(省略可、デフォルトは 2)
|
press_key |
指定されたキーを押して離します。 |
key: strintent: str
|
take_screenshot |
現在の画面のスクリーンショットを返します。 | intent: str |
デスクトップ環境
| コマンド名 | 説明 | 引数(関数呼び出し内) |
|---|---|---|
click |
座標を左クリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
double_click |
座標をダブルクリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
triple_click |
座標をトリプルクリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
middle_click |
座標を中ボタンでクリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
right_click |
座標を右クリックします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
mouse_down |
座標でマウスボタンを長押しします。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
mouse_up |
座標でマウスボタンを離します。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
move |
指定した位置にカーソルを移動します。 |
y: int(0 ~ 999)x: int(0 ~ 999)intent: str
|
type |
テキストを入力します。 |
text: strintent: strpress_enter: bool(省略可、デフォルトは false)
|
drag_and_drop |
start_y と start_x から end_y と end_x にアイテムをドラッグします。 |
start_y: int(0 ~ 999)start_x: int(0 ~ 999)end_y: int(0 ~ 999)end_x: int(0 ~ 999)intent: str
|
wait |
指定した秒数だけ待機します。 |
intent: strseconds: int(省略可、デフォルトは 1)
|
press_key |
指定されたキーを押して離します。 |
key: strintent: str
|
key_down |
指定されたキーを長押しします。 |
key: strintent: str
|
key_up |
指定されたキーを解放します。 |
key: strintent: str
|
hotkey |
指定されたキーの組み合わせを押します。 |
keys: List[str]intent: str
|
take_screenshot |
現在の画面のスクリーンショットを返します。 | intent: str |
scroll |
座標で上下左右にピクセル単位でスクロールします。 |
y: int(0 ~ 999)x: int(0 ~ 999)direction: str(up、down、left、right)intent: strmagnitude_in_pixels: int(0 ~ 999、省略可、デフォルトは 300)
|
Gemini 3 Flash
| コマンド名 | 説明 | 引数(関数呼び出し内) | 関数呼び出しの例 |
|---|---|---|---|
| open_web_browser | ウェブブラウザを開きます。 | なし | {"name": "open_web_browser", "args": {}} |
| wait_5_seconds | 動的コンテンツの読み込みやアニメーションの完了を待つため、実行を 5 秒間一時停止します。 | なし | {"name": "wait_5_seconds", "args": {}} |
| go_back | ブラウザの履歴の前のページに移動します。 | なし | {"name": "go_back", "args": {}} |
| go_forward | ブラウザの履歴の次のページに移動します。 | なし | {"name": "go_forward", "args": {}} |
| search | デフォルトの検索エンジン(Google など)のホームページに移動します。新しい検索タスクを開始するのに便利です。 | なし | {"name": "search", "args": {}} |
| navigate | ブラウザを指定された URL に直接移動します。 | url: str |
{"name": "navigate", "args": {"url": "https://www.wikipedia.org"}}
|
| click_at | ウェブページの特定の座標をクリックします。x 値と y 値は 1000x1000 のグリッドに基づいており、画面の寸法に合わせてスケーリングされます。 | y: int(0~999)、x: int(0~999) |
{"name": "click_at", "args": {"y": 300, "x": 500}}
|
| hover_at | 521963309 ウェブページの特定の座標にマウスを移動します。サブメニューを表示するのに役立ちます。x と y は 1000x1000 のグリッドに基づいています。 | y: int(0~999)、x: int(0~999) |
{"name": "hover_at", "args": {"y": 150, "x": 250}}
|
| type_text_at | 特定の座標にテキストを入力します。デフォルトでは、まずフィールドをクリアしてから入力後に Enter キーを押しますが、これらの動作は無効にできます。x と y は 1000x1000 のグリッドに基づいています。 |
y: int(0 ~ 999)、x: int(0 ~ 999)、text: str、press_enter: bool(省略可、デフォルトは True)、clear_before_typing: bool(省略可、デフォルトは True) |
{"name": "type_text_at", "args": {"y": 250, "x": 400,
"text": "search query", "press_enter": false}}
|
| key_combination | Control+C や Enter などのキーまたはキーの組み合わせを押します。アクション(Enter キーによるフォームの送信など)やクリップボード操作のトリガーに役立ちます。 |
keys: str(例: enter、control+c。許可されているキーの完全なリストについては、API リファレンスをご覧ください) |
{"name": "key_combination", "args": {"keys":
"Control+A"}}
|
| scroll_document | ウェブページ全体を上、下、左、右にスクロールします。 | direction: str(up、down、left、right) |
{"name": "scroll_document", "args": {"direction": "down"}}
|
| scroll_at | 指定された要素または領域の座標(x, y)を、指定された方向に一定の大きさだけスクロールします。座標と大きさ(デフォルトは 800)は 1000x1000 のグリッドに基づいています。 |
y: int(0 ~ 999)、x: int(0 ~ 999)、direction: str(up、down、left、right)、magnitude: int(0 ~ 999、省略可、デフォルトは 800) |
{"name": "scroll_at", "args": {"y": 500, "x": 500,
"direction": "down", "magnitude": 400}}
|
| drag_and_drop | 要素を開始座標 (x, y) からドラッグして、宛先座標 (destination_x, destination_y) にドロップします。すべての座標は 1000x1000 のグリッドに基づいています。 |
y: int(0 ~ 999)、x: int(0 ~ 999)、destination_y: int(0 ~ 999)、destination_x: int(0 ~ 999) |
{"name": "drag_and_drop", "args": {"y": 100, "x": 100,
"destination_y": 500, "destination_x": 500}}
|
安全とセキュリティ
このセクションでは、ユーザーの制御を強化し、安全性を高めるために、コンピュータ使用ツールに組み込まれている保護機能について説明します。また、このツールがもたらす可能性のある新たなリスクを軽減するためのベスト プラクティスについても説明します。
安全性の判断を確認する
アクションによっては、モデルからのレスポンスに内部安全システムの safety_decision が含まれることがあります。この決定により、ツールが安全性について提案したアクションが検証されます。
{
"content": {
"parts": [
{
"text": "I have evaluated step 2. It seems Google detected unusual traffic and is asking me to verify I'm not a robot. I need to click the 'I'm not a robot' checkbox located near the top left (y=98, x=95)."
},
{
"function_call": {
"name": "click_at",
"args": {
"x": 60,
"y": 100,
"safety_decision": {
"explanation": "I have encountered a CAPTCHA challenge that requires interaction. I need you to complete the challenge by clicking the 'I'm not a robot' checkbox and any subsequent verification steps.",
"decision": "require_confirmation"
}
}
}
}
]
}
}
safety_decision が require_confirmation の場合は、アクションの実行に進む前に、エンドユーザーに確認を求める必要があります。
次のコードサンプルでは、アクションを実行する前に確認を求めるプロンプトが表示されます。ユーザーがアクションを確認しない場合、ループは終了します。ユーザーがアクションを確認すると、アクションが実行され、safety_acknowledgement フィールドが True としてマークされます。
import termcolor
def get_safety_confirmation(safety_decision):
"""Prompt user for confirmation when safety check is triggered."""
termcolor.cprint("Safety service requires explicit confirmation!", color="red")
print(safety_decision["explanation"])
decision = ""
while decision.lower() not in ("y", "n", "ye", "yes", "no"):
decision = input("Do you wish to proceed? [Y]es/[N]o\n")
if decision.lower() in ("n", "no"):
return "TERMINATE"
return "CONTINUE"
def execute_function_calls(response, page, screen_width: int, screen_height: int):
# ... Extract function calls from response ...
for function_call in function_calls:
extra_fr_fields = {}
# Check for safety decision
if 'safety_decision' in function_call.args:
decision = get_safety_confirmation(function_call.args['safety_decision'])
if decision == "TERMINATE":
print("Terminating agent loop")
break
extra_fr_fields["safety_acknowledgement"] = "true" # Safety acknowledgement
# ... Execute function call and append to results ...
ユーザーが確認した場合は、FunctionResponse に安全に関する確認事項を含める必要があります。
function_response_parts.append(
FunctionResponse(
name=name,
response={"url": current_url,
**extra_fr_fields}, # Include safety acknowledgement
parts=[
types.FunctionResponsePart(
inline_data=types.FunctionResponseBlob(
mime_type="image/png", data=screenshot
)
)
]
)
)
プロンプト インジェクションの検出
Gemini 3.5 Flash 以降のコンピュータ使用は、プロンプト インジェクション攻撃を検出する高度な安全性メカニズムをサポートしています。この機能を有効にすると、含まれているスクリーンショットにプロンプト インジェクション攻撃を導入する可能性があるかどうかがチェックされます。この機能は、コンピュータの使用構成で設定できます。デフォルトは false です。
次の例は、コンピュータの使用構成を有効にして、プロンプト インジェクションの検出を有効にする方法を示しています。
REST API
リクエストのデータを使用する前に、次のように置き換えます。
- PROJECT_ID: プロジェクト ID。
HTTP メソッドと URL:
POST https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.5-flash:generateContent
リクエストの本文(JSON):
{
"contents": [
{
"role": "user",
"parts": {
"text": "find me a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th. start by navigating directly to flights.google.com"
}
}
],
"generation_config": {
"candidateCount": 1
},
"tools": [
{
"computer_use": {
"environment": "ENVIRONMENT_BROWSER",
"enable_prompt_injection_detection": true
}
}
]
}
リクエストを送信するには、次のいずれかのオプションを展開します。
成功したことを示すステータス コード(2xx)と空のレスポンスが返されます。
Python
次の例では、python-genai バージョン 2.7.0 以降が必要です。
from google import genai
from google.genai.types import (
Part,
GenerateContentConfig,
Content,
Tool,
ComputerUse,
Environment,
ThinkingConfig,
)
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.6-flash",
contents=[
Content(
role="user",
parts=[
Part(text="find me a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th"),
],
)
],
config=GenerateContentConfig(
temperature=1,
top_p=0.95,
top_k=40,
max_output_tokens=8192,
tools=[
Tool(
computer_use=ComputerUse(
environment=Environment.ENVIRONMENT_MOBILE,
enable_prompt_injection_detection=True
),
),
],
thinking_config=ThinkingConfig(
include_thoughts=True
),
)
)
安全に使用するためのおすすめの方法
コンピュータの使用には、デベロッパーが注意すべきリスクがあります。
- 信頼できないコンテンツと詐欺: モデルがユーザーの目標を達成しようとする際に、信頼できない情報源や画面上の指示に依存する可能性があります。
- 意図しないアクションが起こる可能性: モデルがユーザーの目標やウェブページの内容を誤って解釈し、間違ったボタンをクリックしたり、間違ったフォームに記入するなどの誤ったアクションを実行する可能性があります。
- ポリシー違反: API の機能が、CAPTCHA のバイパスやシステムの整合性の侵害など、Google の利用規約やポリシーに違反するアクティビティに使用される可能性があります。
これらのリスクに対処するには、次の安全対策とベスト プラクティスを実装する必要があります。
- 人間参加型(HITL):
- ユーザー確認を実装する: 安全レスポンスで
require_confirmationが示されている場合は、実行前にユーザー確認を実装する必要があります。 - カスタムの安全指示を提供する: 組み込みのユーザー確認チェックに加えて、デベロッパーは、独自の安全ポリシーを適用するカスタム システム指示を追加することもできます。これにより、特定のモデル アクションをブロックしたり、モデルが特定の重大な不可逆アクションを実行する前にユーザー確認を要求したりできます。
クリックしてカスタムの安全システム指示の例を表示
## **RULE 1: Seek User Confirmation (USER_CONFIRMATION)** This is your first and most important check. If the next required action falls into any of the following categories, you MUST stop immediately, and seek the user's explicit permission. **USER_CONFIRMATION Categories:** * **Consent and Agreements:** Terms of Service, Privacy Policies, Cookie banners. * **Robot Detection:** CAPTCHAs of any kind. * **Financial Transactions:** Completing purchases or moving funds. * **Sending Communications:** Emails, forum posts, or chat messages. * **Accessing/Modifying Sensitive Information:** Healthcare, financial, or ID records. * **User Data Management:** Downloading files, transferring user data. * **Browser Data Usage:** Chrome history, bookmarks, autofill passwords. * **Security and Identity:** Logging into accounts or impersonation. ## **RULE 2: Default Behavior (ACTUATE)** If an action does NOT fall under USER_CONFIRMATION, proactively perform all necessary steps to move the user's request forward.
- ユーザー確認を実装する: 安全レスポンスで
- 安全な実行環境: 安全なサンドボックス環境でエージェントを実行して、潜在的な影響を制限します。たとえば、サンドボックス化された仮想マシン(VM)、コンテナ(Docker など)、権限が制限された専用のブラウザ プロファイルなどを使用します。
- 入力のサニタイズ: プロンプト内のユーザーが生成したすべてのテキストをサニタイズして、意図しない指示やプロンプト インジェクションのリスクを軽減します。これはセキュリティの有用なレイヤですが、安全な実行環境の代わりにはなりません。
- コンテンツ ガードレール: ガードレールとコンテンツ安全性 API(Model Armor など)を使用して、ユーザー入力、ツールの入力と出力、エージェントのレスポンスを評価し、適切性、プロンプト インジェクション、ジェイルブレイクを検出します。
- 許可リストとブロックリスト: モデルが移動できる場所と実行できる操作を制御するフィルタリング メカニズムを実装します。禁止されているウェブサイトのブロックリストは適切な出発点ですが、より制限の厳しい許可リストを使用することで安全性を高めることができます。
- オブザーバビリティとロギング: デバッグ、監査、インシデント対応のために詳細なログを保持します。クライアントは、プロンプト、スクリーンショット、モデルが提案したアクション(
function_call)、安全性に関するレスポンス、クライアントが最終的に実行したすべてのアクションをログに記録する必要があります。 - 環境管理: GUI 環境の一貫性を確保します。予期しないポップアップ、システム通知、レイアウトのずれは、モデルを混乱させる可能性があります。可能な場合は、新しいタスクごとに既知のクリーンな状態から開始します。
人間参加型(HITL)の確認
人間参加型(HITL)確認は、モデルが提案したアクションを実行する前にユーザーの確認を求めるプロセスです。このプロセスは、安全上の懸念によりモデルがアクションを実行できない場合に必要です。
Gemini のコンピュータ使用ツールには、HITL 確認を制御するための次のメカニズムが用意されています。
- デベロッパー レベル: デベロッパーは、デフォルトの HITL 確認の一部またはすべてを適用するかどうかを構成できます。
- 組織レベル: 組織管理者は、個々のデベロッパーが一部またはすべての HITL 確認を無効にできないようにする組織レベルのポリシーを作成できます。このポリシーは、デベロッパー レベルの設定よりも優先されます。
HITL の確認をオーバーライドする
次のデフォルトの HITL 確認をオーバーライドできます。
FINANCIAL_TRANSACTIONS: 金融取引の最終ステップの完了(支払い、振込、郵便為替の発行、サブスクリプションの開始または変更、予約の完了など)。SENSITIVE_DATA_MODIFICATION: 医療、財務、政府機関の記録など、機密情報の変更。COMMUNICATION_TOOL: 通信を送信、共有、投稿、またはその他の方法で送信するための通信ツールへのアクセスまたは使用。ACCOUNT_CREATION: 新規ユーザー アカウントまたはサービス アカウントを作成またはプロビジョニングする登録フローまたは登録フローとのやり取り。DATA_MODIFICATION: 閲覧データまたはファイルの変更、管理、共有、保存、送信、削除。USER_CONSENT_MANAGEMENT: ユーザーの同意ダイアログまたはバナーを操作して、決定を行います。LEGAL_TERMS_AND_AGREEMENTS: 利用規約の同意、プライバシー ポリシーのダイアログ、法的通知など、法的拘束力のある契約ダイアログとのやり取り。
これらの HITL 確認の一部またはすべてをオーバーライドするには、コンピュータ使用構成の disabled_safety_policies フィールドにリストします。
Python
GenerateContent API
generate_content_config = genai.types.GenerateContentConfig(
tools=[
types.Tool(
computer_use=types.ComputerUse(
environment=types.Environment.ENVIRONMENT_MOBILE,
disabled_safety_policies=[
types.SafetyPolicy.FINANCIAL_TRANSACTIONS,
types.SafetyPolicy.COMMUNICATION_TOOL,
]
)
),
],
)
contents = [
types.Content(
role="user",
parts=[
types.Part(text="Open the Maps app and find the nearest coffee shop."),
],
)
]
response = client.models.generate_content(
model='gemini-3.5-flash',
contents=contents,
config=generate_content_config,
)Interactions API
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model='gemini-3.5-flash',
input='Open the Maps app and find the nearest coffee shop.',
tools=[
{
'type': 'computer_use',
'environment': 'mobile',
'disabled_safety_policies': [
'financial_transactions',
'communication_tool',
],
}
]
)REST
GenerateContent API
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Open the Maps app and find the nearest coffee shop."
}
]
}
],
"tools": [
{
"computer_use": {
"environment": "ENVIRONMENT_MOBILE",
"disabled_safety_policies" : [
"FINANCIAL_TRANSACTIONS",
"COMMUNICATION_TOOL"
]
}
}
]
}Interactions API
{
"model": "gemini-3.5-flash",
"input": "Open the Maps app and find the nearest coffee shop.",
"tools": [
{
"type": "computer_use",
"environment": "mobile",
"disabled_safety_policies": [
"financial_transactions",
"communication_tool"
]
}
]
}組織のポリシーを作成する
組織管理者は、組織ポリシー サービスを使用して、個々のデベロッパーが一部またはすべての HITL 確認を無効にできないようにする組織レベルのポリシーを作成できます。このポリシーは、デベロッパー レベルの設定よりも優先されます。
ポリシーは、Google Cloud コンソールまたは Google Cloud CLI を使用して作成できます。制約 ID は vertexai.configurableComputerUseToolSafetyPolicies です。組織のポリシーの変更が反映されるまでに、最大 1 時間かかることがあります。
組織のポリシーを作成して管理する方法の詳細については、組織のポリシーを作成するをご覧ください。
料金
コンピュータの使用は Gemini と同じ料金で、同じ SKU を使用します。コンピュータの使用費用を分割するには、カスタム メタデータ ラベルを使用します。費用のモニタリングにカスタム メタデータ ラベルを使用する方法については、カスタム メタデータ ラベルをご覧ください。