Les défenses du web ont été construites autour d’une séparation simple : les humains d’un côté, l’automatisation de l’autre. Un agent IA n’est ni l’un ni l’autre. Il agit sur la demande d’une personne, mais il s’exécute sur un serveur, lit à la vitesse d’une machine et part souvent depuis une IP cloud. Pour les équipes qui développent des agents IA qui utilisent le web, le résultat est un échec que personne n’avait prévu : l’agent se heurte à un mur, et ce qui se passe ensuite dépend de détails que la plupart des couches d’outils ignorent.
Ce guide explique pourquoi les agents tombent entre les catégories, à quoi ressemble ce mur depuis l’intérieur d’un appel d’outil, et comment construire un agent qui le gère honnêtement.
Ni robot d’indexation, ni personne
Les fournisseurs décrivent désormais ces agents comme une classe à part. OpenAI indique que ChatGPT-User « n’est pas utilisé pour explorer le web de manière automatique ». Google indique que Google-Agent est utilisé « pour naviguer sur le web et effectuer des actions à la demande de l’utilisateur ». Anthropic dispose d’un agent Claude-User pour quand les personnes posent des questions à Claude.
Les règles n’ont pas suivi, et les fournisseurs ne s’accordent pas entre eux :
| Fournisseur | Requêtes déclenchées par l’utilisateur et robots.txt |
|---|---|
| OpenAI | « les règles de robots.txt peuvent ne pas s’appliquer » |
| « ignore généralement les règles de robots.txt » | |
| Anthropic | Ses robots respectent les directives de robots.txt |
La RFC 9309 précise que les règles de robots.txt « ne constituent pas une forme d’autorisation d’accès », donc elles n’allaient de toute façon jamais régler cela seules. Pendant ce temps, le trafic augmente : Cloudflare rapporte que l’exploration IA par « action utilisateur » a été multipliée par plus de 15 en 2025, et le Bad Bot Report 2026 de Thales situe les robots à plus de 53 % de l’ensemble du trafic en 2025. Les sites ont plus que jamais de raisons de filtrer l’automatisation, et les agents se font prendre dans ce filtre.
À quoi ressemble le mur depuis un appel d’outil
| Ce qui revient | Ce que cela signifie | Ce que l’agent doit faire |
|---|---|---|
| 200 avec une page de vérification | Un contrôle anti-robot, pas la page | Signaler qu’il n’a pas pu voir la page |
| 401 ou une page de connexion | Le contenu nécessite un compte | Demander à l’utilisateur de se connecter |
| 402 | Le site demande un paiement | Demander avant de payer quoi que ce soit |
| 403 | Le serveur refuse | Le signaler, et ne pas marteler la page |
| 429 | Trop de requêtes | Respecter Retry-After, ou s’arrêter |
| 404 ou 410 | La page n’existe pas | Ne pas réessayer |
La première ligne est la dangereuse. Un 403 ressemble au moins à un échec. Une page de vérification arrive souvent sous forme de 200 avec un corps HTML bien formé, de sorte qu’un simple outil de récupération la transmet au modèle comme s’il s’agissait de l’article.
Cela compte en raison de la façon dont les modèles se comportent face à une mauvaise sortie d’outil. Une prépublication de septembre 2026 sur les agents augmentés par des outils a constaté que lorsqu’un outil renvoyait status:error, la malhonnêteté était absente (0,0 %), mais lorsqu’il renvoyait status:ok avec une valeur caviardée, corrompue, obsolète, malformée, vide ou tronquée, elle atteignait 45,3 %. Cette étude a testé des systèmes internes plutôt que des pages web, donc l’appliquer aux pages de blocage relève de notre inférence. Néanmoins, la leçon se transpose : une erreur honnête est bien plus sûre qu’un succès qui ne contient rien d’utile. Nous avons également traité de la façon dont les pages de vérification altèrent ce que produisent les outils IA.
Un outil de récupération qui dit la vérité
La solution appartient à la couche d’outils. La fonction ci-dessous classe chaque réponse avant que le modèle ne la voie, et ne renvoie le texte de la page que lorsque celle-ci est réelle. Elle n’a besoin que de requests. Nous l’avons exécutée sur Python 3.9 contre un serveur de test local qui renvoie chaque cas.
from __future__ import annotations
from dataclasses import asdict, dataclass
import requests
# Text that marks a page as a wall, not content. Extend it from your own logs.
WALL_MARKERS = ("verify you are human", "unusual traffic", "enable javascript and cookies",
"attention required", "access denied", "captcha")
LOGIN_MARKERS = ("sign in to continue", "log in to continue")
@dataclass
class FetchResult:
outcome: str # ok, wall, login, payment, rate_limited, not_found, error
status: int | None
text: str # only ever page content, empty unless outcome is ok
retry_after: str | None
note: str # what the model should be told
NOTES = {
"wall": "The site showed a bot check. You did not see this page. Say so, do not guess its content.",
"login": "This page needs a login. Ask the user to sign in or to provide the content.",
"payment": "The site asks for payment (HTTP 402). Ask the user before paying anything.",
"rate_limited": "The site asked you to slow down. Wait, or tell the user it is unavailable now.",
"not_found": "The page does not exist. Do not retry it.",
"error": "The fetch failed. You did not see this page. Say so, do not guess its content.",
"ok": "",
}
def classify(status, body):
low = body.lower()
if status == 402:
return "payment"
if status == 429:
return "rate_limited"
if status in (404, 410):
return "not_found"
if any(m in low for m in WALL_MARKERS): # walls often arrive with a 200
return "wall"
if status in (401, 403):
return "login" if status == 401 or any(m in low for m in LOGIN_MARKERS) else "wall"
if status == 200 and any(m in low for m in LOGIN_MARKERS):
return "login"
return "ok" if status == 200 else "error"
def agent_fetch(url, agent_name="example-agent/1.0 (+https://example.com/agent)"):
"""A fetch tool that never hands the model a block page as if it were content."""
try:
r = requests.get(url, headers={"User-Agent": agent_name}, timeout=(10, 30))
except requests.RequestException as exc:
return FetchResult("error", None, "", None, f"{NOTES['error']} ({type(exc).__name__})")
outcome = classify(r.status_code, r.text)
return FetchResult(outcome, r.status_code, r.text if outcome == "ok" else "",
r.headers.get("Retry-After"), NOTES[outcome])
Résultat, sous forme de statut, résultat, indication si le modèle reçoit le texte de la page, et Retry-After :
/article 200 ok content
/challenge 200 wall -
/blocked 403 wall -
/members 200 login -
/priced 402 payment -
/busy 429 rate_limited - 120
/gone 404 not_found -
/broken 503 error -
(no server)None error -
Un seul des neuf cas fournit au modèle le texte de la page. La ligne /challenge est celle qu’un simple fetch interprète mal, puisqu’elle a renvoyé un 200. Considérez les listes de marqueurs comme un point de départ et enrichissez-les à partir de vos propres journaux, car aucune liste ne détecte tous les murs. Si vous servez des outils via un serveur MCP, la spécification prévoit cela : les erreurs d’exécution sont signalées avec isError: true, et les clients « DEVRAIENT fournir les erreurs d’exécution d’outils aux modèles de langage ».
Ne résolvez pas le CAPTCHA
Les fournisseurs sont inhabituellement alignés sur ce point. OpenAI a décrit Operator comme entraîné à demander à l’utilisateur de prendre le relais pour les connexions, les détails de paiement et les CAPTCHA. La documentation de Claude in Chrome d’Anthropic indique qu’à une page de connexion ou un CAPTCHA, il « se met en pause et vous demande de le gérer manuellement ». Les instructions recommandées de Google pour l’utilisation d’ordinateurs indiquent « Vous NE DEVEZ JAMAIS tenter de résoudre ou de contourner » une liste qui inclut « les CAPTCHA (de tout type) ».
Un CAPTCHA est un site qui demande un humain, donc la bonne réponse est de passer la main à un humain. Cela permet aussi un meilleur produit : la personne sait ce qui s’est passé et peut décider.
L’identité est la voie à suivre
La réponse à plus long terme est que les agents indiquent qui ils sont d’une manière vérifiable par les sites. Web Bot Auth permet à un client de signer cryptographiquement ses requêtes avec des HTTP Message Signatures. OpenAI signe déjà les requêtes de son navigateur cloud, avec un en-tête Signature-Agent défini sur https://chatgpt.com, et Google indique qu’il expérimente le protocole. Cloudflare a introduit une catégorie d’agents signés en août 2025, et depuis juillet 2026 fait la distinction entre accès direct et accès intermédiaire par rapport aux robots vérifiés. Le travail de l’IETF n’est encore qu’un brouillon, donc il faut s’attendre à des changements.
Si vous construisez un agent aujourd’hui, envoyez un User-Agent descriptif avec des coordonnées de contact, publiez ce que fait votre agent, et prévoyez la signature.
Le cadre juridique est encore incertain
La première grande affaire montre à quel point la question est ouverte. Amazon a poursuivi Perplexity en novembre 2025 au sujet de son navigateur agentique, alléguant des violations du Computer Fraud and Abuse Act des États-Unis et de son équivalent californien, et l’avis indique que le cœur du litige était la décision de Perplexity de ne pas utiliser une chaîne user-agent. En août 2026, la Ninth Circuit a annulé une injonction préliminaire, estimant qu’Amazon était peu susceptible de démontrer que Perplexity avait « accédé » à ses ordinateurs au sens de cette loi.
La cour a pris soin de délimiter la portée de cette décision : « Nous n’établissons pas un nouveau régime juridique régissant l’IA agentique. » Elle a également indiqué que le résultat ne nuit pas à la capacité d’Amazon à réguler l’accès par le biais de ses conditions d’utilisation. Il ne s’agissait donc pas d’une autorisation pour les agents d’ignorer les souhaits d’un site. Ceci constitue une information générale, et non un avis juridique, et l’affaire est retournée devant le tribunal de district.
Construire pour le mur
- Supposez que les murs sont normaux. Concevez le plan de l’agent autour des pages qu’il ne peut pas atteindre, avec des solutions de repli telles qu’une autre source ou une demande à l’utilisateur.
- Classez avant que le modèle ne voie quoi que ce soit. Utilisez un outil comme celui ci-dessus, et enregistrez les résultats pour voir quels sites échouent.
- Proposez d’abord les voies officielles. Lorsqu’un site dispose d’une API ou d’un produit de données, utilisez-le. C’est plus fiable qu’une session de navigateur.
- Maintenez la cohérence des sessions. Les tâches à plusieurs étapes échouent lorsque l’IP change en cours de route. Notre guide sur les proxies pour les agents IA qui naviguent sur le web traite de la rotation et des sessions persistantes.
- Sachez à quoi sert un proxy. Les proxies résidentiels aident un agent à voir les pages publiques comme le feraient des visiteurs locaux, dans le bon pays et depuis une adresse cohérente. Ils ne changent pas ce qu’un site autorise, et ne constituent pas un moyen de contourner un site qui a dit non. Si un site demande une connexion, un paiement ou une personne, respectez cela.
En résumé
Les agents ont atteint le web avant que celui-ci ne dispose d’une catégorie pour eux, et pour l’instant, le mur fait partie du travail. Traitez-le comme un résultat normal : classez-le dans la couche d’outils, dites la vérité au modèle et à l’utilisateur, renvoyez les CAPTCHA aux humains, et identifiez votre agent. Un agent qui dit « je n’ai pas pu voir cette page » vaut bien plus qu’un agent qui devine.
Sources et références
- OpenAI, documentation des robots : developers.openai.com
- OpenAI, allowlisting du navigateur cloud de ChatGPT Work : help.openai.com
- OpenAI, Introducing Operator (23 janvier 2025) : openai.com
- Google, récupérateurs déclenchés par l’utilisateur : developers.google.com
- Google, Gemini computer use : ai.google.dev
- Anthropic, à propos de l’exploration et des propriétaires de sites : support.claude.com
- Anthropic, Claude in Chrome : code.claude.com
- Cloudflare, agents signés (28 août 2025, documentation mise à jour en novembre 2026) : blog.cloudflare.com, developers.cloudflare.com
- Cloudflare Radar 2025 Year in Review : blog.cloudflare.com
- Thales, Bad Bot Report 2026 : cpl.thalesgroup.com
- IETF, brouillon du protocole Web Bot Auth : datatracker.ietf.org
- RFC 9309, Robots Exclusion Protocol : rfc-editor.org
- RFC 9110 et RFC 6585, codes de statut HTTP : rfc-editor.org, rfc-editor.org
- Model Context Protocol, spécification des outils : modelcontextprotocol.io
- Sethi et al., Fabrication After Tool Failure (prépublication, septembre 2026) : arxiv.org/abs/2609.14758
- Ninth Circuit, Amazon.com Services v. Perplexity AI, No. 26-1444 (4 août 2026) : uscourts.gov