Uso do computador

A ferramenta de uso do computador do Gemini permite criar agentes de controle de navegador, dispositivos móveis e computador que interagem e automatizam tarefas em interfaces gráficas do usuário (GUIs). Quando o uso do computador está ativado, o modelo usa capturas de tela para observar a tela e agir gerando ações específicas da UI, como cliques do mouse, rolagem e entradas do teclado.

O Gemini oferece vários recursos avançados de uso do computador:

  • Suporte a vários ambientes: crie agentes para ambientes de navegador, dispositivos móveis e computadores.
  • Ações simplificadas com intents: as ações incluem um campo intent que explica o raciocínio do modelo por trás de cada etapa.
  • Políticas de segurança configuráveis: ajuste o comportamento de segurança com categorias de políticas e substituições integradas.
  • Detecção de injeção de comandos: verificação de capturas de tela para detectar instruções adversárias ocultas.

Você pode usar o uso do computador para criar agentes que podem:

  • Automatize a entrada de dados repetitiva ou o preenchimento de formulários em sites e aplicativos para computador.
  • Realize testes automatizados de fluxos do usuário na Web, em dispositivos móveis e em computadores.
  • Navegar em sites e aplicativos para coletar informações (por exemplo, comparar informações do produto, preços e avaliações).
  • Ajudar os usuários realizando sequências de ações em várias etapas em aplicativos.

Este guia aborda:

Assim como na chamada de função, é necessário escrever o código do aplicativo do lado do cliente para receber a chamada de função de uso do computador e executar as ações correspondentes.

Neste guia, presumimos que você está usando o SDK de IA generativa do Google para Python e conhece a API Playwright.

A implementação de referência para uso do computador está no GitHub.

Modelos compatíveis

O uso do computador é compatível com os seguintes modelos:

Clique para abrir os modelos compatíveis

Como funciona o uso do computador

Em vez de gerar respostas de texto, o uso do computador determina quando realizar ações específicas da UI, como cliques do mouse, e retorna os parâmetros necessários para executar essas ações. Você precisa escrever o código do aplicativo do lado do cliente para receber o function_call de uso do computador e executar as ações correspondentes.

As interações de uso do computador seguem um processo de loop do agente:

  1. Enviar uma solicitação ao modelo

    • Adicione o uso do computador (e, opcionalmente, outras ferramentas) à sua solicitação de API.
    • Envie um comando ao modelo com a solicitação do usuário e uma captura de tela que represente o estado atual da GUI.
  2. Receber a resposta do modelo

    • O modelo analisa a solicitação do usuário e a captura de tela e gera uma resposta que inclui um function_call sugerido que representa uma ação UI (por exemplo, "clique na coordenada (x,y)" ou "digite 'texto'"). Consulte Ações compatíveis para ver a lista de todas as ações que podem ser usadas com o modelo.
    • A resposta da API também pode incluir um safety_decision de um sistema de segurança interno que verificou a ação proposta pelo modelo. O safety_decision classifica a ação como:
      • Normal ou permitido: a ação é considerada segura. Isso também pode ser representado pela ausência de safety_decision.
      • Requer confirmação: o modelo está prestes a realizar uma ação que pode ser arriscada (por exemplo, clicar em um banner de aceitação de cookies).
  3. Executar a ação recebida

    • O código do lado do cliente recebe o function_call e qualquer safety_decision que o acompanhe.
    • Se o safety_decision indicar regular ou permitido (ou se nenhum safety_decision estiver presente), o código do lado do cliente poderá executar o function_call especificado no ambiente de destino (como um navegador da Web).
    • Se o safety_decision indicar a confirmação necessária, o aplicativo precisará solicitar a confirmação do usuário final antes de executar o function_call. Se o usuário confirmar, execute a ação. Se o usuário negar, não execute a ação.
  4. Capturar o novo estado do ambiente

    • Se a ação tiver sido executada, o cliente vai capturar uma nova captura de tela da GUI e o URL atual para enviar de volta ao modelo como parte de um function_response.
    • Se uma ação foi bloqueada pelo sistema de segurança ou teve a confirmação negada pelo usuário, seu aplicativo pode enviar uma forma diferente de feedback para o modelo ou encerrar a interação.

Uma nova solicitação é enviada ao modelo com o estado atualizado. O processo se repete a partir da etapa 2, com o modelo usando a nova captura de tela (se fornecida) e o objetivo em andamento para sugerir a próxima ação. O loop continua até que a tarefa seja concluída, ocorra um erro ou o processo seja encerrado (por exemplo, se uma resposta for bloqueada por filtros de segurança ou decisão do usuário).

O diagrama a seguir ilustra como funciona o uso do computador:

Fluxograma mostrando um ciclo de interação cíclico de uso do computador. Ele começa com uma
"Tarefa inicial" que leva a "Captura de tela + Contexto anterior". Etapa 1: "Enviar uma
solicitação ao modelo" envia esses dados para o "Modelo". Etapa 2: "Receber a resposta do modelo" transmite uma ação para o "Ambiente do computador (app cliente)". Etapa 3:
"Executar a ação recebida" atualiza o "Ambiente do computador (app cliente)".
Etapa 4: "Capturar o novo estado do ambiente" envia a captura de tela atualizada e o contexto de volta ao início do loop.

Ativar o uso do computador

Para ativar o uso do computador, verifique se o aplicativo está usando um dos modelos compatíveis e adicione o uso do computador à lista de ferramentas ativadas:

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);
      

API REST

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"
        }
      }
    ]
  }'
      

Configurar o ambiente de execução

Antes de criar com a ferramenta de uso do computador, configure:

  • Um ambiente de execução seguro: execute o agente em uma máquina virtual (VM) em sandbox ou em um contêiner (como o Docker) para isolá-lo do sistema host.
  • Um gerenciador de ações do lado do cliente: implemente a lógica do cliente para executar cliques do mouse, pressionamentos de teclas e captura de tela.

Primeiro, instale o SDK e as dependências do navegador e, em seguida, configure o ambiente:

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

Em seguida, inicialize uma instância do navegador Playwright com dimensões de janela de visualização explícitas para que as coordenadas normalizadas (0–1000) sejam dimensionadas com precisão:

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")

Enviar uma solicitação

Depois de configurar a ferramenta de uso do computador, envie um comando para o modelo que inclua o objetivo do usuário e uma captura de tela inicial da GUI.

Também é possível adicionar o seguinte:

  • Ações excluídas: se houver ações na lista de ações UI compatíveis que você não quer que o modelo realize, especifique-as em excluded_predefined_functions.
  • Funções definidas pelo usuário: talvez você queira incluir funções personalizadas definidas pelo usuário, além do uso do computador.

O exemplo de código a seguir ativa o uso do computador e envia a solicitação ao modelo:

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)
      

Também é possível incluir funções definidas pelo usuário personalizadas para ampliar a funcionalidade do modelo. Consulte Casos de uso do Gemini 3.5 Flash ou posterior e de dispositivos móveis ou computadores para saber como configurar o uso do computador para casos de uso de dispositivos móveis adicionando ações como open_app, long_press_at e go_home e excluindo ações específicas do navegador.

Receber respostas

O modelo responde com um ou mais FunctionCalls se determinar que ações UI ou funções definidas pelo usuário são necessárias para concluir a tarefa. O código do aplicativo precisa analisar essas ações, executá-las e coletar os resultados. O uso do computador é compatível com a chamada de função paralela, o que significa que o modelo pode retornar várias ações independentes em uma única rodada.

Para o Gemini 3.5 Flash e modelos mais recentes, cada ação inclui um argumento intent que explica o raciocínio do modelo por trás dessa etapa:

{
  "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."
          }
        }
      }
    ]
  }
}

Dependendo da ação, a resposta da API também pode retornar um safety_decision dentro dos argumentos da chamada de função:

{
  "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"
            }
          }
        }
      }
    ]
  }
}

Executar ações recebidas

Depois de receber uma resposta, analise o function_call, dimensione as coordenadas da grade normalizada de 0 a 1.000 para as dimensões reais de pixel da janela de visualização e execute a ação:

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

Se o safety_decision retornado for require_confirmation, peça para o usuário confirmar antes de prosseguir com a execução da ação. De acordo com os Termos de Serviço, não é permitido ignorar as solicitações de confirmação humana.

Capturar o novo estado

Depois de executar as ações, empacote cada resultado e a captura de tela atualizada em um FunctionResponse para retornar ao modelo:

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,
    )

Criar um loop de agente

Combine essas etapas em um loop completo que itera continuamente entre o modelo e o ambiente de execução:

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 ou posterior e casos de uso em dispositivos móveis ou computadores

O uso do computador permite configurar ambientes para dispositivos móveis (ENVIRONMENT_MOBILE), computadores (ENVIRONMENT_DESKTOP) ou navegadores (ENVIRONMENT_BROWSER). O padrão é ENVIRONMENT_BROWSER.

Os exemplos a seguir demonstram como configurar o ambiente de execução para uso do computador com o Gemini 3.5 Flash ou posterior:

API REST

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • PROJECT_ID: o ID do projeto.

Método HTTP e URL:

POST https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.5-flash:generateContent

Corpo JSON da solicitação:

{
  "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"
      }
    }
  ]
}

Para enviar a solicitação, expanda uma destas opções:

Você receberá um código de status bem-sucedido (2xx) e uma resposta vazia.

Python

O exemplo a seguir requer a versão 2.7.0 ou posterior do python-genai.

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
        ),
    )
)

Funções definidas pelo usuário personalizadas

É possível estender a funcionalidade do modelo combinando computer_use com funções definidas pelo usuário (function_declarations). Por exemplo, em cenários de human-in-the-loop (HITL), é possível excluir ações predefinidas específicas usando excluded_predefined_functions e registrar uma função yield_to_user personalizada para que o agente possa retornar o controle a um humano ao encontrar comandos de 2FA ou telas ambíguas:

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)
      

Ações permitidas

A ferramenta de uso do computador permite que o modelo solicite as seguintes ações usando um FunctionCall. O código do lado do cliente precisa implementar a lógica de execução dessas ações. Consulte a implementação de referência para exemplos. A tabela a seguir mostra as ações compatíveis com o ambiente do navegador. Os modelos Gemini 3 Flash e Gemini 3.5 Flash ou mais recentes têm conjuntos de nomes FunctionCall diferentes.

Gemini 3.5 Flash ou posterior

Gemini 3.5 Flash: você tem acesso a diferentes conjuntos de chamadas de função, dependendo do ambiente selecionado:

Ambiente do navegador

Nome do comando Descrição Argumentos (na chamada de função)
click Clica com o botão esquerdo na coordenada especificada. y: int (0-999)
x: int (0-999)
intent: str
double_click Clica duas vezes na coordenada especificada. y: int (0-999)
x: int (0-999)
intent: str
triple_click Clica três vezes na coordenada especificada. y: int (0-999)
x: int (0-999)
intent: str
middle_click Clica com o botão do meio na coordenada especificada. y: int (0-999)
x: int (0-999)
intent: str
right_click Clica com o botão direito do mouse na coordenada especificada. y: int (0-999)
x: int (0-999)
intent: str
mouse_down Toca e pressiona o botão do mouse na coordenada. y: int (0-999)
x: int (0-999)
intent: str
mouse_up Solta o botão do mouse na coordenada. y: int (0-999)
x: int (0-999)
intent: str
move Move o cursor para a posição especificada. y: int (0-999)
x: int (0-999)
intent: str
type Digita o texto (clicando primeiro em x, y, se quiser). y: int (0-999, opcional)
x: int (0-999, opcional)
text: str
press_enter: bool (opcional, padrão falso)
intent: str
drag_and_drop Arrasta um item de (start_x, start_y) para (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 Aguarda o número especificado de segundos. seconds: int (opcional, padrão 1)
intent: str
press_key Pressiona e solta a tecla especificada. key: str
intent: str
key_down Toca e pressiona a tecla especificada. key: str
intent: str
key_up Libera a chave especificada. key: str
intent: str
hotkey Pressiona a combinação de teclas especificada. keys: List[str]
intent: str
take_screenshot Retorna uma captura da tela atual. intent: str
scroll Rola para cima, para baixo, para a esquerda ou para a direita em uma coordenada por uma distância de pixel. y: int (0-999)
x: int (0-999)
direction: str ("up", "down", "left", "right")
magnitude_in_pixels: int (0-999, opcional, padrão 300)
intent: str
open_web_browser Abre o navegador da Web. intent: str
navigate Navega o navegador diretamente para o URL especificado. url: str
intent: str
go_back Volta para a página da Web anterior no histórico de navegação. intent: str
go_forward Navega para a próxima página da Web no histórico de navegação do navegador. intent: str

Ambiente para dispositivos móveis

Nome do comando Descrição Argumentos (na chamada de função)
open_app Abre um aplicativo pelo nome. intent: str
click Clica com o botão esquerdo na coordenada. y: int (0-999)
x: int (0-999)
intent: str
list_apps Lista os aplicativos disponíveis no dispositivo, retornando os nomes e os nomes de pacotes. intent: str
wait Aguarda o número especificado de segundos. intent: str
seconds: int(opcional, padrão 1)
go_back Volta para a página da Web anterior no histórico do navegador. intent: str
type Digita texto. text: str
intent: str
press_enter: bool(opcional, padrão false)
drag_and_drop Arrasta o item de start_y e start_x para end_y e 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 Toca e mantém pressionada uma coordenada y (0-999), x (0-999) específica na tela. y: int (0-999)
x: int (0-999)
intent: str
seconds: int (opcional, padrão 2)
press_key Pressiona a tecla especificada e a solta. key: str
intent: str
take_screenshot Retorna uma captura da tela atual. intent: str

Ambiente de área de trabalho

Nome do comando Descrição Argumentos (na chamada de função)
click Clica com o botão esquerdo na coordenada. y: int (0-999)
x: int (0-999)
intent: str
double_click Clica duas vezes na coordenada. y: int (0-999)
x: int (0-999)
intent: str
triple_click Clica três vezes na coordenada. y: int (0-999)
x: int (0-999)
intent: str
middle_click Clica com o botão do meio na coordenada. y: int (0-999)
x: int (0-999)
intent: str
right_click Clica com o botão direito do mouse na coordenada. y: int (0-999)
x: int (0-999)
intent: str
mouse_down Toca e pressiona o botão do mouse na coordenada. y: int (0-999)
x: int (0-999)
intent: str
mouse_up Solta o botão do mouse na coordenada. y: int (0-999)
x: int (0-999)
intent: str
move Mova o cursor para a posição especificada. y: int (0-999)
x: int (0-999)
intent: str
type Digita texto. text: str
intent: str
press_enter: bool(opcional, padrão false)
drag_and_drop Arrasta o item de start_y e start_x para end_y e 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 Aguarde o número de segundos especificado. intent: str
seconds: int(opcional, padrão 1)
press_key Pressiona e solta a tecla especificada. key: str
intent: str
key_down Toca e pressiona a tecla especificada. key: str
intent: str
key_up Libera a chave especificada. key: str
intent: str
hotkey Pressiona a combinação de teclas especificada. keys: List[str]
intent: str
take_screenshot Retorna uma captura da tela atual. intent: str
scroll Rola para cima, para baixo, para a esquerda ou para a direita em uma coordenada por uma distância de pixel. y: int (0-999)
x: int (0-999)
direction: str ("up", "down", "left", "right")
intent: str
magnitude_in_pixels: int (0-999, opcional, padrão 300)

Gemini 3 Flash

Nome do comando Descrição Argumentos (na chamada de função) Exemplo de chamada de função
open_web_browser Abre o navegador da Web. Nenhum {"name": "open_web_browser", "args": {}}
wait_5_seconds Pausa a execução por 5 segundos para permitir que o conteúdo dinâmico seja carregado ou que as animações sejam concluídas. Nenhum {"name": "wait_5_seconds", "args": {}}
go_back Navega para a página anterior no histórico do navegador. Nenhum {"name": "go_back", "args": {}}
go_forward Navega para a próxima página no histórico do navegador. Nenhum {"name": "go_forward", "args": {}}
search Navega até a página inicial do mecanismo de pesquisa padrão (por exemplo, Google). Útil para iniciar uma nova tarefa de pesquisa. Nenhum {"name": "search", "args": {}}
navigate Navega o navegador diretamente para o URL especificado. url: str {"name": "navigate", "args": {"url": "https://www.wikipedia.org"}}
click_at Clica em uma coordenada específica na página da Web. Os valores x e y são baseados em uma grade de 1000 x 1000 e são dimensionados de acordo com as dimensões da tela. y: int (0-999), x: int (0-999) {"name": "click_at", "args": {"y": 300, "x": 500}}
hover_at 521963309 Passa o mouse sobre uma coordenada específica na página da Web. Útil para revelar submenus. x e y são baseados em uma grade de 1000x1000. y: int (0-999) x: int (0-999) {"name": "hover_at", "args": {"y": 150, "x": 250}}
type_text_at Digita texto em uma coordenada específica. Por padrão, limpa o campo primeiro e pressiona ENTER depois de digitar, mas essas ações podem ser desativadas. x e y são baseados em uma grade de 1000x1000. y: int (0-999), x: int (0-999), text: str, press_enter: bool (opcional, padrão True), clear_before_typing: bool (opcional, padrão True) {"name": "type_text_at", "args": {"y": 250, "x": 400, "text": "search query", "press_enter": false}}
key_combination Pressiona teclas ou combinações do teclado, como "Control+C" ou "Enter". Útil para acionar ações (como enviar um formulário com "Enter") ou operações de área de transferência. keys: str (por exemplo, "enter", "control+c"). Consulte a referência da API para ver a lista completa de chaves permitidas. {"name": "key_combination", "args": {"keys": "Control+A"}}
scroll_document Rola a página da Web inteira para cima, para baixo, para a esquerda ou para a direita. direction: str ("up", "down", "left" ou "right") {"name": "scroll_document", "args": {"direction": "down"}}
scroll_at Rola um elemento ou uma área específica na coordenada (x, y) na direção especificada por uma determinada magnitude. As coordenadas e a magnitude (padrão 800) são baseadas em uma grade de 1000x1000. y: int (0-999), x: int (0-999), direction: str ("up", "down", "left", "right"), magnitude: int (0-999, opcional, padrão 800) {"name": "scroll_at", "args": {"y": 500, "x": 500, "direction": "down", "magnitude": 400}}
drag_and_drop Arrasta um elemento de uma coordenada inicial (x, y) e o solta em uma coordenada de destino (destination_x, destination_y). Todas as coordenadas são baseadas em uma grade de 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}}

Segurança e proteção

Nesta seção, descrevemos as proteções que a ferramenta de uso do computador tem para melhorar o controle do usuário e a segurança. Ele também descreve as práticas recomendadas para reduzir possíveis novos riscos que a ferramenta pode apresentar.

Confirmar decisão de segurança

Dependendo da ação, a resposta do modelo pode incluir um safety_decision de um sistema de segurança interno. Essa decisão verifica a segurança da ação proposta pela ferramenta.

{
  "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"
            }
          }
        }
      }
    ]
  }
}

Se o safety_decision for require_confirmation, você precisa pedir ao usuário final que confirme antes de prosseguir com a execução da ação.

O exemplo de código a seguir solicita a confirmação do usuário final antes de executar a ação. Se o usuário não confirmar a ação, o loop será encerrado. Se o usuário confirmar a ação, ela será executada, e o campo safety_acknowledgement será marcado como 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 ...

Se o usuário confirmar, inclua a confirmação de segurança no 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
                )
             )
           ]
         )
       )

Detecção de injeção de comandos

O uso do computador no Gemini 3.5 Flash ou posterior oferece suporte a um mecanismo de segurança avançado para detectar ataques de injeção de comandos. Quando ativado, esse recurso verifica se uma captura de tela incluída tem o potencial de introduzir um ataque de injeção de comando. É possível definir esse recurso na configuração de uso do computador. O padrão é false.

Os exemplos a seguir mostram como ativar a configuração de uso do computador para ativar a detecção de injeção de comandos:

API REST

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • PROJECT_ID: o ID do projeto.

Método HTTP e URL:

POST https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.5-flash:generateContent

Corpo JSON da solicitação:

{
  "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
      }
    }
  ]
}

Para enviar a solicitação, expanda uma destas opções:

Você receberá um código de status bem-sucedido (2xx) e uma resposta vazia.

Python

O exemplo a seguir requer a versão 2.7.0 ou posterior do python-genai.

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
        ),
    )
)

Práticas recomendadas de segurança

O uso do computador apresenta riscos que os desenvolvedores precisam considerar:

  • Conteúdo não confiável e golpes:ao tentar atingir o objetivo do usuário, o modelo pode usar fontes de informações não confiáveis e instruções da tela.
  • Ações não intencionais ocasionais: o modelo pode interpretar mal o objetivo de um usuário ou o conteúdo de uma página da Web, fazendo com que ele tome ações incorretas, como clicar no botão errado ou preencher o formulário errado.
  • Violações de política: os recursos da API podem ser direcionados para atividades que violam os termos e as políticas do Google, como burlar CAPTCHAs ou comprometer a integridade do sistema.

Para lidar com esses riscos, implemente as seguintes medidas de segurança e práticas recomendadas:

  1. Human-in-the-loop (HITL):
    • Implementar a confirmação do usuário: quando a resposta de segurança indicar require_confirmation, você precisará implementar a confirmação do usuário antes da execução.
    • Fornecer instruções de segurança personalizadas: além das verificações de confirmação do usuário integradas, os desenvolvedores podem adicionar uma instrução de sistema personalizada que aplique as próprias políticas de segurança, seja para bloquear determinadas ações do modelo ou exigir a confirmação do usuário antes que o modelo tome determinadas ações irreversíveis de alto risco.

    Clique para ver um exemplo de instrução personalizada do sistema de segurança

    ## **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.
        
  2. Ambiente de execução seguro:execute o agente em um ambiente seguro e em sandbox para limitar o impacto potencial (por exemplo, uma máquina virtual (VM) em sandbox, um contêiner (como o Docker) ou um perfil de navegador dedicado com permissões limitadas).
  3. Sanitização de entrada: limpe todo o texto gerado pelo usuário nos comandos para reduzir o risco de instruções não intencionais ou injeção de comandos. Essa é uma camada de segurança útil, mas não substitui um ambiente de execução seguro.
  4. Proteções de conteúdo: use proteções e APIs de segurança de conteúdo (como o Model Armor) para avaliar as entradas do usuário, as entradas e saídas de ferramentas e as respostas do agente quanto à adequação, injeção de comandos e detecção de jailbreak.
  5. Listas de permissões e de bloqueio: implemente mecanismos de filtragem para controlar onde o modelo pode navegar e o que ele pode fazer. Uma lista de bloqueio de sites proibidos é um bom ponto de partida, mas uma lista de permissões mais restritiva é ainda mais segura.
  6. Observabilidade e geração de registros: mantenha registros detalhados para depuração, auditoria e resposta a incidentes. Seu cliente precisa registrar comandos, capturas de tela, ações sugeridas pelo modelo (function_call), respostas de segurança e todas as ações executadas pelo cliente.
  7. Gerenciamento de ambiente: garanta que o ambiente da GUI seja consistente. Pop-ups inesperados, notificações do sistema ou mudanças de layout podem confundir o modelo. Comece de um estado conhecido e limpo para cada nova tarefa, quando possível.

Confirmações de human-in-the-loop (HITL)

As confirmações de human-in-the-loop (HITL) são o processo de buscar a confirmação do usuário antes de executar uma ação sugerida pelo modelo. Esse processo é necessário quando o modelo não pode realizar uma ação devido a questões de segurança.

A ferramenta de uso do computador do Gemini oferece os seguintes mecanismos para controlar as confirmações de HITL:

Substituir confirmações de HITL

É possível modificar as seguintes confirmações padrão do HITL:

  • FINANCIAL_TRANSACTIONS: conclusão da etapa final de uma transação financeira (como pagamentos, transferências de fundos, emissão de uma ordem de pagamento, início ou modificação de uma assinatura ou conclusão de uma reserva).
  • SENSITIVE_DATA_MODIFICATION: modificação de informações sensíveis, como registros de saúde, financeiros ou governamentais.
  • COMMUNICATION_TOOL: acesso ou uso de ferramentas de comunicação para enviar, compartilhar, postar ou transmitir comunicações.
  • ACCOUNT_CREATION: interação com fluxos de registro ou inscrição que criam ou provisionam novas contas de usuário ou de serviço.
  • DATA_MODIFICATION: modificação, gerenciamento, compartilhamento, armazenamento, envio ou exclusão de dados de navegação ou arquivos.
  • USER_CONSENT_MANAGEMENT: interação com caixas de diálogo ou banners de consentimento do usuário ao tomar uma decisão.
  • LEGAL_TERMS_AND_AGREEMENTS: interação com caixas de diálogo de contratos juridicamente vinculativos, como aceitação de Termos de Serviço, caixas de diálogo de Política de Privacidade ou avisos legais.

É possível substituir qualquer uma ou todas essas confirmações de HITL listando-as no campo disabled_safety_policies da configuração de uso do computador:

Python

API GenerateContent

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,
)

API Interactions

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

API GenerateContent

{
  "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"
         ]
      }
    }
  ]
}

API Interactions

{
  "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"
      ]
    }
  ]
}

Criar políticas da organização

Se você for um administrador da organização, poderá criar uma política no nível da organização usando o Serviço de Política da Organização que impede que desenvolvedores individuais desativem algumas ou todas as confirmações de HITL. Esta política substitui todas as configurações no nível do desenvolvedor.

É possível criar uma política usando o console doGoogle Cloud ou a Google Cloud CLI. O ID da restrição é vertexai.configurableComputerUseToolSafetyPolicies. As mudanças na política da organização podem levar até uma hora para serem propagadas.

Para detalhes completos sobre como criar e gerenciar políticas organizacionais, consulte Criar políticas da organização.

Preços

O uso do computador tem o mesmo preço do Gemini e usa as mesmas SKUs. Para dividir os custos de uso do computador, use rótulos de metadados personalizados. Para mais informações sobre como usar rótulos de metadados personalizados para monitoramento de custos, consulte Rótulos de metadados personalizados.