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.idO Uso do computador permite que um modelo opere uma interface de navegador ou desktop. Use o recurso para preencher formulários, testar fluxos de usuário ou concluir tarefas em um aplicativo.
Escolha a integração de acordo com o que o modelo precisa ver e com quem gerencia o ambiente:
| Tarefa | Por onde começar |
|---|---|
| Usar capturas de tela e ações de mouse ou teclado no navegador ou desktop | Use ComputerToolset com a ferramenta de computador da API Responses. |
| Ler o texto da página ou usar controles e abas no navegador | Use BrowserToolset. O driver disponibiliza operações selecionadas como ferramentas de função. |
| Executar um navegador hospedado pela OpenAI | Siga o guia de Uso do computador da API Agents, disponível separadamente. |
Para consultar informações públicas que não exigem interação, use a Pesquisa na Web.
Use o SDK
O SDK executa o ciclo de chamadas de ferramentas da API Responses em Python ou Node. Seu aplicativo fornece um driver, ou seja, o código que lê o ambiente ou executa uma ação permitida. O aplicativo gerencia a sessão, as permissões e a liberação dos recursos.
Conecte um ambiente hospedado
Use o navegador ou desktop de um parceiro para que você não precise manter um por conta própria. Algumas integrações fornecem um driver. Outras disponibilizam controles que seu aplicativo mapeia para o SDK. Consulte o guia do parceiro para configurar o ambiente e verificar as versões de pacotes compatíveis.
| Ambiente | Integração |
|---|---|
| Browserbase | Use o driver de navegador do Stagehand com uma sessão hospedada no Browserbase. Siga o guia de integração do Stagehand ou consulte os exemplos em Python e TypeScript. |
| Browser Use | Use o driver da biblioteca Browser Use ou conecte seu código Playwright existente com a integração do Browser Use Cloud. Os dois guias usam Python. |
| Daytona | Use ComputerToolset com um sandbox de desktop do Daytona. Siga o guia do Daytona sobre funções auxiliares para o Uso do computador (Python). Para ver um exemplo com o SDK Agents, consulte a receita de Uso do computador com o Daytona. |
| E2B Desktop | Execute ações de computador ou código em um sandbox de desktop. Siga o guia de Uso do computador da E2B ou consulte os exemplos em Python e TypeScript. |
Defina um tempo limite para a sessão e encerre ou libere a sessão mesmo se a execução falhar. Se a liberação de recursos falhar, verifique o painel do provedor. Use as regras de rede do provedor para restringir os sites e recursos que a sessão pode acessar.
Execute sua primeira tarefa
Use Python 3.11 ou posterior, ou Node.js 22.6 ou posterior. Crie e exporte uma chave de API. Os dois exemplos usam um navegador local temporário e fazem chamadas à API Responses que podem gerar cobranças.
Instale os pacotes e o Chromium em uma nova pasta:
# Python
python3 -m venv .venv
.venv/bin/python -m pip install openai==3.31.0 playwright==1.61.0
.venv/bin/python -m playwright install chromium
# Node
npm install openai@7.33.0 playwright@1.61.1
npx playwright install chromium
No Windows, use py -3 no lugar de python3 e .venv\Scripts\python.exe no lugar de .venv/bin/python.
O modelo vê uma captura de tela de uma página fictícia de retirada de encomendas e clica para exibir os detalhes da retirada. O driver permite apenas capturas de tela e um clique com o botão esquerdo nesse controle. Ele bloqueia as solicitações da página e fecha o navegador ao fim da execução. O script faz no máximo seis solicitações à API Responses e verifica a página antes de informar que a tarefa foi concluída. Seu projeto precisa ter acesso a um modelo compatível com a ferramenta de computador.
Salve o exemplo correspondente como pickup.py ou pickup.mjs:
import asyncio
import base64
from openai import AsyncComputerToolset, AsyncOpenAI
from playwright.async_api import async_playwright
class PickupDriver:
def __init__(self, page):
self.page = page
async def screenshot(self):
image = await self.page.screenshot(type="png")
return {
"type": "computer_screenshot",
"image_url": "data:image/png;base64," + base64.b64encode(image).decode(),
}
async def allowed(self, action):
if action.type == "screenshot":
return True
if action.type != "click" or action.button != "left" or action.keys:
return False
box = await self.page.locator("summary").bounding_box()
return bool(
box
and box["x"] <= action.x < box["x"] + box["width"]
and box["y"] <= action.y < box["y"] + box["height"]
)
async def click(self, action):
# The page may have changed after approval, so bind the click again.
if not await self.allowed(action):
raise RuntimeError("Pickup details moved or the click is not allowed.")
await self.page.mouse.click(action.x, action.y)
async def refuse(self, action):
raise RuntimeError(f"This exercise does not allow {action.type}.")
double_click = drag = keypress = move = scroll = type = wait = refuse
async def main():
async with (
async_playwright() as playwright,
AsyncOpenAI(timeout=30, max_retries=0) as client,
):
browser = await playwright.chromium.launch(env={}, chromium_sandbox=True)
try:
page = await browser.new_page(viewport={"width": 1024, "height": 768})
await page.route("**/*", lambda route: route.abort())
await page.set_content(
"<title>Parcel pickup</title><main>"
"<h1>Parcel pickup</h1><p>Order #1042 is ready.</p>"
"<details><summary>Show pickup details</summary>"
"<p>Locker 18. Pickup code: 6249.</p></details></main>"
)
driver = PickupDriver(page)
tools = AsyncComputerToolset(driver)
try:
response = await tools.run(
client,
{
"model": "gpt-6.1-sol",
"store": False,
"input": "Take a screenshot. Open 'Show pickup details' and report the locker and pickup code. Use only screenshots and left clicks.",
},
before_action=driver.allowed,
max_steps=6,
)
if await page.locator("details").get_attribute("open") is None:
raise RuntimeError("Pickup details are still closed.")
print(
"Verified pickup details:",
await page.locator("details p").inner_text(),
)
print("Answer:", response.output_text)
finally:
tools.close()
finally:
await browser.close()
if __name__ == "__main__":
asyncio.run(main())Execute .venv/bin/python pickup.py ou node pickup.mjs. Se a tarefa for concluída com sucesso, o script exibe Verified pickup details: Locker 18. Pickup code: 6249. e, em seguida, a resposta do modelo. Verificações de segurança pendentes na API interrompem este exemplo. Adicione um callback de aprovação humana somente quando seu aplicativo puder lidar com essas verificações.
O modelo digita um nome em um formulário de crachá de visitante e clica em Create badge. O driver permite apenas ler a página, digitar e clicar. O callback de confirmação permite usar apenas os controles desse formulário e o nome Mira. O script verifica o resultado na página antes de informar que a tarefa foi concluída.
Salve o exemplo correspondente como badge.py ou badge.mjs:
import asyncio
from openai import AsyncOpenAI
from openai.lib.browser import AsyncBrowserToolset
from openai.lib.responses_tool_runner import AsyncResponsesToolRunner
from playwright.async_api import async_playwright
class BadgeForm:
def __init__(self, page):
self.page = page
async def state(self):
return {
"tabs": [
{
"id": "badge",
"title": await self.page.title(),
"url": self.page.url,
"active": True,
}
]
}
async def read_page(self, args):
return {
"version": 1,
"text": await self.page.locator("body").inner_text(),
"elements": [
{"ref": "name", "role": "textbox", "label": "Name"},
{"ref": "save", "role": "button", "label": "Create badge"},
],
"omitted": [],
}
async def type(self, args):
await self.page.locator("#name").fill(args["text"])
async def click(self, args):
await self.page.locator("#save").click()
async def confirm(self, context):
args = context["arguments"]
if self.page.url != "about:blank" or args["tab_id"] not in (None, "badge"):
return False
return (
context["member"] == "type"
and args["target"] == "name"
and args["text"] == "Mira"
) or (context["member"] == "click" and args["target"] == "save")
async def main():
async with (
async_playwright() as playwright,
AsyncOpenAI(timeout=30, max_retries=0) as client,
):
browser = await playwright.chromium.launch(env={}, chromium_sandbox=True)
try:
page = await browser.new_page()
await page.route("**/*", lambda route: route.abort())
await page.set_content("""
<title>Visitor badge</title>
<label>Name <input id="name"></label>
<button id="save" onclick="document.querySelector('output').innerText =
'Badge ready: ' + document.querySelector('#name').value">Create badge</button>
<output></output>
""")
driver = BadgeForm(page)
tools = AsyncBrowserToolset(
driver, members=["read_page", "type", "click"], confirm=driver.confirm
)
response = await AsyncResponsesToolRunner(browser=tools).run(
client,
{
"model": "gpt-6-astra",
"store": False,
"input": "Create a visitor badge for Mira.",
},
max_steps=6,
)
result = await page.locator("output").inner_text()
if result != "Badge ready: Mira":
raise RuntimeError(f"The badge was not created: {result!r}")
print(result)
print("Answer:", response.output_text)
finally:
await browser.close()
if __name__ == "__main__":
asyncio.run(main())Execute .venv/bin/python badge.py ou node badge.mjs. Se a tarefa for concluída com sucesso, o script exibe Badge ready: Mira e, em seguida, a resposta do modelo.
Se a API rejeitar a ferramenta ou o Chromium não iniciar, consulte as orientações para solucionar problemas de execução. Se os cliques não atingirem o alvo, verifique a captura de tela e as coordenadas.
Verifique o acesso ao modelo, os custos e o uso dos dados
- Modelo: Para usar ferramentas de função no navegador, verifique se o modelo é compatível com a API Responses e com a chamada de função. Se o driver retornar imagens, verifique também se o modelo aceita imagens como entrada. Para ações de computador baseadas em capturas de tela, verifique se a seção Tools do modelo inclui o Uso do computador. Consulte o catálogo de modelos e verifique a quais modelos seu projeto tem acesso.
- Custo: Cada solicitação à API Responses pode gerar cobranças pelos tokens de entrada e saída. Capturas de tela contam como entrada de imagem. Consulte os preços da API, estime o custo das imagens de entrada ou verifique o consumo por solicitação. O ambiente hospedado pode ter cobrança separada.
- Dados: O SDK envia à OpenAI o texto da página ou as capturas de tela que o driver retorna. Os exemplos definem
storecomofalse, mas ainda pode haver outras formas de retenção de dados. Consulte os controles de dados e as exceções para imagens de entrada. O provedor do ambiente tem sua própria política de dados.
Acompanhe e aprove as alterações
Em seguida, experimente a demonstração de reserva em Python ou Node. A demonstração preenche uma reserva fictícia, pede aprovação antes do envio e verifica os campos salvos e a confirmação. Você pode acompanhar o navegador, assumir o controle, devolvê-lo ou interromper a execução. As duas versões incluem um teste local com um navegador real, sem chamadas à API.
Para acompanhar as ações do SDK em um desktop, experimente a demonstração visual de desktop.
Adapte o driver
Substitua a página de exemplo por um ambiente controlado pelo seu aplicativo. Em um driver de navegador, disponibilize apenas as operações necessárias para a tarefa usando members. Em um driver de computador, implemente os métodos obrigatórios e rejeite ações não compatíveis. Mantenha a sessão aberta até o fim da execução e depois feche os recursos que seu aplicativo criou.
O conteúdo da página pode influenciar o modelo. Use um novo perfil de navegador ou um desktop isolado. Limite o acesso à rede e mantenha as credenciais fora do texto da página e das capturas de tela. Peça aprovação antes de fazer alterações e verifique o resultado salvo antes de informar que a tarefa foi concluída. Consulte a referência do driver para saber mais sobre contratos dos métodos, aprovação, política de URLs e recuperação.
Use Decisions quando as opções forem predefinidas
Use a API Responses quando o modelo precisar escolher ações e gerar os argumentos de cada uma. Use Decisions somente quando seu aplicativo já conhecer todas as ações permitidas e todos os argumentos de cada ação, inclusive seus valores. Por exemplo, um aplicativo pode oferecer route_billing, route_technical e review. Decisions seleciona uma opção. Ainda cabe ao aplicativo aprovar e executar a ação e depois verificar o resultado. Descarte as opções quando a página mudar. Consulte o guia de Decisions.
Para experimentar Decisions na demonstração de reserva, use uma chave com acesso a Decisions, defina OPENAI_DECISIONS_MODEL e reinicie o servidor. Inicie uma nova execução e selecione Decisions.
Use a API diretamente
Use a API Responses diretamente quando precisar gerenciar o ciclo de chamadas de ferramentas por conta própria. Você fornece o ambiente e executa as solicitações do modelo. Escolha como conectar o ambiente ao seu aplicativo:
- Execução de código: O modelo escreve código que usa uma biblioteca como PyAutoGUI ou Playwright para operar a interface. Uma única chamada pode combinar ações, laços de repetição ou lógica condicional.
- Ferramenta de computador: O modelo retorna ações estruturadas de mouse e teclado que o aplicativo converte em comandos de entrada para o navegador ou desktop.
Para o GPT-6 Astra, recomendamos a execução de código. A ferramenta computer continua disponível como alternativa compatível.
Se você já disponibiliza operações de interface por meio de chamada de função ou de ferramentas MCP remotas, pode manter essa interface. Consulte Use suas próprias ferramentas de interface para entender as diferenças na forma como essas integrações executam ferramentas e retornam resultados.
Use a execução de código
Uma integração de execução de código fornece ao modelo uma ferramenta de função que aceita um script. Seu aplicativo executa o script em um ambiente isolado de navegador ou desktop e retorna a saída, incluindo capturas de tela. Mantenha o ambiente disponível entre as chamadas para que o modelo possa dar continuidade às etapas anteriores.
Execute o aplicativo de exemplo
O aplicativo de exemplo do CUA inclui implementações em JavaScript com Playwright e em Python com PyAutoGUI, com tarefas locais e um console compartilhado:
- Siga as instruções de configuração da implementação escolhida em um ambiente isolado.
- Escolha um dos cenários incluídos e inicie a execução.
- Examine as ações, as capturas de tela e o estado final para avaliar se a tarefa foi concluída com sucesso.
Consulte o README do aplicativo para obter instruções de instalação e informações sobre permissões do desktop e ambientes compatíveis. Leia Execute com segurança antes de adaptar o aplicativo para sites ou contas reais.
Conecte seu próprio ambiente de execução
O exemplo a seguir mostra o ciclo de chamadas da API para um ambiente de execução fornecido por você. Os clientes em Python, Ruby e Go enviam código Python a um ambiente de desktop que usa PyAutoGUI. O cliente em JavaScript usa Playwright para operar um navegador. Cada cliente disponibiliza uma ferramenta de função comum e retorna texto ou imagens com o call_id original.
A função auxiliar execute_in_sandbox ou executeInSandbox envia código ao seu ambiente de execução e retorna as observações obtidas. Ela deve preservar a sessão do navegador ou desktop, impor limites de execução e aplicar suas regras de permissão. Esses exemplos de integração são independentes da execução do aplicativo de exemplo.
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
endfunc runComputerUse(ctx context.Context, client openai.Client, endpoint, prompt string, terminal *bufio.Scanner, output io.Writer) error {
session := make([]byte, 16)
if _, err := rand.Read(session); err != nil {
return err
}
sessionID := hex.EncodeToString(session)
tool := responses.ToolParamOfFunction("exec_py", map[string]any{
"type": "object", "properties": map[string]any{"code": map[string]any{"type": "string"}},
"required": []string{"code"}, "additionalProperties": false,
}, true)
tool.OfFunction.Description = openai.String("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.")
params := responses.ResponseNewParams{
Model: "gpt-6-astra", Tools: []responses.ToolUnionParam{tool},
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String(prompt)},
}
for turn := 0; turn < 20; turn++ {
response, err := client.Responses.New(ctx, params)
if err != nil {
return err
}
if response.Status != "completed" {
return fmt.Errorf("response stopped with status: %s", response.Status)
}
var calls []responses.ResponseFunctionToolCall
finalMessage := false
for _, item := range response.Output {
if item.Type == "function_call" {
calls = append(calls, item.AsFunctionCall())
}
if item.Type == "message" && item.AsMessage().Phase != "commentary" {
finalMessage = true
}
}
if len(calls) == 0 && finalMessage {
fmt.Fprintln(output, response.OutputText())
return nil
}
if turn == 19 {
return fmt.Errorf("task reached the 20-response limit; inspect the last result")
}
nextInput := responses.ResponseInputParam{}
for _, call := range calls {
if call.Name != "exec_py" {
return fmt.Errorf("unexpected tool: %s", call.Name)
}
var arguments struct {
Code *string `json:"code"`
}
if err := json.Unmarshal([]byte(call.Arguments), &arguments); err != nil {
return err
}
if arguments.Code == nil {
return fmt.Errorf("exec_py requires code")
}
observations, err := executeInSandbox(ctx, endpoint, sessionID, *arguments.Code, terminal, output)
if err != nil {
return err
}
nextInput = append(nextInput, responses.ResponseInputItemUnionParam{
OfFunctionCallOutput: &responses.ResponseInputItemFunctionCallOutputParam{
CallID: openai.String(call.CallID),
Output: responses.ResponseInputItemFunctionCallOutputOutputUnionParam{OfResponseFunctionCallOutputItemArray: observations},
},
})
}
params.Input = responses.ResponseNewParamsInputUnion{OfInputItemList: nextInput}
params.PreviousResponseID = openai.String(response.ID)
}
return nil
}Para ver um adaptador de cliente completo e o formato esperado da saída de texto e imagem, consulte Conecte seu serviço de execução. A interface de serviço desses exemplos pertence ao seu aplicativo. A OpenAI não hospeda esse endpoint.
Preserve o estado e retorne observações
Mantenha a sessão do navegador ou desktop ativa entre as chamadas. Um namespace persistente em Python ou JavaScript também pode preservar variáveis. Descreva os objetos e as funções auxiliares disponíveis na definição da ferramenta para que o modelo saiba o que pode usar.
Quando o estado da interface for desconhecido, forneça ao modelo uma captura da tela atual. Após uma breve sequência de ações, retorne outra captura para que o modelo possa verificar o resultado. Mantenha as imagens na memória e use detail: "original" para preservar a resolução. Se você reduzir a resolução de uma captura, converta as coordenadas do modelo de volta para o sistema de coordenadas do ambiente antes de executar as ações. Consulte Captura de tela e resolução.
A conversa na API e o ambiente de execução mantêm estados separados. Preserve as chamadas de ferramentas e suas saídas na conversa e mantenha o ambiente correspondente disponível no aplicativo. Dar continuidade a uma resposta não restaura a sessão do navegador, o estado de login nem as variáveis do ambiente de execução.
Use a ferramenta de computador
Use essa alternativa quando sua integração esperar ações estruturadas em vez de código gerado.
Para experimentar essa opção, siga as mesmas instruções de configuração do aplicativo de exemplo, selecione o modo Native e execute um dos cenários incluídos. Use um modelo compatível com a ferramenta de computador.
A interação com a API tem três etapas: enviar uma tarefa, executar as ações retornadas e retornar uma captura de tela. Os trechos de código desta seção usam uma página com o controle Show filters e um campo de pesquisa. Ao integrar a ferramenta, adapte a tarefa à sua interface.
Para configurar o ambiente e implementar os manipuladores de ações, consulte as receitas de integração.
Envie a tarefa
Habilite computer no array tools e descreva o resultado desejado:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-6.1-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)Execute as ações solicitadas
Cada computer_call contém um array actions com as ações na ordem de execução. Por exemplo, esta chamada seleciona o campo de pesquisa e digita penguin:
{
"output": [
{
"type": "computer_call",
"call_id": "call_002",
"actions": [
{ "type": "click", "button": "left", "x": 405, "y": 157 },
{ "type": "type", "text": "penguin" }
],
"status": "completed"
}
]
}Seu manipulador de ações converte essas solicitações em comandos de entrada para o navegador ou sistema operacional. Execute as ações permitidas na ordem recebida e depois capture a tela atualizada. O modelo pode solicitar click, double_click, drag, move, scroll, keypress, type, wait ou screenshot.
A primeira chamada pode conter apenas uma ação screenshot. Nesse caso, capture a tela atual e retorne a imagem sem alterar a interface. O campo status: "completed" indica que o modelo terminou de gerar a chamada. Seu aplicativo ainda precisa executá-la.
Consulte os exemplos de manipuladores de ações para ver como mapear teclas, definir trajetórias de arraste e usar teclas modificadoras.
Retorne a captura de tela
Retorne um computer_call_output cujo call_id corresponda à chamada que você processou. Use previous_response_id para continuar a conversa com o modelo:
from openai import OpenAI
client = OpenAI()
def send_computer_screenshot(response, call_id, screenshot_base64):
return client.responses.create(
model="gpt-6.1-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",
},
}
],
)As mesmas orientações sobre capturas de tela e preservação de estado se aplicam a esse ciclo. Mantenha o ambiente disponível enquanto usa previous_response_id para continuar a conversa com o modelo.
Continue até que o modelo pare de retornar itens computer_call. Examine o restante da saída para identificar uma resposta, um pedido de ajuda ou outra chamada de ferramenta e verifique o resultado no aplicativo. Neste exemplo, o painel Filters deve estar aberto e o campo de pesquisa deve conter penguin.
Consulte Repita o ciclo de Uso do computador para ver a estrutura do ciclo e as funções auxiliares necessárias para executar ações e capturar a tela.
Execute com segurança
O Uso do computador pode afetar contas e dados reais. Aplique os controles a seguir no aplicativo, no ambiente de execução e nas instruções do modelo:
- Restrinja o ambiente. Use um navegador isolado ou uma máquina virtual e uma lista de sites e ações permitidos. Limite o acesso ao necessário para a tarefa.
- Trate o conteúdo da tela como não confiável. O texto de uma página, de um documento ou do resultado de uma ferramenta não pode conceder permissão nem se sobrepor às instruções do usuário.
- Confirme ações com consequências importantes. Mantenha o usuário no controle de compras, transmissão de dados, alterações destrutivas e outras ações difíceis de reverter. Digitar informações confidenciais em um formulário já conta como transmissão.
- Defina limites e verifique o resultado. Estabeleça limites de etapas, tempo ou custo, permita o cancelamento e verifique o resultado real em vez de confiar apenas na resposta final do modelo.
Consulte as orientações sobre confirmação e consentimento para conhecer os requisitos específicos de aprovação, saber quando transferir o controle para uma pessoa e ver exemplos de prompts.
Próximas etapas
- Use as receitas de integração para configurar o ambiente, implementar manipuladores de ações, capturar a tela e criar adaptadores para o serviço de execução.
- Siga o guia de migração de computer-use-preview ao atualizar uma integração mais antiga.
- Explore o aplicativo de exemplo do CUA para ver fluxos de trabalho completos no navegador e no desktop.