Computer use
Computer use (컴퓨터 사용) — Generate Content API (Legacy)
Computer Use 도구를 사용하면 브라우저, 모바일, 데스크톱 제어 에이전트를 만들어 작업과 상호작용하고 자동화할 수 있어요. 스크린샷을 사용해 모델이 컴퓨터 화면을 "보고", 마우스 클릭·키보드 입력 같은 특정 UI 액션을 생성해 "행동"할 수 있어요. function calling과 비슷하게, Computer Use 액션을 받아 실행하는 클라이언트 측 실행 환경을 직접 구현해야 해요.
출처: 문서
본문
지원되는 모델 목록은 Model versions를 참고하세요. Gemini 3.x 모델은 몇 가지 고급 기능을 지원해요.
- 다중 환경 지원: 브라우저, 모바일, 데스크톱 환경용 에이전트를 만들 수 있어요.
- 의도가 있는 간소화된 액션: 액션에 각 단계 뒤의 모델 추론을 설명하는
intent필드가 포함돼요. - 구성 가능한 안전 정책: 내장 정책 카테고리와 override로 안전 동작을 세밀하게 조정할 수 있어요.
- 프롬프트 인젝션 탐지: 숨겨진 적대적 지침을 감지하는 옵트인 스크린샷 스캐닝을 켤 수 있어요.
Computer Use로 다음과 같은 에이전트를 만들 수 있어요.
- 웹사이트에서 반복적인 데이터 입력이나 양식 작성을 자동화.
- 웹 애플리케이션과 사용자 흐름의 자동화된 테스트 수행.
- 다양한 웹사이트에서 조사 수행(예: 구매를 위해 이커머스 사이트에서 제품 정보, 가격, 리뷰 수집).
다음은 Computer Use 도구를 활성화하는 최소한의 예시예요.
Python
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Search for 'Gemini API' on Google.",
config=types.GenerateContentConfig(
tools=[types.Tool(
computer_use=types.ComputerUse(
environment=types.Environment.ENVIRONMENT_BROWSER,
)
)]
)
)
print(response.text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash',
contents: "Search for 'Gemini API' on Google.",
config: {
tools: [{
computerUse: {
environment: "ENVIRONMENT_BROWSER",
}
}]
}
});
console.log(response.text);
참고: Computer Use는 프리뷰 기능으로 오류와 보안 취약점이 있을 수 있어요. 중요한 작업에서는 밀접한 감독을 권장하고, 중요한 결정, 민감한 데이터, 또는 심각한 오류를 교정할 수 없는 작업에는 Computer Use 기능을 사용하지 않는 것이 좋아요. Safety best practices, Prohibited Use Policy, Gemini API Additional Terms of Service를 검토해 보시길 권장해요.
Computer Use 작동 방식
Computer Use 모델로 에이전트를 만들려면 애플리케이션과 API 사이에 연속 루프를 설정해야 해요. 각 단계에서 코드가 하는 일은 다음과 같아요.
- 모델에 요청 보내기: 애플리케이션이 Computer Use 도구, 구성 설정(예: 대상 환경), 사용자 프롬프트, 현재 화면 스크린샷을 포함한 API 요청을 보내요.
- 모델 응답 받기: 모델이 화면과 프롬프트를 분석해 UI 액션(예: 클릭, 스크롤, 키 입력)을 나타내는 제안된
function_call를 포함한 응답을 반환해요.- Gemini 3.x 모델의 경우 응답에는 모델이 그 액션을 선택한 이유를 설명하는 추론
intent도 포함돼요. - 응답에는 내부 안전 시스템의
safety_decision도 포함될 수 있는데, 액션을 regular/allowed,require_confirmation(사용자 승인 필요), 또는 blocked로 분류해요.
- Gemini 3.x 모델의 경우 응답에는 모델이 그 액션을 선택한 이유를 설명하는 추론
- 받은 액션 실행: 액션이 허용되면(또는 사용자가 확인하면) 클라이언트 코드가
function_call을 파싱하고, 정규화된 좌표를 자신의 뷰포트에 맞게 스케일하고, Playwright 같은 자동화 도구를 사용해 대상 환경에서 액션을 실행해요. 액션이 차단되면 클라이언트는 실행을 중단하거나 인터럽션을 처리해야 해요. - 새 환경 상태 캡처: 액션 실행이 끝나면 애플리케이션이 새 스크린샷을 캡처해
function_result로 모델에 다시 보내 다음 단계를 요청해요.
이 과정은 2단계부터 반복되며, 작업이 완료되거나 종료될 때까지 모델로부터 계속 다음 액션을 요청해요.
[이미지: /static/gemini-api/docs/images/computer_use.png]
Computer Use 구현 방법
Computer Use 도구로 빌드하기 전에 다음을 설정해야 해요.
- 안전한 실행 환경: 호스트 시스템에서 격리하고 잠재적 영향을 제한하기 위해 에이전트를 샌드박스 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
from google.genai.types import (
Content,
Part,
GenerateContentConfig,
Tool,
ComputerUse,
Environment,
ThinkingConfig,
)
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.8-flash",
contents=[
Content(
role="user",
parts=[
Part(text="Find a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th"),
],
)
],
config=GenerateContentConfig(
tools=[
Tool(
computer_use=ComputerUse(
environment=Environment.ENVIRONMENT_BROWSER,
enable_prompt_injection_detection=True,
),
),
],
thinking_config=ThinkingConfig(
include_thoughts=True
),
)
)
print(response.text)
JavaScript
@google/genai Node.js SDK를 사용해 브라우저 환경을 대상으로 하는 요청을 구성하세요.
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash',
contents: [
{
role: 'user',
parts: [{ text: "Find a flight from SF to Hawaii on Jun 30th, coming back on Jul 6th" }]
}
],
config: {
tools: [{
computerUse: {
environment: "ENVIRONMENT_BROWSER",
enable_prompt_injection_detection: true
}
}],
thinkingConfig: {
includeThoughts: true
}
}
});
console.log(response.text);
REST
curl을 사용해 요청을 보내세요.
curl -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"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"
}
}
],
"tools": [
{
"computer_use": {
"environment": "ENVIRONMENT_BROWSER",
"enable_prompt_injection_detection": true
}
}
]
}'
Gemini 2.5 (Legacy)
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"]
generate_content_config = genai.types.GenerateContentConfig(
tools=[
types.Tool(
computer_use=types.ComputerUse(
environment=types.Environment.ENVIRONMENT_BROWSER,
excluded_predefined_functions=excluded_functions
)
),
],
)
contents=[
Content(
role="user",
parts=[
Part(text="Search for highly rated smart fridges on Google Shopping."),
],
)
]
response = client.models.generate_content(
model='gemini-2.5-computer-use-preview-10-2025',
contents=contents,
config=generate_content_config,
)
print(response)
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
// Specify predefined functions to exclude (optional)
const excludedFunctions = ["drag_and_drop"];
const response = await ai.models.generateContent({
model: 'gemini-2.5-computer-use-preview-10-2025',
contents: [
{
role: 'user',
parts: [{ text: "Search for highly rated smart fridges on Google Shopping." }]
}
],
config: {
tools: [{
computerUse: {
environment: "ENVIRONMENT_BROWSER",
excluded_predefined_functions: excludedFunctions
}
}]
}
});
console.log(response);
2. 모델 응답 받기
응답 모델이 함수 호출을 제안해요. Gemini 3.x 모델의 경우 응답에 좌표와 함께 맞춤화된 추론 intent가 포함돼요. 다음은 두 응답의 예시를 보여줘요.
Gemini 3.x
{
"function_call": {
"name": "click",
"args": {
"x": 450,
"y": 120,
"intent": "Click the search box to type the destination."
}
}
}
Gemini 2.5 (Legacy)
{
"content": {
"parts": [
{
"text": "I will type the search query into the search bar."
},
{
"function_call": {
"name": "type_text_at",
"args": {
"x": 371,
"y": 470,
"text": "highly rated smart fridges",
"press_enter": true
}
}
}
]
}
}
3. 받은 액션 실행
애플리케이션 코드는 모델 응답을 파싱하고, 액션을 실행하고, 결과를 수집해야 해요.
아래 코드는 레거시 도구 명령어(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 = []
# Parse content parts (Handling legacy and Gemini 3 response structures)
parts = candidate.content.parts if hasattr(candidate, 'content') else []
if not parts and hasattr(candidate, 'function_calls'):
function_calls = candidate.function_calls
else:
for part in parts:
if part.function_call:
function_calls.append(part.function_call)
for function_call in function_calls:
action_result = {}
fname = function_call.name
args = function_call.args
print(f" -> Executing: {fname} (Intent: {args.get('intent', 'N/A')})")
try:
if fname in ("open_web_browser", "open_app"):
pass # Handled / already open
elif fname in ("click", "click_at", "double_click", "triple_click", "middle_click", "right_click", "move", "long_press"):
actual_x = denormalize_x(args["x"], screen_width)
actual_y = denormalize_y(args["y"], screen_height)
if fname in ("click", "click_at"):
page.mouse.click(actual_x, actual_y)
elif fname == "double_click":
page.mouse.dblclick(actual_x, actual_y)
elif fname == "right_click":
page.mouse.click(actual_x, actual_y, button="right")
elif fname == "middle_click":
page.mouse.click(actual_x, actual_y, button="middle")
elif fname == "move":
page.mouse.move(actual_x, actual_y)
elif fname in ("type", "type_text_at"):
actual_x = denormalize_x(args["x"], screen_width) if "x" in args else None
actual_y = denormalize_y(args["y"], screen_height) if "y" in args else None
text = args["text"]
press_enter = args.get("press_enter", False)
if actual_x is not None and actual_y is not None:
page.mouse.click(actual_x, actual_y)
# Clear field first
page.keyboard.press("Meta+A")
page.keyboard.press("Backspace")
page.keyboard.type(text)
if press_enter:
page.keyboard.press("Enter")
elif fname == "navigate":
page.goto(args["url"])
elif fname == "go_back":
page.go_back()
elif fname == "go_forward":
page.go_forward()
elif fname == "wait":
time.sleep(args.get("seconds", 1))
else:
print(f"Warning: Custom or unhandled function {fname}")
page.wait_for_load_state(timeout=5000)
time.sleep(1)
except Exception as e:
print(f"Error executing {fname}: {e}")
action_result = {"error": str(e)}
results.append((fname, function_call.id, action_result))
return results
JavaScript
function denormalizeX(x, screenWidth) {
// Convert normalized x coordinate (0-1000) to actual pixel coordinate.
return Math.floor((x / 1000) * screenWidth);
}
function denormalizeY(y, screenHeight) {
// Convert normalized y coordinate (0-1000) to actual pixel coordinate.
return Math.floor((y / 1000) * screenHeight);
}
async function executeFunctionCalls(candidate, page, screenWidth, screenHeight) {
const results = [];
let functionCalls = [];
// Parse function calls from candidate response
const parts = candidate.content?.parts || [];
if (parts.length === 0 && candidate.functionCalls) {
functionCalls = candidate.functionCalls;
} else {
for (const part of parts) {
if (part.functionCall) {
functionCalls.push(part.functionCall);
}
}
}
for (const functionCall of functionCalls) {
const actionResult = {};
const fname = functionCall.name;
const args = functionCall.args;
console.log(` -> Executing: ${fname} (Intent: ${args.intent || 'N/A'})`);
try {
if (fname === "open_web_browser" || fname === "open_app") {
// Handled / already open
} else if (["click", "click_at", "double_click", "triple_click", "middle_click", "right_click", "move", "long_press"].includes(fname)) {
const actualX = denormalizeX(args.x, screenWidth);
const actualY = denormalizeY(args.y, screenHeight);
if (fname === "click" || fname === "click_at") {
await page.mouse.click(actualX, actualY);
} else if (fname === "double_click") {
await page.mouse.dblclick(actualX, actualY);
} else if (fname === "right_click") {
await page.mouse.click(actualX, actualY, { button: "right" });
} else if (fname === "middle_click") {
await page.mouse.click(actualX, actualY, { button: "middle" });
} else if (fname === "move") {
await page.mouse.move(actualX, actualY);
}
} else if (fname === "type" || fname === "type_text_at") {
const actualX = args.x !== undefined ? denormalizeX(args.x, screenWidth) : null;
const actualY = args.y !== undefined ? denormalizeY(args.y, screenHeight) : null;
const text = args.text;
const pressEnter = args.press_enter || false;
if (actualX !== null && actualY !== null) {
await page.mouse.click(actualX, actualY);
}
// Clear field first
await page.keyboard.press("Meta+A");
await page.keyboard.press("Backspace");
await page.keyboard.type(text);
if (pressEnter) {
await page.keyboard.press("Enter");
}
} else if (fname === "navigate") {
await page.goto(args.url);
} else if (fname === "go_back") {
await page.goBack();
} else if (fname === "go_forward") {
await page.goForward();
} else if (fname === "wait") {
await new Promise(resolve => setTimeout(resolve, (args.seconds || 1) * 1000));
} else {
console.log(`Warning: Custom or unhandled function ${fname}`);
}
await page.waitForLoadState('load', { timeout: 5000 }).catch(() => {});
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (e) {
console.log(`Error executing ${fname}: ${e}`);
actionResult.error = e.message;
}
results.push([fname, functionCall.id, actionResult]);
}
return results;
}
4. 새 환경 상태 캡처
화면 표현을 캡처해 모델에 반환하세요.
Python
def get_function_responses(page, results):
screenshot_bytes = page.screenshot(type="png")
current_url = page.url
function_responses = []
for name, call_id, result in results:
function_responses.append({
"type": "function_result",
"name": name,
"call_id": call_id,
"result": [
{
"type": "text",
"text": json.dumps({"url": current_url, **result})
},
{
"type": "image",
"data": base64.b64encode(screenshot_bytes).decode("utf-8"),
"mime_type": "image/png"
}
]
})
return function_responses
JavaScript
async function getFunctionResponses(page, results) {
const screenshotBuffer = await page.screenshot({ type: 'png' });
const screenshotBase64 = screenshotBuffer.toString('base64');
const currentUrl = page.url();
const functionResponses = [];
for (const [name, callId, result] of results) {
functionResponses.push({
type: "function_result",
name: name,
call_id: callId,
result: [
{
type: "text",
text: JSON.stringify({ url: currentUrl, ...result })
},
{
type: "image",
data: screenshotBase64,
mime_type: "image/png"
}
]
});
}
return functionResponses;
}
환경 상태를 캡처·형식화하는 방법을 정의했다면, 이 모든 단계를 연속 실행 루프로 결합할 수 있어요.
에이전트 루프 구축
다단계 상호작용을 활성화하려면 How to implement Computer Use 섹션의 4단계를 단일 루프로 결합하세요. 이 루프는 작업이 완료될 때까지 액션을 요청하고 결과를 모델에 계속 피드백해요.
각 단계에서 모델 응답과 함수 응답을 모두 기록(history)에 추가해 대화 기록을 올바르게 관리하는 것을 잊지 마세요.
Python
import time
from typing import Any, List, Tuple
from playwright.sync_api import sync_playwright
from google import genai
from google.genai import types
client = genai.Client()
SCREEN_WIDTH = 1440
SCREEN_HEIGHT = 900
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()
# Paste helper functions execute_function_calls and get_function_responses here
try:
page.goto("https://ai.google.dev/gemini-api/docs")
config = types.GenerateContentConfig(
tools=[types.Tool(computer_use=types.ComputerUse(
environment=types.Environment.ENVIRONMENT_BROWSER,
enable_prompt_injection_detection=True
))],
thinking_config=types.ThinkingConfig(include_thoughts=True),
)
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}")
contents = [
types.Content(role="user", parts=[
types.Part(text=USER_PROMPT),
types.Part.from_bytes(data=initial_screenshot, mime_type='image/png')
])
]
# Agent Loop
turn_limit = 5
for i in range(turn_limit):
print(f"\n--- Turn {i+1} ---")
print("Thinking...")
response = client.models.generate_content(
model='gemini-3.8-flash',
contents=contents,
config=config,
)
candidate = response.candidates[0]
contents.append(candidate.content)
has_function_calls = any(part.function_call for part in candidate.content.parts)
if not has_function_calls:
text_response = " ".join(
part.text for part in candidate.content.parts if hasattr(part, 'text')
)
print("Agent finished:", text_response)
break
print("Executing actions...")
results = execute_function_calls(candidate, page, SCREEN_WIDTH, SCREEN_HEIGHT)
print("Capturing state...")
function_responses = get_function_responses(page, results)
contents.append(
types.Content(role="user", parts=[types.Part(function_response=fr) for fr in function_responses])
)
finally:
print("Closing browser...")
browser.close()
playwright.stop()
JavaScript
import { chromium } from 'playwright';
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
// Constants for screen dimensions
const SCREEN_WIDTH = 1440;
const SCREEN_HEIGHT = 900;
console.log("Initializing browser...");
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
viewport: { width: SCREEN_WIDTH, height: SCREEN_HEIGHT }
});
const page = await context.newPage();
// Define helper functions. Copy/paste from steps 3 and 4:
// function denormalizeX(...)
// function denormalizeY(...)
// async function executeFunctionCalls(...)
// async function getFunctionResponses(...)
try {
await page.goto("https://ai.google.dev/gemini-api/docs");
const config = {
tools: [{
computerUse: {
environment: "ENVIRONMENT_BROWSER",
enable_prompt_injection_detection: true
}
}],
thinkingConfig: { includeThoughts: true }
};
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}`);
const contents = [
{
role: "user",
parts: [
{ text: USER_PROMPT },
{
inlineData: {
data: initialScreenshotBase64,
mimeType: "image/png"
}
}
]
}
];
// Agent Loop
const turnLimit = 5;
for (let i = 0; i < turnLimit; i++) {
console.log(`\n--- Turn ${i + 1} ---`);
console.log("Thinking...");
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash',
contents: contents,
config: config
});
const candidate = response.candidates[0];
contents.push(candidate.content);
const hasFunctionCalls = candidate.content.parts.some(part => part.functionCall);
if (!hasFunctionCalls) {
const textResponse = candidate.content.parts
.filter(part => part.text)
.map(part => part.text)
.join(" ");
console.log("Agent finished:", textResponse);
break;
}
console.log("Executing actions...");
const results = await executeFunctionCalls(candidate, page, SCREEN_WIDTH, SCREEN_HEIGHT);
console.log("Capturing state...");
const functionResponses = await getFunctionResponses(page, results);
contents.push({
role: "user",
parts: functionResponses.map(fr => ({
...fr
}))
});
}
} finally {
console.log("Closing browser...");
await browser.close();
}
지원되는 환경 (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: str, press_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: str, intent: str |
| key_down | 지정된 키를 누르고 유지 | key: str, intent: str |
| key_up | 지정된 키를 놓음 | key: str, intent: str |
| hotkey | 지정된 키 조합을 누름 | keys: List[str], intent: str |
| take_screenshot | 현재 화면의 스크린샷 반환 | intent: str |
| scroll | 좌표에서 픽셀 거리만큼 위·아래·왼쪽·오른쪽으로 스크롤 | y: int (0-999), x: int (0-999), direction: str ("up", "down", "left", "right"), magnitude_in_pixels: int (0-999, 선택, 기본 300), intent: str |
| go_back | 브라우저 기록에서 이전 웹 페이지로 이동 | intent: str |
| navigate | 지정된 URL로 직접 이동 | url: str, intent: str |
| go_forward | 브라우저 기록에서 다음 웹 페이지로 이동 | intent: str |
모바일 환경 (ENVIRONMENT_MOBILE)
Android에 최적화된 환경 액션:
| 명령어 이름 | 설명 | 인자 (함수 호출 내) |
|---|---|---|
| open_app | 이름으로 애플리케이션 열기 | app_name: str, intent: str |
| click | 해당 좌표에서 왼쪽 클릭 | y: int (0-999), x: int (0-999), intent: str |
| list_apps | 기기의 사용 가능한 애플리케이션 목록(이름·패키지 이름) 반환 | intent: str |
| wait | 지정된 초만큼 실행 일시 중지 | seconds: int (선택, 기본 1), intent: str |
| go_back | 이전 화면이나 웹 페이지로 이동 | intent: str |
| type | 텍스트 입력 | text: str, press_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: str, intent: str |
| take_screenshot | 현재 화면의 스크린샷 반환 | intent: str |
데스크톱 환경 (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: str, press_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: str, intent: str |
| key_down | 지정된 키를 누르고 유지 | key: str, intent: str |
| key_up | 지정된 키를 놓음 | key: str, intent: str |
| hotkey | 지정된 키 조합을 누름 | keys: List[str], intent: str |
| take_screenshot | 현재 화면의 스크린샷 반환 | intent: str |
| scroll | 좌표에서 픽셀 거리만큼 위·아래·왼쪽·오른쪽으로 스크롤 | y: int (0-999), x: int (0-999), direction: str ("up", "down", "left", "right"), magnitude_in_pixels: int (0-999, 선택, 기본 300), intent: str |
레거시 지원 UI 액션 (Gemini 2.5)
레거시 모델(gemini-2.5-computer-use-preview-10-2025)은 다음 액션을 지원해요.
| 명령어 이름 | 설명 | 인자 (함수 호출 내) | 예시 함수 호출 |
|---|---|---|---|
| open_web_browser | 웹 브라우저 열기 | 없음 | {"name": "open_web_browser", "args": {}} |
| wait_5_seconds | 5초 동안 실행 일시 중지 | 없음 | {"name": "wait_5_seconds", "args": {}} |
| go_back | 기록에서 이전 페이지로 이동 | 없음 | {"name": "go_back", "args": {}} |
| go_forward | 기록에서 다음 페이지로 이동 | 없음 | {"name": "go_forward", "args": {}} |
| search | 기본 검색 엔진으로 이동 | 없음 | {"name": "search", "args": {}} |
| navigate | 브라우저를 지정된 URL로 직접 이동 | url: str |
{"name": "navigate", "args": {"url": "https://www.wikipedia.org"}} |
| click_at | 특정 좌표에서 클릭 | y: int (0-999), x: int (0-999) |
{"name": "click_at", "args": {"y": 300, "x": 500}} |
| hover_at | 특정 좌표에서 마우스 호버 | y: int (0-999), x: int (0-999) |
{"name": "hover_at", "args": {"y": 150, "x": 250}} |
| type_text_at | 좌표에서 텍스트 입력 | y: int (0-999), x: int (0-999), text: str, press_enter: bool (선택, 기본 True), clear_before_typing: bool (선택, 기본 True) |
{"name": "type_text_at", "args": {"y": 250, "x": 400, "text": "search", "press_enter": false}} |
| key_combination | 키 또는 조합 누르기 | keys: str |
{"name": "key_combination", "args": {"keys": "Control+A"}} |
| scroll_document | 전체 웹 페이지 스크롤 | direction: str |
{"name": "scroll_document", "args": {"direction": "down"}} |
| scroll_at | 좌표 (x,y)에서 스크롤 | y: int, x: int, direction: str, magnitude: int (선택, 기본 800) |
{"name": "scroll_at", "args": {"y": 500, "x": 500, "direction": "down"}} |
| drag_and_drop | 두 좌표 사이에서 끌어다 놓기 | y: int, x: int, destination_y: int, destination_x: int |
{"name": "drag_and_drop", "args": {"y": 100, "destination_y": 500, "destination_x": 500, "x": 100}} |
커스텀 사용자 정의 함수
커스텀 사용자 정의 함수를 포함해 모델의 기능을 확장할 수 있어요. 예를 들어 인간-인-더-루프(HITL) 시나리오에서 기본 미리 정의된 액션을 제외하고 커스텀 액션을 등록할 수 있어요.
Gemini 3.x 커스텀 도구
Python
표준 미리 정의된 브라우저 액션(예: click)을 제외하고 커스텀 yield_to_user 도구를 등록하세요.
from google import genai
from google.genai import types
client = genai.Client()
yield_to_user_tool = types.FunctionDeclaration(
name="yield_to_user",
description="Yields control back to the user for assistance or verification when an automated action is unsafe or ambiguous.",
parameters=types.Schema(
type="OBJECT",
properties={
"reason": types.Schema(
type="STRING",
description="The reason why the agent is yielding control to the human."
)
},
required=["reason"]
)
)
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Click the submit button. If you need a second factor authentication code, ask me.",
config=types.GenerateContentConfig(
tools=[
types.Tool(
computer_use=types.ComputerUse(
environment="ENVIRONMENT_MOBILE",
excluded_predefined_functions=["click"]
)
),
yield_to_user_tool
]
)
)
Gemini 2.5 (Legacy) 커스텀 도구
Python
from typing import Optional, Dict, Any
from google import genai
from google.genai import types
client = genai.Client()
# Define custom tools here
custom_functions = [...] # Describe parameters as FunctionDeclaration object
def make_generate_content_config():
excluded_functions = ["open_web_browser", "wait_5_seconds", "go_back", "go_forward", "search", "navigate", "hover_at", "scroll_document", "key_combination", "drag_and_drop"]
generate_content_config = types.GenerateContentConfig(
tools=[
types.Tool(
computer_use=types.ComputerUse(
environment=types.Environment.ENVIRONMENT_BROWSER,
excluded_predefined_functions=excluded_functions
)
),
types.Tool(function_declarations=custom_functions)
]
)
return generate_content_config
Thinking 수준 관리 (Gemini 3.x)
컴퓨터 사용 에이전트에서는 액션 품질과 실행 속도의 균형을 맞추기 위해 서로 다른 thinking 수준을 구성할 수 있어요. 낮은 thinking 수준은 일반적으로 표준 자동화 작업에 좋은 균형을 제공해요.
안전과 보안
안전 정책 구성 (Gemini 3.x)
Gemini 3.x 모델에는 사용자 확인이 필요한지 자동으로 결정하는 내장 안전 서비스 카테고리가 포함돼요.
| 안전 정책 카테고리 | 설명 |
|---|---|
FINANCIAL_TRANSACTIONS |
결제, 소매 체크아웃, 규제 상품과 관련된 액션을 차단하거나 확인을 트리거해요. |
SENSITIVE_DATA_MODIFICATION |
건강, 금융, 정부 기록을 무단 수정으로부터 보호해요. |
COMMUNICATION_TOOL |
에이전트가 이메일, 채팅 메시지, 초안을 자율적으로 보내는 것을 제한해요. |
ACCOUNT_CREATION |
에이전트가 웹사이트에 새 계정을 자율적으로 등록하는 것을 제한해요. |
DATA_MODIFICATION |
전체 파일 시스템 수정, 데이터 공유, 저장소 삭제를 규제해요. |
USER_CONSENT_MANAGEMENT |
쿠키 동의 배너와 개인정보 프롬프트에 사용자 개입이 필요해요. |
LEGAL_TERMS_AND_AGREEMENTS |
모델이 이용 약관이나 법적으로 구속력 있는 계약을 자율적으로 수락하지 못하게 해요. |
안전 override
override를 전달해 선택된 정책을 재정의할 수 있어요.
참고: 안전 override는 사용자의 선호를 나타내지만, 어떤 경우에는 모델이 여전히 require_confirmation이 있는 safety_decision을 반환할 수 있어요. 애플리케이션은 구성된 override와 무관하게 항상 안전 결정 처리를 구현해야 해요.
Python
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Clean up the local folder by archiving old logs.",
config=types.GenerateContentConfig(
tools=[
types.Tool(
computer_use=types.ComputerUse(
environment=types.Environment.ENVIRONMENT_DESKTOP,
disabled_safety_policies=[
types.SafetyPolicy.DATA_MODIFICATION
]
)
)
]
)
)
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash',
contents: "Clean up the local folder by archiving old logs.",
config: {
tools: [{
computerUse: {
environment: "ENVIRONMENT_DESKTOP",
disabledSafetyPolicies: [
"DATA_MODIFICATION"
]
}
}]
}
});
프롬프트 인젝션 탐지 (Gemini 3.x)
Gemini 3.5 Flash 이상의 Computer Use는 프롬프트 인젝션 공격을 탐지하는 고급 안전 메커니즘을 지원해요. 이 기능을 켜면 포함된 스크린샷에 "이전 명령어 무시" 같은 숨겨진 적대적 지침이 있는지 확인하고, 감지되면 실행을 차단해요.
프롬프트 인젝션 탐지는 옵트인 기능이에요. 기본값은 false예요.
다음 예시들은 Computer Use 도구 구성에서 프롬프트 인젝션 탐지를 활성화하는 방법을 보여줘요.
Python
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Search for flight deals and summarize top results.",
config=types.GenerateContentConfig(
tools=[
types.Tool(
computer_use=types.ComputerUse(
environment="ENVIRONMENT_DESKTOP",
enable_prompt_injection_detection=True,
)
)
]
),
)
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const response = await ai.models.generateContent({
model: "gemini-3.5-flash",
contents: "Search for flight deals and summarize top results.",
config: {
tools: [{
computerUse: {
environment: "ENVIRONMENT_DESKTOP",
enablePromptInjectionDetection: true,
}
}]
}
});
cURL
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash:generateContent?key=${GEMINI_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"contents": [{
"parts": [{"text": "Search for flight deals and summarize top results."}]
}],
"tools": [{
"computer_use": {
"environment": "ENVIRONMENT_DESKTOP",
"enable_prompt_injection_detection": true
}
}]
}'
안전 결정 확인 (Acknowledge safety decision)
응답에는 함수 호출 인자에 safety_decision 파라미터가 포함될 수 있어요.
{
"function_call": {
"name": "click_at",
"args": {
"x": 60,
"y": 100,
"safety_decision": {
"explanation": "Must check check-box",
"decision": "require_confirmation"
}
}
}
}
safety_decision가 require_confirmation이면 최종 사용자에게 확인을 요청하세요. 사용자가 확인하면 FunctionResponse에 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.args:
decision = get_safety_confirmation(function_call.args['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
from google.genai import types
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
"""
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Prepare a draft but do not send.",
config=types.GenerateContentConfig(
system_instruction=system_instruction,
tools=[types.Tool(computer_use=types.ComputerUse(environment="ENVIRONMENT_BROWSER"))]
)
)
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI();
const systemInstruction = `
## **RULE 1: Seek User Confirmation (USER_CONFIRMATION)**
This is your first and most important check. If the next required action falls
into any of the following categories, you MUST stop immediately, and seek the
user's explicit permission.
**Procedure for Seeking Confirmation:**
* **For Consequential Actions:** Perform all preparatory steps (e.g., navigating,
filling out forms, typing a message). You will ask for confirmation **AFTER**
all necessary information is entered on the screen, but **BEFORE** you perform
the final, irreversible action (e.g., before clicking "Send", "Submit",
"Confirm Purchase", "Share").
* **For Prohibited Actions:** If the action is strictly forbidden (e.g., accepting
legal terms, solving a CAPTCHA), you must first inform the user about the
required action and ask for their confirmation to proceed.
**USER_CONFIRMATION Categories:**
* **Consent and Agreements:** You are FORBIDDEN from accepting, selecting, or
agreeing to any of the following on the user's behalf. You must ask the
user to confirm before performing these actions.
* Terms of Service
* Privacy Policies
* Cookie consent banners
* End User License Agreements (EULAs)
* Any other legally significant contracts or agreements.
* **Robot Detection:** You MUST NEVER attempt to solve or bypass the
following. You must ask the user to confirm before performing these actions.
* CAPTCHAs (of any kind)
* Any other anti-robot or human-verification mechanisms, even if you are
capable.
* **Financial Transactions:**
* Compleying 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 response = await ai.models.generateContent({
model: 'gemini-3.8-flash',
contents: "Prepare a draft but do not send.",
config: {
systemInstruction: systemInstruction,
tools: [{
computerUse: {
environment: "ENVIRONMENT_BROWSER"
}
}]
}
});
- 안전한 실행 환경: 잠재적 영향을 제한하기 위해 에이전트를 안전한 샌드박스 환경에서 실행하세요. 샌드박스 VM, 컨테이너(예: Docker), 또는 권한이 제한된 전용 브라우저 프로필일 수 있어요. Docker를 사용한 샌드박스 설정 안내는 GitHub 참조 구현을 참고하세요.
- 입력 살균(Input sanitization): 의도하지 않은 지침이나 프롬프트 인젝션의 위험을 완화하기 위해 프롬프트의 모든 사용자 생성 텍스트를 살균하세요. 이는 도움이 되는 보안 계층이지만 안전한 실행 환경을 대체하지는 않아요.
- 콘텐츠 가드레일: 가드레일과 콘텐츠 안전 API를 사용해 사용자 입력, 도구 입력·출력, 에이전트의 응답을 적절성, 프롬프트 인젝션, jailbreak 탐지 측면에서 평가하세요.
- 허용 목록(Allowlists)과 차단 목록(Blocklists): 모델이 탐색할 수 있는 곳과 할 수 있는 일을 통제하는 필터링 메커니즘을 구현하세요. 금지 웹사이트의 차단 목록이 좋은 시작점이며, 더 제한적인 허용 목록이 더 안전해요.
- 관찰 가능성과 로깅: 디버깅, 감사, 사고 대응을 위해 상세 로그를 유지하세요. 클라이언트는 프롬프트, 스크린샷, 모델이 제안한 액션(
function_call), 안전 응답, 클라이언트가 결국 실행한 모든 액션을 기록해야 해요. - 환경 관리: GUI 환경이 일관되도록 보장하세요. 예상치 못한 팝업, 알림, 레이아웃 변경은 모델을 혼란스럽게 할 수 있어요. 가능하면 각 새 작업을 알려진 깨끗한 상태에서 시작하세요.
모델 버전 (Model versions)
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 Preview(
gemini-3-flash-preview): 컴퓨터 사용을 지원하는 프리뷰 모델이에요. - Gemini 2.5 (Legacy Preview)(
gemini-2.5-computer-use-preview-10-2025): 브라우저 기반 컴퓨터 사용에 최적화된 레거시 프리뷰 모델이에요.
다음 단계 (What's next)
- Browserbase 데모 환경에서 Computer Use를 실험해 보세요.
- 참조 구현에서 예제 코드를 확인하세요.
- 다른 Gemini API 도구에 대해 알아보세요: Function calling, Google Search 기반 접지.
더 알아보기 (Learn more)
- 최신 모델 가이드는 Gemini 3.8 Flash 페이지를 참고하세요.
- Function calling 문서로 커스텀 도구를 배워 보세요.
- Grounding with Google Search로 접지 기능을 살펴보세요.