Curs
Imaginează-ți un checkout care arată 48 $ în coș și 24 $ pe pagina de revizuire. Clientul vede două totaluri în același checkout.
Echipele rulează de obicei teste de asigurare a calității (QA) pe acest flux cu un script de browser: dă clic pe butonul acesta, deschide pagina aceea, verifică valoarea asta. Un test scriptat verifică doar stările pe care autorul le-a notat.
Un agent AI este un model care poate întreprinde acțiuni pentru a atinge un obiectiv. Agents API de la OpenAI gestionează bucla agentului și păstrează munca lui într-o sesiune. În acest tutorial, Computer Use oferă și browserul găzduit.
Northstar Checkout este un magazin de test fictiv cu un bug ascuns la subtotal.
Agentul primește rezultatul corect al checkout-ului, dar nu și locația bugului sau o listă de butoane pe care să apese. Un mic program Python, numit harness, compară valorile raportate de agent și apoi cere aceleiași sesiuni să testeze magazinul reparat.
În acest tutorial, îți arăt cum să:
- Creezi o sesiune Agents API cu Computer Use care poate ajunge doar la site-ul de test
- Aprobi cererea browserului de a deschide acel site și să refuzi orice altceva
- Lași propriul cod să decidă dacă testul a trecut
- Retestezi site-ul reparat în aceeași sesiune și calculezi cât a costat experimentul
Codul și măsurătorile folosesc versiunea 3.22.1 a pachetului Python openai.
Pe scurt
Dacă ai doar un minut, iată ideile principale.
- Build-ul cu bug a eșuat doar la subtotalul de revizuire; cantitatea a rămas corectă.
- Build-ul reparat a trecut în aceeași sesiune, fără a doua aprobare de origine.
- Contoarele de tokeni au produs o estimare la tarif standard de 0,9469 $. Taxele pentru scriere în cache și compute în sandbox-ul găzduit nu sunt incluse, iar utilizarea Agents API este best-effort, nu o factură finală.
- În fiecare test, API-ul a returnat 2 capturi de ecran, din 7, respectiv 5 elemente
computer_use_call.
Acesta este un singur magazin de test cu un singur bug plantat, nu un benchmark de fiabilitate.
Ce este Computer Use în OpenAI Agents API?
Computer Use este un instrument în OpenAI Agents API care permite unui agent să opereze un browser rulând pe serverele OpenAI. Codul tău urmărește evenimentele sesiunii și îi răspunde la cereri. OpenAI listează testarea de website-uri ca un caz de utilizare.
OpenAI gestionează bucla agentului, sesiunea și recuperarea. Tutorialul nostru despre OpenAI Agents API acoperă aceste elemente de bază.
Setările mai vechi pentru computer use, precum cea din tutorialul nostru pentru GPT-5.4 computer use, fac ca bucla de captură de ecran și acțiune să fie rulată de codul dezvoltatorului.

De ce să folosești Computer Use pentru testarea QA în browser?
În QA de browser, chiar pagina este obiectul testului.
A apela direct un API de checkout ar sări peste pagina unde trăiește bugul Northstar, așa că agentul urmează același traseu ca un client: de la pagina de produs la coș, checkout și revizuire.

Harness, sesiune, browser găzduit, site de staging. Imagine de autor.
OpenAI gestionează sesiunea și browserul în zona gri; harness-ul și Northstar rămân în afara ei.
Ce vom construi cu Agents API Computer Use?
Proiectul constă într-un magazin de staging fictiv, un harness Python și o sesiune Agents API.
Codul complet este în acest repository GitHub.
Cazul de test Northstar Checkout
Northstar vinde o singură Trail Bottle de 24 $. Testul merge de la produs la coș, checkout și revizuire; nu există livrare, taxe, login sau buton funcțional de cumpărare.

Pagina de produs Northstar înainte de test. Imagine de autor.
Build-ul ns-1041 conține bugul, în timp ce ns-1042 conține remedierea. Adăugarea lui ?reset=1 la URL-ul de start al unui build golește coșul înaintea oricărui test.
Cererea QA este scrisă ca obiectiv. Criteriile de acceptare îi cer agentului să:
- Găsească Trail Bottle și să pună 2 în coș
- Verifice că subtotalul coșului este 48,00 $
- Continue la pagina de revizuire a comenzii și să verifice că cantitatea și subtotalul încă se potrivesc
- Raporteze doar valori vizibile în browser
O constrângere separată de siguranță spune să nu plaseze, trimită sau plătească vreo comandă. Cererea definește rezultatul, nu clicurile.
Bugul plantat în checkout
Build-ul cu bug adună prețurile unitare pe pagina de revizuire și uită cantitatea. Ambele pagini arată cantitatea 2, dar subtotalul coșului este 48,00 $, iar subtotalul de revizuire este 24,00 $.
Cheia de răspuns trăiește în codul aplicației. Nici instrucțiunile, nici mesajul sarcinii nu menționează bugul.
Cum decide codul aplicației „pass” sau „fail”
Agentul raportează ID-ul build-ului și 4 valori observate printr-un singur instrument funcție, record_qa_result.
Harness-ul verifică mai întâi că build-ul raportat este cel aflat în test, deoarece ambele build-uri împart un hostname, apoi compară valorile cu cheia de răspuns.
Un instrument funcție rulează doar dacă agentul îl apelează. O înregistrare lipsă, o valoare lipsă sau un build greșit face rezultatul incomplete, care nu contează niciodată ca „pass”.

De la obiectivul QA la verdictul aplicației. Imagine de autor.
Cum să configurezi testarea în browser cu OpenAI Agents API
Ai nevoie de Python, o cheie API cu scope-uri potrivite, acces la GPT-6 Astra și o sesiune cu Computer Use.
Precondiții pentru Agents API Computer Use
- Python 3.10 sau mai nou și
openai==3.22.1(SDK-ul trimite antetulOpenAI-Beta: agents=v1pentru tine) - O cheie API cu scope-urile
api.agents.read,api.agents.writeșiapi.responses.write, pe un proiect care poate folosigpt-6-astra
Agents API este în beta publică, așa că numele câmpurilor și comportamentul pot varia între versiunile SDK. Repository-ul fixează versiunea 3.22.1 în requirements.txt.
Browserul găzduit are nevoie de un URL accesibil, așa că codul folosește un deployment Vercel al Northstar.
git clone https://github.com/KhalidAbdelaty/OpenAI-Agents-API.git
cd OpenAI-Agents-API
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item .env.example .env # then add your OPENAI_API_KEY
python run_qa.py
Pentru mai multe despre izolarea dependențelor, vezi ghidul nostru despre environment-uri virtuale. Pe macOS sau Linux, activează cu source .venv/bin/activate și copiază fișierul cu cp. Ține cheia în .env, niciodată în cod.
Experimentul folosește GPT-6 Astra, modelul din exemplele OpenAI pentru Computer Use. Prezentarea noastră GPT-6 Astra acoperă modelul.
Codul folosește Agents API (client.beta.agents), nu Agents SDK și nici instrumentul computer din Responses API folosit în tutorialul nostru GPT-6 Astra API.
Configurează o sesiune Computer Use
Creează o sesiune cu instrumentul computer_use și un desktop găzduit de OpenAI, apoi refolosește-o pentru ambele teste:
session = client.beta.agents.sessions.create(
agent={"model": MODEL, "instructions": INSTRUCTIONS,
"reasoning": {"effort": REASONING_EFFORT}, # "medium", set explicitly
"tools": [{"type": "computer_use", "include_screenshots": True}, RECORD_QA_RESULT]},
environment={"type": "openai_hosted", "desktop": {"enabled": True},
"network": {"access": "restricted", "allowed_domains": [host]}},
metadata={"experiment": "northstar-browser-qa"},
)
include_screenshots: True expune orice capturi de ecran returnează API-ul, în timp ce accesul de rețea restricționat limitează browserul la Northstar.
Mediul folosește dimensiunea implicită medium (2 vCPU, 4 GB RAM).
Adaugă o funcție pentru rezultatele QA
Funcția înregistrează ce a observat agentul. Dacă agentul nu poate citi una dintre cele 4 valori verificate de cantitate sau subtotal, trebuie să raporteze acel câmp ca null.
Listarea fiecărei proprietăți sub required îi spune modelului să răspundă la toate, folosind null pentru orice nu a văzut. Harness-ul tot tratează un câmp lipsă ca incomplete:
"properties": {
"build_id": {"type": "string", "description": "Build id shown on the page."},
"stage_reached": {"type": "string", "enum": ["product", "cart", "checkout_details", "review"]},
"cart_quantity": {"type": ["integer", "null"]},
"cart_subtotal": {"type": ["string", "null"], "description": "Exactly as displayed, e.g. $10.00"},
"review_quantity": {"type": ["integer", "null"]},
"review_subtotal": {"type": ["string", "null"], "description": "Exactly as displayed"},
"purchase_control": {"type": "string", "enum": ["disabled", "absent", "enabled", "not_seen"]},
"evidence_note": {"type": "string", "description": "One or two sentences on what you saw."},
},
"required": ["build_id", "stage_reached", "cart_quantity", "cart_subtotal",
"review_quantity", "review_subtotal", "purchase_control", "evidence_note"],
"additionalProperties": False,
Harness-ul convertește fiecare preț afișat în cenți, verifică ID-ul build-ului și compară valorile cu cheia de răspuns:
EXPECTED = {"cart_quantity": 2, "cart_subtotal_cents": 4800,
"review_quantity": 2, "review_subtotal_cents": 4800}
def judge(record, expected_build):
observed = {
"cart_quantity": record.get("cart_quantity"),
"cart_subtotal_cents": to_cents(record.get("cart_subtotal")),
"review_quantity": record.get("review_quantity"),
"review_subtotal_cents": to_cents(record.get("review_subtotal")),
}
missing = [field for field, value in observed.items() if value is None]
if record.get("build_id") != expected_build:
return {"verdict": "incomplete", "observed": observed, "failed_checks": [],
"missing": ["build_id="+str(expected_build), *missing]}
if record.get("stage_reached") != "review":
missing.append("stage_reached=review")
failed = [{"field": field, "expected": EXPECTED[field], "observed": value}
for field, value in observed.items()
if value is not None and value != EXPECTED[field]]
verdict = "fail" if failed else "incomplete" if missing else "pass"
return {"verdict": verdict, "observed": observed, "failed_checks": failed, "missing": missing}
O valoare ilizibilă sau lipsă produce un verdict incomplete, niciodată „pass”.
Un raport din build-ul greșit returnează incomplete înainte ca valorile sale să poată influența verdictul.
Scrie instrucțiunile QA
Aceleasi instrucțiuni guvernează ambele teste:
INSTRUCTIONS = (
"You are a QA tester for the Northstar Checkout staging site. "
"Use the browser to run the test you are given. "
"Stay on the approved staging origin and do not visit any other website. "
"Inspect what is visible on a page before you make any claim about it. "
"Stop before any purchase: never place, submit, or pay for an order. "
"Never invent an observed value. If you could not see a value, report null. "
"Call record_qa_result once, only after the browser test is finished, then give a short summary."
)
Doar build-ul website-ului se schimbă între teste.
Cum să rulezi un test QA în browser cu Computer Use
Deschide fluxul de evenimente, trimite obiectivul QA o singură dată, apoi gestionează aprobările și apelurile de funcții până se încheie turul.
Trimite o sarcină QA către sesiunea Agents API
Deschide mai întâi fluxul de evenimente, apoi trimite sarcina exact o dată:
with self.client.beta.agents.sessions.events.stream(self.session_id) as events:
if not sent: # open the stream first, then send the task exactly once
self.client.beta.agents.sessions.events.create(self.session_id, events=[message(text)])
sent = True
else: # reconnected: act on what is still pending, never resend the task
yield from self.handle_required_actions()
for event in events:
yield from self.handle(event)
Stream-urile nu redau evenimentele ratate. Dacă fluxul cade, deschide unul nou, apoi recuperează sesiunea și elementele salvate cât timp rămâne conectat.
Mesajul sarcinii numește build-ul, criteriile de acceptare și constrângerea de siguranță, dar nimic despre bug:
QA objective for Northstar Checkout staging build ns-1041. Start at https://northstar-checkout-staging.vercel.app/b/ns-1041/?reset=1
Scenario: a customer adds 2 Trail Bottles to the cart and continues through checkout to the order review page.
Acceptance criteria:
- The cart shows quantity 2 and a subtotal of $48.00 (unit price $24.00, no shipping or taxes).
- The order review page shows the same quantity and subtotal as the cart.
Safety constraint: never place, submit, or pay for an order.
Record the cart values and the review values as separate fields.
Păstrează ID-ul sesiunii pentru retest.
Gestionează aprobarea originii browserului
Browserul găzduit cere aprobare înainte de a deschide fiecare nouă origine de website.
Fluxul emite agent.session.requires_action; recuperează sesiunea și citește required_actions pentru cerere.
def answer_approval(self, action):
request = action.request
if request.type == "browser_origin_access":
decision = "approve" if request.origin.rstrip("/") == self.origin else "deny"
response = {"type": "browser_origin_access", "decision": decision}
else: # browser_authentication: Northstar has no login, so sign-in is refused
response = {"type": "browser_authentication", "action": "cancel"}
self.client.beta.agents.sessions.events.create(self.session_id, events=[{
"type": "agent.session.input.computer_use_approval_request_result",
"request_id": action.request_id, "response": response}])
Urmărește activitatea browserului cu evenimentele sesiunii
Munca în browser apare ca elemente computer_use_call, fiecare cu un titlu scurt și un status. Fluxul de evenimente pentru primul test a arătat:
12.4s turn sent build=ns-1041
59.4s browser completed Connecting to the staging test browser
63.6s browser completed Connecting to the staging test browser
68.6s approval approve https://northstar-checkout-staging.vercel.app
70.8s browser completed Inspecting the Trail Bottle product
73.5s browser completed Adding the first Trail Bottle
78.2s browser completed Checking cart quantity and subtotal
85.7s browser completed Continuing to checkout details
89.2s browser completed Checking order review values
95.9s record cart 2 $48.00, review 2 $24.00, purchase disabled
Au trecut aproximativ 47 de secunde înainte de prima activitate în browser.
Toate cele 7 elemente computer_use_call s-au încheiat, dar statusul unui element nu este verdictul QA; rezultatul funcției este.
A prins agentul bugul din checkout?
Da. Mai important, apelul funcției a izolat eșecul la un singur câmp: subtotalul de revizuire.
Ce a raportat GPT-6 Astra
Apelul record_qa_result a conținut:
{
"build_id": "ns-1041",
"cart_quantity": 2,
"cart_subtotal": "$48.00",
"review_quantity": 2,
"review_subtotal": "$24.00",
"stage_reached": "review",
"purchase_control": "disabled"
}
Fiecare valoare se potrivește cu pagina cu bug. Cantitatea a rămas 2 pe pagina de revizuire, ceea ce exclude o nepotrivire vizibilă a cantității.
Cum a transformat harness-ul raportul într-un eșec
judge() a confirmat build-ul ns-1041, a comparat cele 4 valori cu cele așteptate și a găsit greșit doar subtotalul de revizuire.
Acesta este singurul verdict folosit în experiment:
{
"verdict": "fail",
"failed_checks": [{"field": "review_subtotal_cents", "expected": 4800, "observed": 2400}],
"missing": []
}
Retestează o remediere în aceeași sesiune Agents API
După ce remedierea este live, trimite încă un mesaj în aceeași sesiune.
Acest mic test de regresie folosește aceleași instrucțiuni și aceeași funcție de verdict.
Livrarea remedierii fără a schimba testul
Remedierea din build-ul ns-1042 este o linie din JavaScript-ul Northstar:
-const reviewSubtotal = (cart) => cart.reduce((sum, line) => sum + line.unitCents, 0);
+const reviewSubtotal = (cart) => cart.reduce((sum, line) => sum + line.unitCents * line.qty, 0);
Trimite follow-up-ul în aceeași sesiune
Linkul de start include ?reset=1, astfel încât retestul începe cu un coș gol. Apoi follow-up-ul merge în aceeași sesiune:
A fix is deployed as staging build ns-1042 at https://northstar-checkout-staging.vercel.app/b/ns-1042/?reset=1
That link starts from an empty cart. Run the same QA objective and acceptance criteria against this build from the start of the journey, and record a new result.
Retestul a păstrat mediul găzduit și nu a necesitat o nouă aprobare de origine. Nu te baza pe starea browserului, deoarece cookie-urile pot expira, iar reciclarea mediului o golește.

O singură sesiune a dus ambele teste QA. Imagine de autor.
Un sandbox găzduit poate fi șters dacă activitatea și keep-alive-urile se opresc timp de 1 oră. Fii atent la agent.session.environment.reset și începe fiecare retest dintr-o stare cunoscută.
A trecut retestul?
Da. Retestul a raportat cantitatea din coș 2 și 48,00 $, apoi cantitatea la revizuire 2 și 48,00 $, iar judge() a returnat „pass” fără verificări eșuate.
A durat 38,9 secunde cu 5 elemente de activitate în browser, față de 96,5 secunde și 7 elemente la primul test, care a inclus o așteptare de 47 de secunde înainte de începerea activității în browser.

Retestul a trecut fără o nouă aprobare. Imagine de autor.
Returnează Computer Use o captură de ecran pentru fiecare activitate?
Nu neapărat. Chiar și cu include_screenshots setat, primul test a returnat 2 capturi de ecran din 7 elemente de activitate în browser, iar retestul a returnat 2 din 5.
Unele elemente returnează output: null, deci rapoartele nu pot presupune o imagine pentru fiecare activitate.
Fluxul de evenimente nu este un feed video continuu al browserului găzduit; returnează elemente de activitate ale browserului și capturi de ecran când sunt disponibile.
Northstar folosește rrweb pentru a captura schimbări și interacțiuni din Document Object Model (DOM), a le trimite către același host și a reda ambele călătorii mai jos.
Browserul agentului pe ambele build-uri de staging. Video de autor.
Redarea arată cantitatea 2 și 24,00 $ pe ns-1041, apoi 48,00 $ pe ns-1042; butonul dezactivat de cumpărare rămâne neatins.
Repository-ul include și un mic viewer Streamlit pentru verdictul salvat, dovezile din browser, detaliile sesiunii, costul și jurnalul de evenimente.
Cât a costat testul Agents API Computer Use?
Contoarele de utilizare best-effort au produs o estimare de 0,9469 $ la tarif standard pentru ambele teste.
Utilizarea de tokeni pentru cele 2 teste
| Metrică | Test 1 (ns-1041) |
Retest (ns-1042) |
|---|---|---|
| Tokeni input | 255.550 | 223.533 |
| Tokeni input în cache | 217.041 (84,9%) | 219.449 (98,2%) |
| Tokeni output | 982 | 708 |
| Cost estimat tokeni | 0,6512 $ | 0,2957 $ |
| Timp pe tură | 96,5 secunde | 38,9 secunde |
| Elemente activitate browser | 7 | 5 |
Retestul a folosit mai puțini tokeni de input, iar 98,2% dintre ei au venit din prompt cache. Împreună, cele 2 teste au costat 0,9469 $.
Ghidul de observabilitate spune că utilizarea poate fi null când este necunoscută și că numărătorile înregistrate pot varia, așa că verifică-le din nou înainte de a șterge sesiunea.
Ce nu includ cifrele de utilizare din Agents API
Când am rulat testele, acestea erau tarifele standard GPT-6 Astra pe pagina de prețuri OpenAI:
| Tip de token | Tarif per 1M tokeni |
|---|---|
| Input | 10,00 $ |
| Input în cache | 1,00 $ |
| Scrieri în cache | 12,50 $ |
| Output | 50,00 $ |
Pragul de context lung de 272K se aplică per cerere. Inputul combinat al ambelor ture a rămas sub acesta, deci nicio cerere nu ar fi putut declanșa tarifele mai mari pentru context lung.
Estimarea tot nu poate reproduce factura finală deoarece utilizarea Agents API este best-effort și nu expune numărători separate pentru scrieri în cache.
Sandbox-ul găzduit este facturat separat la tarife standard pentru containere. Pagina de prețuri listează containerul medium de 4 GB la 0,12 $ per sesiune de 20 de minute, cu sesiunile eligibile facturate la minut și un minim de 5 minute.
Cum să păstrezi testele Agents API Computer Use în siguranță
Siguranța depinde de ce poate atinge browserul și ce permite pagina să facă.

Trei straturi între agent și checkout. Imagine de autor
Ce acoperă aprobarea originii în Computer Use
Politica de rețea controlează ce hosturi poate atinge browserul, iar aprobarea originii decide dacă poate deschide fiecare origine nouă. Niciuna nu confirmă acțiuni individuale în browser.
A aproba northstar-checkout-staging.vercel.app nu înseamnă, așadar, a aproba fiecare clic în parte.
Regula „fără cumpărare” este o constrângere de siguranță, iar purchase_control este salvat ca dovadă, mai degrabă decât judecat ca un criteriu de acceptare. Butonul dezactivat „Place order” din Northstar este controlul care o impune.
Cum limitează politica de rețea browserul găzduit
Sub restricted, browserul poate atinge doar hostname-urile pe care le listezi.
Ghidul sandbox de la OpenAI acceptă între 1 și 100 de hostname-uri exacte, fără wildcard-uri, protocoale, căi sau porturi. Rețelele de livrare de conținut (CDN), subdomeniile și destinațiile redirectărilor au nevoie de intrări separate.
Cum să gestionezi capturile de ecran și datele sesiunii
Capturile de ecran și înregistrările rrweb conțin orice arată pagina, deci Northstar folosește date fictive, nu are login și declară înregistrarea în subsol.
Recorderul maschează inputurile, dar un deployment de producție ar avea totuși nevoie de o politică de date și o mascarea potrivite pentru pagină.
Agents API suportă rezidența datelor doar în Statele Unite și nu este eligibil pentru Zero Data Retention (ZDR), nici măcar cu un sandbox self-hosted.
Salvează rezultatele și capturile de ecran de care ai nevoie, apoi șterge sesiunea, în loc să lași un checkout de staging în stare de sesiune reținută.
Ștergerea sesiunii din Agents API nu șterge înregistrările rrweb stocate de site. Elimină-le separat conform politicii de înregistrare.
Gânduri finale
Northstar a eșuat când subtotalurile din coș și din revizuire s-au despărțit, apoi a trecut după remediere, în aceeași sesiune. Harness-ul, nu rezumatul modelului, a decis ambele verdicte.
Aș păstra testele de regresie scriptate pentru invarianti cunoscuți și aș folosi agenți de browser ghidați de obiective pentru călătorii exploratorii care sunt mai greu de exprimat ca o asertare. Agentul explorează; codul aplicației decide.
Pentru elementele de bază ale API-ului, îți recomand cursul nostru Working with the OpenAI API.
Întrebări frecvente
Este Computer Use din Agents API disponibil în general?
Nu, vine ca parte a beta-ului public Agents API, iar fiecare cerere poartă antetul OpenAI-Beta: agents=v1. Fixează versiunea SDK-ului cu care testezi, deoarece numele evenimentelor și câmpurile încă se pot schimba înainte de disponibilitatea generală.
Înseamnă o pondere mare de input în cache că retestul a economisit bani?
Nu de la sine. Ghidul de observabilitate spune că un procent mare de input în cache nu măsoară economiile la costul total al sarcinii, deoarece inputul în cache este tot facturat, iar apelurile repetate pot reprocesează un istoric mare.
Acoperă o singură aprobare de origine și turele ulterioare ale sesiunii?
A făcut-o aici: retestul nu a ridicat nicio nouă cerere. Ține handlerul de aprobare în funcțiune la fiecare tură și nu presupune niciodată că un site este încă aprobat.
De ce listener-ul tău nu vede niciodată agent.session.action_required?
Acel nume aparține webhook-ului. Pe fluxul de evenimente, pauza sosește ca agent.session.requires_action. Gestioneaz-o prin același flux de acțiuni necesare folosit pentru aprobarea originii.
Ce se întâmplă dacă agentul apelează record_qa_result de două ori într-o tură?
Harness-ul păstrează ultimul apel, ceea ce e în regulă pentru o verificare read-only. Dacă funcția ta scrie undeva, stochează fiecare rezultat pe sesiune, tură și ID de apel și verifică un rezultat anterior înainte de a acționa de două ori.