Cours
Imaginez un checkout qui affiche 48 $ dans le panier et 24 $ sur la page de récapitulatif. Le client voit deux totaux dans le même parcours d'achat.
Les équipes exécutent généralement des tests d'assurance qualité (QA) de ce flux à l'aide d'un script navigateur : cliquez sur ce bouton, ouvrez cette page, vérifiez cette valeur. Un test scripté ne vérifie que les états que son auteur a décrits.
Un agent IA est un modèle capable d'agir pour atteindre un objectif. L'Agents API d'OpenAI orchestre la boucle de l'agent et conserve son travail dans une session. Dans ce tutoriel, Computer Use fournit également le navigateur hébergé.
Northstar Checkout est une boutique de test fictive avec un bug caché sur le sous-total.
L'agent reçoit le résultat correct attendu au checkout, mais pas l'emplacement du bug ni une liste de boutons à cliquer. Un petit programme Python, appelé le harnais (harness), compare les valeurs rapportées par l'agent puis demande, dans la même session, de tester la version corrigée.
Dans ce tutoriel, je vous montre comment :
- Créer une session Agents API avec Computer Use qui ne peut atteindre que le site de test
- Approuver la demande du navigateur pour ouvrir ce site et refuser toute autre origine
- Laisser votre propre code décider si le test est réussi
- Relancer le test sur la version corrigée dans la même session et estimer le coût de l'expérience
Le code et les mesures utilisent la version 3.22.1 du package Python openai.
En bref
Si vous n'avez qu'une minute, voici l'essentiel.
- La version défectueuse échoue uniquement sur le sous-total du récapitulatif ; la quantité reste correcte.
- La version corrigée réussit dans la même session, sans nouvelle approbation d'origine.
- Les compteurs de tokens estiment un coût standard de 0,9469 $. Les frais d'écriture dans le cache et le calcul du sandbox hébergé ne sont pas inclus, et l'usage Agents API est indicatif plutôt qu'une facture finale.
- À chaque test, l'API a renvoyé 2 captures d'écran, pour 7 et 5 éléments
computer_use_callrespectivement.
Il s'agit d'une seule boutique de test avec un bug volontaire, pas d'un benchmark de fiabilité.
Qu'est-ce que Computer Use dans l'OpenAI Agents API ?
Computer Use est un outil de l'Agents API d'OpenAI qui permet à un agent de piloter un navigateur exécuté sur les serveurs d'OpenAI. Votre code suit les événements de la session et répond à ses requêtes. OpenAI cite le test de sites web parmi ses cas d'usage.
OpenAI gère la boucle de l'agent, la session et la reprise. Notre tutoriel OpenAI Agents API couvre ces bases.
Les anciens montages de computer use, comme dans notre tutoriel GPT-5.4 computer use, confiaient plutôt au code développeur la boucle capture d'écran + action.

Pourquoi utiliser Computer Use pour la QA navigateur ?
En QA navigateur, c'est la page elle‑même qui est testée.
Appeler directement une API de checkout ignorerait la page où se trouve le bug de Northstar, donc l'agent suit le même parcours qu'un client : page produit, panier, checkout, puis récapitulatif.

Harnais, session, navigateur hébergé, site de préproduction. Image de l'auteur.
OpenAI gère la session et le navigateur dans la zone grisée ; le harnais et Northstar restent en dehors.
Que va‑t‑on construire avec Agents API Computer Use ?
Le projet comprend une boutique de préproduction fictive, un harnais Python et une session Agents API.
Le code complet est dans ce dépôt GitHub.
Le cas de test Northstar Checkout
Northstar vend une Trail Bottle à 24 $. Le test va du produit au panier, puis au checkout et au récapitulatif ; pas d'expédition, taxes, connexion ni bouton d'achat fonctionnel.

Page produit Northstar avant le test. Image de l'auteur.
La build ns-1041 contient le bug, tandis que ns-1042 contient le correctif. Ajouter ?reset=1 à l'URL de départ d'une build vide le panier avant chaque test.
La demande QA est formulée comme un objectif. Ses critères d'acceptation demandent à l'agent de :
- Trouver la Trail Bottle et en mettre 2 dans le panier
- Vérifier que le sous-total du panier est 48,00 $
- Poursuivre jusqu'à la page de récapitulatif de commande et vérifier que la quantité et le sous-total correspondent toujours
- Ne rapporter que des valeurs visibles dans le navigateur
Une contrainte de sécurité séparée impose de ne jamais passer, soumettre ou payer une commande. La demande définit l'issue, pas les clics.
Le bug implanté au checkout
La build défectueuse additionne les prix unitaires sur la page de récapitulatif et oublie la quantité. Les deux pages affichent une quantité de 2, mais le sous-total du panier est 48,00 $ et celui du récapitulatif 24,00 $.
Le corrigé de référence est dans le code de l'application. Ni les instructions ni le message de tâche ne mentionnent le bug.
Comment le code applicatif décide le succès ou l'échec
L'agent transmet l'ID de build et 4 valeurs observées via un seul outil de fonction, record_qa_result.
Le harnais vérifie d'abord que la build rapportée est bien celle testée, car les deux builds partagent le même hostname, puis compare les valeurs au corrigé.
Un outil de fonction n'est exécuté que si l'agent l'appelle. Un enregistrement manquant, une valeur manquante ou une build erronée donnent un résultat incomplete, qui ne compte jamais comme un succès.

De l'objectif QA au verdict applicatif. Image de l'auteur.
Comment configurer des tests navigateur avec OpenAI Agents API
Il vous faut Python, une clé API avec les bons scopes, l'accès à GPT-6 Astra, et une session avec Computer Use.
Prérequis pour Agents API Computer Use
- Python 3.10 ou plus récent et
openai==3.22.1(le SDK envoie pour vous l'en-têteOpenAI-Beta: agents=v1) - Une clé API avec les scopes
api.agents.read,api.agents.writeetapi.responses.write, sur un projet autorisé à utilisergpt-6-astra
L'Agents API est en bêta publique, les noms de champs et comportements peuvent donc évoluer entre versions du SDK. Le dépôt fige la 3.22.1 dans requirements.txt.
Le navigateur hébergé a besoin d'une URL accessible ; le code utilise un déploiement Vercel de 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 # puis ajoutez votre OPENAI_API_KEY
python run_qa.py
Pour en savoir plus sur l'isolement des dépendances, consultez notre guide sur les environnements virtuels. Sous macOS ou Linux, activez avec source .venv/bin/activate et copiez le fichier avec cp. Gardez la clé dans .env, jamais en dur dans le code.
L'expérience utilise GPT-6 Astra, le modèle des exemples Computer Use d'OpenAI. Notre présentation de GPT-6 Astra couvre le modèle lui‑même.
Le code utilise l'Agents API (client.beta.agents), pas le Agents SDK ni l'outil computer de la Responses API utilisé dans notre tutoriel GPT-6 Astra API.
Configurer une session Computer Use
Créez une session avec l'outil computer_use et un bureau hébergé par OpenAI, puis réutilisez‑la pour les deux tests :
session = client.beta.agents.sessions.create(
agent={"model": MODEL, "instructions": INSTRUCTIONS,
"reasoning": {"effort": REASONING_EFFORT}, # "medium", défini explicitement
"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 expose toutes les captures renvoyées par l'API, tandis que l'accès réseau restreint limite le navigateur à Northstar.
L'environnement utilise la taille par défaut medium (2 vCPU, 4 Go de RAM).
Ajouter une fonction pour enregistrer les résultats QA
La fonction consigne ce que l'agent a observé. Si l'agent ne peut pas lire l'une des 4 valeurs (quantité ou sous-total), il doit renseigner ce champ à null.
Lister chaque propriété sous required indique au modèle de répondre à toutes, en utilisant null pour ce qu'il n'a pas vu. Le harnais traite malgré tout un champ manquant comme 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,
Le harnais convertit chaque prix affiché en cents, vérifie l'ID de build et compare les valeurs au corrigé :
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}
Une valeur illisible ou manquante produit un verdict incomplete, jamais un succès.
Un rapport provenant de la mauvaise build renvoie incomplete avant que ses valeurs puissent influer sur le verdict.
Rédiger les instructions QA
Les mêmes instructions régissent les deux tests :
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."
)
Seule la version du site change entre les tests.
Comment exécuter un test QA navigateur avec Computer Use
Ouvrez le flux d'événements, envoyez l'objectif QA une fois, puis traitez les approbations et appels de fonction jusqu'à la fin du tour.
Envoyer une tâche QA à la session Agents API
Ouvrez d'abord le flux d'événements, puis envoyez la tâche une seule fois :
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)
Les flux ne rejouent pas les événements manqués. Si le flux tombe, ouvrez‑en un nouveau, puis récupérez la session et ses éléments sauvegardés tant qu'il reste connecté.
Le message de tâche indique la build, les critères d'acceptation et la contrainte de sécurité, mais rien sur le 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.
Conservez l'ID de session pour le re-test.
Gérer l'approbation d'origine du navigateur
Le navigateur hébergé demande une approbation avant d'ouvrir chaque nouvelle origine de site.
Le flux émet agent.session.requires_action ; récupérez la session et lisez required_actions pour obtenir la demande.
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}])
Suivre l'activité du navigateur via les événements de session
Le travail du navigateur apparaît sous forme d'éléments computer_use_call, chacun avec un court titre et un statut. Le flux d'événements du premier test a montré :
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
Environ 47 secondes se sont écoulées avant la première activité du navigateur.
Les 7 éléments computer_use_call se sont terminés, mais le statut d'un élément n'est pas le verdict QA ; c'est le résultat de la fonction qui fait foi.
L'agent a‑t‑il détecté le bug du checkout ?
Oui. Plus important encore, l'appel de fonction a isolé l'échec à un seul champ : le sous-total du récapitulatif.
Ce que GPT-6 Astra a rapporté
L'appel record_qa_result contenait :
{
"build_id": "ns-1041",
"cart_quantity": 2,
"cart_subtotal": "$48.00",
"review_quantity": 2,
"review_subtotal": "$24.00",
"stage_reached": "review",
"purchase_control": "disabled"
}
Toutes les valeurs correspondent à la page défectueuse. La quantité est restée à 2 sur la page de récapitulatif, ce qui écarte un écart visible sur la quantité.
Comment le harnais a transformé le rapport en échec
judge() a confirmé la build ns-1041, comparé les 4 valeurs aux attentes, et trouvé que seul le sous-total du récapitulatif était erroné.
C'est le seul format de verdict utilisé dans l'expérience :
{
"verdict": "fail",
"failed_checks": [{"field": "review_subtotal_cents", "expected": 4800, "observed": 2400}],
"missing": []
}
Re-tester un correctif dans la même session Agents API
Une fois le correctif déployé, envoyez un message supplémentaire dans la même session.
Ce petit test de non-régression réutilise les mêmes instructions et la même fonction de verdict.
Livrer le correctif sans changer le test
Le correctif de la build ns-1042 tient en une ligne de JavaScript de 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);
Envoyer le suivi dans la même session
Le lien de départ inclut ?reset=1, donc le re‑test commence avec un panier vide. Ensuite, le suivi part dans la même session :
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.
Le re‑test a conservé l'environnement hébergé et n'a pas nécessité de nouvelle approbation d'origine. Ne dépendez pas de l'état du navigateur, car les cookies peuvent expirer et le recyclage de l'environnement les efface.

Une seule session a porté les deux tests QA. Image de l'auteur.
Un sandbox hébergé peut être supprimé si l'activité et les keep‑alives cessent pendant 1 heure. Surveillez agent.session.environment.reset et démarrez chaque re‑test depuis un état connu.
Le re‑test a‑t‑il réussi ?
Oui. Le re‑test a rapporté une quantité panier de 2 et 48,00 $, puis une quantité récapitulatif de 2 et 48,00 $, et judge() a renvoyé un succès sans échec.
Il a pris 38,9 secondes avec 5 éléments d'activité navigateur, contre 96,5 secondes et 7 éléments pour le premier test, qui incluait 47 secondes d'attente avant la première activité.

Le re‑test a réussi sans nouvelle approbation. Image de l'auteur.
Computer Use renvoie‑t‑il une capture d'écran pour chaque action ?
Pas nécessairement. Même avec include_screenshots activé, le premier test a renvoyé 2 captures d'écran pour 7 actions, et le re‑test 2 pour 5.
Certains éléments renvoient output: null, donc les rapports ne peuvent pas supposer une image pour chaque action.
Le flux d'événements n'est pas un flux vidéo continu du navigateur hébergé ; il renvoie des actions navigateur et des captures quand elles sont disponibles.
Northstar utilise rrweb pour capturer les changements du DOM et les interactions, les envoyer au même hôte et rejouer les deux parcours ci‑dessous.
Le navigateur de l'agent sur les deux builds de préproduction. Vidéo de l'auteur.
La relecture montre la quantité 2 et 24,00 $ sur ns-1041, puis 48,00 $ sur ns-1042 ; le bouton d'achat désactivé reste intact.
Le dépôt inclut également un petit visualiseur Streamlit pour le verdict sauvegardé, les preuves navigateur, les détails de session, le coût et le journal des événements.
Quel a été le coût du test Agents API Computer Use ?
Les compteurs d'usage indicatifs ont produit une estimation standard de 0,9469 $ en tokens pour les deux tests.
Consommation de tokens pour les 2 tests
| Métrique | Test 1 (ns-1041) |
Re‑test (ns-1042) |
|---|---|---|
| Tokens en entrée | 255 550 | 223 533 |
| Tokens d'entrée mis en cache | 217 041 (84,9 %) | 219 449 (98,2 %) |
| Tokens en sortie | 982 | 708 |
| Coût estimé en tokens | 0,6512 $ | 0,2957 $ |
| Durée du tour | 96,5 secondes | 38,9 secondes |
| Actions navigateur | 7 | 5 |
Le re‑test a utilisé moins de tokens en entrée, dont 98,2 % issus du cache d'invite. Ensemble, les 2 tests coûtent 0,9469 $.
Le guide d'observabilité précise que l'usage peut être null s'il est inconnu et que les comptages enregistrés peuvent évoluer ; re‑vérifiez avant de supprimer la session.
Ce que les chiffres d'usage Agents API n'incluent pas
Lors de mes essais, voici les tarifs standard de GPT-6 Astra sur la page de tarification d'OpenAI :
| Type de token | Tarif pour 1 M de tokens |
|---|---|
| Entrée | 10,00 $ |
| Entrée mise en cache | 1,00 $ |
| Écritures de cache | 12,50 $ |
| Sortie | 50,00 $ |
Le seuil long-contexte de 272 K s'applique par requête. L'entrée combinée des deux tours est restée en dessous, donc aucune requête n'a pu déclencher les tarifs long-contexte plus élevés.
L'estimation ne peut toujours pas reproduire la facture finale, car l'usage Agents API est indicatif et n'expose pas les écritures de cache séparément.
Le sandbox hébergé est facturé séparément aux tarifs standard des conteneurs. La page de tarification liste le conteneur medium 4 Go à 0,12 $ par session de 20 minutes, avec une facturation à la minute pour les sessions éligibles et un minimum de 5 minutes.
Comment garder les tests Agents API Computer Use sûrs
La sécurité dépend de ce que le navigateur peut atteindre et de ce que la page lui permet de faire.

Trois couches entre l'agent et le checkout. Image de l'auteur
Ce que couvre l'approbation d'origine dans Computer Use
La politique réseau contrôle quels hôtes le navigateur peut atteindre, et l'approbation d'origine décide s'il peut ouvrir chaque nouvelle origine. Aucune ne confirme les actions individuelles du navigateur.
Approuver northstar-checkout-staging.vercel.app n'approuve donc pas chaque clic séparément.
La règle « pas d'achat » est une contrainte de sécurité, et purchase_control est conservé comme preuve plutôt que jugé comme un critère d'acceptation. Le bouton « Place order » désactivé de Northstar est le contrôle qui la fait respecter.
Comment la politique réseau limite le navigateur hébergé
En mode restricted, le navigateur ne peut atteindre que les noms d'hôtes que vous listez.
Le guide du sandbox d'OpenAI accepte de 1 à 100 noms d'hôtes exacts, sans jokers, protocoles, chemins ni ports. Les CDNs, sous-domaines et cibles de redirection exigent des entrées séparées.
Comment gérer les captures et les données de session
Les captures et enregistrements rrweb contiennent tout ce que la page affiche, donc Northstar utilise des données fictives, n'a pas de connexion et signale l'enregistrement en pied de page.
L'enregistreur masque les saisies, mais un déploiement en production nécessiterait tout de même une politique de données et un masquage adaptés à la page.
L'Agents API prend en charge la résidence des données uniquement aux États‑Unis et n'est pas éligible au Zero Data Retention (ZDR), même avec un sandbox auto‑hébergé.
Enregistrez les résultats et captures nécessaires, puis supprimez la session au lieu de laisser un checkout de préproduction dans un état de session conservé.
Supprimer la session Agents API ne supprime pas les enregistrements rrweb stockés par le site. Retirez‑les séparément conformément à la politique d'enregistrement.
Conclusion
Northstar a échoué lorsque les sous‑totaux panier et récapitulatif ont divergé, puis a réussi après correctif dans la même session. C'est le harnais, et non le résumé du modèle, qui a tranché les deux verdicts.
Je conserverais des tests de régression scriptés pour les invariants connus et j'utiliserais des agents navigateurs pilotés par objectif pour les parcours exploratoires, plus difficiles à exprimer sous forme d'assert. L'agent explore ; le code applicatif décide.
Pour les bases de l'API, je vous recommande notre cours Working with the OpenAI API.
FAQs
Computer Use dans l'Agents API est‑il en disponibilité générale ?
Non, elle est proposée dans la bêta publique de l'Agents API, et chaque requête porte l'en‑tête OpenAI-Beta: agents=v1. Figez la version du SDK avec laquelle vous testez, car les noms d'événements et les champs peuvent encore changer avant la disponibilité générale.
Un fort taux d'entrée mise en cache signifie‑t‑il que le re‑test a économisé de l'argent ?
Pas à elle seule. Le guide d'observabilité indique qu'un pourcentage élevé d'entrée mise en cache ne mesure pas les économies sur le coût total de la tâche, puisque l'entrée mise en cache est tout de même facturée et que des appels répétés peuvent retraiter un long historique.
Une approbation d'origine couvre‑t‑elle les tours ultérieurs de la session ?
Ici oui : le re‑test n'a pas soulevé de nouvelle demande. Gardez le gestionnaire d'approbation actif à chaque tour et ne supposez jamais qu'un site est encore approuvé.
Pourquoi votre écouteur ne voit‑il jamais agent.session.action_required ?
Ce nom appartient au webhook. Sur le flux d'événements, la pause arrive sous agent.session.requires_action. Traitez‑la via le même flux d'actions requises que pour l'approbation d'origine.
Et si l'agent appelle deux fois record_qa_result dans un même tour ?
Le harnais conserve le dernier appel, ce qui convient pour une vérification en lecture seule. Si votre fonction écrit quelque part, stockez chaque résultat par session, tour et id d'appel, et vérifiez l'existence d'un résultat antérieur avant d'agir deux fois.
Je suis ingénieur de données et créateur de communautés. Je travaille sur les pipelines de données, le cloud et les outils d'IA, tout en rédigeant des tutoriels pratiques et percutants pour DataCamp et les développeurs émergents.

