コンピューターの使用では、モデルがブラウザやデスクトップのインターフェースを操作できます。フォームへの入力、ユーザーフローのテスト、アプリケーションの UI を通じたタスクの実行などに利用できます。
環境を用意し、モデルからのリクエストを実行するのは開発者側です。モデルはスクリーンショットやその他のツールの結果を基に、次に何をするかを判断します。アプリケーションとの接続方法を選択してください。
- コード実行: モデルが PyAutoGUI や Playwright などのライブラリを使ってインターフェースを操作するコードを記述します。1 回の呼び出しで、アクション、ループ、条件分岐を組み合わせることができます。
- コンピューターツール: モデルがマウスやキーボードのアクションを構造化された形式で返し、アプリケーションがそれをブラウザやデスクトップへの入力に変換します。
GPT-6 Astra ではコード実行を推奨します。代替手段として computer ツールも引き続きサポートされています。
すでに Function Calling やリモート MCP ツールを通じて UI 操作を提供している場合は、そのインターフェースを引き続き使用できます。これらの連携方法によるツールの実行方法や結果の返し方の違いについては、独自の UI ツールの使用を参照してください。
コード実行の使用
コード実行による連携では、スクリプトを受け取る関数ツールをモデルに提供します。アプリケーションは隔離されたブラウザ環境やデスクトップ環境でスクリプトを実行し、スクリーンショットを含む出力を返します。モデルがそれまでの作業を引き継げるよう、呼び出しと呼び出しの間も環境を維持してください。
サンプルアプリの実行
CUA サンプルアプリには、JavaScript/Playwright と Python/PyAutoGUI による実装に加え、ローカル環境のタスクと共通のコンソールが含まれています。
- 隔離された環境で、選択した実装のセットアップ手順に従ってください。
- 組み込みのシナリオを選択し、実行を開始します。
- アクション、スクリーンショット、最終状態を確認し、タスクが成功したかどうかを判断します。
インストール、デスクトップの権限、対応環境については、アプリの README を参照してください。実際のサイトやアカウントで使うように変更する前に、安全な実行を確認してください。
独自のランタイムの接続
以下の例は、独自に用意したランタイムを使う API ループを示しています。Python と Ruby のクライアントは、PyAutoGUI を使うデスクトップランタイムに Python コードを送信します。JavaScript のクライアントは、Playwright を使ってブラウザを操作します。各クライアントは通常の関数ツールを公開し、元の call_id とともにテキストまたは画像を返します。
execute_in_sandbox または executeInSandbox ヘルパーは、実行環境にコードを送信し、そこで観測した結果を返します。このヘルパーでは、ブラウザやデスクトップのセッションを維持し、実行上限を守らせ、開発者が定めた権限ルールを適用する必要があります。これらは連携の実装例であり、サンプルアプリの実行手順とは別のものです。
import json
import uuid
from openai import OpenAI
from openai.types.responses import (
FunctionToolParam,
ResponseInputParam,
)
def run_computer_use(endpoint, prompt, model="gpt-6-astra"):
client = OpenAI()
session_id = str(uuid.uuid4())
tools: list[FunctionToolParam] = [
{
"type": "function",
"name": "exec_py",
"description": (
"Run Python in a persistent desktop. Variables persist across calls. "
"PyAutoGUI operations are synchronous. Available: pyautogui, time, "
"log(value), and display(PIL_image). Inspect the screen with "
"display(pyautogui.screenshot()) before acting. Use screenshot "
"coordinates and check the screen after a short group of actions. "
"Keep screenshots in memory and PyAutoGUI's fail-safe enabled."
),
"parameters": {
"type": "object",
"properties": {"code": {"type": "string"}},
"required": ["code"],
"additionalProperties": False,
},
"strict": True,
}
]
next_input: ResponseInputParam = [{"role": "user", "content": prompt}]
previous_response_id = None
for turn in range(20):
response = client.responses.create(
model=model,
tools=tools,
input=next_input,
previous_response_id=previous_response_id,
)
if response.status != "completed":
raise RuntimeError(f"Response stopped with status: {response.status}")
calls = [item for item in response.output if item.type == "function_call"]
if not calls and any(
item.type == "message" and item.phase != "commentary"
for item in response.output
):
print(response.output_text)
return
if turn == 19:
raise RuntimeError(
"The task reached the 20-response limit. Inspect the last result."
)
next_input = []
for call in calls:
if call.name != "exec_py":
raise ValueError(f"Unexpected tool: {call.name}")
code = json.loads(call.arguments)["code"]
output = execute_in_sandbox(code, session_id, endpoint)
next_input.append(
{
"type": "function_call_output",
"call_id": call.call_id,
"output": output,
}
)
previous_response_id = response.idimport { randomUUID } from "node:crypto";
import OpenAI from "openai";
async function runComputerUse(endpoint, prompt, model = "gpt-6-astra") {
const client = new OpenAI();
const sessionId = randomUUID();
const tools = [
{
type: "function",
name: "exec_js",
description: `Run JavaScript in a persistent browser. Available: Playwright's
browser, context, and page objects; console.log(value); and display(base64Image).
Save reusable variables on globalThis. Inspect a screenshot before acting and
check the screen after a short group of actions. Keep screenshots in memory.
Use top-level await for async operations. Return images with display() and concise
text with console.log(). The context viewport is 1440x900.`,
parameters: {
type: "object",
properties: { code: { type: "string" } },
required: ["code"],
additionalProperties: false,
},
strict: true,
},
];
let nextInput = [{ role: "user", content: prompt }];
let previousResponseId;
for (let turn = 0; turn < 20; turn++) {
const response = await client.responses.create({
model,
tools,
input: nextInput,
previous_response_id: previousResponseId,
reasoning: { effort: "low" },
});
if (response.status !== "completed") {
throw new Error(`Response stopped with status: ${response.status}`);
}
const calls = response.output.filter(
(item) => item.type === "function_call"
);
if (
calls.length === 0 &&
response.output.some(
(item) => item.type === "message" && item.phase !== "commentary"
)
) {
console.log(response.output_text);
return;
}
if (turn === 19) {
throw new Error(
"The task reached the 20-response limit. Inspect the last result."
);
}
nextInput = [];
for (const call of calls) {
if (call.name !== "exec_js")
throw new Error(`Unexpected tool: ${call.name}`);
const { code } = JSON.parse(call.arguments);
const output = await executeInSandbox(code, sessionId, endpoint);
nextInput.push({
type: "function_call_output",
call_id: call.call_id,
output,
});
}
previousResponseId = response.id;
}
}require "json"
require "openai"
require "securerandom"
def run_computer_use(endpoint, prompt)
client = OpenAI::Client.new
session_id = SecureRandom.uuid
tools = [
{
type: :function,
name: "exec_py",
description: "Run Python in a persistent desktop. Variables persist across calls. PyAutoGUI operations are synchronous. Available: pyautogui, time, log(value), and display(PIL_image). Inspect the screen with display(pyautogui.screenshot()) before acting. Use screenshot coordinates and check the screen after a short group of actions. Keep screenshots in memory and PyAutoGUI's fail-safe enabled.",
parameters: {
type: :object,
properties: { code: { type: :string } },
required: ["code"],
additionalProperties: false
},
strict: true
}
]
next_input = []
next_input << {
role: :user,
content: prompt
}
history = {}
20.times do |turn|
response = client.responses.create(
model: "gpt-6-astra", tools: tools, input: next_input, previous_response_id: history[:id]
)
raise "Response stopped with status: #{response.status}" unless response.status == OpenAI::Responses::ResponseStatus::COMPLETED
calls = response.output.grep(OpenAI::Responses::ResponseFunctionToolCall)
if calls.empty? && response.output.any? { |item| item.is_a?(OpenAI::Responses::ResponseOutputMessage) && item.phase != :commentary }
puts(response.output_text)
return response
end
raise "The task reached the 20-response limit" if turn == 19
next_input.clear
calls.each do |call|
raise "Unexpected tool: #{call.name}" unless call.name == "exec_py"
code = JSON.parse(call.arguments).fetch("code")
raise "Expected Python source text" unless code.is_a?(String)
output = execute_in_sandbox(code, session_id, endpoint)
next_input << {
type: :function_call_output,
call_id: call.call_id,
output: output
}
end
history[:id] = response.id
end
endクライアントアダプターの完全な実装例と、想定されるテキストおよび画像の出力形式については、実行サービスへの接続を参照してください。これらの例にあるサービスインターフェースは、開発者のアプリケーション側に用意するものです。OpenAI がホストするエンドポイントではありません。
状態の保持と観測結果の返却
呼び出しと呼び出しの間も、ブラウザやデスクトップのセッションを維持してください。Python や JavaScript の名前空間を維持すれば、変数も保持できます。モデルが利用できるものを把握できるよう、ツール定義に利用可能なオブジェクトとヘルパーを記述してください。
UI の状態が不明な場合は、現在のスクリーンショットをモデルに渡してください。少数のアクションを実行するたびに、結果を確認できるよう新しいスクリーンショットを返します。画像はメモリ内に保持し、detail: "original" を使用して解像度を維持してください。スクリーンショットを縮小する場合は、アクションを実行する前にモデルが返した座標を環境の座標系に変換し直してください。スクリーンショットの取得と解像度を参照してください。
API の会話と実行環境は、それぞれ別の状態を持ちます。会話にはツール呼び出しとその出力を保持し、アプリケーションでは対応する環境を維持してください。レスポンスを継続しても、ブラウザのセッション、ログイン状態、ランタイムの変数は復元されません。
コンピューターツールの使用
生成されたコードではなく構造化されたアクションを受け取る連携を実装している場合は、この代替手段を使用してください。推奨される方法を使う場合は、コード実行から始めてください。
この方法を試すには、同じサンプルアプリのセットアップ手順に従い、 ネイティブ モードを選択して、組み込みのシナリオを実行します。コンピューターツールに対応したモデルを使用してください。
API とのやり取りは、タスクの送信、返されたアクションの実行、スクリーンショットの返却という 3 つのステップで構成されます。ここに示すコード例では、 フィルターを表示 コントロールと検索フィールドを備えたページを使用します。ツールを組み込む際は、自分のインターフェースに合わせてタスクを調整してください。
環境のセットアップとアクションハンドラーについては、連携の実装レシピを参照してください。
タスクの送信
tools 配列で computer を有効にし、期待する結果を記述します。
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.6-sol",
tools=[{"type": "computer"}],
input="Check whether the Filters panel is open. If it is not open, click Show filters. Then type penguin in the search box. Use the computer tool for UI interaction.",
)
print(response.output)リクエストされたアクションの実行
computer_call には、実行順に並んだ actions 配列が含まれます。たとえば、次の呼び出しでは検索フィールドを選択し、penguin と入力します。
{
"output": [
{
"type": "computer_call",
"call_id": "call_002",
"actions": [
{ "type": "click", "button": "left", "x": 405, "y": 157 },
{ "type": "type", "text": "penguin" }
],
"status": "completed"
}
]
}アクションハンドラーは、これらのリクエストをブラウザやオペレーティングシステムへの入力に変換します。許可されたアクションを順番に実行し、更新された画面を取得してください。モデルは click、double_click、drag、move、scroll、keypress、type、wait、screenshot をリクエストできます。
最初の呼び出しには、screenshot アクションだけが含まれる場合があります。その場合は UI を変更せずに、現在の画面を取得して返してください。呼び出しの status: "completed" は、モデルがその呼び出しの生成を完了したことを意味します。アプリケーション側では、その呼び出しを実行する必要がまだあります。
キーのマッピング、ドラッグの経路、修飾キーについては、アクションハンドラーの実装例を参照してください。
スクリーンショットの返却
処理した呼び出しと call_id が一致する computer_call_output を返します。previous_response_id を使用してモデルとの会話を継続します。
from openai import OpenAI
client = OpenAI()
def send_computer_screenshot(response, call_id, screenshot_base64):
return client.responses.create(
model="gpt-5.6-sol",
tools=[{"type": "computer"}],
previous_response_id=response.id,
input=[
{
"type": "computer_call_output",
"call_id": call_id,
"output": {
"type": "computer_screenshot",
"image_url": f"data:image/png;base64,{screenshot_base64}",
"detail": "original",
},
}
],
)このループにも、同じスクリーンショットと状態に関するガイダンスが適用されます。previous_response_id でモデルとの会話を継続している間は、環境を維持してください。
モデルが computer_call 項目を返さなくなるまで繰り返します。残りの出力に回答、支援の依頼、別のツール呼び出しが含まれていないかを確認し、アプリケーションで結果を検証してください。この例では、フィルターパネルが開き、検索フィールドに penguin が入力されているはずです。
必要なアクション用およびスクリーンショット用ヘルパーを含むループの基本構造については、コンピューターの使用ループの反復を参照してください。
安全な実行
コンピューターの使用は、実際のアカウントやデータに影響を与える可能性があります。モデルへの指示に加え、アプリケーションと実行環境にも次の制御を適用してください。
- 環境を制限します。 隔離されたブラウザまたは VM を使用し、サイトと操作の許可リストを設けます。アクセスはタスクに必要な範囲に限定します。
- 画面の内容は信頼できないものとして扱います。 ページ、ドキュメント、ツールの結果に含まれるテキストは、権限を付与したり、ユーザーの指示を上書きしたりする根拠にはなりません。
- 重大な影響を伴う操作はユーザーに確認します。 購入、データ送信、破壊的な変更など、元に戻すことが難しい操作は、ユーザーが判断できるようにします。機密情報をフォームに入力することも送信に当たります。
- 実行に上限を設け、結果を検証します。 ステップ数、時間、またはコストに上限を設定し、キャンセルできるようにします。モデルの最終回答だけに頼らず、実際の結果を確認します。
具体的な承認要件、人への引き継ぎ、プロンプトの例については、確認と同意に関するガイダンスを参照してください。
次のステップ
- 環境のセットアップ、アクションハンドラー、スクリーンショットの取得、実行サービス用アダプターについては、連携の実装例を参照してください。
- 以前の連携実装を更新する場合は、computer-use-preview からの移行に従ってください。
- ブラウザとデスクトップのワークフロー全体を確認するには、CUA サンプルアプリを参照してください。