1. no se quedará quieto
Si ha creado un agente web recientemente, conoce el patrón de error. Le asigna una tarea como "extraer todos los listados de este directorio a una hoja de cálculo" y observar cómo avanza poco a poco. Lee la página. Predice un clic. Espera el nuevo DOM, la estructura de página que ve el navegador. Vuelve a leer, vuelve a predecir, vuelve a esperar.
Luego, alrededor del paso 40, las cosas se desmoronan. Un modal aparece inesperadamente. El botón “página siguiente” se mueve. El agente confunde un elemento con otro. Cualquiera de estos puede descarrilar toda la tarea. El problema más profundo no es el mal clic. Así es como opera el agente: mira la página, decide una acción, ve qué cambió y luego vuelve a decidir. Repite este ciclo una y otra vez, sin un plan duradero sobre cómo completar la tarea de principio a fin.
El campo ha probado algunas formas diferentes de hacer que este bucle sea más confiable. Algunos agentes, como el Operador de OpenAI y el Uso de la Computadora de Anthropic, trabajan a partir de capturas de pantalla e interactúan con un sitio web de manera muy similar a como lo haría una persona. Otros, como WebVoyager, utilizan el DOM de la página para comprender qué elementos están disponibles y decidir con cuál interactuar.
Puntos de referencia como Mind2Web y WebArena hicieron que estos sistemas fueran más fáciles de comparar al brindarles a los agentes un conjunto estándar de acciones: hacer clic, escribir, desplazarse, seleccionar. Y las herramientas de código abierto como el uso del navegador, Skyvern, Stagehand y LaVague han empaquetado estas ideas en API que los ingenieros pueden integrar más fácilmente en aplicaciones reales.
Estos enfoques hacen que el ciclo sea más confiable, pero no cambian su funcionamiento fundamental: el agente aún realiza una acción a la vez, espera a ver qué sucede y luego decide qué hacer a continuación. Y cuando la tarea termina, no ha creado nada reutilizable: solo ha completado una secuencia de clics.
Webwright, un marco de agente de navegador de Microsoft Research y la Universidad de Hong Kong, adopta un enfoque diferente. Su eslogan captura la idea: "Un terminal es todo lo que necesitan los agentes web".
En lugar de pedirle al modelo que determine el siguiente clic, Webwright hace que los agentes escriban y ejecuten código, utilizando scripts bash y Playwright para abrir navegadores, inspeccionar páginas y llevar a cabo la tarea. El resultado no es sólo una larga secuencia de acciones del navegador. Es un programa que los ingenieros pueden inspeccionar, volver a ejecutar, modificar y reutilizar.
Esta diferencia es más importante cuando la web es su fuente de datos: paneles, catálogos de productos, resultados de búsqueda, herramientas internas, sitios con mucho JavaScript y flujos de trabajo que espera ejecutar más de una vez. En esos casos, la pregunta no es sólo si un agente puede terminar la tarea. Se trata de si debe seguir haciendo clic en el navegador o escribir un programa reutilizable para hacer el trabajo.
Comenzaremos con los cuatro enfoques principales para crear agentes web y las limitaciones que aún comparten. Luego veremos el interior de Webwright: cómo funcionan sus tres componentes principales, cómo se desempeña un marco de aproximadamente mil líneas en los puntos de referencia y qué dicen los resultados sobre el costo y la confiabilidad. Finalmente, aplicaremos el enfoque en tres problemas comunes de scraping: páginas paginadas, contenido renderizado en JavaScript y feeds de desplazamiento infinito.
2. ¿Por qué los agentes web siguen fallando?
El cambio a “escribir código” es importante porque aborda el problema subyacente, no sólo los síntomas. Los agentes web actuales difieren en cómo entienden una página (algunos miran capturas de pantalla, otros leen el DOM), pero la mayoría sigue funcionando de la misma manera: realiza una acción del navegador, ve qué sucede y luego decide sobre la siguiente.
Eso funciona para tareas cortas. Pero cuanto más se ejecute la tarea, más posibilidades habrá de que un clic incorrecto, una página modificada o un elemento mal leído arruine todo.
Los agentes de visión son fáciles de entender: miran la página de forma muy parecida a como lo hace una persona y deciden dónde hacer clic. Esto funciona bien para muchas tareas del navegador, pero el raspado exige más coherencia. Un pequeño cambio en el diseño puede mover un botón lo suficiente como para que el agente haga clic en el lugar equivocado, o en nada.
También hay un costo por mirar repetidamente capturas de pantalla. Cada nueva captura de pantalla consume tokens y el agente tiene que transmitir suficiente contexto para recordar lo que ya hizo. En una tarea larga, ese contexto se vuelve más difícil y costoso de mantener.
Los agentes DOM y de árbol de accesibilidad evitan algunos de los problemas que surgen con las capturas de pantalla. En lugar de adivinar dónde está un elemento en función de los píxeles, pueden leer la estructura de la página e identificar botones, enlaces, formularios y otros elementos directamente. WebVoyager, por ejemplo, informó alrededor del 59% de éxito en tareas en 50 sitios web del mundo real, significativamente mejor que las líneas base de solo texto.
Pero esto crea un problema diferente: demasiados datos de página. Una página compleja puede generar un árbol de accesibilidad de más de 50 KB. A medida que el agente avanza en una tarea, el estado antiguo de la página se acumula en su contexto aunque gran parte de él ya no sea útil. Las referencias que utiliza para identificar elementos también pueden cambiar cuando una página carga contenido de forma diferida, se vuelve a representar o navega a un lugar nuevo.
Por lo tanto, un mejor acceso a la estructura de la página no necesariamente hace que las tareas largas del navegador sean confiables. En VisualWebArena, los principales agentes de visión y lenguaje completaron solo alrededor del 16% de las tareas, en comparación con aproximadamente el 89% de los humanos.
Las API de acción fija hicieron que los agentes web fueran más fáciles de crear y comparar. Dale al modelo un pequeño conjunto de acciones (hacer clic, escribir, desplazarte, seleccionar) y luego dejar que observe el resultado y elija nuevamente. La desventaja es que el agente sólo puede expresar un pequeño paso a la vez. Naturalmente, no puede decir "sigue haciendo clic en Siguiente hasta que no queden páginas", "vuelve a intentarlo si este elemento no aparece" o "reúne estas 1000 filas y guárdalas en un CSV". Cada uno de ellos debe dividirse en muchas acciones individuales, con otro modelo de llamada en el medio.
Marcos como el uso del navegador, Skyvern, Stagehand y LaVague hacen que los agentes del navegador sean mucho más fáciles de construir e integrar. Esto es útil, pero no resuelve un problema importante para el trabajo de datos recurrente: cuando la tarea finaliza, a menudo no queda nada reutilizable. Es posible que el agente haya recopilado los datos una vez, pero la próxima semana tendrá que volver a funcionar a través del navegador.
Las investigaciones ya habían apuntado hacia otro enfoque. En el artículo de ICML 2024 Las acciones de código ejecutable obtienen mejores agentes LLM, los investigadores detrás de CodeAct reemplazaron las acciones predefinidas de estilo JSON con Python ejecutable. Informaron tasas de éxito hasta un 20 % más altas y utilizaron aproximadamente un 30 % menos de pasos.
La razón es sencilla: el código permite que el modelo haga más que una acción a la vez. Puede usar bucles, almacenar variables, reintentar errores, escribir archivos e inspeccionar errores, todo dentro de un programa que puede ejecutar nuevamente. Webwright aporta la misma idea a la automatización del navegador.
3. El punto único de Webwright: hacer del espacio de trabajo el estado
La mayoría de los agentes del navegador mantienen su progreso en la sesión del navegador. Cierra la pestaña y ese estado desaparecerá.
Webwright le da la vuelta a esto. El navegador es temporal; el espacio de trabajo local es lo que persiste. El agente escribe scripts, registros, capturas de pantalla y archivos de salida mientras trabaja, y eventualmente convierte una ejecución exitosa en una herramienta reutilizable. Este cambio tiene algunos beneficios prácticos.
Interacciones más sólidas: los selectores de dramaturgos y las condiciones de espera son más confiables que las coordenadas de píxeles o los ID de elementos temporales. Mejor composición: los bucles y las funciones pueden manejar cientos de acciones repetidas en un programa. Estado visible: el progreso es visible en archivos y registros. Salida reutilizable: una vez que la tarea funciona, el código se puede reproducir en lugar de empezar desde cero.
De dónde provienen las cuatro ventajas declaradas del proyecto:
Interacciones sólidas y reutilizables: el agente actúa a través de consultas y comprobaciones de espera de condiciones (page.locator(…), wait_for_selector(…)) en lugar de coordenadas de píxeles o ID de elementos congelados, por lo que un script sobrevive a los cambios de diseño y se vuelve a renderizar. Composición eficiente: los bucles, funciones y variables permiten que un solo turno diga "haga esto para cada fila", trabajo que un agente de una acción a la vez debe explicar paso a paso. Espacio de trabajo como estado: el progreso reside en archivos, no en una sesión frágil o en una ventana contextual repleta de volcados de páginas obsoletas. Mínimo por diseño: todo el sistema se basa en cuatro bibliotecas (httpx, pydantic, dramaturgo, typer) sin ningún marco oculto debajo, y aún publica números de última generación.
3.1 Hagamos comparaciones rápidas entre Webwright y otras opciones en algunos escenarios.
3.1.1 Demostración 1 · Cuando hacer clic no es lo suficientemente preciso
La tarea: utilice la calculadora de IRA de Chase para comparar una IRA tradicional con una Roth para alguien que tiene 30 años, se jubila a los 65, ahorra $300 al mes, obtiene un rendimiento del 3 % y tiene tasas impositivas del 13 % hoy y del 24 % durante la jubilación.
El desafío es que la calculadora utiliza seis controles deslizantes interactivos de JavaScript.
Resultado:
Webwright establece los valores directamente en el código actualizando las entradas DOM y activando los eventos necesarios. Los valores son exactos, el gráfico se representa correctamente y la solución funcional se guarda como un script reutilizable. Un agente de visión tiene que manipular los controles deslizantes visualmente. Se acerca, pero no lo suficiente: la contribución de 300 dólares equivale a 294 dólares.
3.1.2 Demostración 2 · Cuando vuelve la misma tarea
La tarea: buscar en Google Vuelos un viaje de ida y vuelta de Seattle a San Francisco, incluidas las fechas, y obtener los resultados clasificados.
Resultado:
Webwright completa la búsqueda como lo harían otros agentes de navegador. La diferencia importante es lo que sucede después: mantiene el código de trabajo. Cuando más tarde aparece una búsqueda de vuelo similar, el agente no tiene que averiguar cada campo, seleccionar la fecha y hacer clic nuevamente. Puede reutilizar el script anterior, cambiar las entradas y ejecutarlo nuevamente.
Eso es lo que Microsoft quiere decir con "su historial de navegación es código en lugar de clics". Una tarea completada se convierte en un punto de partida para la siguiente, en lugar de una sesión del navegador que desaparece cuando finaliza.
3.2 En qué se diferencia Webwright de otros repositorios de agentes de navegador
Las alternativas son útiles, pero aún así colocan al navegador en el centro del flujo de trabajo. Stagehand combina Dramaturgo con comandos de lenguaje natural. agent-browser proporciona a los agentes una CLI para realizar pequeñas acciones en el navegador. El uso del navegador lee repetidamente la página, elige una acción y la ejecuta.
Webwright adopta un enfoque diferente. En lugar de elegir la siguiente acción del navegador, el modelo puede escribir un script Python completo. El navegador es temporal; el código, los registros y los resultados permanecen en el espacio de trabajo local. Y cuando se resuelve la tarea, el agente deja un programa que se puede ejecutar nuevamente.
Esa es la idea central: al hacer clic se completa la tarea una vez; El código lo completa y mantiene la solución.
3.3 Dentro de Webwright
Entonces, ¿qué se necesita para crear un agente como este? Sorprendentemente poco.
La mayoría de los agentes web colocan un arnés (el software que conecta el modelo al navegador) entre los dos. Ese arnés generalmente le da al modelo un conjunto fijo de acciones: hacer clic en este elemento, escribir en este campo, desplazarse por la página, leer el DOM, tomar una captura de pantalla.
Webwright adopta un enfoque diferente. En lugar de darle al modelo un menú de acciones del navegador, le da una terminal y le permite decidir qué comandos ejecutar.
Eso hace que el sistema sea sorprendentemente pequeño. El conjunto principal consta de aproximadamente 1000 líneas de código en tres componentes. El repositorio completo se acerca a las 1500 líneas una vez que se incluye la interfaz de línea de comandos y el soporte para diferentes proveedores de modelos. No existe una gran biblioteca de acciones de navegador predefinidas. Sin motor DOM personalizado. El sistema central consta de sólo tres piezas:
Runner (~150 líneas): realiza un seguimiento de la tarea y de todo lo que ha sucedido hasta el momento: lo que el agente está intentando hacer, el estado actual de su espacio de trabajo y los resultados de acciones anteriores. Punto final del modelo (~550 líneas): conecta Webwright al modelo de lenguaje. Proporciona backends para OpenAI, Anthropic y OpenRouter. Entorno (~300 líneas): le da al modelo un terminal conectado a Playwright que ejecuta Chromium. Aquí es donde realmente se ejecutan los comandos, se producen las interacciones del navegador y se almacenan los archivos creados durante la tarea.
La interacción entre estas piezas es un bucle simple.
Runner le da al modelo la tarea y el contexto más reciente. El modelo decide qué hacer a continuación y devuelve un comando de shell. El entorno ejecuta ese comando y envía lo que sucedió: salida del terminal, registros, capturas de pantalla o mensajes de error. Webwright agrega esos resultados al contexto y le pregunta al modelo qué hacer a continuación.
En resumen, el bucle se ve así:
comprender el estado actual → elegir un comando → ejecutarlo → ver qué sucedió → repetir
El proceso continúa hasta que el modelo cree que la tarea está completa y una autoevaluación final da la razón. Webwright no intenta codificar todas las interacciones posibles del navegador en el arnés. Le da al modelo una interfaz de propósito general (la terminal) y le permite descubrir cómo usarla.
Los puntos de referencia respaldan el diseño. En Online-Mind2Web, GPT-5.4 con Webwright obtiene una puntuación del 86,7 %, la más alta entre los arneses AutoEval de código abierto, mientras que Claude Opus 4.7 alcanza el 84,7 % y funciona mejor en las tareas más difíciles.
La señal más importante proviene de Odysseys. GPT-5.4 que utiliza control de navegador basado en coordenadas obtiene una puntuación del 33,5 %. Con Webwright, el mismo modelo alcanza el 60,1%: una ganancia de 26,6 puntos al cambiar el arnés, no el modelo.
La página del proyecto de Webwright enumera el 60,8%; Utilizo el 60,1% informado en su comparación de GitHub para mantener la coherencia.
Otro resultado respalda la tesis: una vez que Webwright ha creado herramientas reutilizables, el modelo puede hacerse más pequeño. Microsoft informa que incluso un modelo abierto 9B (Qwen-3.5-9B) funciona bien en Online-Mind2Web una vez que hay cinco o más herramientas disponibles. La herramienta no sólo ahorra trabajo, sino que reduce la capacidad del modelo necesaria la próxima vez.
Hay compensaciones. Estas son puntuaciones de AutoEval evaluadas por LLM y el resultado principal de Mind2Web utiliza 100 de 300 tareas. Tampoco es barato: alrededor de 2,37 dólares por tarea con GPT-5.4 y 6,09 dólares con Claude Opus 4.7. Webwright invierte más computación por adelantado para crear herramientas que sean más sólidas y reutilizables.
4. Experimentos y resultados
Probé Webwright en tres sitios cada vez más difíciles, utilizando un agente Claude Sonnet independiente para cada ejecución. Esto es para ver qué tan robusto es Webwright donde generalmente se rompe el raspado.
Utilicé el complemento Claude Code en lugar del arnés de referencia independiente. Mantiene la misma configuración principal (terminal + Playwright), pero Claude Code ejecuta el ciclo del agente. Eso elimina la necesidad de una clave API separada o una factura API por tarea, aunque no el costo de cómputo.
La compensación es el uso de tokens. En el ejemplo de Microsoft, la habilidad alojada en Codex utilizó ~3,3 millones de tokens frente a ~424.000 para el arnés independiente, aproximadamente 8 veces más, en gran parte a partir del contexto almacenado en caché. El costo se traslada a la sesión del anfitrión en lugar de desaparecer.
La configuración tomó un comando:
dramaturgo instala Firefox # la habilidad Claude Code impulsa Firefox sin cabeza, ~110 MB por única vez
4.1 🔧 Prueba 1: paginación estática · books.toscrape.com
books.toscrape.com es el más sencillo entre tres casos: 50 páginas de catálogo numeradas, 20 libros cada una, presentadas como HTML simple. La tarea consistía en extraer cada título de libro, precio, calificación, disponibilidad y URL, y luego crear una CLI reutilizable con –pages y –out.
Antes de escribir el raspador, el agente inspeccionó el sitio y probó sus límites: la página 50 no tenía el siguiente enlace, mientras que la página 51 devolvió un 404. Luego extrajo selectores de una tarjeta de producto real y creó un bucle de paginación simple.
para n en el rango(1, páginas + 1): url = CATALOGUE_URL_TEMPLATE.format(n=n) await page.goto(url, wait_until="domcontentloaded") cards = page.locator("article.product_pod") count = await cards.count() log(n, f"página del catálogo cargada {n}/{pages} ({url}) -> {count} tarjetas de libros encontradas")
Un agente basado en clics podría manejar este sitio, pero el código era más limpio. Un problema sutil fueron las URL relativas de los libros, que cambian según las páginas. En lugar de construirlos manualmente, el raspador utilizó los valores href resueltos por el navegador.
El resultado no fueron solo datos extraídos, sino una herramienta CLI independiente que podía ejecutarse nuevamente sin un agente.
$ python final_script.py –uso de ayuda: final_script.py [-h] [–pages PAGES] [–out OUT] Elimina todos los libros enumerados en las páginas del catálogo de books.toscrape.com. –pages PAGES Número de páginas del catálogo a recorrer… Predeterminado: 50. –out OUT Ruta del archivo CSV de salida… Predeterminado: books.csv. $ python final_script.py –pages 2 –out sample.csv -> 40 filas escritas en …/sample.csv
Resultado: 1000 libros en 50 páginas, cero campos vacíos, en aproximadamente 37 segundos.
El paso de verificación también detectó un error: la primera versión borró accidentalmente su registro de evidencia al ejecutar –help. El agente encontró el efecto secundario, lo solucionó, probó la solución y volvió a ejecutarlo exitosamente. Incluso en este sitio simple, la ventaja era clara: un programa reutilizable y depurable en lugar de un seguimiento de un solo clic.
4.2 🔧 Prueba 2: renderizado en JavaScript · quotes.toscrape.com/js
La segunda prueba agrega JavaScript. Las comillas no están presentes en el HTML sin formato; aparecen sólo después de que el navegador ejecuta el JavaScript de la página. El agente verificó esto primero: una solicitud HTTP directa devolvió cero elementos de comillas, mientras que la página renderizada mostró 10. Una solicitud básica + un raspador BeautifulSoup no devolvería nada silenciosamente.
Eso significa que cada página debe renderizarse antes de la extracción. Hay otro problema: la página 11 todavía devuelve HTTP 200, por lo que los códigos de estado no pueden indicarle al raspador cuándo detenerse. En cambio, el programa comprueba el DOM en vivo para buscar el siguiente enlace y se detiene cuando desaparece en la página 10.
while True: url = BASE_URL if n == 1 else PAGE_URL_TEMPLATE.format(n=n) await page.goto(url, wait_until="domcontentloaded") await page.wait_for_selector(".quote", timeout=10000) # espere a que JS inyecte las comillas… # lea las 10 tarjetas .quote renderizadas has_next = await page.locator("li.next a").count() > 0 si no has_next o n >= páginas: # parada en el DOM, no es una interrupción del código de estado n += 1
Nuevamente, el resultado se convirtió en una CLI reutilizable con –pages y –out, capaz de ejecutarse sin un agente.
La recompensa: la CLI diseñada. Al igual que en la ejecución de los libros, el script de trabajo se convirtió en una herramienta reutilizable scrape_quotes(pages, out) con una interfaz argparse (–pages, predeterminado 10; –out, default quotes.csv) que se vuelve a ejecutar de forma independiente, sin agente en el bucle.
Resultado: 100 citas en 10 páginas en 8,9 segundos, sin texto vacío ni campos de autor.
La tirada también expuso una mala suposición en mi informe: esperaba que dos páginas produjeran 40 filas, tomando prestado el recuento de 20 por página del sitio de libros. Este sitio ofrece 10, por lo que el resultado correcto fue 20. El agente devolvió los datos reales y marcó la discrepancia en lugar de forzar la salida para que se ajustara a las especificaciones.
4.3 🔧 Prueba 3: desplazamiento infinito · quotes.toscrape.com/scroll
La tercera prueba elimina la paginación por completo. Las citas se cargan de 10 a la vez a través de AJAX a medida que se desplaza la página, por lo que no hay URL de página para recorrer. El raspador tiene que desplazarse, esperar contenido nuevo, medir la página y decidir cuándo finaliza la carga.
El agente primero confirmó el comportamiento del sitio: has_next se vuelve falso en la página 10 y la página 11 no devuelve comillas. Luego creó un bucle de desplazamiento hasta estabilizarse que se detiene cuando no aparece contenido nuevo.
para i in range(1, max_scrolls + 1): await page.evaluate("window.scrollTo(0, document.body.scrollHeight)") await page.wait_for_timeout(1000) count = await page.locator(".quote").count() if count == prev_count: # no llegaron nuevas cotizaciones stable_iters += 1 if stable_iters >= 2: # detenerse en estabilidad, no un descanso de conteo fijo else: stable_iters = 0 prev_count = conteo
El recuento de DOM creció 10 -> 20 -> … -> 100, se mantuvo en 100 durante dos desplazamientos y se detuvo en la iteración 11. –max-scrolls era solo un respaldo de seguridad. Forzar –max-scrolls 5 devolvió exactamente 60 filas, lo que demuestra que la condición de detención respondió a la página, no una constante oculta.
Resultado: 100 citas en 11 iteraciones, en aproximadamente 17 segundos.
En las tres pruebas, el valor del código se vuelve más claro a medida que los sitios se vuelven más difíciles. La paginación estática es sencilla; JavaScript requiere un navegador real; El desplazamiento infinito requiere que el programa razone sobre cuándo detenerse.
También hay una verificación cruzada útil: los peldaños 2 y 3 extraen las mismas 100 comillas a través de dos interfaces diferentes (paginación y desplazamiento infinito) y producen resultados coincidentes fila por fila. Eso nos da una verificación de integridad que realmente podemos diferenciar.
Hay compensaciones. La configuración requirió una descarga de Firefox de ~110 MB y algunas correcciones del entorno de Windows. El complemento Claude Code también utiliza Firefox sin cabeza y sus propias capacidades de captura de pantalla en lugar de la configuración estándar Chromium de Webwright. Para un clic único, este enfoque es excesivo. La recompensa aparece cuando las tareas implican repetición, contenido dinámico o resultados que es necesario verificar y reutilizar.
5. Conclusión
En general, estas tres pruebas muestran que la generación de código basada en navegador es más que una forma de automatizar los clics. El resultado final es un programa Playwright reutilizable que se puede ejecutar nuevamente sin el agente. A medida que los sitios web se volvieron más complejos, el código generado también se volvió más capaz. Pasó de simples bucles de páginas a representar JavaScript y, finalmente, a razonar sobre cuándo había terminado un desplazamiento infinito.
Los experimentos también muestran el valor de la verificación. El agente encontró errores en su propio código, cuestionó suposiciones incorrectas en la descripción de la tarea y confirmó que los datos extraídos estaban completos. Los resultados coincidentes de las versiones paginada y de desplazamiento infinito del sitio de citas brindan una confianza adicional de que no se perdió nada. Esto es difícil de lograr con una sola grabación del navegador.
Hay costos. Ejecutar Playwright requiere una descarga del navegador y más configuración que un simple raspado HTTP o grabación de clics. Los programas generados también son más largos y requieren algunos conocimientos técnicos para comprenderlos. Sin embargo, esos costos se ven compensados cuando es necesario repetir, mantener o verificar la tarea. En general, las pruebas sugieren que la generación de código basado en navegador es un enfoque práctico para crear raspadores web confiables que pueden adaptarse a diferentes diseños de sitios web y al mismo tiempo producir código reutilizable, transparente y fácil de probar.
La contribución de Webwright no es un modelo más amplio ni un mensaje mejor. Es una idea más sencilla:
Dale al modelo una terminal, déjalo programar el navegador y guarda el resultado como código reutilizable.
Eso cambia el bucle del agente web. En lugar de clics frágiles y replanificación constante, el agente puede escribir, ejecutar, depurar y reutilizar un programa.
La idea se extiende más allá de los navegadores. Cuando un modelo puede codificar y su entorno puede ejecutar ese código, puede ser mejor escribir el programa que realiza la tarea que predecir cada acción paso a paso.
Los mejores agentes web no se limitan a hacer clic. Escriben la herramienta y la dejan atrás.
6. Fuentes
Webwright (primario)
El paisaje
Diagramas: creados por el autor (matplotlib). Animaciones familiares: creación del autor. Capturas de pantalla y CLI generadas