La herramienta de uso de la computadora de Gemini te permite crear agentes de control de navegadores, dispositivos móviles y computadoras que interactúan con interfaces gráficas de usuario (GUI) y automatizan tareas en ellas. Cuando se habilita el uso de la computadora, el modelo usa capturas de pantalla para observar la pantalla y actuar generando acciones específicas de la IU, como clics del mouse, desplazamientos y entradas de teclado.
Gemini admite varias funciones avanzadas de uso de la computadora:
- Compatibilidad con varios entornos: Crea agentes para entornos de navegador, dispositivos móviles y computadoras.
- Acciones optimizadas con intents: Las acciones incluyen un campo
intentque explica el razonamiento del modelo detrás de cada paso. - Políticas de seguridad configurables: Ajusta el comportamiento de seguridad con categorías y anulaciones de políticas integradas.
- Detección de inyección de instrucciones: Análisis de capturas de pantalla opcional para detectar instrucciones adversas ocultas.
Puedes utilizar el uso de computadoras para crear agentes que puedan hacer lo siguiente:
- Automatiza el ingreso de datos repetitivo o el llenado de formularios en sitios web y aplicaciones de escritorio.
- Realiza pruebas automatizadas de los flujos de usuarios web, móviles y de escritorio.
- Navegar por sitios web y aplicaciones para recopilar información (por ejemplo, comparar información de productos, precios y opiniones)
- Ayudar a los usuarios realizando secuencias de acciones de varios pasos en todas las aplicaciones.
En esta guía, se tratan los siguientes temas:
- Cómo funciona el uso de la computadora
- Cómo habilitar el uso de la computadora
- Cómo configurar tu entorno, enviar solicitudes, recibir respuestas y compilar bucles de agentes
- Entornos y funciones personalizadas compatibles
- Qué acciones de la computadora se admiten
- Asistencia de seguridad y protección
- Precios
Al igual que con la llamada a funciones, debes escribir el código de la aplicación del cliente para recibir la llamada a la función de uso de la computadora y ejecutar las acciones correspondientes.
En esta guía, se supone que usas el SDK de IA generativa de Google para Python y que conoces la API de Playwright.
Puedes encontrar la implementación de referencia para el uso de computadoras en GitHub.
Modelos compatibles
El uso de la computadora es compatible con los siguientes modelos:
Haz clic para expandir los modelos compatibles
Cómo funciona el uso de la computadora
En lugar de generar respuestas de texto, el uso de la computadora determina cuándo
realizar acciones específicas de la IU, como clics del mouse, y devuelve los parámetros necesarios
para ejecutar estas acciones. Debes escribir el código de la aplicación del cliente para
recibir el function_call de uso de la computadora y ejecutar las acciones
correspondientes.
Las interacciones de uso de la computadora siguen un proceso de bucle de agente:
Envía una solicitud al modelo
- Agrega el uso de la computadora (y, de forma opcional, cualquier herramienta adicional) a tu solicitud a la API.
- Envía una instrucción al modelo con la solicitud del usuario y una captura de pantalla que represente el estado actual de la GUI.
Recibe la respuesta del modelo
- El modelo analiza la solicitud del usuario y la captura de pantalla, y genera una
respuesta que incluye un
function_callsugerido que representa una acción de la IU (por ejemplo, "haz clic en la coordenada (x,y)" o "escribe 'texto'"). Consulta Acciones admitidas para obtener la lista de todas las acciones que puedes usar con el modelo. - La respuesta de la API también puede incluir un
safety_decisionde un sistema de seguridad interno que haya verificado la acción propuesta por el modelo. Estesafety_decisionclasifica la acción de la siguiente manera:- Regular o permitida: La acción se considera segura. Esto también puede
representarse por la ausencia de
safety_decision. - Requiere confirmación: El modelo está a punto de realizar una acción que puede ser riesgosa (por ejemplo, hacer clic en un banner de "aceptar cookies").
- Regular o permitida: La acción se considera segura. Esto también puede
representarse por la ausencia de
- El modelo analiza la solicitud del usuario y la captura de pantalla, y genera una
respuesta que incluye un
Ejecuta la acción recibida
- Tu código del cliente recibe el
function_cally cualquiersafety_decisionque lo acompañe. - Si el
safety_decisionindica que es normal o permitido (o si no hay ningúnsafety_decisionpresente), tu código del cliente puede ejecutar elfunction_callespecificado en tu entorno de destino (como un navegador web). - Si el
safety_decisionindica que se requiere confirmación, tu aplicación debe solicitarle al usuario final que confirme antes de ejecutar elfunction_call. Si el usuario confirma, continúa con la ejecución de la acción. Si el usuario rechaza, no ejecutes la acción.
- Tu código del cliente recibe el
Captura el estado del entorno nuevo
- Si se ejecutó la acción, tu cliente captura una nueva captura de pantalla
de la GUI y la URL actual para enviarla de vuelta al modelo como parte de un
function_response. - Si el sistema de seguridad bloqueó una acción o el usuario rechazó la confirmación, tu aplicación podría enviar un tipo diferente de comentarios al modelo o finalizar la interacción.
- Si se ejecutó la acción, tu cliente captura una nueva captura de pantalla
de la GUI y la URL actual para enviarla de vuelta al modelo como parte de un
Se envía una solicitud nueva al modelo con el estado actualizado. El proceso se repite desde el paso 2, con el modelo que usa la nueva captura de pantalla (si se proporciona) y el objetivo en curso para sugerir la siguiente acción. El bucle continúa hasta que se completa la tarea, se produce un error o se finaliza el proceso (por ejemplo, si los filtros de seguridad o la decisión del usuario bloquean una respuesta).
En el siguiente diagrama, se ilustra cómo funciona el uso de la computadora:

Habilitar el uso de la computadora
Para habilitar el uso de la computadora, asegúrate de que tu aplicación use uno de los modelos compatibles y agrega el uso de la computadora a tu lista de herramientas habilitadas:
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 de 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" } } ] }'
Configura tu entorno de ejecución
Antes de compilar con la herramienta de uso de computadoras, configura lo siguiente:
- Un entorno de ejecución seguro: Ejecuta tu agente en una máquina virtual (VM) o un contenedor (como Docker) en una zona de pruebas para aislarlo de tu sistema host.
- Un controlador de acciones del cliente: Implementa la lógica del cliente para ejecutar clics del mouse, pulsaciones del teclado y capturas de pantalla.
Primero, instala el SDK y las dependencias del navegador y, luego, configura tu entorno:
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
A continuación, inicializa una instancia del navegador Playwright con dimensiones de viewport explícitas para que las coordenadas normalizadas (0-1000) se ajusten con precisión:
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")
Envía una solicitud
Después de configurar la herramienta de uso de la computadora, envía una instrucción al modelo que incluya el objetivo del usuario y una captura de pantalla inicial de la GUI.
También puedes agregar lo siguiente de forma opcional:
- Acciones excluidas: Si hay acciones de la lista de acciones de IU compatibles que no quieres que realice el modelo, especifícalas en
excluded_predefined_functions. - Funciones definidas por el usuario: Es posible que quieras incluir funciones personalizadas definidas por el usuario, además del uso de la computadora.
En el siguiente código de muestra, se habilita el uso de la computadora y se envía la solicitud al 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)
También puedes incluir funciones definidas por el usuario personalizadas para extender la funcionalidad
del modelo. Consulta Gemini 3.5 Flash o versiones posteriores y casos de uso para dispositivos móviles o computadoras para obtener información sobre cómo puedes configurar el uso de la computadora para casos de uso para dispositivos móviles agregando acciones como open_app, long_press_at y go_home, y excluyendo acciones específicas del navegador.
Recibe respuestas
El modelo responde con uno o más FunctionCalls si determina que se necesitan acciones de la IU o funciones definidas por el usuario para completar la tarea. El código de tu aplicación
debe analizar estas acciones, ejecutarlas y recopilar los resultados.
El uso de computadoras admite la llamada paralela a funciones, lo que significa
que el modelo puede devolver varias acciones independientes en un solo turno.
Para Gemini 3.5 Flash y los modelos posteriores, cada acción incluye un argumento intent
que explica el razonamiento del modelo detrás de ese paso:
{ "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." } } } ] } }
Según la acción, la respuesta de la API también puede devolver un safety_decision
dentro de los argumentos de la llamada a función:
{ "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" } } } } ] } }
Ejecutar acciones recibidas
Después de recibir una respuesta, analiza el function_call, escala las coordenadas
de la cuadrícula normalizada de 0 a 1000 a las dimensiones reales de píxeles del viewport y ejecuta
la acción:
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
Si el safety_decision que se muestra es require_confirmation, debes pedirle al usuario que confirme antes de continuar con la ejecución de la acción. Según las condiciones
del servicio, no se te permite omitir las solicitudes de confirmación humana.
Captura el estado nuevo
Después de ejecutar las acciones, empaqueta cada resultado de acción y la captura de pantalla actualizada
en un FunctionResponse para devolverlo al 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, )
Crea un bucle de agentes
Combina estos pasos en un bucle de extremo a extremo que itere de forma continua entre el modelo y el entorno de ejecución:
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 o versiones posteriores, y casos de uso para dispositivos móviles o computadoras
El uso de computadoras admite la configuración de entornos para dispositivos móviles (ENVIRONMENT_MOBILE),
computadoras de escritorio (ENVIRONMENT_DESKTOP) o navegadores (ENVIRONMENT_BROWSER). El valor predeterminado es ENVIRONMENT_BROWSER.
En los siguientes ejemplos, se muestra cómo configurar el entorno de ejecución para el uso de la computadora con Gemini 3.5 Flash o versiones posteriores:
API de REST
Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:
- PROJECT_ID: ID del proyecto
HTTP method and URL:
POST https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.5-flash:generateContent
Cuerpo JSON de la solicitud:
{
"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 tu solicitud, expande una de estas opciones:
Deberías recibir un código de estado exitoso (2xx) y una respuesta vacía.
Python
En el siguiente ejemplo, se requiere la versión 2.7.0 o posterior de 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
),
)
)
Funciones definidas por el usuario personalizadas
Puedes extender la funcionalidad del modelo combinando computer_use con funciones definidas por el usuario (function_declarations). Por ejemplo, en situaciones con intervención humana (HITL), puedes excluir acciones predefinidas específicas con excluded_predefined_functions y registrar una función yield_to_user personalizada para que el agente pueda devolver el control a un humano cuando encuentre mensajes de 2FA o pantallas ambiguas:
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)
Acciones compatibles
La herramienta de uso de la computadora permite que el modelo solicite las siguientes
acciones con un FunctionCall. Tu código del cliente debe implementar la
lógica de ejecución para estas acciones. Consulta la implementación de referencia para ver ejemplos. En la siguiente tabla, se muestran las acciones admitidas para el entorno del navegador.
Los modelos Gemini 3 Flash y Gemini 3.5 Flash o versiones posteriores tienen
diferentes conjuntos de nombres de FunctionCall.
Gemini 3.5 Flash o una versión posterior
Gemini 3.5 Flash: Tienes acceso a diferentes conjuntos de llamadas a funciones según el entorno que selecciones:Entorno del navegador
| Nombre del comando | Descripción | Argumentos (en la llamada a función) |
|---|---|---|
click |
Hace clic con el botón izquierdo en la coordenada especificada. |
y: int (0-999)x: int (0-999)intent: str
|
double_click |
Hace doble clic en la coordenada especificada. |
y: int (0-999)x: int (0-999)intent: str
|
triple_click |
Hace clic tres veces en la coordenada especificada. |
y: int (0-999)x: int (0-999)intent: str
|
middle_click |
Hace clic con el botón central en la coordenada especificada. |
y: int (0-999)x: int (0-999)intent: str
|
right_click |
Hace clic con el botón derecho en la coordenada especificada. |
y: int (0-999)x: int (0-999)intent: str
|
mouse_down |
Mantiene presionado el botón del mouse en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
mouse_up |
Suelta el botón del mouse en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
move |
Mueve el cursor a la posición especificada. |
y: int (0-999)x: int (0-999)intent: str
|
type |
Escribe texto (opcionalmente, haz clic primero en x, y). |
y: int (0-999, opcional)x: int (0-999, opcional)text: strpress_enter: bool (opcional, el valor predeterminado es falso)intent: str
|
drag_and_drop |
Arrastra un elemento de (start_x, start_y) a (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 |
Espera la cantidad de segundos especificada. |
seconds: int (opcional, el valor predeterminado es 1)intent: str
|
press_key |
Presiona la tecla especificada y la suelta. |
key: strintent: str
|
key_down |
Mantiene presionada la tecla especificada. |
key: strintent: str
|
key_up |
Suelta la tecla especificada. |
key: strintent: str
|
hotkey |
Presiona la combinación de teclas especificada. |
keys: List[str]intent: str
|
take_screenshot |
Muestra una captura de pantalla de la pantalla actual. | intent: str |
scroll |
Se desplaza hacia arriba, abajo, izquierda o derecha en una coordenada por una distancia de píxeles. |
y: int (0-999)x: int (0-999)direction: str ("up", "down", "left", "right")magnitude_in_pixels: int (0-999, opcional, predeterminado 300)intent: str
|
open_web_browser |
Abre el navegador web. | intent: str |
navigate |
Navega el navegador directamente a la URL especificada. |
url: strintent: str
|
go_back |
Regresa a la página web anterior en el historial de navegación. | intent: str |
go_forward |
Navega hacia adelante a la siguiente página web en el historial de navegación. | intent: str |
Entorno para dispositivos móviles
| Nombre del comando | Descripción | Argumentos (en la llamada a función) |
|---|---|---|
open_app |
Abre una aplicación por su nombre. | intent: str |
click |
Hace clic con el botón izquierdo en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
list_apps |
Muestra una lista de las aplicaciones disponibles en el dispositivo y devuelve sus nombres y nombres de paquetes. | intent: str |
wait |
Espera la cantidad de segundos especificada. |
intent: strseconds: int(opcional, el valor predeterminado es 1)
|
go_back |
Vuelve a la página web anterior en el historial del navegador. | intent: str |
type |
Escribe texto. |
text: strintent: strpress_enter: bool(Opcional, predeterminado: falso)
|
drag_and_drop |
Arrastra el elemento de start_y y start_x a end_y y end_x |
start_y: int (0-999)start_x: int (0-999)end_y: int (0-999)end_x: int (0-999)intent: str
|
long_press |
Mantiene presionada una coordenada específica y (0-999), x (0-999) en la pantalla. |
y: int (0-999)x: int (0-999)intent: strseconds: int (opcional, valor predeterminado 2)
|
press_key |
Presiona la tecla especificada y la suelta. |
key: strintent: str
|
take_screenshot |
Muestra una captura de pantalla de la pantalla actual. | intent: str |
Entorno de escritorio
| Nombre del comando | Descripción | Argumentos (en la llamada a función) |
|---|---|---|
click |
Hace clic con el botón izquierdo en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
double_click |
Hace doble clic en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
triple_click |
Hace clic tres veces en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
middle_click |
Hace clic con el botón central en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
right_click |
Hace clic con el botón derecho en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
mouse_down |
Mantiene presionado el botón del mouse en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
mouse_up |
Suelta el botón del mouse en la coordenada. |
y: int (0-999)x: int (0-999)intent: str
|
move |
Mueve el cursor a la posición especificada. |
y: int (0-999)x: int (0-999)intent: str
|
type |
Escribe texto. |
text: strintent: strpress_enter: bool(Opcional, falso de forma predeterminada)
|
drag_and_drop |
Arrastra el elemento de start_y y start_x a end_y y end_x. |
start_y: int (0-999)start_x: int (0-999)end_y: int (0-999)end_x: int (0-999)intent: str
|
wait |
Espera la cantidad de segundos especificada. |
intent: strseconds: int(opcional, el valor predeterminado es 1)
|
press_key |
Presiona la tecla especificada y la suelta. |
key: strintent: str
|
key_down |
Mantiene presionada la tecla especificada. |
key: strintent: str
|
key_up |
Suelta la tecla especificada. |
key: strintent: str
|
hotkey |
Presiona la combinación de teclas especificada. |
keys: List[str]intent: str
|
take_screenshot |
Muestra una captura de pantalla de la pantalla actual. | intent: str |
scroll |
Se desplaza hacia arriba, abajo, izquierda o derecha en una coordenada por una distancia de píxeles. |
y: int (0-999)x: int (0-999)direction: str ("up", "down", "left", "right")intent: strmagnitude_in_pixels: int (0-999, opcional, valor predeterminado 300)
|
Gemini 3 Flash
| Nombre del comando | Descripción | Argumentos (en la llamada a función) | Ejemplo de llamada a función |
|---|---|---|---|
| open_web_browser | Abre el navegador web. | Ninguno | {"name": "open_web_browser", "args": {}} |
| wait_5_seconds | Pausa la ejecución durante 5 segundos para permitir que se cargue el contenido dinámico o que se completen las animaciones. | Ninguno | {"name": "wait_5_seconds", "args": {}} |
| go_back | Navega a la página anterior en el historial del navegador. | Ninguno | {"name": "go_back", "args": {}} |
| go_forward | Navega a la página siguiente del historial del navegador. | Ninguno | {"name": "go_forward", "args": {}} |
| search | Navega a la página principal del motor de búsqueda predeterminado (por ejemplo, Google). Es útil para iniciar una nueva tarea de búsqueda. | Ninguno | {"name": "search", "args": {}} |
| navigate | Navega el navegador directamente a la URL especificada. | url: str |
{"name": "navigate", "args": {"url": "https://www.wikipedia.org"}}
|
| click_at | Hace clic en una coordenada específica de la página web. Los valores x e y se basan en una cuadrícula de 1,000 x 1,000 y se ajustan a las dimensiones de la pantalla. | y: int (0-999), x: int (0-999) |
{"name": "click_at", "args": {"y": 300, "x": 500}}
|
| hover_at | 521963309 Coloca el mouse sobre una coordenada específica de la página web. Es útil para revelar submenús. x e y se basan en una cuadrícula de 1000 × 1000. | y: int (0-999) x: int (0-999) |
{"name": "hover_at", "args": {"y": 150, "x": 250}}
|
| type_text_at | Escribe texto en una coordenada específica. De forma predeterminada, primero se borra el campo y se presiona INTRO después de escribir, pero estas acciones se pueden inhabilitar. x e y se basan en una cuadrícula de 1000 x 1000. |
y: int (0-999), x: int (0-999),
text: str, press_enter: bool (opcional,
valor predeterminado True), clear_before_typing: bool (opcional,
valor predeterminado True)
|
{"name": "type_text_at", "args": {"y": 250, "x": 400,
"text": "search query", "press_enter": false}}
|
| key_combination | Presiona teclas o combinaciones de teclado, como "Control+C" o "Intro". Es útil para activar acciones (como enviar un formulario con "Intro") o realizar operaciones en el portapapeles. |
keys: str (por ejemplo, 'enter', 'control+c'). Consulta la referencia de la API para ver la lista completa de claves permitidas.
|
{"name": "key_combination", "args": {"keys":
"Control+A"}}
|
| scroll_document | Desplaza toda la página web "hacia arriba", "hacia abajo", "hacia la izquierda" o "hacia la derecha". | direction: str ("up", "down", "left" o "right") |
{"name": "scroll_document", "args": {"direction": "down"}}
|
| scroll_at | Desplaza un elemento o un área específicos en la coordenada (x, y) en la dirección especificada según una magnitud determinada. Las coordenadas y la magnitud (800 de forma predeterminada) se basan en una cuadrícula de 1000 x 1000. |
y: int (0-999), x: int (0-999),
direction: str ("up", "down", "left", "right"),
magnitude: int (0-999, opcional, predeterminado 800)
|
{"name": "scroll_at", "args": {"y": 500, "x": 500,
"direction": "down", "magnitude": 400}}
|
| drag_and_drop | Arrastra un elemento desde una coordenada de inicio (x, y) y lo suelta en una coordenada de destino (destination_x, destination_y). Todas las coordenadas se basan en una cuadrícula de 1000 × 1000. |
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}}
|
Seguridad y protección
En esta sección, se describen las protecciones que tiene la herramienta de uso de la computadora para mejorar el control y la seguridad de los usuarios. También se describen las prácticas recomendadas para mitigar los posibles riesgos nuevos que podría presentar la herramienta.
Reconoce la decisión de seguridad
Según la acción, la respuesta del modelo puede incluir un
safety_decision de un sistema de seguridad interno. Esta decisión verifica la
acción que propone la herramienta para garantizar la seguridad.
{
"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"
}
}
}
}
]
}
}
Si el safety_decision es require_confirmation, debes pedirle al usuario final que confirme antes de continuar con la ejecución de la acción.
En la siguiente muestra de código, se solicita la confirmación del usuario final antes de ejecutar la
acción. Si el usuario no confirma la acción, el bucle finaliza. Si el usuario
confirma la acción, esta se ejecuta y el campo safety_acknowledgement
se marca 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 ...
Si el usuario confirma, debes incluir el reconocimiento de seguridad en tu 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
)
)
]
)
)
Detección de inyección de instrucciones
El uso de la computadora en Gemini 3.5 Flash o versiones posteriores admite
un mecanismo de seguridad avanzado para detectar ataques de inyección de instrucciones. Cuando está habilitada,
esta función verifica si una captura de pantalla incluida tiene el potencial de introducir un
ataque de inyección de instrucciones. Puedes establecer esta función en la configuración de uso de la computadora. El valor predeterminado es false.
En los siguientes ejemplos, se muestra cómo habilitar la configuración de uso de la computadora para habilitar la detección de inyección de instrucciones:
API de REST
Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:
- PROJECT_ID: ID del proyecto
HTTP method and URL:
POST https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.5-flash:generateContent
Cuerpo JSON de la solicitud:
{
"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 tu solicitud, expande una de estas opciones:
Deberías recibir un código de estado exitoso (2xx) y una respuesta vacía.
Python
En el siguiente ejemplo, se requiere la versión 2.7.0 o posterior de 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ácticas recomendadas de seguridad
El uso de computadoras presenta riesgos que los desarrolladores deben tener en cuenta:
- Contenido no confiable y estafas: Mientras el modelo intenta alcanzar el objetivo del usuario, puede depender de fuentes de información e instrucciones no confiables de la pantalla.
- Acciones ocasionales no deseadas: El modelo puede malinterpretar el objetivo de un usuario o el contenido de una página web, lo que hace que realice acciones incorrectas, como hacer clic en el botón equivocado o completar el formulario incorrecto.
- Incumplimientos de políticas: Las funciones de la API podrían dirigirse a actividades que incumplen las condiciones y políticas de Google, como omitir CAPTCHA o comprometer la integridad del sistema.
Para abordar estos riesgos, debes implementar las siguientes medidas de seguridad y prácticas recomendadas:
- Con intervención humana (HITL):
- Implementa la confirmación del usuario: Cuando la respuesta de seguridad indique
require_confirmation, debes implementar la confirmación del usuario antes de la ejecución. - Proporciona instrucciones de seguridad personalizadas: Además de las verificaciones de confirmación del usuario integradas, los desarrolladores pueden agregar de forma opcional una instrucción del sistema personalizada que aplique sus propias políticas de seguridad, ya sea para bloquear ciertas acciones del modelo o requerir la confirmación del usuario antes de que el modelo realice ciertas acciones irreversibles de alto riesgo.
Haz clic para ver un ejemplo de instrucción del sistema de seguridad personalizada
## **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.
- Implementa la confirmación del usuario: Cuando la respuesta de seguridad indique
- Entorno de ejecución seguro: Ejecuta tu agente en un entorno seguro y aislado para limitar su impacto potencial (por ejemplo, una máquina virtual (VM) aislada, un contenedor (como Docker) o un perfil de navegador dedicado con permisos limitados).
- Limpieza de entradas: Limpia todo el texto generado por el usuario en las instrucciones para mitigar el riesgo de instrucciones no deseadas o inyección de instrucciones. Esta es una capa de seguridad útil, pero no reemplaza un entorno de ejecución seguro.
- Protecciones de contenido: Usa protecciones y APIs de seguridad de contenido (como Model Armor) para evaluar las entradas de los usuarios, las entradas y salidas de las herramientas, y las respuestas del agente en busca de adecuación, inyección de instrucciones y detección de jailbreak.
- Listas de entidades permitidas y bloqueadas: Implementa mecanismos de filtrado para controlar por dónde puede navegar el modelo y qué puede hacer. Una lista de entidades bloqueadas de sitios web prohibidos es un buen punto de partida, mientras que una lista de entidades permitidas más restrictiva es aún más segura.
- Observabilidad y registro: Mantén registros detallados para la depuración,
la auditoría y la respuesta ante incidentes. Tu cliente debe registrar las instrucciones,
las capturas de pantalla, las acciones sugeridas por el modelo (
function_call), las respuestas de seguridad y todas las acciones que finalmente ejecute el cliente. - Administración del entorno: Asegúrate de que el entorno de la GUI sea coherente. Las ventanas emergentes inesperadas, las notificaciones del sistema o los cambios de diseño pueden confundir al modelo. Comienza desde un estado conocido y limpio para cada tarea nueva cuando sea posible.
Confirmaciones con intervención humana (HITL)
Las confirmaciones con intervención humana (HITL) son el proceso de solicitar la confirmación del usuario antes de ejecutar una acción sugerida por el modelo. Este proceso es necesario cuando el modelo no puede realizar una acción debido a problemas de seguridad.
La herramienta de uso de la computadora de Gemini proporciona los siguientes mecanismos para controlar las confirmaciones de HITL:
- A nivel del desarrollador: Los desarrolladores pueden configurar si se aplican o no algunas o todas las confirmaciones de HITL predeterminadas.
- A nivel de la organización: Los administradores de la organización pueden crear una política a nivel de la organización que impida que los desarrolladores individuales inhabiliten algunas o todas las confirmaciones de HITL. Esta política reemplaza cualquier parámetro de configuración a nivel del desarrollador.
Anula las confirmaciones de HITL
Puedes anular las siguientes confirmaciones de HITL predeterminadas:
FINANCIAL_TRANSACTIONS: Es la finalización del último paso de una transacción financiera (como pagos, transferencias de fondos, emisión de una orden de pago, inicio o modificación de una suscripción, o finalización de una reserva).SENSITIVE_DATA_MODIFICATION: Modificación de información sensible, como registros de atención médica, financieros o gubernamentales.COMMUNICATION_TOOL: Acceso a herramientas de comunicación o uso de ellas para enviar, compartir, publicar o transmitir comunicaciones de cualquier otra formaACCOUNT_CREATION: Es la interacción con los flujos de registro o de acceso que crean o aprovisionan cuentas de servicio o de usuario nuevas.DATA_MODIFICATION: Modificación, administración, uso compartido, almacenamiento, envío o eliminación de datos de navegación o archivos del navegador.USER_CONSENT_MANAGEMENT: Es la interacción con los diálogos o banners de consentimiento del usuario para tomar una decisión.LEGAL_TERMS_AND_AGREEMENTS: Interacción con diálogos de acuerdos legalmente vinculantes, como la aceptación de las condiciones del servicio, los diálogos de la política de privacidad o los avisos legales.
Puedes anular algunas o todas estas confirmaciones de HITL si las incluyes en
el campo disabled_safety_policies de la configuración de uso de la computadora:
Python
API de 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 de 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 de 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 de 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"
]
}
]
}Crea políticas de la organización
Si eres administrador de la organización, puedes crear una política a nivel de la organización con el servicio de Política de la organización que impida que los desarrolladores individuales inhabiliten algunas o todas las confirmaciones de HITL. Esta política reemplaza cualquier parámetro de configuración a nivel del desarrollador.
Puedes crear una política con la
consola deGoogle Cloud
o con
Google Cloud CLI.
El ID de la restricción es vertexai.configurableComputerUseToolSafetyPolicies.
Los cambios en la política de la organización pueden tardar hasta una hora en propagarse.
Para obtener todos los detalles sobre cómo crear y administrar políticas de la organización, consulta Crea políticas de la organización.
Precios
El uso de la computadora tiene el mismo precio que Gemini y usa los mismos SKU. Para dividir los costos de uso de procesamiento, usa etiquetas de metadatos personalizadas. Para obtener más información sobre el uso de etiquetas de metadatos personalizados para la supervisión de costos, consulta Etiquetas de metadatos personalizados.