Las defensas de la web se construyeron en torno a una división simple: las personas por un lado, la automatización por el otro. Un agente de IA no es ninguna de las dos cosas. Actúa a petición de una persona, pero se ejecuta en un servidor, lee a velocidad de máquina y a menudo sale desde una IP en la nube. Para los equipos que construyen agentes de IA que usan la web, el resultado es un fallo que nadie había previsto: el agente choca contra un muro, y lo que ocurre a continuación depende de detalles que la mayoría de las capas de herramientas ignoran.
Esta guía explica por qué los agentes caen entre las categorías, cómo es ese muro visto desde dentro de una llamada a herramienta, y cómo construir un agente que lo gestione con honestidad.
Ni rastreador ni persona
Los proveedores describen ahora estos agentes como una clase aparte. OpenAI dice que ChatGPT-User “no se usa para rastrear la web de forma automática”. Google dice que Google-Agent se usa “para navegar por la web y realizar acciones a petición del usuario”. Anthropic tiene un agente Claude-User para cuando las personas hacen preguntas a Claude.
Las normas no se han puesto al día, y los proveedores no se ponen de acuerdo sobre ellas:
| Proveedor | Peticiones iniciadas por el usuario y robots.txt |
|---|---|
| OpenAI | ”es posible que las normas de robots.txt no se apliquen” |
| ”generalmente ignora las normas de robots.txt” | |
| Anthropic | Sus bots respetan las directivas de robots.txt |
El RFC 9309 añade que las normas de robots.txt “no son una forma de autorización de acceso”, así que nunca iban a resolver esto por sí solas. Mientras tanto, el tráfico crece: Cloudflare informa de que el rastreo de IA por “acción del usuario” creció más de 15 veces en 2025, y el Bad Bot Report 2026 de Thales sitúa a los bots en más del 53% de todo el tráfico en 2025. Los sitios tienen más motivos que nunca para filtrar la automatización, y los agentes quedan atrapados en ese filtro.
Cómo es el muro visto desde una llamada a herramienta
| Qué se recibe | Qué significa | Qué debería hacer el agente |
|---|---|---|
| 200 con una página de verificación | Una comprobación antibot, no la página | Informar de que no pudo ver la página |
| 401 o una página de inicio de sesión | El contenido requiere una cuenta | Pedir al usuario que inicie sesión |
| 402 | El sitio pide un pago | Preguntar antes de pagar nada |
| 403 | El servidor se niega | Informar de ello, y no insistir con la página |
| 429 | Demasiadas peticiones | Respetar Retry-After, o detenerse |
| 404 o 410 | La página no existe | No reintentar |
La primera fila es la peligrosa. Un 403 al menos parece un fallo. Una página de verificación a menudo llega como un 200 con un cuerpo HTML bien formado, de modo que una herramienta de fetch simple se lo entrega al modelo como si fuera el artículo.
Eso importa por cómo se comportan los modelos ante una salida de herramienta defectuosa. Un preprint de septiembre de 2026 sobre agentes aumentados con herramientas descubrió que cuando una herramienta devolvía status:error, la deshonestidad estaba ausente (0,0%), pero cuando devolvía status:ok con un valor redactado, corrupto, obsoleto, malformado, vacío o truncado, alcanzaba el 45,3%. Ese estudio probó sistemas internos en lugar de páginas web, así que aplicarlo a las páginas de bloqueo es inferencia nuestra. Aun así, la lección se traslada: un error honesto es mucho más seguro que un éxito que no contiene nada útil. También hemos tratado cómo las páginas de verificación contaminan lo que producen las herramientas de IA.
Una herramienta de fetch que dice la verdad
La solución pertenece a la capa de herramientas. La función siguiente clasifica cada respuesta antes de que el modelo la vea, y devuelve el texto de la página solo cuando la página es real. Solo necesita requests. La ejecutamos en Python 3.9 contra un servidor de pruebas local que devuelve cada caso.
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])
Salida, mostrando estado, resultado, si el modelo recibe el texto de la página, y 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 -
Solo uno de los nueve casos le da al modelo algún texto de página. La fila /challenge es la que un fetch sencillo interpreta mal, ya que devolvió un 200. Trata las listas de marcadores como un punto de partida y amplíalas a partir de tus propios registros, porque ninguna lista detecta todos los muros. Si sirves herramientas a través de un servidor MCP, la especificación tiene un lugar para esto: los errores de ejecución se informan con isError: true, y los clientes “SHOULD provide tool execution errors to language models”.
No resuelvas el CAPTCHA
Los proveedores están inusualmente alineados en esto. OpenAI describió que Operator está entrenado para pedir al usuario que tome el control en inicios de sesión, datos de pago y CAPTCHAs. La documentación de Claude in Chrome de Anthropic dice que ante una página de inicio de sesión o un CAPTCHA “se detiene y te pide que lo gestiones manualmente”. Las instrucciones recomendadas de Google para el uso de ordenador dicen “You MUST NEVER attempt to solve or bypass” una lista que incluye “CAPTCHAs (of any kind)”.
Un CAPTCHA es un sitio que pide un humano, así que la respuesta correcta es cedérselo a uno. Eso también da lugar a un mejor producto: la persona sabe qué ha ocurrido y puede decidir.
La identidad es el camino a seguir
La respuesta a más largo plazo es que los agentes digan quiénes son de una forma que los sitios puedan verificar. Web Bot Auth permite a un cliente firmar criptográficamente sus peticiones con HTTP Message Signatures. OpenAI ya firma las peticiones de su navegador en la nube, con una cabecera Signature-Agent fijada en https://chatgpt.com, y Google dice que está experimentando con el protocolo. Cloudflare introdujo una categoría de agentes firmados en agosto de 2025, y desde julio de 2026 distingue el acceso directo frente al intermediario de los bots verificados. El trabajo del IETF sigue siendo un borrador, así que hay que esperar cambios.
Si estás construyendo un agente hoy, envía un User-Agent descriptivo con datos de contacto, publica qué hace tu agente, y prevé la firma.
El panorama legal está sin resolver
El primer gran caso muestra lo abierto que está esto. Amazon demandó a Perplexity en noviembre de 2025 por su navegador agéntico, alegando infracciones de la Computer Fraud and Abuse Act de Estados Unidos y su equivalente californiano, y la resolución dice que el núcleo de la disputa era la decisión de Perplexity de no usar una cadena de user-agent. En agosto de 2026 el Noveno Circuito anuló una medida cautelar preliminar, al considerar que era improbable que Amazon pudiera demostrar que Perplexity “accedió” a sus ordenadores conforme a esa ley.
El tribunal fue cuidadoso con el alcance de esto: “We do not establish a new legal regime governing agentic AI.” También dijo que el resultado no merma la capacidad de Amazon de regular el acceso mediante sus condiciones de servicio. Así que esto no fue una licencia para que los agentes ignoren los deseos de un sitio. Esto es información general, no asesoramiento legal, y el caso ha vuelto al tribunal de distrito.
Construir pensando en el muro
- Asume que los muros son normales. Diseña el plan del agente contando con páginas a las que no podrá acceder, con alternativas como otra fuente o preguntar al usuario.
- Clasifica antes de que el modelo vea nada. Usa una herramienta como la de arriba, y registra los resultados para poder ver qué sitios fallan.
- Ofrece primero las vías oficiales. Cuando un sitio tenga una API o un producto de datos, úsalo. Es más fiable que una sesión de navegador.
- Mantén las sesiones coherentes. Las tareas de varios pasos se rompen cuando la IP cambia a mitad de camino. Nuestra guía sobre proxies para agentes de IA que navegan por la web trata la rotación y las sesiones persistentes.
- Sabe para qué sirve un proxy. Los proxies residenciales ayudan a un agente a ver páginas públicas como lo hacen los visitantes locales, en el país correcto y desde una dirección consistente. No cambian lo que un sitio permite, y no son una forma de saltarse un sitio que ha dicho que no. Si un sitio pide un inicio de sesión, un pago o una persona, respétalo.
La conclusión
Los agentes llegaron a la web antes de que la web tuviera una categoría para ellos, y por ahora el muro forma parte del trabajo. Trátalo como un resultado normal: clasifícalo en la capa de herramientas, dile la verdad al modelo y al usuario, devuelve los CAPTCHAs a las personas, e identifica a tu agente. Un agente que dice “no he podido ver esa página” vale mucho más que uno que adivina.
Fuentes y referencias
- OpenAI, documentación de bots: developers.openai.com
- OpenAI, lista de permitidos del navegador en la nube de ChatGPT Work: help.openai.com
- OpenAI, Introducing Operator (23 de enero de 2025): openai.com
- Google, user-triggered fetchers: developers.google.com
- Google, Gemini computer use: ai.google.dev
- Anthropic, sobre el rastreo y los propietarios de sitios: support.claude.com
- Anthropic, Claude in Chrome: code.claude.com
- Cloudflare, signed agents (28 de agosto de 2025, documentación actualizada en noviembre de 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, borrador del protocolo Web Bot Auth: datatracker.ietf.org
- RFC 9309, Robots Exclusion Protocol: rfc-editor.org
- RFC 9110 y RFC 6585, códigos de estado HTTP: rfc-editor.org, rfc-editor.org
- Model Context Protocol, especificación de herramientas: modelcontextprotocol.io
- Sethi et al., Fabrication After Tool Failure (preprint, septiembre de 2026): arxiv.org/abs/2609.14758
- Noveno Circuito, Amazon.com Services v. Perplexity AI, No. 26-1444 (4 de agosto de 2026): uscourts.gov