Webwright: Vì sao AI web agent nên viết mã thay vì bấm chuột?
Microsoft Research ra mắt Webwright, một framework cho phép AI web agent viết và chạy mã thay vì mô phỏng từng cú click. Kết quả thử nghiệm cho thấy điểm thành công trên tác vụ dài tăng từ 33,5% lên 60,1% với cùng một mô hình GPT-5.4, đồng thời tạo ra các công cụ dòng lệnh có thể tái sử dụng. Bài viết phân tích kiến trúc, kết quả benchmark và thử nghiệm thực tế trên ba dạng website phổ biến.

Webwright: Vì sao AI web agent nên viết mã thay vì bấm chuột?
Trong nhiều năm, các web agent AI vận hành theo cách "nhìn trang web, dự đoán cú click, chờ DOM thay đổi, rồi lặp lại" – một vòng lặp dễ vỡ và tốn kém khi gặp tác vụ kéo dài. Webwright, một framework mã nguồn mở từ Microsoft Research và Đại học Hồng Kông, đảo ngược cách tiếp cận: thay vì bấm từng nút, hãy để mô hình viết một chương trình hoàn chỉnh. Kết quả không chỉ cải thiện độ chính xác vượt trội– từ 33,5% lên 60,1% trên cùng một mô hình – mà còn để lại một thứ có thể tái sử dụng: một công cụ dòng lệnh thực thụ.
Vấn đề kinh niên: một cú click sai là mọi thứ sụp đổ
Nếu bạn từng xây dựng web agent, bạn sẽ quen với kịch bản thất bại này: giao tác vụ "kéo toàn bộ danh sách từ thư mục này vào bảng tính", và xem nó tiến từng bước: đọc trang, dự đoán click, chờ DOM mới, đọc lại, dự đoán tiếp. Đến khoảng bước thứ 40, mọi thứ vỡ vụn vì một modal bất ngờ hiện ra, nút "trang sau" đổi vị trí, hoặc agent nhầm phần tử này với phần tử khác.
Có bốn "gia đình" web agent chính, và tất cả đều vướng vào các nhược điểm riêng:
| Loại agent | Mô hình nhìn thấy gì | Điểm mạnh | Điểm yếu |
|---|---|---|---|
| Vision (như OpenAI Operator) | Ảnh chụp màn hình | Hoạt động khi trang chỉ hiểu bằng mắt | Lệch layout là sai, token đắt, dễ mơ hồ |
| DOM / set-of-marks (như WebVoyager) | Cây HTML, accessibility tree | Chính xác hơn pixel | Trang phức tạp có thể tạo DOM > 50KB, tích lũy context khổng lồ |
| Fixed action API (click/type/scroll) | Menu hành động cố định | Dễ benchmark và lặp lại | Không thể diễn đạt vòng lặp, retry, ghi file |
| Framework đóng gói (browser-use, Stagehand...) | API bọc sẵn | Dễ tích hợp | Vẫn từng bước, không để lại sản phẩm tái dùng |
Vấn đề cốt lõi: vòng lặp "nhìn – quyết định – thực thi" không thay đổi dù mô hình có mạnh hơn. Mỗi bước là một cơ hội mới để đọc sai, và khi tác vụ dài, chi phí context tăng vọt.
Sơ đồ các thế hệ web agent và trục thời gian phát triển
Webwright: "Một terminal là tất cả những gì bạn cần"
Ý tưởng của Webwright cực kỳ đơn giản, như cách nhà nghiên cứu của họ nói: hãy trao cho mô hình một terminal, để nó viết và chạy mã thay vì đoán từng cú click. Cụ thể hơn, agent có thể viết script Python sử dụng Playwright để mở trình duyệt, kiểm tra trang, trích xuất dữ liệu, xử lý lỗi – và quan trọng nhất, lưu kết quả thành một chương trình có thể chạy lại bất cứ lúc nào.
Một điều bất ngờ: hệ thống lõi chỉ có khoảng 1.000 dòng mã (bao gồm CLI và hỗ trợ model provider là ~1.500 dòng), chia làm ba thành phần:
- Runner (~150 dòng): Theo dõi tác vụ, trạng thái workspace, kết quả các hành động trước.
- Model Endpoint (~550 dòng): Kết nối với OpenAI, Anthropic, hoặc OpenRouter.
- Environment (~300 dòng): Một terminal kết nối với Playwright chạy Chromium, nơi mọi lệnh được thực thi.
Vòng lặp hoạt động như sau: Runner đưa tác vụ và context mới nhất cho model → model quyết định lệnh shell nào cần chạy → Environment thực thi và trả về output (terminal, log, screenshot, lỗi) → thêm vào context và hỏi model bước tiếp theo. Quá trình lặp cho đến khi model tin rằng hoàn thành và bước tự kiểm tra cuối cùng đồng ý.
Điểm mấu chốt: Workspace là trạng thái, không phải session trình duyệt
Hầu hết web agent lưu tiến trình trong phiên trình duyệt; đóng tab là mất hết. Webwright đảo ngược điều đó: trình duyệt là thứ dùng một lần, workspace cục bộ là thứ tồn tại lâu dài. Mỗi script, log, screenshot, file output được lưu lại và sau đó trở thành công cụ tái sử dụng.
Điều này mang lại bốn lợi ích thực tế:
- Tương tác bền vững hơn: Selector Playwright và điều kiện chờ (wait_for_selector) ổn định hơn tọa độ pixel hoặc ID phần tử tạm thời.
- Khả năng tổng hợp tốt hơn: Vòng lặp và hàm xử lý hàng trăm lần lặp chỉ trong một chương trình.
- Trạng thái hiển thị rõ ràng: Tiến trình nằm trong file và log, không bị ẩn trong session.
- Output tái sử dụng: Tác vụ thành công → có code chạy lại mà không cần agent.
Kết quả benchmark: Con số biết nói
Điểm số quan trọng nhất đến từ benchmark Odysseys: GPT-5.4 dùng điều khiển theo tọa độ chỉ đạt 33,5%, nhưng cũng mô hình đó chạy qua Webwright đạt 60,1% – một mức tăng 26,6 điểm phần trăm chỉ từ việc thay đổi harness, không phải thay model. Trên Online-Mind2Web, Webwright đạt 86,7% với GPT-5.4, là mức cao nhất trong số các AutoEval harness mã nguồn mở.
Đáng chú ý hơn: khi có sẵn 5+ công cụ tái sử dụng, ngay cả mô hình mã nguồn mở nhỏ Qwen-3.5-9B cũng hoạt động tốt trên Online-Mind2Web. Nghĩa là công cụ không chỉ tiết kiệm công sức mà còn giảm yêu cầu năng lực mô hình cho những lần sau.
Tất nhiên có đánh đổi: chi phí trung bình khoảng $2,37/tác vụ với GPT-5.4 và $6,09 với Claude Opus 4.7 – đắt hơn vì phải chi compute để xây công cụ, nhưng bù lại output bền và tái dùng được.
So sánh hiệu quả giữa dự đoán hành động và viết mã
Thử nghiệm thực chiến trên ba loại website phổ biến
Để kiểm chứng độ bền của Webwright, tôi tiến hành thử nghiệm với Claude Sonnet agent trên ba loại trang có độ khó tăng dần:
1. Phân trang tĩnh (books.toscrape.com)
Tác vụ: trích xuất tên sách, giá, rating, availability, URL của 1.000 cuốn trên 50 trang.
Agent trước tiên kiểm tra trang: trang 50 không có liên kết "next", trang 51 trả về 404. Sau đó nó viết vòng lặp đơn giản và tạo một CLI với --pages và --out. Kết quả: 1.000 sách, 0 trường trống, chỉ mất 37 giây. Quan trọng hơn, quá trình tự kiểm tra phát hiện và sửa một bug: phiên bản đầu tiên xóa log bằng chứng khi chạy --help.
2. Nội dung render bằng JavaScript (quotes.toscrape.com/js)
Trang này mới thật sự khó: quote chỉ xuất hiện sau khi trình duyệt chạy JavaScript, và trang 11 vẫn trả HTTP 200. Agent xác nhận điều này trước: request HTTP trực tiếp trả về 0 quote, còn trang render ra 10. Thay vì dựa vào status code, script kiểm tra DOM trực tiếp để dừng khi không còn nút "next". Kết quả: 100 quote trong 8,9 giây. Điều thú vị: agent phát hiện giả định sai trong yêu cầu (tôi kỳ vọng 40 dòng từ 2 trang) và báo lại thay vì ép output khớp spec.
3. Infinite scroll (quotes.toscrape.com/scroll)
Không có URL phân trang, quote nạp 10 cái mỗi lần cuộn. Script dùng vòng lặp "cuộn đến khi DOM ngừng phát triển": đếm .quote, chờ 1 giây, lặp lại. Nó dừng sau 2 vòng lặp ổn định, tổng cộng 11 lần lặp và 17 giây. Kiểm tra chéo với bài test 2: cả hai đều cho 100 quote giống nhau từng dòng một – một phương pháp xác minh đầy đủ mà click-trace không bao giờ có được.
Sơ đồ mô tả sự khác biệt giữa browser session và workspace code
Kết luận: Tương lai của web agent không nằm ở cú click
Giá trị của Webwright không phải là một mô hình mạnh hơn hay prompt hay hơn, mà là một tư duy khác: trao cho mô hình một terminal, để nó lập trình trình duyệt, và giữ lại kết quả dưới dạng mã tái sử dụng. Thay vì vòng lặp click mong manh, agent có thể viết, chạy, gỡ lỗi và tái sử dụng một chương trình.
Như thử nghiệm cho thấy, khi website càng phức tạp (JS render, infinite scroll), code càng chứng minh lợi thế. Cú click hoàn thành tác vụ một lần; mã hoàn thành tác vụ và giữ lại giải pháp. Với các nhà phát triển Việt Nam đang làm việc với dữ liệu web, dashboard nội bộ, hoặc bất kỳ quy trình nào cần chạy lặp lại, Webwright mở ra một hướng tiếp cận thiết thực: web agent tốt nhất không chỉ bấm chuột – chúng viết ra công cụ và để lại nó.


