Penggunaan Komputer

Alat Penggunaan Komputer memungkinkan Anda membuat agen kontrol browser, seluler, dan desktop yang berinteraksi dengan dan mengotomatiskan tugas. Dengan menggunakan screenshot, model dapat "melihat" layar komputer, dan "bertindak" dengan membuat tindakan UI tertentu seperti klik mouse dan input keyboard. Mirip dengan panggilan fungsi, Anda harus menerapkan lingkungan eksekusi sisi klien untuk menerima dan mengeksekusi tindakan Penggunaan Komputer.

Gemini 3.5 Flash adalah model yang direkomendasikan untuk Penggunaan Komputer, dan memperkenalkan beberapa kemampuan baru:

  • Dukungan multi-lingkungan: agen build untuk lingkungan browser, seluler, dan desktop.
  • Tindakan yang disederhanakan dengan maksud: tindakan mencakup kolom intent yang menjelaskan alasan model di balik setiap langkah.
  • Kebijakan keamanan yang dapat dikonfigurasi: sesuaikan perilaku keamanan dengan kategori dan penggantian kebijakan bawaan.
  • Deteksi injeksi perintah: aktifkan pemindaian screenshot untuk mendeteksi petunjuk berbahaya yang tersembunyi.

Dengan Penggunaan Komputer, Anda dapat membuat agen yang:

  • Mengotomatiskan entri data atau pengisian formulir yang berulang di situs.
  • Melakukan pengujian otomatis aplikasi web dan alur pengguna
  • Melakukan riset di berbagai situs (misalnya, mengumpulkan informasi produk, harga, dan ulasan dari situs e-commerce untuk membantu pembelian)

Berikut adalah contoh minimal untuk menginisialisasi klien dan mengirimkan perintah ke model dengan alat computer_use yang diaktifkan untuk lingkungan browser:

Python

from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.5-flash",
    input="Search for 'Gemini API' on Google.",
    tools=[{"type": "computer_use", "environment": "browser"}]
)

print(interaction)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI();

const interaction = await ai.interactions.create({
  model: 'gemini-3.5-flash',
  input: "Search for 'Gemini API' on Google.",
  tools: [{ type: "computer_use", environment: "browser" }]
});

console.log(interaction);


Cara kerja Penggunaan Komputer

Untuk membuat agen dengan model Penggunaan Komputer, Anda perlu menyiapkan loop berkelanjutan antara aplikasi dan API. Berikut adalah fungsi kode Anda di setiap langkah:

  1. Mengirim permintaan ke model
    • Aplikasi Anda mengirimkan permintaan API yang berisi alat Penggunaan Komputer, setelan konfigurasi Anda (seperti lingkungan target), perintah pengguna, dan screenshot layar saat ini.
  2. Menerima respons model
    • Model menganalisis layar dan perintah, lalu menampilkan respons yang mencakup function_call yang disarankan yang merepresentasikan tindakan UI (seperti klik, scroll, atau penekanan tombol).
    • Untuk Gemini 3.5 Flash, respons juga mencakup penalaran intent yang menjelaskan alasan model memilih tindakan tersebut.
    • Respons juga dapat mencakup safety_decision dari sistem keamanan internal yang mengklasifikasikan tindakan sebagai reguler/diizinkan, require_confirmation (memerlukan persetujuan pengguna), atau diblokir.
  3. Jalankan tindakan yang diterima
    • Jika tindakan diizinkan (atau pengguna mengonfirmasinya), kode sisi klien Anda akan mengurai function_call, menskalakan koordinat yang dinormalisasi agar sesuai dengan area tampilan, dan menjalankan tindakan di lingkungan target menggunakan alat otomatisasi (seperti Playwright). Jika tindakan diblokir, klien Anda harus menghentikan eksekusi atau menangani gangguan.
  4. Merekam status lingkungan baru
    • Setelah tindakan selesai dieksekusi, aplikasi Anda akan mengambil screenshot baru dan mengirimkannya kembali ke model dalam function_result untuk meminta langkah berikutnya.

Kemudian, proses ini diulang dari langkah 2, terus-menerus meminta tindakan berikutnya dari model hingga tugas selesai atau dihentikan.

Ringkasan Penggunaan Komputer

Cara menerapkan Penggunaan Komputer

Sebelum membangun dengan alat Penggunaan Komputer, Anda harus menyiapkan:

  • Lingkungan eksekusi yang aman: Jalankan agen Anda di VM atau container sandbox untuk mengisolasinya dari sistem host Anda dan membatasi potensi dampaknya. Penerapan referensi mencakup sandbox berbasis Docker siap pakai yang dapat Anda gunakan sebagai titik awal.
  • Handler tindakan sisi klien: Terapkan logika sisi klien untuk menjalankan koordinat, mengetik teks, dan mengambil screenshot.

Contoh di bawah menggunakan browser web sebagai lingkungan eksekusi dan Playwright sebagai handler sisi klien.

0. Menyiapkan Playwright

Pertama, instal paket yang diperlukan:

pip install google-genai playwright
playwright install chromium

Kemudian, inisialisasi instance browser Playwright untuk digunakan dalam eksekusi:

from playwright.sync_api import sync_playwright

# 1. Configure screen dimensions for the target environment
SCREEN_WIDTH = 1440
SCREEN_HEIGHT = 900

# 2. Start the Playwright browser
# In production, utilize a sandboxed environment.
playwright = sync_playwright().start()
# Set headless=False to see the actions performed on your screen
browser = playwright.chromium.launch(headless=False)

# 3. Create a context and page with the specified dimensions
context = browser.new_context(
    viewport={"width": SCREEN_WIDTH, "height": SCREEN_HEIGHT}
)
page = context.new_page()

# 4. Navigate to an initial page to start the task
page.goto("https://www.google.com")

# The 'page', 'SCREEN_WIDTH', and 'SCREEN_HEIGHT' variables
# will be used in the steps below.

1. Mengirim permintaan ke model

Lakukan inisialisasi library klien dan konfigurasi alat Penggunaan Komputer. Perhatikan bahwa tidak perlu menentukan ukuran tampilan saat mengeluarkan permintaan; model memprediksi koordinat piksel yang diskalakan ke tinggi dan lebar layar.

Python

Gunakan google-genai Python SDK (versi 2.7.0 atau yang lebih tinggi) untuk mengonfigurasi permintaan yang menargetkan lingkungan browser:

from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model='gemini-3.5-flash',
    input="Find a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th",
    tools=[
        {
            "type": "computer_use",
            "environment": "browser",
            "enable_prompt_injection_detection": True
        }
    ]
)

print(interaction)

JavaScript

Gunakan @google/genai Node.js SDK untuk mengonfigurasi permintaan yang menargetkan lingkungan browser:

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI();

const interaction = await ai.interactions.create({
  model: 'gemini-3.5-flash',
  input: "Find a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th",
  tools: [
    {
      type: "computer_use",
      environment: "browser",
      enable_prompt_injection_detection: true
    }
  ]
});

console.log(interaction);

REST

Gunakan curl untuk mengirim permintaan:

curl -X POST \
  "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.5-flash",
    "input": "Find me a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th. Start by navigating directly to flights.google.com",
    "tools": [
      {
        "type": "computer_use",
        "environment": "browser",
        "enable_prompt_injection_detection": true
      }
    ]
  }'

Gemini 2.5 (Versi Lama)

Python

from google import genai

client = genai.Client()

# Specify predefined functions to exclude (optional)
excluded_functions = ["drag_and_drop"]

interaction = client.interactions.create(
    model='gemini-2.5-computer-use-preview-10-2025',
    input="Search for highly rated smart fridges on Google Shopping.",
    tools=[
        {
            "type": "computer_use",
            "environment": "browser",
            "excluded_predefined_functions": excluded_functions
        }
    ]
)

print(interaction)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI();

// Specify predefined functions to exclude (optional)
const excludedFunctions = ["drag_and_drop"];

const interaction = await ai.interactions.create({
  model: 'gemini-2.5-computer-use-preview-10-2025',
  input: "Search for highly rated smart fridges on Google Shopping.",
  tools: [
    {
      type: "computer_use",
      environment: "browser",
      excluded_predefined_functions: excludedFunctions
    }
  ]
});

console.log(interaction);

2. Menerima respons model

Model respons menyarankan panggilan fungsi. Untuk Gemini 3.5 Flash, respons berisi maksud penalaran yang disesuaikan bersama dengan koordinat. Berikut contoh kedua respons:

Gemini 3.5 Flash

{
  "steps": [
    {
      "type": "function_call",
      "name": "click",
      "arguments": {
        "x": 450,
        "y": 120,
        "intent": "Click the search box to type the destination."
      }
    }
  ]
}

Gemini 2.5 (Versi Lama)

{
  "steps": [
    {
      "type": "model_output",
      "content": [
        {
          "type": "text",
          "text": "I will type the search query into the search bar."
        }
      ]
    },
    {
      "type": "function_call",
      "name": "type_text_at",
      "arguments": {
        "x": 371,
        "y": 470,
        "text": "highly rated smart fridges",
        "press_enter": true
      }
    }
  ]
}

3. Menjalankan tindakan yang diterima

Aplikasi Anda harus mengurai koordinat respons, menjalankan tindakan, dan menskalakannya dari koordinat 1000x1000 yang dinormalisasi.

Kode di bawah menangani perintah alat lama (click_at, type_text_at) dan perintah yang disederhanakan Gemini 3.5 Flash (click, type).

Python

from typing import Any, List, Tuple
import time

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 execute_function_calls(interaction, page, screen_width, screen_height):
    results = []
    function_calls = [
        step for step in interaction.steps if step.type == "function_call"
    ]

    for function_call in function_calls:
        action_result = {}
        fname = function_call.name
        args = function_call.arguments
        print(f"  -> Executing: {fname} (Intent: {args.get('intent', 'N/A')})")

        try:
            if fname in ("open_web_browser", "open_app"):
                pass # Handled / already open
            elif fname in ("click", "click_at", "double_click", "triple_click", "middle_click", "right_click", "move", "long_press"):
                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 == "right_click":
                    page.mouse.click(actual_x, actual_y, button="right")
                elif fname == "middle_click":
                    page.mouse.click(actual_x, actual_y, button="middle")
                elif fname == "move":
                    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)

                if actual_x is not None and actual_y is not None:
                    page.mouse.click(actual_x, actual_y)
                # Clear field first
                page.keyboard.press("Meta+A")
                page.keyboard.press("Backspace")
                page.keyboard.type(text)
                if press_enter:
                    page.keyboard.press("Enter")
            elif fname == "navigate":
                page.goto(args["url"])
            elif fname == "go_back":
                page.go_back()
            elif fname == "go_forward":
                page.go_forward()
            elif fname == "wait":
                time.sleep(args.get("seconds", 1))
            else:
                print(f"Warning: Custom or 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, function_call.id, action_result))

    return results

JavaScript

function denormalizeX(x, screenWidth) {
    // Convert normalized x coordinate (0-1000) to actual pixel coordinate.
    return Math.floor((x / 1000) * screenWidth);
}

function denormalizeY(y, screenHeight) {
    // Convert normalized y coordinate (0-1000) to actual pixel coordinate.
    return Math.floor((y / 1000) * screenHeight);
}

async function executeFunctionCalls(interaction, page, screenWidth, screenHeight) {
    const results = [];
    const functionCalls = interaction.steps.filter(step => step.type === "function_call");

    for (const functionCall of functionCalls) {
        const actionResult = {};
        const fname = functionCall.name;
        const args = functionCall.arguments;
        console.log(`  -> Executing: ${fname} (Intent: ${args.intent || 'N/A'})`);

        try {
            if (fname === "open_web_browser" || fname === "open_app") {
                // Handled / already open
            } else if (["click", "click_at", "double_click", "triple_click", "middle_click", "right_click", "move", "long_press"].includes(fname)) {
                const actualX = denormalizeX(args.x, screenWidth);
                const actualY = denormalizeY(args.y, screenHeight);

                if (fname === "click" || fname === "click_at") {
                    await page.mouse.click(actualX, actualY);
                } else if (fname === "double_click") {
                    await page.mouse.dblclick(actualX, actualY);
                } else if (fname === "right_click") {
                    await page.mouse.click(actualX, actualY, { button: "right" });
                } else if (fname === "middle_click") {
                    await page.mouse.click(actualX, actualY, { button: "middle" });
                } else if (fname === "move") {
                    await page.mouse.move(actualX, actualY);
                }
            } else if (fname === "type" || fname === "type_text_at") {
                const actualX = args.x !== undefined ? denormalizeX(args.x, screenWidth) : null;
                const actualY = args.y !== undefined ? denormalizeY(args.y, screenHeight) : null;
                const text = args.text;
                const pressEnter = args.press_enter || false;

                if (actualX !== null && actualY !== null) {
                    await page.mouse.click(actualX, actualY);
                }
                // Clear field first
                await page.keyboard.press("Meta+A");
                await page.keyboard.press("Backspace");
                await page.keyboard.type(text);
                if (pressEnter) {
                    await page.keyboard.press("Enter");
                }
            } else if (fname === "navigate") {
                await page.goto(args.url);
            } else if (fname === "go_back") {
                await page.goBack();
            } else if (fname === "go_forward") {
                await page.goForward();
            } else if (fname === "wait") {
                await new Promise(resolve => setTimeout(resolve, (args.seconds || 1) * 1000));
            } else {
                console.log(`Warning: Custom or unhandled function ${fname}`);
            }

            await page.waitForLoadState('load', { timeout: 5000 }).catch(() => {});
            await new Promise(resolve => setTimeout(resolve, 1000));
        } catch (e) {
            console.log(`Error executing ${fname}: ${e}`);
            actionResult.error = e.message;
        }

        results.push([fname, functionCall.id, actionResult]);
    }

    return results;
}

4. Merekam status lingkungan baru

Setelah menjalankan tindakan, kirim hasil eksekusi fungsi kembali ke model agar model dapat menggunakan informasi ini untuk membuat tindakan berikutnya. Jika beberapa tindakan (panggilan paralel) dijalankan, Anda harus mengirimkan function_result untuk setiap tindakan pada giliran pengguna berikutnya.

Python

import json
import base64

def get_function_responses(page, results):
    screenshot_bytes = page.screenshot(type="png")
    current_url = page.url
    function_responses = []
    for name, call_id, result in results:
        function_responses.append({
            "type": "function_result",
            "name": name,
            "call_id": call_id,
            "result": [
                {
                    "type": "text",
                    "text": json.dumps({"url": current_url, **result})
                },
                {
                    "type": "image",
                    "data": base64.b64encode(screenshot_bytes).decode("utf-8"),
                    "mime_type": "image/png"
                }
            ]
        })
    return function_responses

JavaScript

async function getFunctionResponses(page, results) {
    const screenshotBuffer = await page.screenshot({ type: 'png' });
    const screenshotBase64 = screenshotBuffer.toString('base64');
    const currentUrl = page.url();
    const functionResponses = [];

    for (const [name, callId, result] of results) {
        functionResponses.push({
            type: "function_result",
            name: name,
            call_id: callId,
            result: [
                {
                    type: "text",
                    text: JSON.stringify({ url: currentUrl, ...result })
                },
                {
                    type: "image",
                    data: screenshotBase64,
                    mime_type: "image/png"
                }
            ]
        });
    }
    return functionResponses;
}

Setelah menentukan cara merekam dan memformat status lingkungan, Anda dapat menggabungkan semua langkah ini ke dalam loop eksekusi berkelanjutan.

Membangun loop agen

Untuk mengaktifkan interaksi multi-langkah, gabungkan empat langkah dari bagian Cara menerapkan Penggunaan Komputer menjadi satu loop. Loop ini terus meminta tindakan dan mengirimkan kembali hasilnya ke model hingga tugas selesai.

Ingatlah untuk mengelola histori percakapan dengan benar dengan menambahkan respons model dan respons fungsi Anda ke histori di setiap langkah.

Python

import time
from typing import Any, List, Tuple
from playwright.sync_api import sync_playwright

from google import genai

client = genai.Client()

# Constants for screen dimensions
SCREEN_WIDTH = 1440
SCREEN_HEIGHT = 900

# Setup Playwright
print("Initializing browser...")
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()

# Define helper functions. Copy/paste from steps 3 and 4
# def denormalize_x(...)
# def denormalize_y(...)
# def execute_function_calls(...)
# def get_function_responses(...)

try:
    # Go to initial page
    page.goto("https://ai.google.dev/gemini-api/docs")

    # Take initial screenshot
    initial_screenshot = page.screenshot(type="png")
    USER_PROMPT = "Go to ai.google.dev/gemini-api/docs and search for pricing."
    print(f"Goal: {USER_PROMPT}")

    # First interaction
    interaction = client.interactions.create(
        model='gemini-3.5-flash',
        input=[
            {"type": "text", "text": USER_PROMPT},
            {"type": "image", "data": base64.b64encode(initial_screenshot).decode("utf-8"), "mime_type": "image/png"}
        ],
        tools=[{
            "type": "computer_use",
            "environment": "browser",
            "enable_prompt_injection_detection": True
        }]
    )

    # Agent Loop
    turn_limit = 5
    for i in range(turn_limit):
        print(f"\n--- Turn {i+1} ---")

        has_function_calls = any(
            step.type == "function_call"
            for step in interaction.steps
        )
        if not has_function_calls:
            text_response = " ".join([
                content_block.text for step in interaction.steps if step.type == "model_output"
                for content_block in step.content if content_block.type == "text"
            ])
            print("Agent finished:", text_response)
            break

        print("Executing actions...")
        results = execute_function_calls(interaction, page, SCREEN_WIDTH, SCREEN_HEIGHT)

        print("Capturing state...")
        function_responses = get_function_responses(page, results)

        # Continue conversation with function responses
        interaction = client.interactions.create(
            model='gemini-3.5-flash',
            previous_interaction_id=interaction.id,
            input=function_responses,
            tools=[{
                "type": "computer_use",
                "environment": "browser",
                "enable_prompt_injection_detection": True
            }]
        )

finally:
    # Cleanup
    print("\nClosing browser...")
    browser.close()
    playwright.stop()

JavaScript

import { chromium } from 'playwright';
import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI();

// Constants for screen dimensions
const SCREEN_WIDTH = 1440;
const SCREEN_HEIGHT = 900;

console.log("Initializing browser...");
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
    viewport: { width: SCREEN_WIDTH, height: SCREEN_HEIGHT }
});
const page = await context.newPage();

// Define helper functions. Copy/paste from steps 3 and 4:
// function denormalizeX(...)
// function denormalizeY(...)
// async function executeFunctionCalls(...)
// async function getFunctionResponses(...)

try {
    // Go to initial page
    await page.goto("https://ai.google.dev/gemini-api/docs");

    // Take initial screenshot
    const initialScreenshotBuffer = await page.screenshot({ type: 'png' });
    const initialScreenshotBase64 = initialScreenshotBuffer.toString('base64');
    const USER_PROMPT = "Go to ai.google.dev/gemini-api/docs and search for pricing.";
    console.log(`Goal: ${USER_PROMPT}`);

    // First interaction
    let interaction = await ai.interactions.create({
        model: 'gemini-3.5-flash',
        input: [
            { type: 'text', text: USER_PROMPT },
            { type: 'image', data: initialScreenshotBase64, mime_type: 'image/png' }
        ],
        tools: [{
            type: 'computer_use',
            environment: 'browser',
            enable_prompt_injection_detection: true
        }]
    });

    // Agent Loop
    const turnLimit = 5;
    for (let i = 0; i < turnLimit; i++) {
        console.log(`\n--- Turn ${i + 1} ---`);

        const hasFunctionCalls = interaction.steps.some(step => step.type === "function_call");
        if (!hasFunctionCalls) {
            const textResponses = [];
            for (const step of interaction.steps) {
                if (step.type === "model_output") {
                    for (const contentBlock of step.content || []) {
                        if (contentBlock.type === "text") {
                            textResponses.push(contentBlock.text);
                        }
                    }
                }
            }
            console.log("Agent finished:", textResponses.join(" "));
            break;
        }

        console.log("Executing actions...");
        const results = await executeFunctionCalls(interaction, page, SCREEN_WIDTH, SCREEN_HEIGHT);

        console.log("Capturing state...");
        const functionResponses = await getFunctionResponses(page, results);

        // Continue conversation with function responses
        interaction = await ai.interactions.create({
            model: 'gemini-3.5-flash',
            previous_interaction_id: interaction.id,
            input: functionResponses,
            tools: [{
                type: 'computer_use',
                environment: 'browser',
                enable_prompt_injection_detection: true
            }]
        });
    }
} finally {
    // Cleanup
    console.log("\nClosing browser...");
    await browser.close();
}

Lingkungan yang didukung (Gemini 3.5 Flash)

Gemini 3.5 Flash mendukung tiga lingkungan yang ditentukan dalam konfigurasi computer_use:

Lingkungan browser (ENVIRONMENT_BROWSER)

Tindakan yang tersedia di alat browser:

Nama perintah Deskripsi Argumen (dalam panggilan fungsi)
click Klik kiri pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
double_click Klik dua kali pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
triple_click Klik tiga kali pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
middle_click Klik tengah pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
right_click Klik kanan pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
mouse_down Menekan dan menahan tombol mouse pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
mouse_up Melepaskan tombol mouse pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
pindah Memindahkan kursor ke posisi yang ditentukan. y: int (0-999)
x: int (0-999)
intent: str
jenis Mengetik teks. text: str
press_enter: bool (Opsional, default false)
intent: str
drag_and_drop Menarik item dari koordinat awal ke koordinat akhir. start_y: int (0-999)
start_x: int (0-999)
end_y: int (0-999)
end_x: int (0-999)
intent: str
wait Menjeda eksekusi selama jumlah detik yang ditentukan. seconds: int (Opsional, default 1)
intent: str
press_key Menekan tombol yang ditentukan, lalu melepaskannya. key: str
intent: str
key_down Menekan dan menahan tombol yang ditentukan. key: str
intent: str
key_up Melepaskan kunci yang ditentukan. key: str
intent: str
tombol pintas Menekan kombinasi tombol yang ditentukan. keys: List[str]
intent: str
take_screenshot Menampilkan screenshot layar saat ini. intent: str
scroll Men-scroll ke atas, bawah, kiri, atau kanan pada koordinat dengan jarak piksel. y: int (0-999)
x: int (0-999)
direction: str ("up", "down", "left", "right")
magnitude_in_pixels: int (0-999, Opsional, default 300)
intent: str
go_back Kembali ke halaman web sebelumnya dalam histori browser. intent: str
navigate Membuka langsung URL tertentu. url: str
intent: str
go_forward Membuka halaman web berikutnya dalam histori browser. intent: str

Lingkungan seluler (ENVIRONMENT_MOBILE)

Tindakan lingkungan yang dioptimalkan untuk Android:

Nama perintah Deskripsi Argumen (dalam panggilan fungsi)
open_app Membuka aplikasi berdasarkan namanya. app_name: str
intent: str
click Klik kiri pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
list_apps Mencantumkan aplikasi yang tersedia di perangkat, menampilkan nama dan nama paketnya. intent: str
wait Menjeda eksekusi selama jumlah detik yang ditentukan. seconds: int (Opsional, default 1)
intent: str
go_back Kembali ke layar atau halaman web sebelumnya. intent: str
jenis Mengetik teks. text: str
press_enter: bool (Opsional, default false)
intent: str
drag_and_drop Menarik item dari koordinat awal ke koordinat akhir. start_y: int (0-999)
start_x: int (0-999)
end_y: int (0-999)
end_x: int (0-999)
intent: str
long_press Melakukan tekan lama pada koordinat di layar. y: int (0-999)
x: int (0-999)
seconds: int (Opsional, default 2)
intent: str
press_key Menekan tombol yang ditentukan, lalu melepaskannya. key: str
intent: str
take_screenshot Menampilkan screenshot layar saat ini. intent: str

Lingkungan desktop (ENVIRONMENT_DESKTOP)

Perintah kursor tingkat OS lingkungan desktop:

Nama perintah Deskripsi Argumen (dalam panggilan fungsi)
click Klik kiri pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
double_click Klik dua kali pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
triple_click Klik tiga kali pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
middle_click Klik tengah pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
right_click Klik kanan pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
mouse_down Menekan dan menahan tombol mouse pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
mouse_up Melepaskan tombol mouse pada koordinat. y: int (0-999)
x: int (0-999)
intent: str
pindah Memindahkan kursor ke posisi yang ditentukan. y: int (0-999)
x: int (0-999)
intent: str
jenis Mengetik teks. text: str
press_enter: bool (Opsional, default false)
intent: str
drag_and_drop Menarik item dari koordinat awal ke koordinat akhir. start_y: int (0-999)
start_x: int (0-999)
end_y: int (0-999)
end_x: int (0-999)
intent: str
wait Menjeda eksekusi selama jumlah detik yang ditentukan. seconds: int (Opsional, default 1)
intent: str
press_key Menekan tombol yang ditentukan, lalu melepaskannya. key: str
intent: str
key_down Menekan dan menahan tombol yang ditentukan. key: str
intent: str
key_up Melepaskan kunci yang ditentukan. key: str
intent: str
tombol pintas Menekan kombinasi tombol yang ditentukan. keys: List[str]
intent: str
take_screenshot Menampilkan screenshot layar saat ini. intent: str
scroll Men-scroll ke atas, bawah, kiri, atau kanan pada koordinat dengan jarak piksel. y: int (0-999)
x: int (0-999)
direction: str ("up", "down", "left", "right")
magnitude_in_pixels: int (0-999, Opsional, default 300)
intent: str

Tindakan UI yang Didukung Lama (Gemini 2.5)

Untuk model lama (gemini-2.5-computer-use-preview-10-2025), tindakan berikut didukung:

Nama perintah Deskripsi Argumen (dalam panggilan fungsi) Contoh panggilan fungsi
open_web_browser Membuka browser web. Tidak ada {"name": "open_web_browser", "arguments": {}}
wait_5_seconds Menjeda eksekusi selama 5 detik. Tidak ada {"name": "wait_5_seconds", "arguments": {}}
go_back Membuka halaman sebelumnya dalam histori. Tidak ada {"name": "go_back", "arguments": {}}
go_forward Membuka halaman berikutnya dalam histori. Tidak ada {"name": "go_forward", "arguments": {}}
search Membuka mesin telusur default. Tidak ada {"name": "search", "arguments": {}}
navigate Membuka URL yang ditentukan secara langsung di browser. url: str {"name": "navigate", "arguments": {"url": "https://www.wikipedia.org"}}
click_at Mengklik pada koordinat tertentu. y: int (0-999), x: int (0-999) {"name": "click_at", "arguments": {"y": 300, "x": 500}}
hover_at Mengarahkan kursor ke koordinat tertentu. y: int (0-999), x: int (0-999) {"name": "hover_at", "arguments": {"y": 150, "x": 250}}
type_text_at Mengetik teks pada koordinat. y: int (0-999), x: int (0-999), text: str, press_enter: bool (Opsional, default Benar), clear_before_typing: bool (Opsional, default Benar) {"name": "type_text_at", "arguments": {"y": 250, "x": 400, "text": "search", "press_enter": false}}
key_combination Tekan tombol atau kombinasi tombol. keys: str {"name": "key_combination", "arguments": {"keys": "Control+A"}}
scroll_document Men-scroll seluruh halaman web. direction: str {"name": "scroll_document", "arguments": {"direction": "down"}}
scroll_at Men-scroll di koordinat (x,y). y: int, x: int, direction: str, magnitude: int (Opsional, default 800) {"name": "scroll_at", "arguments": {"y": 500, "x": 500, "direction": "down"}}
drag_and_drop Menarik antara dua koordinat. y: int, x: int, destination_y: int, destination_x: int {"name": "drag_and_drop", "arguments": {"y": 100, "destination_y": 500, "destination_x": 500, "x": 100}}

Fungsi kustom yang ditentukan pengguna

Anda dapat memperluas fungsi model dengan menyertakan fungsi kustom yang ditentukan pengguna. Misalnya, dalam skenario human-in-the-loop (HITL), Anda dapat mengecualikan tindakan default yang telah ditentukan sebelumnya dan mendaftarkan tindakan kustom.

Alat Kustom Gemini 3.5 Flash

Python

Mengecualikan tindakan browser standar yang telah ditentukan sebelumnya (seperti click) dan mendaftarkan alat yield_to_user kustom:

from google import genai

client = genai.Client()

yield_to_user_tool = {
    "type": "function",
    "name": "yield_to_user",
    "description": "Yields control back to the user for assistance or verification when an automated action is unsafe or ambiguous.",
    "parameters": {
        "type": "object",
        "properties": {
            "reason": {
                "type": "string",
                "description": "The reason why the agent is yielding control to the human."
            }
        },
        "required": ["reason"]
    }
}

interaction = client.interactions.create(
    model="gemini-3.5-flash",
    input="Click the submit button. If you need a second factor authentication code, ask me.",
    tools=[
        {
            "type": "computer_use",
            "environment": "mobile",
            "excluded_predefined_functions": ["click"]
        },
        yield_to_user_tool
    ]
)

JavaScript

Mengecualikan tindakan browser standar yang telah ditentukan sebelumnya (seperti click) dan mendaftarkan alat yield_to_user kustom:

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI();

const yieldToUserTool = {
    type: "function",
    name: "yield_to_user",
    description: "Yields control back to the user for assistance or verification when an automated action is unsafe or ambiguous.",
    parameters: {
        type: "object",
        properties: {
            reason: {
                type: "string",
                description: "The reason why the agent is yielding control to the human."
            }
        },
        required: ["reason"]
    }
};

const interaction = await ai.interactions.create({
    model: "gemini-3.5-flash",
    input: "Click the submit button. If you need a second factor authentication code, ask me.",
    tools: [
        {
            type: "computer_use",
            environment: "mobile",
            excluded_predefined_functions: ["click"]
        },
        yieldToUserTool
    ]
});

Alat Kustom Gemini 2.5 (Versi Lama)

Python

from google import genai

client = genai.Client()

# Define custom tools here
custom_functions = [...]  # Describe parameters as function declarations

excluded_functions = [
    "open_web_browser",
    "wait_5_seconds",
    "go_back",
    "go_forward",
    "search",
    "navigate",
    "hover_at",
    "scroll_document",
    "key_combination",
    "drag_and_drop",
]

interaction = client.interactions.create(
    model='gemini-2.5-computer-use-preview-10-2025',
    input="Open Chrome, then long-press at 200,400.",
    tools=[
        {
            "type": "computer_use",
            "environment": "browser",
            "excluded_predefined_functions": excluded_functions
        },
        *custom_functions
    ]
)

print(interaction)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI();

// Define custom tools here
const customFunctions = [...]; // Describe parameters as function declarations

const excludedFunctions = [
    "open_web_browser",
    "wait_5_seconds",
    "go_back",
    "go_forward",
    "search",
    "navigate",
    "hover_at",
    "scroll_document",
    "key_combination",
    "drag_and_drop",
];

const interaction = await ai.interactions.create({
    model: 'gemini-2.5-computer-use-preview-10-2025',
    input: "Open Chrome, then long-press at 200,400.",
    tools: [
        {
            type: "computer_use",
            environment: "browser",
            excluded_predefined_functions: excludedFunctions
        },
        ...customFunctions
    ]
});

console.log(interaction);

Mengelola tingkat penalaran (Gemini 3.5 Flash)

Untuk agen penggunaan komputer, Anda dapat mengonfigurasi tingkat pemikiran yang berbeda untuk menyeimbangkan kualitas tindakan dan kecepatan eksekusi. Tingkat pemikiran yang lebih rendah umumnya mencapai keseimbangan yang baik untuk tugas otomatisasi standar.

Keselamatan dan keamanan

Mengonfigurasi kebijakan keselamatan (Gemini 3.5 Flash)

Model Gemini 3.5 Flash mencakup kategori layanan keamanan bawaan yang secara otomatis menentukan apakah konfirmasi pengguna diperlukan.

Kategori kebijakan keselamatan Deskripsi
FINANCIAL_TRANSACTIONS Memblokir atau memicu konfirmasi untuk tindakan yang melibatkan pembayaran, checkout retail, atau barang yang diatur oleh hukum.
SENSITIVE_DATA_MODIFICATION Melindungi catatan kesehatan, keuangan, atau pemerintah dari modifikasi yang tidak sah.
COMMUNICATION_TOOL Membatasi agen agar tidak mengirim email, pesan chat, atau draf secara mandiri.
ACCOUNT_CREATION Membatasi agen agar tidak mendaftarkan akun baru secara mandiri di situs.
DATA_MODIFICATION Mengatur modifikasi sistem file secara keseluruhan, berbagi data, dan penghapusan penyimpanan.
USER_CONSENT_MANAGEMENT Memerlukan pengambilalihan pengguna untuk banner izin cookie dan dialog privasi.
LEGAL_TERMS_AND_AGREEMENTS Mencegah model menerima Persyaratan Layanan atau kontrak yang mengikat secara hukum secara mandiri.

Penggantian keamanan

Anda dapat mengganti kebijakan tertentu dengan meneruskan penggantian:

Python

from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.5-flash",
    input="Clean up the local folder by archiving old logs.",
    tools=[
        {
            "type": "computer_use",
            "environment": "desktop",
            "disabled_safety_policies": [
                "data_modification"
            ]
        }
    ]
)

JavaScript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI();

const interaction = await ai.interactions.create({
    model: "gemini-3.5-flash",
    input: "Clean up the local folder by archiving old logs.",
    tools: [
        {
            type: "computer_use",
            environment: "desktop",
            disabled_safety_policies: [
                "data_modification"
            ]
        }
    ]
});

Deteksi injeksi perintah (Gemini 3.5 Flash)

Mekanisme keamanan keikutsertaan yang memindai piksel screenshot untuk mendeteksi petunjuk perintah berniat jahat tersembunyi (misalnya, "Abaikan perintah sebelumnya") dan memblokir eksekusi saat terdeteksi.

Mengonfirmasi keputusan keamanan

Respons dapat menyertakan parameter safety_decision dalam argumen panggilan fungsi:

{
  "steps": [
    {
      "type": "function_call",
      "name": "click_at",
      "arguments": {
        "x": 60,
        "y": 100,
        "safety_decision": {
          "explanation": "Must check check-box",
          "decision": "require_confirmation"
        }
      }
    }
  ]
}

Jika safety_decision adalah require_confirmation, minta pengguna akhir. Jika pengguna mengonfirmasi, tetapkan safety_acknowledgement di function_result.

Python

def get_safety_confirmation(safety_decision):
    # Prompt user for confirmation
    print(f"Safety confirmation required: {safety_decision.get('explanation', '')}")
    return "CONTINUE" # Or TERMINATE

# Inside execute_function_calls, check for safety_decision:
if 'safety_decision' in function_call.arguments:
    decision = get_safety_confirmation(function_call.arguments['safety_decision'])
    if decision == "TERMINATE":
        break
    # Include safety_acknowledgement inside the action result
    action_result["safety_acknowledgement"] = True

Praktik terbaik keamanan

Penggunaan Komputer menimbulkan risiko keamanan dan operasional yang unik, karena model yang bertindak atas nama pengguna dapat menemukan konten yang tidak tepercaya di layar atau melakukan kesalahan dalam menjalankan tindakan. Terapkan praktik terbaik berikut untuk melindungi data dan sistem pengguna:

  1. Human-in-the-Loop (HITL):

    • Menerapkan konfirmasi pengguna: Jika respons keselamatan menunjukkan require_confirmation (atau keputusan keselamatan lama memerlukannya), minta persetujuan pengguna.
    • Memberikan petunjuk keamanan kustom: Terapkan petunjuk sistem kustom untuk menentukan dan menerapkan batas keamanan Anda sendiri. Contoh:

      Python

      from google import genai
      
      client = genai.Client()
      
      system_instruction = """
      ## **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.
      
      **Procedure for Seeking Confirmation:**
      * **For Consequential Actions:** Perform all preparatory steps (e.g., navigating,
        filling out forms, typing a message). You will ask for confirmation **AFTER**
        all necessary information is entered on the screen, but **BEFORE** you perform
        the final, irreversible action (e.g., before clicking "Send", "Submit",
        "Confirm Purchase", "Share").
      * **For Prohibited Actions:** If the action is strictly forbidden (e.g., accepting
        legal terms, solving a CAPTCHA), you must first inform the user about the
        required action and ask for their confirmation to proceed.
      
      **USER_CONFIRMATION Categories:**
      
      *   **Consent and Agreements:** You are FORBIDDEN from accepting, selecting, or
          agreeing to any of the following on the user's behalf. You must ask the
          user to confirm before performing these actions.
          *   Terms of Service
          *   Privacy Policies
          *   Cookie consent banners
          *   End User License Agreements (EULAs)
          *   Any other legally significant contracts or agreements.
      *   **Robot Detection:** You MUST NEVER attempt to solve or bypass the
          following. You must ask the user to confirm before performing these actions.
          *   CAPTCHAs (of any kind)
          *   Any other anti-robot or human-verification mechanisms, even if you are
              capable.
      *   **Financial Transactions:**
          *   Completing any purchase.
          *   Managing or moving money (e.g., transfers, payments).
          *   Purchasing regulated goods or participating in gambling.
      *   **Sending Communications:**
          *   Sending emails.
          *   Sending messages on any platform (e.g., social media, chat apps).
          *   Posting content on social media or forums.
      *   **Accessing or Modifying Sensitive Information:**
          *   Health, financial, or government records (e.g., medical history, tax
              forms, passport status).
          *   Revealing or modifying sensitive personal identifiers (e.g., SSN, bank
              account number, credit card number).
      *   **User Data Management:**
          *   Accessing, downloading, or saving files from the web.
          *   Sharing or sending files/data to any third party.
          *   Transferring user data between systems.
      *   **Browser Data Usage:**
          *   Accessing or managing Chrome browsing history, bookmarks, autofill data,
              or saved passwords.
      *   **Security and Identity:**
          *   Logging into any user account.
          *   Any action that involves misrepresentation or impersonation (e.g.,
              creating a fan account, posting as someone else).
      *   **Insurmountable Obstacles:** If you are technically unable to interact with
          a user interface element or are stuck in a loop you cannot resolve, ask the
          user to take over.
      ---
      
      ## **RULE 2: Default Behavior (ACTUATE)**
      
      If an action does **NOT** fall under the conditions for `USER_CONFIRMATION`,
      your default behavior is to **Actuate**.
      
      **Actuation Means:**  You MUST proactively perform all necessary steps to move
      the user's request forward. Continue to actuate until you either complete the
      non-consequential task or encounter a condition defined in Rule 1.
      
      *   **Example 1:** If asked to send money, you will navigate to the payment
          portal, enter the recipient's details, and enter the amount. You will then
          **STOP** as per Rule 1 and ask for confirmation before clicking the final
          "Send" button.
      *   **Example 2:** If asked to post a message, you will navigate to the site,
          open the post composition window, and write the full message. You will then
          **STOP** as per Rule 1 and ask for confirmation before clicking the final
          "Post" button.
      
          After the user has confirmed, remember to get the user's latest screen
          before continuing to perform actions.
      
      # Final Response Guidelines:
      Write final response to the user in the following cases:
      - User confirmation
      - When the task is complete or you have enough information to respond to the user
      """
      
      interaction = client.interactions.create(
          model="gemini-3.5-flash",
          system_instruction=system_instruction,
          input="Prepare a draft but do not send.",
          tools=[{
              "type": "computer_use",
              "environment": "browser"
          }]
      )
      

      JavaScript

      import { GoogleGenAI } from '@google/genai';
      
      const ai = new GoogleGenAI();
      
      const systemInstruction = `
      ## **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.
      
      **Procedure for Seeking Confirmation:**
      * **For Consequential Actions:** Perform all preparatory steps (e.g., navigating,
        filling out forms, typing a message). You will ask for confirmation **AFTER**
        all necessary information is entered on the screen, but **BEFORE** you perform
        the final, irreversible action (e.g., before clicking "Send", "Submit",
        "Confirm Purchase", "Share").
      * **For Prohibited Actions:** If the action is strictly forbidden (e.g., accepting
        legal terms, solving a CAPTCHA), you must first inform the user about the
        required action and ask for their confirmation to proceed.
      
      **USER_CONFIRMATION Categories:**
      
      *   **Consent and Agreements:** You are FORBIDDEN from accepting, selecting, or
          agreeing to any of the following on the user's behalf. You must ask the
          user to confirm before performing these actions.
          *   Terms of Service
          *   Privacy Policies
          *   Cookie consent banners
          *   End User License Agreements (EULAs)
          *   Any other legally significant contracts or agreements.
      *   **Robot Detection:** You MUST NEVER attempt to solve or bypass the
          following. You must ask the user to confirm before performing these actions.
          *   CAPTCHAs (of any kind)
          *   Any other anti-robot or human-verification mechanisms, even if you are
              capable.
      *   **Financial Transactions:**
          *   Completing any purchase.
          *   Managing or moving money (e.g., transfers, payments).
          *   Purchasing regulated goods or participating in gambling.
      *   **Sending Communications:**
          *   Sending emails.
          *   Sending messages on any platform (e.g., social media, chat apps).
          *   Posting content on social media or forums.
      *   **Accessing or Modifying Sensitive Information:**
          *   Health, financial, or government records (e.g., medical history, tax
              forms, passport status).
          *   Revealing or modifying sensitive personal identifiers (e.g., SSN, bank
              account number, credit card number).
      *   **User Data Management:**
          *   Accessing, downloading, or saving files from the web.
          *   Sharing or sending files/data to any third party.
          *   Transferring user data between systems.
      *   **Browser Data Usage:**
          *   Accessing or managing Chrome browsing history, bookmarks, autofill data,
              or saved passwords.
      *   **Security and Identity:**
          *   Logging into any user account.
          *   Any action that involves misrepresentation or impersonation (e.g.,
              creating a fan account, posting as someone else).
      *   **Insurmountable Obstacles:** If you are technically unable to interact with
          a user interface element or are stuck in a loop you cannot resolve, ask the
          user to take over.
      ---
      
      ## **RULE 2: Default Behavior (ACTUATE)**
      
      If an action does **NOT** fall under the conditions for `USER_CONFIRMATION`,
      your default behavior is to **Actuate**.
      
      **Actuation Means:**  You MUST proactively perform all necessary steps to move
      the user's request forward. Continue to actuate until you either complete the
      non-consequential task or encounter a condition defined in Rule 1.
      
      *   **Example 1:** If asked to send money, you will navigate to the payment
          portal, enter the recipient's details, and enter the amount. You will then
          **STOP** as per Rule 1 and ask for confirmation before clicking the final
          "Send" button.
      *   **Example 2:** If asked to post a message, you will navigate to the site,
          open the post composition window, and write the full message. You will then
          **STOP** as per Rule 1 and ask for confirmation before clicking the final
          "Post" button.
      
          After the user has confirmed, remember to get the user's latest screen
          before continuing to perform actions.
      
      # Final Response Guidelines:
      Write final response to the user in the following cases:
      - User confirmation
      - When the task is complete or you have enough information to respond to the user
      `;
      
      const interaction = await ai.interactions.create({
          model: "gemini-3.5-flash",
          system_instruction: systemInstruction,
          input: "Prepare a draft but do not send.",
          tools: [{
              type: "computer_use",
              environment: "browser"
          }]
      });
      
  2. Lingkungan eksekusi yang aman: Jalankan agen Anda di lingkungan yang aman dan sandbox untuk membatasi potensi dampaknya. Hal ini dapat berupa mesin virtual (VM) yang di-sandbox, container (misalnya, Docker), atau profil browser khusus dengan izin terbatas. Lihat implementasi referensi GitHub untuk panduan penyiapan sandbox menggunakan Docker.

  3. Pembersihan input: Bersihkan semua teks buatan pengguna dalam perintah untuk memitigasi risiko perintah yang tidak diinginkan atau injeksi perintah. Ini adalah lapisan keamanan yang berguna, tetapi bukan pengganti lingkungan eksekusi yang aman.

  4. Pembatasan konten: Gunakan pembatasan dan API keamanan konten untuk mengevaluasi input pengguna, input dan output alat, serta respons agen untuk mengetahui kesesuaian, deteksi injeksi perintah, dan deteksi jailbreak.

  5. Daftar yang diizinkan dan daftar yang tidak diizinkan: Terapkan mekanisme pemfilteran untuk mengontrol ke mana model dapat membuka dan apa yang dapat dilakukannya. Daftar situs yang dilarang yang tidak diizinkan adalah titik awal yang baik, sementara daftar yang diizinkan yang lebih ketat akan lebih aman.

  6. Observabilitas dan logging: Pertahankan log mendetail untuk proses debug, audit, dan respons insiden. Klien Anda harus mencatat perintah, screenshot, tindakan yang disarankan model (function_call), respons keamanan, dan semua tindakan yang akhirnya dieksekusi oleh klien.

  7. Pengelolaan lingkungan: Pastikan lingkungan GUI konsisten. Pop-up, notifikasi, atau perubahan tata letak yang tidak terduga dapat membingungkan model. Mulai dari status bersih yang diketahui untuk setiap tugas baru jika memungkinkan.

Versi model

Anda dapat menggunakan Penggunaan Komputer dengan model berikut:

  • Gemini 3.5 Flash (gemini-3.5-flash): Model yang direkomendasikan untuk penggunaan komputer, yang menampilkan tindakan yang disederhanakan dengan maksud, dukungan untuk lingkungan browser, seluler, dan desktop, kebijakan keamanan yang dapat dikonfigurasi, dan deteksi injeksi perintah.
  • Pratinjau Gemini 3 Flash (gemini-3-flash-preview): Model pratinjau yang mendukung penggunaan komputer.
  • Gemini 2.5 (Pratinjau Lama) (gemini-2.5-computer-use-preview-10-2025): Model pratinjau lama yang dioptimalkan untuk penggunaan komputer berbasis browser.

Langkah berikutnya