Pourquoi les agents de codage réinventent constamment le navigateur
Pourquoi les agents de codage à exécution prolongée convergent vers des outils de type navigateur : scripts d’aide, cookies en tant que mémoire, vues de page compactes, solutions de secours HTTP et biais des données d’entraînement.
Le navigateur que personne n’a demandé
Les agents de codage présentent une habitude récurrente. Avec un accès gratuit au web, la capacité d’écrire et d’exécuter du code, ainsi qu’un travail qui dure suffisamment longtemps, ils ont tendance à créer quelque chose qui ressemble à un navigateur. Le désir d’avoir un navigateur n’est pas le motif ; ce qu’ils cherchent, c’est un outil bon marché et réutilisable capable d’ouvrir une URL, de cliquer, de remplir des formulaires, d’attendre des données pour les extraire, de conserver des cookies et des sessions, et de prendre une capture d’écran en cas d’échec. Vu de cette façon, il s’agit simplement d’ingénierie de tous les jours, du genre que ferait un développeur humain.
Chromium en tant que produit n’est pas la destination finale. Ces agents visent plutôt la fonction que remplit un navigateur : transformer les protocoles et conventions web en opérations concrètes.
Produit versus abstraction
Un navigateur au sens de Chrome ou Firefox est une application volumineuse : des onglets, une barre d’adresses, un moteur de rendu, un modèle de processus. Rien de tout cela ne correspond aux besoins d’un agent. Celui-ci souhaite plutôt accomplir la tâche fondamentale consistant à transformer le fonctionnement du web en opérations pouvant être exécutées.
Les utilisateurs emploient cette interface sans s’en rendre compte. Une page de connexion demande évidemment des identifiants, un bouton peut évidemment être cliqué, on le clique, on attend la page suivante et on continue. Un agent ne peut pas s’appuyer sur cette compréhension tacite, il doit donc transformer la même tâche en opérations explicites. Lorsque l’on demande à un agent de codage de travailler sur des sites web arbitraires, on lui pose un problème dont l’abstraction naturelle est déjà connue, ce qui le pousse à s’orienter vers cette abstraction.
Le web moderne n’a pas non plus été conçu pour être utilisé comme une API bien structurée. En général, on trouve un document HTML entouré de JavaScript, ainsi que des sessions de connexion, des cookies, des redirections, un rendu côté client, un défilement infini, des fenêtres contextuelles, des téléchargements de fichiers et des requêtes asynchrones. Une simple requête HTTP GET n’est que le début ; les tâches réelles dans ce contexte exigent finalement un ensemble d’opérations de ce type.
open(url)
click(selector)
fill(selector, text)
wait_for(selector)
extract(selector)
go_back()
screenshot()
Ce n’est pas un navigateur graphique, mais c’est indéniablement une interface polyvalente pour le web.
Pourquoi les tâches longues génèrent des outils d’aide
Les tâches courtes peuvent être gérées ponctuellement. Une recherche ponctuelle s’effectue de manière brute sans aucune infrastructure, puisqu’elle ne se reproduit pas et se termine en quelques secondes.
"Find the current exchange rate."
"Look up this company's homepage."
"Find the opening hours of this restaurant."
Le travail à long terme est différent. Imaginez un agent qui surveille des centaines de sites toutes les quelques heures, exécute en boucle un flux de travail complexe, extrait des pages tout en restant connecté, collecte des preuves sur plusieurs jours ou interroge un service jusqu’à ce que quelque chose change. Si le modèle gère chaque clic et chaque inspection, les coûts explosent. Une exécution naïve se déroule comme suit :
- Ouvrir un navigateur, qui est l’outil utilisé pour récupérer la page.
- Inspecter la page, en utilisant le DOM rendu comme source d’observations.
- Trouver la boîte de recherche, saisir la requête, cliquer sur Rechercher et attendre.
- Extraire les données.
- Analyser ces données.
- Reprendre le processus.
Un agent compétent réagit comme un développeur humain, en écrivant un outil réutilisable. L’exécution suivante se déroule alors ainsi :
- Exécuter le script.
- Vérifier si le résultat est toujours correct.
C’est un changement architectural majeur. Le modèle cesse d’exécuter toutes les opérations. Il devient alors la partie chargée de déterminer quelle procédure doit être exécutée, tandis que le logiciel ordinaire utilise l’outil choisi et collecte les observations. En d’autres termes, l’agent compile sa propre expérience en un script.
Explorer dans un navigateur, rejouer en code
Un navigateur est un endroit excellent pour explorer. Un agent peut explorer, naviguer, observer les résultats et déterminer quelle séquence d’actions permet d’atteindre un objectif. Après cela, raisonner à nouveau sur chaque action est inutile.
Supposons que l’agent apprenne qu’il faut toujours se rendre sur la page d’accueil d’un site de shopping pour trouver un produit, y rechercher « câbles USB-C », appliquer des filtres pour des produits notés quatre étoiles ou plus, avec livraison rapide et un plafond de prix, parcourir les résultats, puis extraire les titres, les prix et les IDs des produits. Il n’y a aucune raison pour qu’un modèle de langage doive redécouvrir ces cinq opérations à chaque exécution. Il peut les transformer en une procédure et la réutiliser pour des problèmes similaires. Cela nécessite cependant une session en temps réel avec des cookies, donc l’agent choisit Puppeteer, Playwright ou un outil similaire comme outil d’acquisition de pages.
async function getNewProducts(query) {
const browser = await playwright.chromium.connectOverCDP(
`wss://${AUTH}@brd.superproxy.io:9222`,
);
const page = await browser.newPage();
await page.goto("https://example.com/products");
await page.fill("input[name=q]", query);
await page.click("button[type=submit]");
await page.waitForSelector(".results");
return extractResults(page);
}
Cette partie du code relie Playwright à un navigateur hébergé à distance via le protocole Chrome DevTools. Un navigateur hébergé s’avère utile lorsque l’agent doit maintenir sa session active toutes les quelques heures, sans l’intervention d’un modèle. Cela nécessite des identifiants de compte formatés en chaîne de connexion, représentés par le symbole ${AUTH}.
Une extraction structurée et reproductible sur un site ne disposant pas de script d’extraction prédéfini n’exige même pas de fichier Playwright local. Le même flux de travail peut être intégré dans un outil d’extraction hébergé : il suffit de décrire les données souhaitées en langage simple, de recevoir un outil d’extraction généré et de l’exécuter sans modèle lors du cycle de clics. Ses fonctions d’interaction et de parsing correspondent aux mêmes tâches d’ouverture, de clic, de remplissage, d’attente, d’extraction et de prise de screenshot, simplement hébergées ailleurs.
Un tel script échoue dès que les sélecteurs CSS changent, forçant l’agent à explorer à nouveau et à en écrire un autre. Si cette procédure se trouve à l’intérieur d’une outil hébergé, l’IA peut peut-être la réparer sans que personne ait à réécrire les sélecteurs.
Les développeurs humains se comportent de la même manière. La première visite à un site web permet de comprendre son fonctionnement, et par la suite personne ne réfléchit à chaque clic. Lorsque le site change, il faut l’apprendre à nouveau, bien que cette connaissance reste implicite. Un LLM dispose d’une mémoire bien plus coûteuse. S’il doit reconstruire la procédure à partir du contexte à chaque fois, il paie à nouveau pour les mêmes découvertes. C’est pourquoi il enregistre le flux de travail appris dans un script et l’exécute, jusqu’à ce que la page cesse de correspondre.
Les cookies comme mémoire en dehors du modèle
Aucun modèle de langage ne peut conserver une longue session web dans son contexte, du moins pour l’instant. L’écriture d’un fichier .py fait toujours appel au modèle, tandis que le stockage de cookies ne le fait pas. Au fil de la session, le navigateur accumule de la mémoire de manière autonome, ce qui la place donc en dehors du stockage destiné à l’agent. Ce dernier comporte trois parties pertinentes :
- Le répertoire des cookies, y compris les cookies HttpOnly et ceux définis par JavaScript après un connexion ou une vérification de bot. Souvent, le modèle ne peut pas du tout les lire, mais le navigateur les conserve et les associe à la demande suivante.
- Le stockage d’origine, c’est-à-dire
localStorage,sessionStorageet IndexedDB, qui contiennent presque exclusivement des valeurs écrites par le site. - Le historique de la session, c’est-à-dire la pile de navigation qui permet l’utilisation des fonctions
back()outabs.goBack().
Certaines états existent en dehors du stockage du navigateur, comme une session côté serveur ou une URL qui n’existe que lorsque JavaScript s’exécute. L’agent n’a pas besoin de les lire lui-même ; il doit simplement faire fonctionner une couche de navigateur qui contient déjà la session.
Risques de sécurité liés à la cession d’un navigateur
Lorsqu’un agent peut lire n’importe quelle page et n’importe quel cookie ainsi que gérer une session en temps réel, l’injection de commandes cesse d’être une question de formulaires plus sûrs pour devenir un risque architectural. Tout système utilisant un navigateur en temps réel est confronté à ce problème, mais les agents codés sont encore plus vulnérables, car ils peuvent généralement écrire et exécuter tout ce qu’ils rencontrent. Restreignez les actions de l’agent en l’absence de surveillance humaine, en commençant par un environnement isolé.
Un bon modèle est la liste de contrôle pour l’utilisation informatique d’Anthropic : utiliser une VM ou un conteneur dédié, éviter les connexions sauf si la tâche l’exige, conserver les listes d’autorisation de domaine, et exiger l’approbation d’un humain pour tout ce qui concerne de l’argent ou le consentement.
Pourquoi le HTML brut est une mauvaise entrée
Les pages brutes constituent une entrée médiocre pour un modèle de langage en raison du grand nombre d’éléments parasites. Ce dont l’agent a besoin peut être enfoui parmi des milliers de tokens de balises, de styles et de mécanismes d’application. Une bonne outil de navigateur restitue donc un ensemble plus restreint d’actions et d’observations à la place du HTML complet.
La figure montre le Document Object Model d’une page HTML, l’arbre que doit réduire une vue compacte ou un arbre d’accessibilité. Un outil utile peut le transformer en quelque chose de beaucoup plus petit. Au lieu d’un document entier, il peut fournir au modèle un bref résumé comme celui-ci.
Title: Search results
Links:
[1] Home
[2] Next page
Forms:
search: input[name=q]
Buttons:
submit: button[type=submit]
Main content:
...
Il peut également exposer un arbre d’accessibilité.
- navigation
- link "Home"
- link "Search"
- main
- heading "Results"
- list
- listitem "Item 1"
- listitem "Item 2"
Ce format est bien plus proche de ce qu’un modèle de raisonnement peut utiliser. La couche en forme de navigateur permet donc bien plus que simplement une interaction : elle réduit l’environnement à un ensemble compact d’actions et d’observations. L’agent ne voit que les éléments du web pertinents pour sa tâche, et non le mécanisme sous-jacent à l’affichage des pages. Le contexte est conservé, l’inférence devient moins coûteuse et les erreurs diminuent souvent, bien que pas toujours.
Il y a cependant une réservation : un aperçu complet de l’accessibilité incluant toutes les références peut finir par être plus volumineux que le texte visible. La compression n’a d’effet que lorsque l’encadrement renvoie réellement une liste courte et gérable de contrôles. La longueur de cette liste dépend du modèle. Un modèle petit ne peut pas utiliser un DOM brut, tandis qu’un modèle puissant le peut, mais doit néanmoins payer pour les tokens. Aucun des deux ne souhaite recevoir le HTML complet.
Lorsque le HTTP simple suffit
Lorsque l’agent a compris le fonctionnement d’un site, la solution la moins chère et la plus fiable peut ne pas nécessiter du tout l’automatisation du navigateur. Parfois, il s’avère que le navigateur effectue en réalité une tâche très simple en arrière-plan. Un bouton « Page suivante » peut finalement ne faire que cela.
GET /api/products?page=2
Lorsque c’est le cas, afficher la page est inutile, et l’agent peut appeler directement l’endpoint. Le résultat est une série d’options en cascade.
human interface
↓
browser automation
↓
discovered workflow
↓
direct HTTP/API calls ← only if the site still allows it
Sa valeur résidait dans la démonstration du comportement de l’application. Une fois cela compris, l’agent peut supprimer les couches supplémentaires et parfois passer à un HTTP pur. Un agent qui ne traite jamais de pages lourdes en JavaScript peut éviter complètement l’automatisation du navigateur et se contenter d’HTTP, de préférence avec un service de déblocage prêt à intervenir en cas de demande refusée. Quelle que soit la méthode, les agents autonomes ont besoin d’une solution de secours, car un pare-feu Cloudflare ou une vérification anti-bot est presque inévitable sur le web ouvert. Sans possibilité de tentative de réessai peu coûteuse, le modèle erre, consomme des tokens et augmente la facture.
Deux complications surviennent.
First, de nombreux sites ne peuvent pas être réduits à HTTP. La plupart ne permettent pas d’être reverse-engineered : ils limitent le trafic non provenant d’un navigateur, modifient les sélecteurs, identifient les clients par leurs caractéristiques uniques et ajoutent des vérifications anti-bot ou des CAPTCHAs. Pour ces sites, il faut conserver une approche complète via un navigateur, que ce soit en local ou hébergé.
Deuxièmement, recourir à une solution de secours n’est pas toujours rentable. Une API JSON publique bien documentée est structurée, bien délimitée et facile à journaliser. Un point d’entrée interne sans documentation, que l’agent a découvert par lui-même, c’est autre chose : il est certes moins cher à appeler, mais il est plus difficile à auditer pour un humain que des scripts cliquant sur des boutons visibles, avec des journaux d’activité plus succincts. Une réponse 200 remplie de données inutiles est facile à négliger, tandis qu’une page défectueuse se distingue facilement.
En fin de compte, l’agent n’a aucune loyauté envers les navigateurs. Ce qu’il cherche, c’est l’interface la moins coûteuse vers son environnement qui fonctionne néanmoins :
- Si cette interface est un point d’entrée JSON et que le site le prend en charge, utilisez JSON.
- Si des exécutions JavaScript et un état de session sont nécessaires, utilisez un vrai navigateur via Puppeteer ou Playwright, ou un navigateur hébergé.
- Si seuls des fichiers HTML téléchargés sont requis, utilisez HTTP, avec un proxy ou un outil de déblocage si la requête GET est bloquée.
Les agents web à longue durée de vie utilisent généralement plusieurs de ces méthodes en même temps. La compétence essentielle consiste à passer d’un niveau à l’autre de la hiérarchie selon les besoins de la situation.
Les données d’entraînement suffisent-elles à l’expliquer ?
La réponse est mitigée. Les données d’entraînement peuvent expliquer pourquoi un modèle recourt à Playwright ou Puppeteer, mais elles ne peuvent pas expliquer la création, dès le départ, d’outils similaires à des navigateurs.
Une étude menée en 2026 par Oxford et Microsoft, intitulée BiasBusters, a testé une version proche de cette question, à savoir si l’exposition durant l’entraînement influence le choix du modèle. L’équipe a continué à entraîner un petit modèle sur un corpus riche en métadonnées provenant d’une seule API météorologique, parmi plusieurs offrant le même service.
- Auparavant, le modèle choisissait presque jamais cette API, soit environ 0,6 % du temps, ce qui correspond à peu près à la probabilité aléatoire.
- Après entraînement sur ce corpus biaisé, elle était choisie dans environ 12 % des cas, soit vingt fois plus souvent.
En bref, l’exposition pendant l’entraînement seul, quel que soit la tâche, influence de manière mesurable le choix du outil ou du produit préféré par un modèle. Il s’agit cependant essentiellement de sélectionner un outil. L’abstraction (ouvrir, cliquer, remplir, attendre, extraire sous forme de forme géométrique, quel que soit le bibliothèque qui la fournit) est déterminée par l’environnement. Un modèle qui n’aurait jamais vu Playwright aurait néanmoins besoin d’un moyen pour ouvrir des pages, attendre le chargement du contenu et rapporter les résultats, car les pages interactives l’exigent.
Deux éléments distincts sont en jeu :
- L’abstraction de
ouvrir,cliquer,remplir,attendreetextraireest imposée par l’environnement. Les pages interactives comportent une navigation, des délais, des contrôles et un affichage, que Playwright fasse ou non partie des poids du modèle. - Le outil, Playwright par rapport à un client développé en interne, provient de ce que le modèle a observé, comme l’ont montré BiasBusters pour des API interchangeables.
Les données d’entraînement couvrent ce dernier mais omettent le premier. Elles ne peuvent pas expliquer pourquoi le problème continue de se diriger vers des abstractions similaires à celles des navigateurs. La raison la plus fondamentale est que le web est déjà organisé selon ces principes.
Adaptateurs offrant les meilleurs résultats
Des agents comme Claude Code ne créent pas vraiment des navigateurs. Ils développent des adaptateurs entre un système de raisonnement et un environnement qui se trouve être de forme navigateur.
La biologie évolutive connaît un concept appelé carcinisation : la tendance étrange de crustacés non apparentés à converger, avec le temps, vers un corps ressemblant à celui d’un crabe.
Ces espèces n’ont pas conclu que devenir crabe était une bonne stratégie. Leur environnement continuait simplement à récompenser la même réponse aux mêmes problèmes. Les agents de programmation pourraient suivre une voie similaire : ils remarquent que l’approche actuelle est lente, écrivent alors un script, ajoutent des tentatives de réessai en cas d’échec, intègrent la persistance des sessions une fois l’authentification obtenue, et ajoutent des outils d’extraction du DOM ou d’accessibilité lorsque les pages deviennent trop volumineuses pour être analysées correctement.
The task requires the web.
↓
The web exposes a browser-shaped interface.
↓
The agent needs a way to operate that interface.
↓
Repeated operations make ad-hoc reasoning expensive.
↓
The agent writes reusable tools.
↓
Those tools accumulate state, retries, and abstractions.
↓
The tools start looking like a browser.
↓
Known workflows get compiled into deterministic code.
↓
The page changes so the agent re-explores.
↓
If an API exists, use it to get the data.
If not, and the site allows it, fall back to regular HTTP.
If not, stay on the browser.
Au bout de suffisamment de tours, le résultat ressemble étonnamment à un petit navigateur. C’est un modèle mental plus adapté pour les agents autonomes que l’idée de personnes numériques ayant un intérêt étrange pour les navigateurs. Ils se comportent comme de bons ingénieurs : ils étudient un environnement complexe, identifient l’interface qu’il offre réellement, et construisent des abstractions autour de tout ce qui est répétitif, à état et coûteux. Le web dispose déjà d’une abstraction ancienne et très efficace à cette fin, et elle s’appelle navigateur.