Corso
Immagina un checkout che mostra 48 $ nel carrello e 24 $ nella pagina di riepilogo. Il cliente vede due totali nello stesso checkout.
Di solito i team eseguono test di quality assurance (QA) su questo flusso con uno script per browser: clicca questo pulsante, apri quella pagina, controlla questo valore. Un test scriptato verifica solo gli stati annotati da chi l'ha scritto.
Un agente AI è un modello che può compiere azioni verso un obiettivo. L'Agents API di OpenAI gestisce il loop dell'agente e conserva il suo lavoro in una sessione. In questo tutorial, Computer Use fornisce anche il browser ospitato.
Northstar Checkout è un negozio di test fittizio con un bug nascosto nel subtotale.
L'agente riceve il risultato corretto del checkout, ma non l'ubicazione del bug o un elenco di pulsanti da premere. Un piccolo programma Python, chiamato harness, confronta i valori riportati dall'agente e poi chiede alla stessa sessione di testare lo store corretto.
In questo tutorial, vedremo come:
- Creare una sessione dell'Agents API con Computer Use che possa raggiungere solo il sito di test
- Approvare la richiesta del browser di aprire quel sito e rifiutare qualunque altro
- Far decidere al tuo codice se il test è passato
- Ritestare lo store corretto nella stessa sessione e calcolare il costo dell'esperimento
Il codice e le misurazioni usano la versione 3.22.1 del pacchetto Python openai.
In breve
Se hai solo un minuto, ecco i punti chiave.
- La build con bug ha fallito solo il subtotale del riepilogo; la quantità è rimasta corretta.
- La build corretta è passata nella stessa sessione senza una seconda approvazione dell'origine.
- I contatori dei token hanno prodotto una stima a tariffa standard di 0,9469 $. Le spese di scrittura in cache e il compute del sandbox ospitato non sono inclusi e l'uso dell'Agents API è a migliore sforzo, non una fattura finale.
- In ciascun test, l'API ha restituito 2 screenshot, da 7 e 5 elementi
computer_use_callrispettivamente.
Questo è un solo negozio di test con un solo bug inserito ad arte, non un benchmark di affidabilità.
Che cos'è Computer Use nell'Agents API di OpenAI?
Computer Use è uno strumento dell'Agents API di OpenAI che consente a un agente di usare un browser in esecuzione sui server di OpenAI. Il tuo codice segue gli eventi della sessione e risponde alle sue richieste. OpenAI elenca il testing di siti web tra gli usi possibili.
OpenAI gestisce il loop dell'agente, la sessione e il ripristino. Il nostro tutorial sull'Agents API di OpenAI copre queste basi.
Impostazioni più vecchie per l'uso del computer, come quella nel nostro tutorial su GPT-5.4 e l'uso del computer, fanno sì che sia il codice dello sviluppatore a eseguire il loop di screenshot e azioni.

Perché usare Computer Use per il QA del browser?
Nel QA del browser, la pagina stessa è l'oggetto del test.
Chiamare direttamente un'API di checkout salterebbe la pagina in cui vive il bug di Northstar, quindi l'agente segue lo stesso percorso di un cliente: dalla pagina prodotto al carrello, al checkout, fino al riepilogo.

Harness, sessione, browser ospitato, sito di staging. Immagine dell'autore.
OpenAI gestisce la sessione e il browser all'interno della zona grigia; l'harness e Northstar restano all'esterno.
Cosa costruiremo con l'Agents API Computer Use?
Il progetto comprende un negozio di staging fittizio, un harness Python e una sessione dell'Agents API.
Il codice completo è in questo repository GitHub.
Il caso di test di Northstar Checkout
Northstar vende una sola Trail Bottle da 24 $. Il test passa da prodotto a carrello, checkout e riepilogo; non ci sono spedizione, tasse, login né un pulsante di acquisto funzionante.

Pagina prodotto di Northstar prima del test. Immagine dell'autore.
La build ns-1041 contiene il bug, mentre ns-1042 contiene la correzione. Aggiungere ?reset=1 all'URL di avvio di una build svuota il carrello prima di ciascun test.
La richiesta QA è scritta come un obiettivo. I suoi criteri di accettazione chiedono all'agente di:
- Trovare la Trail Bottle e metterne 2 nel carrello
- Verificare che il subtotale del carrello sia 48,00 $
- Continuare alla pagina di riepilogo ordine e verificare che quantità e subtotale corrispondano ancora
- Riportare solo valori visibili nel browser
Un vincolo di sicurezza separato dice di non effettuare mai, inviare o pagare un ordine. La richiesta definisce l'esito, non i clic.
Il bug inserito nel checkout
La build con bug somma i prezzi unitari nella pagina di riepilogo e dimentica la quantità. Entrambe le pagine mostrano quantità 2, ma il subtotale del carrello è 48,00 $ e quello del riepilogo è 24,00 $.
La soluzione di riferimento vive nel codice dell'applicazione. Né le istruzioni né il messaggio dell'attività menzionano il bug.
Come il codice dell'applicazione decide pass o fail
L'agente riporta l'ID build e 4 valori osservati tramite uno strumento funzione, record_qa_result.
L'harness prima verifica che la build riportata sia quella in test, poiché entrambe le build condividono un hostname, quindi confronta i valori con la soluzione di riferimento.
Uno strumento funzione esegue solo se l'agente lo chiama. Un record mancante, un valore mancante o la build sbagliata producono il risultato incomplete, che non conta mai come pass.

Dall'obiettivo QA al verdetto dell'applicazione. Immagine dell'autore.
Come configurare i test del browser con l'Agents API di OpenAI
Ti servono Python, una chiave API con scope, accesso a GPT-6 Astra e una sessione con Computer Use.
Prerequisiti per Computer Use nell'Agents API
- Python 3.10 o successivo e
openai==3.22.1(l'SDK invia per te l'headerOpenAI-Beta: agents=v1) - Una chiave API con gli scope
api.agents.read,api.agents.writeeapi.responses.write, su un progetto che può usaregpt-6-astra
L'Agents API è in beta pubblica, quindi i nomi dei campi e il comportamento possono cambiare tra le versioni dell'SDK. Il repository fissa la versione 3.22.1 in requirements.txt.
Il browser ospitato ha bisogno di un URL raggiungibile, quindi il codice usa un deployment Vercel di 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
Per saperne di più sulle dipendenze isolate, vedi la nostra guida agli ambienti virtuali. Su macOS o Linux, attiva con source .venv/bin/activate e copia il file con cp. Tieni la chiave in .env, mai nel codice.
L'esperimento usa GPT-6 Astra, il modello negli esempi di OpenAI per Computer Use. La nostra panoramica su GPT-6 Astra copre il modello stesso.
Il codice usa l'Agents API (client.beta.agents), non l'Agents SDK né lo strumento computer della Responses API usato nel nostro tutorial sull'API di GPT-6 Astra.
Configura una sessione di Computer Use
Crea una sessione con lo strumento computer_use e un desktop ospitato da OpenAI, poi riusala per entrambi i test:
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 espone eventuali screenshot restituiti dall'API, mentre l'accesso di rete limitato vincola il browser a Northstar.
L'ambiente usa la dimensione predefinita medium (2 vCPU, 4 GB di RAM).
Aggiungi una funzione per i risultati QA
La funzione registra ciò che l'agente ha osservato. Se l'agente non riesce a leggere uno dei 4 valori di quantità o subtotale verificati, deve riportare quel campo come null.
Elencare ogni proprietà sotto required dice al modello di rispondere a tutte, usando null per ciò che non ha visto. L'harness considera comunque un campo mancante come 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,
L'harness converte ogni prezzo visualizzato in centesimi, verifica l'ID build e confronta i valori con la soluzione di riferimento:
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": [f"build_id={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}
Un valore illeggibile o mancante produce un verdetto incomplete, mai un pass.
Un report dalla build sbagliata restituisce incomplete prima che i suoi valori possano influire sul verdetto.
Scrivi le istruzioni QA
Le stesse istruzioni governano entrambi i test:
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."
)
Cambia solo la build del sito web tra i test.
Come eseguire un test QA del browser con Computer Use
Apri lo stream di eventi, invia l'obiettivo QA una volta sola, poi gestisci approvazioni e chiamate di funzione finché il turno non si completa.
Invia un'attività QA alla sessione dell'Agents API
Apri prima lo stream di eventi, poi invia l'attività una volta sola:
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)
Gli stream non riproducono gli eventi persi. Se lo stream cade, aprine uno nuovo, poi recupera la sessione e i suoi elementi salvati mentre resta connesso.
Il messaggio dell'attività nomina la build, i criteri di accettazione e il vincolo di sicurezza, ma nulla riguardo al 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.
Tieni l'ID della sessione per il ritest.
Gestisci l'approvazione dell'origine del browser
Il browser ospitato chiede un'approvazione prima di aprire ogni nuova origine del sito web.
Lo stream emette agent.session.requires_action; recupera la sessione e leggi required_actions per la richiesta.
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}])
Traccia l'attività del browser con gli eventi di sessione
Il lavoro del browser compare come elementi computer_use_call, ciascuno con un breve titolo e uno stato. Lo stream di eventi per il primo test mostrava:
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
Sono passati circa 47 secondi prima della prima attività del browser.
Tutti e 7 gli elementi computer_use_call si sono completati, ma lo stato di un elemento non è il verdetto QA; lo è il risultato della funzione.
L'agente ha individuato il bug del checkout?
Sì. Ancora più importante, la chiamata di funzione ha isolato il problema a un solo campo: il subtotale del riepilogo.
Cosa ha riportato GPT-6 Astra
La chiamata record_qa_result conteneva:
{
"build_id": "ns-1041",
"cart_quantity": 2,
"cart_subtotal": "$48.00",
"review_quantity": 2,
"review_subtotal": "$24.00",
"stage_reached": "review",
"purchase_control": "disabled"
}
Ogni valore corrisponde alla pagina con bug. La quantità è rimasta 2 nella pagina di riepilogo, il che esclude un disallineamento visibile della quantità.
Come l'harness ha trasformato il report in un fail
judge() ha confermato la build ns-1041, ha confrontato i 4 valori con quelli attesi e ha trovato errato solo il subtotale del riepilogo.
Questo è l'unico verdetto usato dall'esperimento:
{
"verdict": "fail",
"failed_checks": [{"field": "review_subtotal_cents", "expected": 4800, "observed": 2400}],
"missing": []
}
Ritestare una correzione nella stessa sessione dell'Agents API
Dopo che la correzione è online, invia un altro messaggio alla stessa sessione.
Questo piccolo test di regressione usa le stesse istruzioni e la stessa funzione di verdetto.
Distribuisci la correzione senza cambiare il test
La correzione nella build ns-1042 è una riga del JavaScript di 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);
Invia il seguito nella stessa sessione
Il link di avvio include ?reset=1, quindi il ritest parte da un carrello vuoto. Poi l'istruzione di follow-up va alla stessa sessione:
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.
Il ritest ha mantenuto l'ambiente ospitato e non ha richiesto una nuova approvazione dell'origine. Non fare affidamento sullo stato del browser, perché i cookie possono scadere e il riciclo dell'ambiente lo azzera.

Una sessione ha gestito entrambi i test QA. Immagine dell'autore.
Un sandbox ospitato può essere eliminato se attività e keep-alive si fermano per 1 ora. Tieni d'occhio agent.session.environment.reset e inizia ogni ritest da uno stato noto.
Il ritest è passato?
Sì. Il ritest ha riportato quantità carrello 2 e 48,00 $, poi quantità riepilogo 2 e 48,00 $, e judge() ha restituito un pass senza controlli falliti.
Ha impiegato 38,9 secondi con 5 elementi di attività browser, contro 96,5 secondi e 7 elementi per il primo test, che includeva un'attesa di 47 secondi prima dell'attività del browser.

Il ritest è passato senza una nuova approvazione. Immagine dell'autore.
Computer Use restituisce uno screenshot per ogni attività?
Non necessariamente. Anche con include_screenshots attivo, il primo test ha restituito 2 screenshot su 7 elementi di attività browser, e il ritest 2 su 5.
Alcuni elementi restituiscono output: null, quindi i report non possono dare per scontata un'immagine per ogni attività.
Lo stream di eventi non è un flusso video continuo del browser ospitato; restituisce elementi di attività del browser e screenshot quando disponibili.
Northstar usa rrweb per catturare i cambiamenti del Document Object Model (DOM) e le interazioni, inviarli allo stesso host e riprodurre entrambi i percorsi qui sotto.
Il browser dell'agente su entrambe le build di staging. Video dell'autore.
La riproduzione mostra quantità 2 e 24,00 $ su ns-1041, poi 48,00 $ su ns-1042; il pulsante di acquisto disattivato resta intatto.
Il repository include anche un piccolo viewer Streamlit per il verdetto salvato, le evidenze del browser, i dettagli della sessione, il costo e il log degli eventi.
Quanto è costato il test con l'Agents API Computer Use?
I contatori di utilizzo a migliore sforzo hanno prodotto una stima a tariffa standard di 0,9469 $ in token per entrambi i test.
Token usati per i 2 test
| Metric | Test 1 (ns-1041) |
Retest (ns-1042) |
|---|---|---|
| Input tokens | 255,550 | 223,533 |
| Cached input tokens | 217,041 (84.9%) | 219,449 (98.2%) |
| Output tokens | 982 | 708 |
| Estimated token cost | $0.6512 | $0.2957 |
| Turn time | 96.5 seconds | 38.9 seconds |
| Browser activity items | 7 | 5 |
Il ritest ha usato meno token di input e il 98,2% di essi proveniva dalla cache dei prompt. Insieme, i 2 test sono costati 0,9469 $.
La guida all'osservabilità dice che l'uso può essere null quando sconosciuto e che i conteggi registrati possono cambiare, quindi ricontrollali prima di eliminare la sessione.
Cosa escludono i numeri di utilizzo dell'Agents API
Quando ho eseguito i test, queste erano le tariffe standard di GPT-6 Astra sulla pagina dei prezzi di OpenAI:
| Token type | Rate per 1M tokens |
|---|---|
| Input | $10.00 |
| Cached input | $1.00 |
| Cache writes | $12.50 |
| Output | $50.00 |
La soglia di contesto lungo da 272K si applica per richiesta. L'input combinato di entrambi i turni è rimasto sotto, quindi nessuna singola richiesta avrebbe potuto attivare le tariffe più alte per contesti lunghi.
La stima comunque non può riprodurre la fattura finale perché l'uso dell'Agents API è a migliore sforzo e non espone conteggi separati di scritture in cache.
Il sandbox ospitato è fatturato separatamente a tariffe standard per container. La pagina dei prezzi elenca il container medium da 4 GB a 0,12 $ per sessione di 20 minuti, con le sessioni di container idonee fatturate al minuto e un minimo di 5 minuti.
Come mantenere sicuri i test Computer Use dell'Agents API
La sicurezza dipende da cosa il browser può raggiungere e da cosa la pagina gli consente di fare.

Tre livelli tra agente e checkout. Immagine dell'autore
Cosa copre l'approvazione dell'origine in Computer Use
La policy di rete controlla quali host il browser può raggiungere e l'approvazione dell'origine decide se può aprire ogni nuova origine. Nessuna delle due conferma le singole azioni del browser.
Approvare northstar-checkout-staging.vercel.app quindi non approva separatamente ogni clic.
La regola no-purchase è un vincolo di sicurezza e purchase_control è salvato come evidenza piuttosto che giudicato come criterio di accettazione. Il pulsante disattivato "Place order" di Northstar è il controllo che la impone.
Come la policy di rete limita il browser ospitato
Con restricted, il browser può raggiungere solo gli hostname che elenchi.
La guida al sandbox di OpenAI accetta da 1 a 100 hostname esatti, senza wildcard, protocolli, path o porte. Le CDN, i sottodomini e le destinazioni di reindirizzamento richiedono voci separate.
Come gestire screenshot e dati di sessione
Screenshot e registrazioni rrweb contengono tutto ciò che la pagina mostra, quindi Northstar usa dati fittizi, non ha login e dichiara la registrazione nel footer.
Il registratore maschera gli input, ma un deployment in produzione avrebbe comunque bisogno di una policy sui dati e di un mascheramento adeguato alla pagina.
L'Agents API supporta la residenza dei dati solo negli Stati Uniti e non è idonea per Zero Data Retention (ZDR), anche con un sandbox self-hosted.
Salva i risultati e gli screenshot di cui hai bisogno, poi elimina la sessione invece di lasciare un checkout di staging in stato di sessione conservato.
Eliminare la sessione dell'Agents API non elimina le registrazioni rrweb archiviate dal sito. Rimuovile separatamente secondo la policy di registrazione.
Considerazioni finali
Northstar ha fallito quando i subtotali di carrello e riepilogo si sono separati, poi è passato dopo la correzione nella stessa sessione. L'harness, non il riepilogo del modello, ha deciso entrambi i verdetti.
Terrei i test di regressione scriptati per gli invarianti noti e userei agenti di browser basati su obiettivi per percorsi esplorativi più difficili da esprimere come un'asserzione. L'agente esplora; il codice dell'applicazione decide.
Per le basi dell'API, ti consiglio il nostro corso Working with the OpenAI API.
FAQs
Computer Use nell'Agents API è generalmente disponibile?
No, arriva come parte della beta pubblica dell'Agents API e ogni richiesta include l'header OpenAI-Beta: agents=v1. Fissa la versione dell'SDK con cui testi, perché i nomi degli eventi e i campi possono ancora cambiare prima della disponibilità generale.
Una quota elevata di input in cache significa che il ritest ha fatto risparmiare?
Non di per sé. La guida all'osservabilità afferma che un'alta percentuale di input in cache non misura il risparmio sul costo totale del task, dato che l'input in cache è comunque fatturato e chiamate ripetute possono rielaborare una cronologia ampia.
Un'approvazione dell'origine copre i turni successivi della sessione?
In questo caso sì: il ritest non ha generato alcuna nuova richiesta. Tieni l'handler di approvazione attivo a ogni turno e non dare mai per scontato che un sito sia ancora approvato.
Perché il tuo listener non vede mai agent.session.action_required?
Quel nome appartiene al webhook. Sullo stream di eventi, la pausa arriva come agent.session.requires_action. Gestiscila tramite lo stesso flusso di azioni richieste usato per l'approvazione dell'origine.
E se l'agente chiama record_qa_result due volte nello stesso turno?
L'harness conserva l'ultima chiamata, il che va bene per un controllo in sola lettura. Se la tua funzione scrive da qualche parte, archivia ogni risultato per sessione, turno e ID chiamata, e controlla un risultato precedente prima di agire due volte.
Sono un data engineer e community builder: lavoro su pipeline dati, cloud e strumenti di AI, e scrivo tutorial pratici e ad alto impatto per DataCamp e per sviluppatori alle prime armi.


