Computer Use 도구를 사용하면 브라우저, 모바일, 데스크톱 제어 에이전트를 빌드하여 태스크와 상호작용하고 태스크를 자동화할 수 있습니다. 스크린샷을 사용하면 모델이 컴퓨터 화면을 '보고' 마우스 클릭 및 키보드 입력과 같은 특정 UI 작업을 생성하여 '작업'할 수 있습니다. 함수 호출과 마찬가지로 Computer Use 작업을 수신하고 실행하는 클라이언트 측 실행 환경을 구현해야 합니다.
지원되는 모델 목록은 모델 버전을 참고하세요. Gemini 3.x 모델은 다음과 같은 여러 고급 기능을 지원합니다.
- 멀티 환경 지원: 브라우저, 모바일, 데스크톱 환경용 빌드 에이전트
- 의도를 사용한 간소화된 작업: 작업에는 각 단계의 모델 추론을 설명하는
intent필드가 포함됩니다. - 구성 가능한 안전 정책: 내장 정책 카테고리 및 재정의를 사용하여 안전 동작을 미세 조정합니다.
- 프롬프트 인젝션 감지: 숨겨진 적대적 명령어를 감지하려면 스크린샷 스캔을 선택하세요.
Computer Use를 사용하면 다음 작업을 할 수 있는 에이전트를 빌드할 수 있습니다.
- 웹사이트에서 반복적인 데이터 입력과 양식 작성을 자동화합니다.
- 웹 애플리케이션 및 사용자 흐름의 자동 테스트 실행
- 다양한 웹사이트에서 조사 수행 (예: 전자상거래 사이트에서 제품 정보, 가격, 리뷰를 수집하여 구매에 대한 정보 제공)
다음은 브라우저 환경에서 computer_use 도구를 사용 설정하여 클라이언트를 초기화하고 모델에 프롬프트를 전송하는 간단한 예시입니다.
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Search for 'Gemini API' on Google.",
tools=[{"type": "computer_use", "environment": "browser"}]
)
print(interaction)
자바스크립트
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const interaction = await ai.interactions.create({
model: 'gemini-3.8-flash',
input: "Search for 'Gemini API' on Google.",
tools: [{ type: "computer_use", environment: "browser" }]
});
console.log(interaction);
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
Computer Use 작동 방식
컴퓨터 사용 모델을 사용하는 에이전트를 구축하려면 애플리케이션과 API 간에 지속적인 루프를 설정해야 합니다. 각 단계에서 코드가 실행하는 작업은 다음과 같습니다.
- 모델에게 요청을 보냅니다
- 애플리케이션은 Computer Use 도구, 구성 설정 (예: 타겟 환경), 사용자 프롬프트, 현재 화면의 스크린샷이 포함된 API 요청을 전송합니다.
- 모델 대답 수신
- 모델은 화면과 프롬프트를 분석하여 UI 작업을 나타내는 추천
function_call(예: 클릭, 스크롤, 키 입력)이 포함된 대답을 반환합니다. - Gemini 3.x 모델의 경우 모델이 해당 작업을 선택한 이유를 설명하는 추론
intent도 응답에 포함됩니다. - 대답에는 작업을 일반/허용,
require_confirmation(사용자 승인 필요) 또는 차단으로 분류하는 내부 안전 시스템의safety_decision도 포함될 수 있습니다.
- 모델은 화면과 프롬프트를 분석하여 UI 작업을 나타내는 추천
- 수신된 작업 실행
- 동작이 허용되거나 사용자가 확인하면 클라이언트 측 코드는
function_call를 파싱하고, 정규화된 좌표를 뷰포트에 맞게 조정하고, 자동화 도구(예: Playwright)를 사용하여 대상 환경에서 동작을 실행합니다. 작업이 차단되면 클라이언트는 실행을 중지하거나 중단을 처리해야 합니다.
- 동작이 허용되거나 사용자가 확인하면 클라이언트 측 코드는
- 새 환경 상태 캡처
- 작업이 실행되면 애플리케이션이 새 스크린샷을 캡처하고 다음 단계를 요청하기 위해
function_result에서 모델에 다시 전송합니다.
- 작업이 실행되면 애플리케이션이 새 스크린샷을 캡처하고 다음 단계를 요청하기 위해
그런 다음 이 프로세스는 2단계부터 반복되어 작업이 완료되거나 종료될 때까지 모델에서 다음 작업을 계속 요청합니다.

컴퓨터 사용 구현 방법
컴퓨터 사용 도구로 빌드하기 전에 다음을 설정해야 합니다.
- 안전한 실행 환경: 샌드박스 VM 또는 컨테이너에서 에이전트를 실행하여 호스트 시스템에서 격리하고 잠재적 영향을 제한합니다. 참조 구현에는 시작점으로 사용할 수 있는 즉시 사용 가능한 Docker 기반 샌드박스가 포함되어 있습니다.
- 클라이언트 측 작업 핸들러: 좌표를 실행하고, 텍스트를 입력하고, 스크린샷을 찍는 클라이언트 측 로직을 구현합니다.
아래 예에서는 웹브라우저를 실행 환경으로 사용하고 Playwright를 클라이언트 측 핸들러로 사용합니다.
0. Playwright 설정
먼저 필요한 패키지를 설치합니다.
pip install google-genai playwright
playwright install chromium
그런 다음 실행에 사용할 Playwright 브라우저 인스턴스를 초기화합니다.
from playwright.sync_api import sync_playwright
# 1. Configure screen dimensions for the target environment
SCREEN_WIDTH = 1440
SCREEN_HEIGHT = 900
# 2. Start the Playwright browser
# In production, utilize a sandboxed environment.
playwright = sync_playwright().start()
# Set headless=False to see the actions performed on your screen
browser = playwright.chromium.launch(headless=False)
# 3. Create a context and page with the specified dimensions
context = browser.new_context(
viewport={"width": SCREEN_WIDTH, "height": SCREEN_HEIGHT}
)
page = context.new_page()
# 4. Navigate to an initial page to start the task
page.goto("https://www.google.com")
# The 'page', 'SCREEN_WIDTH', and 'SCREEN_HEIGHT' variables
# will be used in the steps below.
1. 모델에 요청 보내기
클라이언트 라이브러리를 초기화하고 Computer Use 도구를 구성합니다. 요청을 발행할 때 디스플레이 크기를 지정할 필요는 없습니다. 모델은 화면의 높이와 너비에 맞게 조정된 픽셀 좌표를 예측합니다.
Gemini 3.x
Python
google-genai Python SDK (버전 2.7.0 이상)를 사용하여 브라우저 환경을 타겟팅하는 요청을 구성합니다.
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model='gemini-3.8-flash',
input="Find a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th",
tools=[
{
"type": "computer_use",
"environment": "browser",
"enable_prompt_injection_detection": True
}
]
)
print(interaction)
자바스크립트
@google/genai Node.js SDK를 사용하여 브라우저 환경을 타겟팅하는 요청을 구성합니다.
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const interaction = await ai.interactions.create({
model: 'gemini-3.8-flash',
input: "Find a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th",
tools: [
{
type: "computer_use",
environment: "browser",
enable_prompt_injection_detection: true
}
]
});
console.log(interaction);
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
REST
curl을 사용하여 요청을 보냅니다.
curl -X POST \
"https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "Find me a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th. Start by navigating directly to flights.google.com",
"tools": [
{
"type": "computer_use",
"environment": "browser",
"enable_prompt_injection_detection": true
}
]
}'
Gemini 2.5 (기존)
Python
from google import genai
client = genai.Client()
# Specify predefined functions to exclude (optional)
excluded_functions = ["drag_and_drop"]
interaction = client.interactions.create(
model='gemini-2.5-computer-use-preview-10-2025',
input="Search for highly rated smart fridges on Google Shopping.",
tools=[
{
"type": "computer_use",
"environment": "browser",
"excluded_predefined_functions": excluded_functions
}
]
)
print(interaction)
자바스크립트
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
// Specify predefined functions to exclude (optional)
const excludedFunctions = ["drag_and_drop"];
const interaction = await ai.interactions.create({
model: 'gemini-2.5-computer-use-preview-10-2025',
input: "Search for highly rated smart fridges on Google Shopping.",
tools: [
{
type: "computer_use",
environment: "browser",
excluded_predefined_functions: excludedFunctions
}
]
});
console.log(interaction);
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
2. 모델 응답 수신
대답 모델이 함수 호출을 제안합니다. Gemini 3.x 모델의 경우 응답에는 좌표와 함께 맞춤형 추론 의도가 포함됩니다. 다음은 두 응답의 예시를 보여줍니다.
Gemini 3.x
{
"steps": [
{
"type": "function_call",
"name": "click",
"arguments": {
"x": 450,
"y": 120,
"intent": "Click the search box to type the destination."
}
}
]
}
Gemini 2.5 (기존)
{
"steps": [
{
"type": "model_output",
"content": [
{
"type": "text",
"text": "I will type the search query into the search bar."
}
]
},
{
"type": "function_call",
"name": "type_text_at",
"arguments": {
"x": 371,
"y": 470,
"text": "highly rated smart fridges",
"press_enter": true
}
}
]
}
3. 수신된 작업 실행
애플리케이션은 응답 좌표를 파싱하고 작업을 실행하고 정규화된 1000x1000 좌표에서 확장해야 합니다.
아래 코드는 기존 도구 명령어 (click_at, type_text_at)와 최신 간소화된 명령어 (click, type)를 모두 처리합니다.
Python
from typing import Any, List, Tuple
import time
def denormalize_x(x: int, screen_width: int) -> int:
"""Convert normalized x coordinate (0-1000) to actual pixel coordinate."""
return int(x / 1000 * screen_width)
def denormalize_y(y: int, screen_height: int) -> int:
"""Convert normalized y coordinate (0-1000) to actual pixel coordinate."""
return int(y / 1000 * screen_height)
def execute_function_calls(interaction, page, screen_width, screen_height):
results = []
function_calls = [
step for step in interaction.steps if step.type == "function_call"
]
for function_call in function_calls:
action_result = {}
fname = function_call.name
args = function_call.arguments
print(f" -> Executing: {fname} (Intent: {args.get('intent', 'N/A')})")
try:
if fname in ("open_web_browser", "open_app"):
pass # Handled / already open
elif fname in ("click", "click_at", "double_click", "triple_click", "middle_click", "right_click", "move", "long_press"):
actual_x = denormalize_x(args["x"], screen_width)
actual_y = denormalize_y(args["y"], screen_height)
if fname in ("click", "click_at"):
page.mouse.click(actual_x, actual_y)
elif fname == "double_click":
page.mouse.dblclick(actual_x, actual_y)
elif fname == "right_click":
page.mouse.click(actual_x, actual_y, button="right")
elif fname == "middle_click":
page.mouse.click(actual_x, actual_y, button="middle")
elif fname == "move":
page.mouse.move(actual_x, actual_y)
elif fname in ("type", "type_text_at"):
actual_x = denormalize_x(args["x"], screen_width) if "x" in args else None
actual_y = denormalize_y(args["y"], screen_height) if "y" in args else None
text = args["text"]
press_enter = args.get("press_enter", False)
if actual_x is not None and actual_y is not None:
page.mouse.click(actual_x, actual_y)
# Clear field first
page.keyboard.press("Meta+A")
page.keyboard.press("Backspace")
page.keyboard.type(text)
if press_enter:
page.keyboard.press("Enter")
elif fname == "navigate":
page.goto(args["url"])
elif fname == "go_back":
page.go_back()
elif fname == "go_forward":
page.go_forward()
elif fname == "wait":
time.sleep(args.get("seconds", 1))
else:
print(f"Warning: Custom or unhandled function {fname}")
page.wait_for_load_state(timeout=5000)
time.sleep(1)
except Exception as e:
print(f"Error executing {fname}: {e}")
action_result = {"error": str(e)}
results.append((fname, function_call.id, action_result))
return results
자바스크립트
function denormalizeX(x, screenWidth) {
// Convert normalized x coordinate (0-1000) to actual pixel coordinate.
return Math.floor((x / 1000) * screenWidth);
}
function denormalizeY(y, screenHeight) {
// Convert normalized y coordinate (0-1000) to actual pixel coordinate.
return Math.floor((y / 1000) * screenHeight);
}
async function executeFunctionCalls(interaction, page, screenWidth, screenHeight) {
const results = [];
const functionCalls = interaction.steps.filter(step => step.type === "function_call");
for (const functionCall of functionCalls) {
const actionResult = {};
const fname = functionCall.name;
const args = functionCall.arguments;
console.log(` -> Executing: ${fname} (Intent: ${args.intent || 'N/A'})`);
try {
if (fname === "open_web_browser" || fname === "open_app") {
// Handled / already open
} else if (["click", "click_at", "double_click", "triple_click", "middle_click", "right_click", "move", "long_press"].includes(fname)) {
const actualX = denormalizeX(args.x, screenWidth);
const actualY = denormalizeY(args.y, screenHeight);
if (fname === "click" || fname === "click_at") {
await page.mouse.click(actualX, actualY);
} else if (fname === "double_click") {
await page.mouse.dblclick(actualX, actualY);
} else if (fname === "right_click") {
await page.mouse.click(actualX, actualY, { button: "right" });
} else if (fname === "middle_click") {
await page.mouse.click(actualX, actualY, { button: "middle" });
} else if (fname === "move") {
await page.mouse.move(actualX, actualY);
}
} else if (fname === "type" || fname === "type_text_at") {
const actualX = args.x !== undefined ? denormalizeX(args.x, screenWidth) : null;
const actualY = args.y !== undefined ? denormalizeY(args.y, screenHeight) : null;
const text = args.text;
const pressEnter = args.press_enter || false;
if (actualX !== null && actualY !== null) {
await page.mouse.click(actualX, actualY);
}
// Clear field first
await page.keyboard.press("Meta+A");
await page.keyboard.press("Backspace");
await page.keyboard.type(text);
if (pressEnter) {
await page.keyboard.press("Enter");
}
} else if (fname === "navigate") {
await page.goto(args.url);
} else if (fname === "go_back") {
await page.goBack();
} else if (fname === "go_forward") {
await page.goForward();
} else if (fname === "wait") {
await new Promise(resolve => setTimeout(resolve, (args.seconds || 1) * 1000));
} else {
console.log(`Warning: Custom or unhandled function ${fname}`);
}
await page.waitForLoadState('load', { timeout: 5000 }).catch(() => {});
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (e) {
console.log(`Error executing ${fname}: ${e}`);
actionResult.error = e.message;
}
results.push([fname, functionCall.id, actionResult]);
}
return results;
}
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
4. 새 환경 상태 캡처
작업을 실행한 후 이 정보를 사용하여 다음 작업을 생성할 수 있도록 함수 실행 결과를 모델에 다시 전송합니다. 작업 여러 개(병렬 호출)가 실행된 경우 후속 사용자 턴에서 작업마다 function_result를 전송해야 합니다.
Python
import json
import base64
def get_function_responses(page, results):
screenshot_bytes = page.screenshot(type="png")
current_url = page.url
function_responses = []
for name, call_id, result in results:
function_responses.append({
"type": "function_result",
"name": name,
"call_id": call_id,
"result": [
{
"type": "text",
"text": json.dumps({"url": current_url, **result})
},
{
"type": "image",
"data": base64.b64encode(screenshot_bytes).decode("utf-8"),
"mime_type": "image/png"
}
]
})
return function_responses
자바스크립트
async function getFunctionResponses(page, results) {
const screenshotBuffer = await page.screenshot({ type: 'png' });
const screenshotBase64 = screenshotBuffer.toString('base64');
const currentUrl = page.url();
const functionResponses = [];
for (const [name, callId, result] of results) {
functionResponses.push({
type: "function_result",
name: name,
call_id: callId,
result: [
{
type: "text",
text: JSON.stringify({ url: currentUrl, ...result })
},
{
type: "image",
data: screenshotBase64,
mime_type: "image/png"
}
]
});
}
return functionResponses;
}
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
환경 상태를 캡처하고 포맷하는 방법을 정의한 후에는 이러한 모든 단계를 연속 실행 루프로 결합할 수 있습니다.
에이전트 루프 빌드
다단계 상호작용을 사용 설정하려면 컴퓨터 사용 구현 방법 섹션의 네 단계를 단일 루프로 결합합니다. 이 루프는 작업이 완료될 때까지 작업을 요청하고 결과를 모델에 다시 제공합니다.
대화 기록을 올바르게 관리하려면 각 단계에서 모델 응답과 함수 응답을 모두 기록에 추가해야 합니다.
Python
import time
from typing import Any, List, Tuple
from playwright.sync_api import sync_playwright
from google import genai
client = genai.Client()
# Constants for screen dimensions
SCREEN_WIDTH = 1440
SCREEN_HEIGHT = 900
# Setup Playwright
print("Initializing browser...")
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
context = browser.new_context(viewport={"width": SCREEN_WIDTH, "height": SCREEN_HEIGHT})
page = context.new_page()
# Define helper functions. Copy/paste from steps 3 and 4
# def denormalize_x(...)
# def denormalize_y(...)
# def execute_function_calls(...)
# def get_function_responses(...)
try:
# Go to initial page
page.goto("https://ai.google.dev/gemini-api/docs")
# Take initial screenshot
initial_screenshot = page.screenshot(type="png")
USER_PROMPT = "Go to ai.google.dev/gemini-api/docs and search for pricing."
print(f"Goal: {USER_PROMPT}")
# First interaction
interaction = client.interactions.create(
model='gemini-3.8-flash',
input=[
{"type": "text", "text": USER_PROMPT},
{"type": "image", "data": base64.b64encode(initial_screenshot).decode("utf-8"), "mime_type": "image/png"}
],
tools=[{
"type": "computer_use",
"environment": "browser",
"enable_prompt_injection_detection": True
}]
)
# Agent Loop
turn_limit = 5
for i in range(turn_limit):
print(f"\n--- Turn {i+1} ---")
has_function_calls = any(
step.type == "function_call"
for step in interaction.steps
)
if not has_function_calls:
text_response = " ".join([
content_block.text for step in interaction.steps if step.type == "model_output"
for content_block in step.content if content_block.type == "text"
])
print("Agent finished:", text_response)
break
print("Executing actions...")
results = execute_function_calls(interaction, page, SCREEN_WIDTH, SCREEN_HEIGHT)
print("Capturing state...")
function_responses = get_function_responses(page, results)
# Continue conversation with function responses
interaction = client.interactions.create(
model='gemini-3.8-flash',
previous_interaction_id=interaction.id,
input=function_responses,
tools=[{
"type": "computer_use",
"environment": "browser",
"enable_prompt_injection_detection": True
}]
)
finally:
# Cleanup
print("\nClosing browser...")
browser.close()
playwright.stop()
자바스크립트
import { chromium } from 'playwright';
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
// Constants for screen dimensions
const SCREEN_WIDTH = 1440;
const SCREEN_HEIGHT = 900;
console.log("Initializing browser...");
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
viewport: { width: SCREEN_WIDTH, height: SCREEN_HEIGHT }
});
const page = await context.newPage();
// Define helper functions. Copy/paste from steps 3 and 4:
// function denormalizeX(...)
// function denormalizeY(...)
// async function executeFunctionCalls(...)
// async function getFunctionResponses(...)
try {
// Go to initial page
await page.goto("https://ai.google.dev/gemini-api/docs");
// Take initial screenshot
const initialScreenshotBuffer = await page.screenshot({ type: 'png' });
const initialScreenshotBase64 = initialScreenshotBuffer.toString('base64');
const USER_PROMPT = "Go to ai.google.dev/gemini-api/docs and search for pricing.";
console.log(`Goal: ${USER_PROMPT}`);
// First interaction
let interaction = await ai.interactions.create({
model: 'gemini-3.8-flash',
input: [
{ type: 'text', text: USER_PROMPT },
{ type: 'image', data: initialScreenshotBase64, mime_type: 'image/png' }
],
tools: [{
type: 'computer_use',
environment: 'browser',
enable_prompt_injection_detection: true
}]
});
// Agent Loop
const turnLimit = 5;
for (let i = 0; i < turnLimit; i++) {
console.log(`\n--- Turn ${i + 1} ---`);
const hasFunctionCalls = interaction.steps.some(step => step.type === "function_call");
if (!hasFunctionCalls) {
const textResponses = [];
for (const step of interaction.steps) {
if (step.type === "model_output") {
for (const contentBlock of step.content || []) {
if (contentBlock.type === "text") {
textResponses.push(contentBlock.text);
}
}
}
}
console.log("Agent finished:", textResponses.join(" "));
break;
}
console.log("Executing actions...");
const results = await executeFunctionCalls(interaction, page, SCREEN_WIDTH, SCREEN_HEIGHT);
console.log("Capturing state...");
const functionResponses = await getFunctionResponses(page, results);
// Continue conversation with function responses
interaction = await ai.interactions.create({
model: 'gemini-3.8-flash',
previous_interaction_id: interaction.id,
input: functionResponses,
tools: [{
type: 'computer_use',
environment: 'browser',
enable_prompt_injection_detection: true
}]
});
}
} finally {
// Cleanup
console.log("\nClosing browser...");
await browser.close();
}
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
지원되는 환경 (Gemini 3.x)
Gemini 3.x 모델은 computer_use 구성에 지정된 세 가지 환경을 지원합니다.
브라우저 환경 (ENVIRONMENT_BROWSER)
브라우저 도구에서 사용할 수 있는 작업:
| 명령어 이름 | 설명 | 인수 (함수 호출에서) |
|---|---|---|
| click | 좌표에서 왼쪽 클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| double_click | 좌표를 더블클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| triple_click | 좌표를 세 번 클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| middle_click | 좌표에서 가운데 클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| right_click | 좌표에서 마우스 오른쪽 버튼 클릭 | y: int (0~999)x: int (0~999)intent: str |
| mouse_down | 좌표에서 마우스 버튼을 누르고 있습니다. | y: int (0~999)x: int (0~999)intent: str |
| mouse_up | 좌표에서 마우스 버튼을 놓습니다. | y: int (0~999)x: int (0~999)intent: str |
| move | 커서를 지정된 위치로 이동합니다. | y: int (0~999)x: int (0~999)intent: str |
| type | 텍스트를 입력합니다. | text: strpress_enter: bool (선택사항, 기본값: false)intent: str |
| drag_and_drop | 시작 좌표에서 종료 좌표로 항목을 드래그합니다. | start_y: int (0~999)start_x: int (0~999)end_y: int (0~999)end_x: int (0~999)intent: str |
| wait | 지정된 시간(초) 동안 실행을 일시중지합니다. | seconds: int (선택사항, 기본값 1)intent: str |
| press_key | 지정된 키를 눌렀다가 놓습니다. | key: strintent: str |
| key_down | 지정된 키를 누른 상태로 유지합니다. | key: strintent: str |
| key_up | 지정된 키를 해제합니다. | key: strintent: str |
| 핫키 | 지정된 키 조합을 누릅니다. | keys: List[str]intent: str |
| take_screenshot | 현재 화면의 스크린샷을 반환합니다. | intent: 문자열 |
| scroll | 좌표에서 픽셀 거리만큼 위, 아래, 왼쪽 또는 오른쪽으로 스크롤합니다. | y: 정수 (0~999)x: 정수 (0~999)direction: 문자열 ("up", "down", "left", "right")magnitude_in_pixels: 정수 (0~999, 선택사항, 기본값: 300)intent: 문자열 |
| go_back | 브라우저 기록의 이전 웹페이지로 돌아갑니다. | intent: 문자열 |
| navigate | 지정된 URL로 직접 이동합니다. | url: strintent: str |
| go_forward | 브라우저 기록의 다음 웹페이지로 이동합니다. | intent: 문자열 |
모바일 환경 (ENVIRONMENT_MOBILE)
Android 최적화 환경 작업:
| 명령어 이름 | 설명 | 인수 (함수 호출에서) |
|---|---|---|
| open_app | 이름으로 애플리케이션을 엽니다. | app_name: strintent: str |
| click | 좌표에서 왼쪽 클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| list_apps | 기기에서 사용 가능한 애플리케이션을 나열하여 이름과 패키지 이름을 반환합니다. | intent: 문자열 |
| wait | 지정된 시간(초) 동안 실행을 일시중지합니다. | seconds: int (선택사항, 기본값 1)intent: str |
| go_back | 이전 화면이나 웹페이지로 돌아갑니다. | intent: 문자열 |
| type | 텍스트를 입력합니다. | text: strpress_enter: bool (선택사항, 기본값: false)intent: str |
| drag_and_drop | 시작 좌표에서 종료 좌표로 항목을 드래그합니다. | start_y: int (0~999)start_x: int (0~999)end_y: int (0~999)end_x: int (0~999)intent: str |
| long_press | 화면의 좌표에서 길게 누르기를 실행합니다. | y: int (0~999)x: int (0~999)seconds: int (선택사항, 기본값 2)intent: str |
| press_key | 지정된 키를 눌렀다가 놓습니다. | key: strintent: str |
| take_screenshot | 현재 화면의 스크린샷을 반환합니다. | intent: 문자열 |
데스크톱 환경 (ENVIRONMENT_DESKTOP)
데스크톱 환경 OS 수준 커서 명령:
| 명령어 이름 | 설명 | 인수 (함수 호출에서) |
|---|---|---|
| click | 좌표에서 왼쪽 클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| double_click | 좌표를 더블클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| triple_click | 좌표를 세 번 클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| middle_click | 좌표에서 가운데 클릭합니다. | y: int (0~999)x: int (0~999)intent: str |
| right_click | 좌표에서 마우스 오른쪽 버튼 클릭 | y: int (0~999)x: int (0~999)intent: str |
| mouse_down | 좌표에서 마우스 버튼을 누르고 있습니다. | y: int (0~999)x: int (0~999)intent: str |
| mouse_up | 좌표에서 마우스 버튼을 놓습니다. | y: int (0~999)x: int (0~999)intent: str |
| move | 커서를 지정된 위치로 이동합니다. | y: int (0~999)x: int (0~999)intent: str |
| type | 텍스트를 입력합니다. | text: strpress_enter: bool (선택사항, 기본값: false)intent: str |
| drag_and_drop | 시작 좌표에서 종료 좌표로 항목을 드래그합니다. | start_y: int (0~999)start_x: int (0~999)end_y: int (0~999)end_x: int (0~999)intent: str |
| wait | 지정된 시간(초) 동안 실행을 일시중지합니다. | seconds: int (선택사항, 기본값 1)intent: str |
| press_key | 지정된 키를 눌렀다가 놓습니다. | key: strintent: str |
| key_down | 지정된 키를 누른 상태로 유지합니다. | key: strintent: str |
| key_up | 지정된 키를 해제합니다. | key: strintent: str |
| 핫키 | 지정된 키 조합을 누릅니다. | keys: List[str]intent: str |
| take_screenshot | 현재 화면의 스크린샷을 반환합니다. | intent: 문자열 |
| scroll | 좌표에서 픽셀 거리만큼 위, 아래, 왼쪽 또는 오른쪽으로 스크롤합니다. | y: 정수 (0~999)x: 정수 (0~999)direction: 문자열 ("up", "down", "left", "right")magnitude_in_pixels: 정수 (0~999, 선택사항, 기본값: 300)intent: 문자열 |
기존 지원 UI 작업 (Gemini 2.5)
기존 모델 (gemini-2.5-computer-use-preview-10-2025)의 경우 다음 작업이 지원됩니다.
| 명령어 이름 | 설명 | 인수 (함수 호출에서) | 함수 호출 예시 |
|---|---|---|---|
| open_web_browser | 웹브라우저를 엽니다. | 없음 | {"name": "open_web_browser", "arguments": {}} |
| wait_5_seconds | 5초 동안 실행을 일시중지합니다. | 없음 | {"name": "wait_5_seconds", "arguments": {}} |
| go_back | 방문 기록의 이전 페이지로 이동합니다. | 없음 | {"name": "go_back", "arguments": {}} |
| go_forward | 방문 기록의 다음 페이지로 이동합니다. | 없음 | {"name": "go_forward", "arguments": {}} |
| search | 기본 검색엔진으로 이동합니다. | 없음 | {"name": "search", "arguments": {}} |
| navigate | 브라우저를 지정된 URL로 직접 이동합니다. | url: 문자열 |
{"name": "navigate", "arguments": {"url": "https://www.wikipedia.org"}} |
| click_at | 특정 좌표를 클릭합니다. | y: 정수(0~999), x: 정수(0~999) |
{"name": "click_at", "arguments": {"y": 300, "x": 500}} |
| hover_at | 특정 좌표에 마우스를 가져갑니다. | y: 정수(0~999), x: 정수(0~999) |
{"name": "hover_at", "arguments": {"y": 150, "x": 250}} |
| type_text_at | 좌표에 텍스트를 입력합니다. | y: 정수 (0~999), x: 정수 (0~999), text: 문자열, press_enter: 불리언 (선택사항, 기본값: True), clear_before_typing: 불리언 (선택사항, 기본값: True) |
{"name": "type_text_at", "arguments": {"y": 250, "x": 400, "text": "search", "press_enter": false}} |
| key_combination | 키 또는 조합을 누릅니다. | keys: 문자열 |
{"name": "key_combination", "arguments": {"keys": "Control+A"}} |
| scroll_document | 전체 웹페이지를 스크롤합니다. | direction: 문자열 |
{"name": "scroll_document", "arguments": {"direction": "down"}} |
| scroll_at | 좌표 (x,y)에서 스크롤합니다. | y: int, x: int, direction: str, magnitude: int (선택사항, 기본값: 800) |
{"name": "scroll_at", "arguments": {"y": 500, "x": 500, "direction": "down"}} |
| drag_and_drop | 두 좌표 사이를 드래그합니다. | y: int, x: int, destination_y: int, destination_x: int |
{"name": "drag_and_drop", "arguments": {"y": 100, "destination_y": 500, "destination_x": 500, "x": 100}} |
맞춤 사용자 정의 함수
맞춤 사용자 정의 함수를 포함하여 모델의 기능을 확장할 수 있습니다. 예를 들어 인간 참여형 (HITL) 시나리오에서 기본 사전 정의된 작업을 제외하고 맞춤 작업을 등록할 수 있습니다.
Gemini 3.x 맞춤 도구
Python
표준 사전 정의된 브라우저 작업 (예: click)을 제외하고 맞춤 yield_to_user 도구를 등록합니다.
from google import genai
client = genai.Client()
yield_to_user_tool = {
"type": "function",
"name": "yield_to_user",
"description": "Yields control back to the user for assistance or verification when an automated action is unsafe or ambiguous.",
"parameters": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "The reason why the agent is yielding control to the human."
}
},
"required": ["reason"]
}
}
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Click the submit button. If you need a second factor authentication code, ask me.",
tools=[
{
"type": "computer_use",
"environment": "mobile",
"excluded_predefined_functions": ["click"]
},
yield_to_user_tool
]
)
자바스크립트
표준 사전 정의된 브라우저 작업 (예: click)을 제외하고 맞춤 yield_to_user 도구를 등록합니다.
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const yieldToUserTool = {
type: "function",
name: "yield_to_user",
description: "Yields control back to the user for assistance or verification when an automated action is unsafe or ambiguous.",
parameters: {
type: "object",
properties: {
reason: {
type: "string",
description: "The reason why the agent is yielding control to the human."
}
},
required: ["reason"]
}
};
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "Click the submit button. If you need a second factor authentication code, ask me.",
tools: [
{
type: "computer_use",
environment: "mobile",
excluded_predefined_functions: ["click"]
},
yieldToUserTool
]
});
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
Gemini 2.5 (레거시) 맞춤 도구
Python
from google import genai
client = genai.Client()
# Define custom tools here
custom_functions = [...] # Describe parameters as function declarations
excluded_functions = [
"open_web_browser",
"wait_5_seconds",
"go_back",
"go_forward",
"search",
"navigate",
"hover_at",
"scroll_document",
"key_combination",
"drag_and_drop",
]
interaction = client.interactions.create(
model='gemini-2.5-computer-use-preview-10-2025',
input="Open Chrome, then long-press at 200,400.",
tools=[
{
"type": "computer_use",
"environment": "browser",
"excluded_predefined_functions": excluded_functions
},
*custom_functions
]
)
print(interaction)
자바스크립트
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
// Define custom tools here
const customFunctions = [...]; // Describe parameters as function declarations
const excludedFunctions = [
"open_web_browser",
"wait_5_seconds",
"go_back",
"go_forward",
"search",
"navigate",
"hover_at",
"scroll_document",
"key_combination",
"drag_and_drop",
];
const interaction = await ai.interactions.create({
model: 'gemini-2.5-computer-use-preview-10-2025',
input: "Open Chrome, then long-press at 200,400.",
tools: [
{
type: "computer_use",
environment: "browser",
excluded_predefined_functions: excludedFunctions
},
...customFunctions
]
});
console.log(interaction);
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
사고 수준 관리 (Gemini 3.x)
컴퓨터 사용 에이전트의 경우 작업 품질과 실행 속도의 균형을 맞추기 위해 다양한 사고 수준을 구성할 수 있습니다. 일반적으로 낮은 사고 수준이 표준 자동화 작업에 적합한 균형을 제공합니다.
안전 및 보안
안전 정책 구성 (Gemini 3.x)
Gemini 3.x 모델에는 사용자 확인이 필요한지 자동으로 판단하는 기본 안전 서비스 카테고리가 포함되어 있습니다.
| 안전 정책 카테고리 | 설명 |
|---|---|
FINANCIAL_TRANSACTIONS |
결제, 소매 결제 또는 규제 상품과 관련된 작업의 확인을 차단하거나 트리거합니다. |
SENSITIVE_DATA_MODIFICATION |
건강, 금융 또는 정부 기록을 무단 수정으로부터 보호합니다. |
COMMUNICATION_TOOL |
에이전트가 이메일, 채팅 메시지 또는 초안을 자율적으로 전송하는 것을 제한합니다. |
ACCOUNT_CREATION |
에이전트가 웹사이트에 새 계정을 자율적으로 등록하는 것을 제한합니다. |
DATA_MODIFICATION |
전반적인 파일 시스템 수정, 데이터 공유, 스토리지 삭제를 규제합니다. |
USER_CONSENT_MANAGEMENT |
쿠키 사용 동의 배너 및 개인 정보 보호 메시지에 사용자 인계가 필요합니다. |
LEGAL_TERMS_AND_AGREEMENTS |
모델이 서비스 약관이나 법적 구속력이 있는 계약을 자율적으로 수락하는 것을 방지합니다. |
안전 재정의
재정의를 전달하여 선택한 정책을 재정의할 수 있습니다.
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Clean up the local folder by archiving old logs.",
tools=[
{
"type": "computer_use",
"environment": "desktop",
"disabled_safety_policies": [
"data_modification"
]
}
]
)
자바스크립트
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "Clean up the local folder by archiving old logs.",
tools: [
{
type: "computer_use",
environment: "desktop",
disabled_safety_policies: [
"data_modification"
]
}
]
});
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
프롬프트 삽입 감지 (Gemini 3.x)
Gemini 3.5 Flash 이상의 Computer Use는 프롬프트 인젝션 공격을 감지하는 고급 안전 메커니즘을 지원합니다. 이 기능을 사용 설정하면 포함된 스크린샷에 숨겨진 적대적 명령어 (예: '이전 명령어 무시')가 포함되어 있는지 확인하고 감지되면 실행을 차단합니다.
프롬프트 삽입 감지는 선택 기능입니다. 기본값은 false입니다.
다음 예시에서는 Computer Use 도구 구성에서 프롬프트 삽입 감지를 사용 설정하는 방법을 보여줍니다.
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.5-flash",
input="Search for flight deals and summarize top results.",
tools=[
{
"type": "computer_use",
"environment": "desktop",
"enable_prompt_injection_detection": True,
}
],
)
자바스크립트
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const interaction = await ai.interactions.create({
model: "gemini-3.5-flash",
input: "Search for flight deals and summarize top results.",
tools: [
{
type: "computer_use",
environment: "desktop",
enablePromptInjectionDetection: true,
}
]
});
자바
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
cURL
curl "https://generativelanguage.googleapis.com/v1beta/interactions?key=${GEMINI_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"model": "gemini-3.5-flash",
"input": "Search for flight deals and summarize top results.",
"tools": [
{
"type": "computer_use",
"environment": "desktop",
"enable_prompt_injection_detection": true
}
]
}'
안전 결정 확인
대답에는 함수 호출 인수에서 safety_decision 매개변수가 포함될 수 있습니다.
{
"steps": [
{
"type": "function_call",
"name": "click_at",
"arguments": {
"x": 60,
"y": 100,
"safety_decision": {
"explanation": "Must check check-box",
"decision": "require_confirmation"
}
}
}
]
}
safety_decision이 require_confirmation인 경우 최종 사용자에게 메시지를 표시합니다. 사용자가 확인하면 function_result에서 safety_acknowledgement을 설정합니다.
Python
def get_safety_confirmation(safety_decision):
# Prompt user for confirmation
print(f"Safety confirmation required: {safety_decision.get('explanation', '')}")
return "CONTINUE" # Or TERMINATE
# Inside execute_function_calls, check for safety_decision:
if 'safety_decision' in function_call.arguments:
decision = get_safety_confirmation(function_call.arguments['safety_decision'])
if decision == "TERMINATE":
break
# Include safety_acknowledgement inside the action result
action_result["safety_acknowledgement"] = True
안전 권장사항
Computer Use는 모델이 사용자를 대신하여 작동할 때 화면에서 신뢰할 수 없는 콘텐츠를 접하거나 작업을 실행할 때 오류가 발생할 수 있으므로 고유한 보안 및 운영 위험이 있습니다. 사용자 데이터와 시스템을 보호하려면 다음 권장사항을 구현하세요.
- 인간 참여형 (HITL):
- 사용자 확인 시행: 안전 대답에
require_confirmation이 표시되면 (또는 기존 안전 결정에 필요한 경우) 사용자에게 승인을 요청합니다. 맞춤 안전 요청 사항 제공: 맞춤 시스템 요청 사항을 구현하여 자체 안전 경계를 정의하고 적용합니다. 예를 들면 다음과 같습니다.
Python
from google import genai client = genai.Client() system_instruction = """ ## **RULE 1: Seek User Confirmation (USER_CONFIRMATION)** This is your first and most important check. If the next required action falls into any of the following categories, you MUST stop immediately, and seek the user's explicit permission. **Procedure for Seeking Confirmation:** * **For Consequential Actions:** Perform all preparatory steps (e.g., navigating, filling out forms, typing a message). You will ask for confirmation **AFTER** all necessary information is entered on the screen, but **BEFORE** you perform the final, irreversible action (e.g., before clicking "Send", "Submit", "Confirm Purchase", "Share"). * **For Prohibited Actions:** If the action is strictly forbidden (e.g., accepting legal terms, solving a CAPTCHA), you must first inform the user about the required action and ask for their confirmation to proceed. **USER_CONFIRMATION Categories:** * **Consent and Agreements:** You are FORBIDDEN from accepting, selecting, or agreeing to any of the following on the user's behalf. You must ask the user to confirm before performing these actions. * Terms of Service * Privacy Policies * Cookie consent banners * End User License Agreements (EULAs) * Any other legally significant contracts or agreements. * **Robot Detection:** You MUST NEVER attempt to solve or bypass the following. You must ask the user to confirm before performing these actions. * CAPTCHAs (of any kind) * Any other anti-robot or human-verification mechanisms, even if you are capable. * **Financial Transactions:** * Completing any purchase. * Managing or moving money (e.g., transfers, payments). * Purchasing regulated goods or participating in gambling. * **Sending Communications:** * Sending emails. * Sending messages on any platform (e.g., social media, chat apps). * Posting content on social media or forums. * **Accessing or Modifying Sensitive Information:** * Health, financial, or government records (e.g., medical history, tax forms, passport status). * Revealing or modifying sensitive personal identifiers (e.g., SSN, bank account number, credit card number). * **User Data Management:** * Accessing, downloading, or saving files from the web. * Sharing or sending files/data to any third party. * Transferring user data between systems. * **Browser Data Usage:** * Accessing or managing Chrome browsing history, bookmarks, autofill data, or saved passwords. * **Security and Identity:** * Logging into any user account. * Any action that involves misrepresentation or impersonation (e.g., creating a fan account, posting as someone else). * **Insurmountable Obstacles:** If you are technically unable to interact with a user interface element or are stuck in a loop you cannot resolve, ask the user to take over. --- ## **RULE 2: Default Behavior (ACTUATE)** If an action does **NOT** fall under the conditions for `USER_CONFIRMATION`, your default behavior is to **Actuate**. **Actuation Means:** You MUST proactively perform all necessary steps to move the user's request forward. Continue to actuate until you either complete the non-consequential task or encounter a condition defined in Rule 1. * **Example 1:** If asked to send money, you will navigate to the payment portal, enter the recipient's details, and enter the amount. You will then **STOP** as per Rule 1 and ask for confirmation before clicking the final "Send" button. * **Example 2:** If asked to post a message, you will navigate to the site, open the post composition window, and write the full message. You will then **STOP** as per Rule 1 and ask for confirmation before clicking the final "Post" button. After the user has confirmed, remember to get the user's latest screen before continuing to perform actions. # Final Response Guidelines: Write final response to the user in the following cases: - User confirmation - When the task is complete or you have enough information to respond to the user """ interaction = client.interactions.create( model="gemini-3.8-flash", system_instruction=system_instruction, input="Prepare a draft but do not send.", tools=[{ "type": "computer_use", "environment": "browser" }] )자바스크립트
import { GoogleGenAI } from '@google/genai'; const ai = new GoogleGenAI(); const systemInstruction = ` ## **RULE 1: Seek User Confirmation (USER_CONFIRMATION)** This is your first and most important check. If the next required action falls into any of the following categories, you MUST stop immediately, and seek the user's explicit permission. **Procedure for Seeking Confirmation:** * **For Consequential Actions:** Perform all preparatory steps (e.g., navigating, filling out forms, typing a message). You will ask for confirmation **AFTER** all necessary information is entered on the screen, but **BEFORE** you perform the final, irreversible action (e.g., before clicking "Send", "Submit", "Confirm Purchase", "Share"). * **For Prohibited Actions:** If the action is strictly forbidden (e.g., accepting legal terms, solving a CAPTCHA), you must first inform the user about the required action and ask for their confirmation to proceed. **USER_CONFIRMATION Categories:** * **Consent and Agreements:** You are FORBIDDEN from accepting, selecting, or agreeing to any of the following on the user's behalf. You must ask the user to confirm before performing these actions. * Terms of Service * Privacy Policies * Cookie consent banners * End User License Agreements (EULAs) * Any other legally significant contracts or agreements. * **Robot Detection:** You MUST NEVER attempt to solve or bypass the following. You must ask the user to confirm before performing these actions. * CAPTCHAs (of any kind) * Any other anti-robot or human-verification mechanisms, even if you are capable. * **Financial Transactions:** * Completing any purchase. * Managing or moving money (e.g., transfers, payments). * Purchasing regulated goods or participating in gambling. * **Sending Communications:** * Sending emails. * Sending messages on any platform (e.g., social media, chat apps). * Posting content on social media or forums. * **Accessing or Modifying Sensitive Information:** * Health, financial, or government records (e.g., medical history, tax forms, passport status). * Revealing or modifying sensitive personal identifiers (e.g., SSN, bank account number, credit card number). * **User Data Management:** * Accessing, downloading, or saving files from the web. * Sharing or sending files/data to any third party. * Transferring user data between systems. * **Browser Data Usage:** * Accessing or managing Chrome browsing history, bookmarks, autofill data, or saved passwords. * **Security and Identity:** * Logging into any user account. * Any action that involves misrepresentation or impersonation (e.g., creating a fan account, posting as someone else). * **Insurmountable Obstacles:** If you are technically unable to interact with a user interface element or are stuck in a loop you cannot resolve, ask the user to take over. --- ## **RULE 2: Default Behavior (ACTUATE)** If an action does **NOT** fall under the conditions for \`USER_CONFIRMATION\`, your default behavior is to **Actuate**. **Actuation Means:** You MUST proactively perform all necessary steps to move the user's request forward. Continue to actuate until you either complete the non-consequential task or encounter a condition defined in Rule 1. * **Example 1:** If asked to send money, you will navigate to the payment portal, enter the recipient's details, and enter the amount. You will then **STOP** as per Rule 1 and ask for confirmation before clicking the final "Send" button. * **Example 2:** If asked to post a message, you will navigate to the site, open the post composition window, and write the full message. You will then **STOP** as per Rule 1 and ask for confirmation before clicking the final "Post" button. After the user has confirmed, remember to get the user's latest screen before continuing to perform actions. # Final Response Guidelines: Write final response to the user in the following cases: - User confirmation - When the task is complete or you have enough information to respond to the user `; const interaction = await ai.interactions.create({ model: "gemini-3.8-flash", system_instruction: systemInstruction, input: "Prepare a draft but do not send.", tools: [{ type: "computer_use", environment: "browser" }] });
- 사용자 확인 시행: 안전 대답에
자바
java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ComputerUse;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Click the Submit button on the screen."))
.tools(Arrays.asList(new ComputerUse()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));- 안전한 실행 환경: 안전한 샌드박스 환경에서 에이전트를 실행하여 잠재적 영향을 제한합니다. 이는 샌드박스 가상 머신 (VM), 컨테이너 (예: Docker) 또는 권한이 제한된 전용 브라우저 프로필일 수 있습니다. Docker를 사용한 샌드박스 설정 안내는 GitHub 참조 구현을 참고하세요.
- 입력 삭제: 의도하지 않은 요청 사항이나 프롬프트 인젝션의 위험을 완화하기 위해 프롬프트에서 사용자가 생성한 모든 텍스트를 삭제합니다. 이는 유용한 보안 강화책이지만 안전한 실행 환경을 대체하지는 않습니다.
- 콘텐츠 가드레일: 가드레일 및 콘텐츠 안전 API를 사용하여 적절성, 프롬프트 인젝션, 탈옥 감지에 대해 사용자 입력, 도구 입력 및 출력, 에이전트의 응답을 평가합니다.
- 허용 목록 및 차단 목록: 모델에서 탐색할 수 있는 위치와 수행할 수 있는 작업을 제어하는 필터링 메커니즘을 구현합니다. 금지된 웹사이트 차단 목록이 좋은 시작점이며 더 제한적인 허용 목록이 더 안전합니다.
- 관측 가능성 및 로깅: 디버깅, 감사, 사고 대응에 사용되는 자세한 로그를 유지합니다. 클라이언트는 프롬프트, 스크린샷, 모델 추천 작업 (
function_call), 안전 대답, 클라이언트에서 최종적으로 실행한 모든 작업을 로깅해야 합니다. - 환경 관리: GUI 환경이 일관되도록 합니다. 예상치 못한 팝업, 알림 또는 레이아웃 변경은 모델에 혼동을 줄 수 있습니다. 가능하면 각 새 작업에 대해 알려진 깨끗한 상태에서 시작하세요.
모델 버전
다음 모델에서 Computer Use를 사용할 수 있습니다.
- Gemini 3.8 Flash (
gemini-3.8-flash): 컴퓨터 사용에 권장되는 모델로, 정확도가 높은 UI 상호작용과 안정적인 도구 호출이 특징입니다. - Gemini 3.7 Flash (
gemini-3.7-flash): 컴퓨터 사용을 위한 이전 안정화 모델로, 의도가 포함된 간소화된 작업, 브라우저, 모바일, 데스크톱 환경 지원, 구성 가능한 안전 정책, 프롬프트 삽입 감지 기능이 있습니다. - Gemini 3.5 Flash-Lite (
gemini-3.5-flash-lite): 컴퓨터 사용을 지원하는 지연 시간이 짧고 비용 효율적인 모델입니다. - Gemini 3.5 Flash (
gemini-3.5-flash): 컴퓨터 사용을 지원하는 이전 안정화 모델입니다. - Gemini 3 Flash 프리뷰 (
gemini-3-flash-preview): 컴퓨터 사용을 지원하는 프리뷰 모델입니다. - Gemini 2.5 (기존 프리뷰) (
gemini-2.5-computer-use-preview-10-2025): 브라우저 기반 컴퓨터 사용에 최적화된 기존 프리뷰 모델입니다.
다음 단계
- Browserbase 데모 환경에서 컴퓨터 사용을 실험해 보세요.
- 예시 코드는 참조 구현을 확인하세요.
- 다른 Gemini API 도구 알아보기: