# Browser Agents Don't Need Better Models. They Need Better Eyes.

Kushan Raj · Sarvam AI · AI Engineer World's Fair 2026: Online Track

> Browser agent chậm và hay kẹt vì nhìn trang quá tệ: một bản markdown cả trang (~1.800 token) cộng feedback sau mỗi click giúp model rẻ chạy nhanh và đúng.

Topics: Agents, Context Engineering, Dev Tools

Canonical: https://homus.dev/talks/browser-agents-dont-need-better-models-they-need-better-eyes

## 1. Browser agent hay đến vậy, sao ít ai dùng?

Kushan mở đầu ngắn gọn: anh là Kushan, đã làm founding engineer ở [Sarvam AI](https://www.sarvam.ai) trong 2 năm. Điều anh đang quan tâm lúc này là browser agent, tức agent tự điều khiển trình duyệt thay con người: mở trang, đọc, click, điền form, đi qua nhiều bước cho tới khi xong việc.

Theo anh, browser agent về mặt ý tưởng thì cực kỳ hay. Đáng lẽ nó phải bùng nổ. Nhưng chính anh không thấy mức độ adoption đó ngoài đời, và bản thân anh cũng không dùng browser agent nhiều. Anh đã dành một thời gian để khám phá mảng này và cố hiểu vì sao lại như vậy. Cả talk là câu trả lời của anh cho câu hỏi đó, kèm một prototype anh đang tự xây.

## 2. Browser challenge: 30 bước, và agent mất cả chục giây cho một cú click

Thứ đầu tiên anh cho xem là một "browser challenge". Đây là một benchmark rất thú vị cho browser agent, vì nó bắt agent làm rất nhiều việc khác nhau, nối thành một chuỗi task dài (long-horizon sequencing). Và theo Kushan, chính benchmark này phơi ra vì sao browser agent hiện nay "suck".

![Claude in Chrome đang làm Step 1 of 30 của Browser Navigation Challenge, màn hình phủ đầy popup Alert và Click here for amazing deals](https://homus.dev/photos/JnubYCYunk8-0024.jpg)

Claude in Chrome đang thử Browser Navigation Challenge, bước 1 trên 30. Trang cố tình chồng nhiều popup lên nhau: có popup ghi thẳng rằng nút close là giả và phải tìm cách đóng khác, có popup "Click here for amazing deals", có hộp Cookie Consent. Bên phải là panel của Claude với goal "Complete all steps of the browser challenge" và gợi ý rằng đáp án đúng luôn có dạng "Option [Letter] - Correct Choice".

Nếu xem từ đầu video, agent này mất khoảng 10 tới 20 giây chỉ để click nút start. Lúc anh đang nói thì nó mới tới bước 1. Challenge có tất cả 30 bước, vậy mà agent đã tốn ngần ấy thời gian chỉ để bấm một cái nút.

## 3. Cùng website, chạy trên runtime của Kushan

"Thôi, đủ rồi", anh nói, và chuyển sang thứ anh đang xây. Vẫn đúng website đó. Anh cố tái tạo cảm giác được nhìn thấy chuyện gì đang diễn ra: bạn vẫn thấy browser agent đang nghĩ gì ở từng bước, giống như khi xem panel của Claude. Nhưng như mọi người thấy, nó nhanh hơn rất nhiều, gọn hơn rất nhiều, và anh đang dùng một model rẻ hơn nhiều.

![Terminal của agent Kushan in FAST_CLICK, MUTATIONS, UNBLOCKED, TEXT_CHANGED bên cạnh challenge ở Step 2 of 30 với modal Please Select an Option](https://homus.dev/photos/JnubYCYunk8-0056.jpg)

Runtime của Kushan với model [gpt-oss-120b](https://huggingface.co/openai/gpt-oss-120b) (chú thích trên màn hình: "This my browser infra + GPT OSS 120B"). Bên trái là log của agent: các lệnh FAST_CLICK tới từng element, danh sách MUTATIONS sau mỗi bước (phần tử mới, phần tử bị xoá, thuộc tính thay đổi như aria-checked chuyển từ false sang true, nút "Submit & Continue" hết disabled), dòng UNBLOCKED cho biết những element nào vừa hết bị che, và hàng loạt TEXT_CHANGED khi trang tráo chữ trên các lựa chọn. Bên phải, challenge đã sang bước 2 với modal "Please Select an Option".

Khác biệt nằm ở chỗ agent không phải đoán. Mỗi bước nó đều được báo lại trang vừa đổi những gì, thứ gì vừa xuất hiện, thứ gì vừa biến mất, nút nào vừa bấm được. Phần sau của talk sẽ giải thích cơ chế này.

## 4. Giả thuyết: model đủ thông minh, hạ tầng xung quanh mới tệ

Giả thuyết (hypothesis) của Kushan là: model hiện nay đã khá thông minh, cái tệ là phần infra bao quanh chúng. Nếu để ý video lúc nãy (anh nói có lẽ sẽ chèn một screenshot vào), agent đang cố debug xem chuyện gì đang xảy ra. Nó cố click vào một thứ gì đó, nhưng nó không hiểu chuyện gì đang diễn ra trên trang.

![Một bước sau của challenge: form Enter Code to Proceed to Step 2, hàng nút Move On, Continue Journey, Click Here, và panel Claude đang Troubleshooting page visibility issue](https://homus.dev/photos/JnubYCYunk8-0104.jpg)

Screenshot từ video của Claude lúc nãy: trang có ô "Enter Code to Proceed to Step 2" và cả một hàng nút mồi như Move On, Continue Journey, Click Here, Next Section, Keep Going. Panel của Claude (khoanh đỏ) đang ở trạng thái "Troubleshooting page visibility issue" rồi lại "Take screenshot": agent đang tự debug xem trang đang ra sao chứ chưa tiến được bước nào.

Vì vậy luận điểm cốt lõi (core thesis) của anh là: hãy cho agent một môi trường dễ dùng. Một môi trường mà ở đó agent có thể lên kế hoạch cho những chuỗi hành động dài, có thể tự tìm ra mình đã fail ở đâu và chuyện gì đang diễn ra, và có thể lên kế hoạch click cho đúng.

Điều anh tìm ra là một cách biểu diễn (representation) rất hay: nó nén website lại và cho agent nhìn thấy toàn bộ trang chỉ với rất ít token.

Hai hướng cải thiện browser agent. Bên trái là hướng phổ biến: đổi sang model mạnh hơn nhưng vẫn cho nó nhìn trang qua screenshot từng phần. Bên phải là hướng của talk: giữ model, đổi thứ model nhìn thấy, thứ nó làm được và thứ nó học được sau mỗi hành động (phần mô tả chính thức của talk đi kèm video cũng chia đúng ba trục này: what the model sees, what it can do, what it learns from).

## 5. Ví dụ thật thứ nhất: tải Aadhaar

Sau browser challenge, Kushan chuyển sang vài ví dụ đời thật. Giả sử anh muốn tải Aadhaar của mình. Aadhaar là mã định danh cá nhân của cư dân Ấn Độ, và bản điện tử (e-Aadhaar) được tải từ cổng myAadhaar của UIDAI (myaadhaar.uidai.gov.in).

![Trang myAadhaar của Unique Identification Authority of India với các ô Address update, Download Aadhaar, Order Aadhaar PVC card; panel Claude bên phải với yêu cầu download my aadhar](https://homus.dev/photos/JnubYCYunk8-0128.jpg)

Claude in Chrome trên trang myAadhaar: nút "Download Aadhaar" nằm ngay ở hàng dịch vụ đầu tiên, cạnh Address update và Order Aadhaar PVC card. Yêu cầu gõ vào panel của Claude chỉ là "download my aadhar". Video của Claude dài khoảng 2 phút.

Đây là Claude đang thử làm việc đó. Anh cho rằng đây phải là việc rất đơn giản với một browser agent: chụp screenshot, thấy cái nút nằm ngay đó, click vào. Nhưng điều thú vị là sau đó agent bị kẹt. Từ giây thứ 46 cho tới hết video, nó chụp screenshot, rồi scroll vì một lý do nào đó, rồi lại chụp screenshot. Tổng cộng cả quá trình mất 2 phút.

Còn với agent của anh, trong video của nhóm, nó khởi động lên, và "boom", xong. Theo Kushan, đó mới là cái đẹp của một browser agent: nhanh tới mức đó, và anh đang dùng một model rất rẻ cho việc này. Trong log của agent, phần trace cho thấy nó đọc bản representation của trang, nhận ra có một service "Download Aadhaar" với một nút cụ thể, click đúng nút đó ngay ở bước đầu tiên, rồi sang trang tải tiếp theo.

## 6. Ví dụ thật thứ hai: đặt chỗ trekking trên một website tiếng Kannada

Ví dụ thú vị tiếp theo: Kushan và bạn bè định đi trekking vào Chủ nhật. Trang đặt chỗ là Aranya Vihaara của bang Karnataka (aranyavihaara.karnataka.gov.in), viết bằng tiếng Kannada, và anh nói mình không rành tiếng Kannada lắm. Chính anh cũng mất một lúc mới hiểu được website này.

![Trang Aranya Vihaara Trekking bằng tiếng Kannada với khung Notifications đỏ, form chọn quận, tuyến trek và ngày; panel Claude với yêu cầu Book Ramnagara district, Savandura, 5th April](https://homus.dev/photos/JnubYCYunk8-0208.jpg)

Trang trekking Aranya Vihaara bằng tiếng Kannada: một khung thông báo màu đỏ, dòng nhắc rằng trek phải đặt trước ít nhất 1 ngày và chỉ được đặt trước tối đa 15 ngày, rồi form gồm ba ô: quận, tên tuyến trek và ngày (dd-mm-yyyy). Yêu cầu gửi cho Claude là đặt trek ở quận Ramanagara, tuyến Savandurga, ngày 5 tháng 4.

Anh hỏi Claude: "Hey, can you book this for me?", nhờ nó đặt giúp. Tới cuối video, Claude không chọn được ngày và cứ thế kẹt lại.

Rồi anh cho xem video của agent mình. Nó chọn tuyến, điền ngày, và "boom", xong. Theo anh, browser agent về lý thuyết là thứ đơn giản và tiện đến thế.

![Agent của Kushan trên trang Aranya Vihaara: dropdown tên tuyến trek đang mở, terminal bên trái in MUTATIONS với các option mới xuất hiện](https://homus.dev/photos/JnubYCYunk8-0232.jpg)

Agent của Kushan trên cùng trang: ô quận đã được chọn, dropdown tên tuyến trek đang mở với các lựa chọn bằng tiếng Kannada. Terminal bên trái cho thấy cơ chế phía sau: sau mỗi lần chọn, agent nhận về danh sách MUTATIONS gồm các option mới xuất hiện (NEW) và các option cũ bị gỡ (REMOVED), nên nó biết ngay dropdown kế tiếp vừa có dữ liệu.

## 7. Bước tiếp theo: open source, API, website hoặc plugin

Vậy tiếp theo là gì, anh định làm gì? Kushan đang tính open source project này, vì như anh nói thẳng, phần code này không quá "defensible", tức không phải thứ khó bắt chước tới mức phải giữ kín.

Sản phẩm anh muốn đưa ra có thể là một API. Như mọi người thấy, trong các demo anh đang chạy agent bằng lệnh trong terminal. Có lẽ anh chỉ cần expose chính lệnh đó thành API: bạn đưa một URL, đưa intent của bạn, anh sẽ thực thi giúp và trả kết quả về. Hoặc có thể mở nó thành một website, hoặc expose thành một plugin.

Hướng sản phẩm Kushan nói tới: đưa vào một URL và một intent, runtime tự thực thi trên trình duyệt rồi trả kết quả về. Anh còn đang cân nhắc giữa API, website hay plugin, và có thể open source luôn phần code.

Nhưng điểm mấu chốt (bottom line) là: anh muốn làm cho browser agent nhanh hơn, rẻ hơn, đáng tin cậy (reliable) hơn, và muốn mọi người trên thế giới đều dùng chúng, vì chúng có thể làm cho bạn rất nhiều việc. "Đó là ý tưởng tổng thể", anh nói, rồi cảm ơn mọi người đã xem.

## 8. Bên trong: một bản markdown cho cả trang web

Sau lời cảm ơn, talk chuyển sang phần "Implementation Overview", nơi Kushan mở code và các file kết quả để giải thích cơ chế. Thứ đầu tiên là bản markdown: toàn bộ file markdown này biểu diễn website, cụ thể là trang đang mở.

![File v5-step1-full-unedited.md mở trong editor: Page Representation (V5) với các mục Overlays và Content, mỗi element có aid, z-index và chú thích blocked by](https://homus.dev/photos/JnubYCYunk8-0328.jpg)

File "Page Representation (V5)" cho bước 1 của challenge. Trang được chia thành phần Overlays (các popup đang nổi lên trên) và phần Content. Mỗi element có một handle ổn định dạng `aid-NN`, kiểu element (radio, button, textbox, form), chữ hiển thị, z-index và chú thích như `[blocked by aid-75]` hoặc `[disabled, cursor:not-allowed]`. Chú thích trên màn hình: markdown này được dựng từ DOM tree, AX tree (accessibility tree) và các công cụ, API gốc của trình duyệt, để cô một trang web lại thành một representation đơn giản.

Rồi anh làm một phép so sánh thú vị. Anh mở Google AI Studio. Toàn bộ DOM của trang này rơi vào khoảng 20.000 token. Giả sử ta có một screenshot của trang: screenshot đó tốn khoảng 1.100 token. Bản markdown của anh tốn khoảng 1.800 token. Và thay vì một screenshot chỉ thấy được một mẩu của trang, với markdown agent nhìn thấy cả website.

Ba cách đưa cùng một trang cho model, theo con số Kushan đọc trong demo: DOM đầy đủ khoảng 20.000 token, một screenshot khoảng 1.100 token, bản markdown khoảng 1.800 token. Markdown chỉ đắt hơn screenshot một chút nhưng chứa toàn bộ trang, còn screenshot chỉ chứa phần đang hiện trên màn hình.

![Google AI Studio với chú thích đỏ: browser challenge là một trang khá đơn giản, nhưng nhìn chung markdown nén khoảng 20 lần so với DOM](https://homus.dev/photos/JnubYCYunk8-0344.jpg)

Chú thích trên màn hình lúc so sánh trong [Google AI Studio](https://aistudio.google.com): browser challenge là một trang khá đơn giản, còn tính chung trên nhiều trang web, markdown nén được khoảng 20 lần số token so với DOM.

## 9. Feedback sau mỗi hành động

Một vài điều nữa mà Kushan cho là quan trọng: phải cho agent feedback. Sau mỗi hành động, hệ thống nói với agent: "Này, đây là những thứ mới vừa hiện lên trên trang. Thứ này giờ đã biến mất." Tương tự, nó có thể báo rằng cái thứ đang chắn những gì bạn muốn click giờ đã được gỡ đi.

![File feedback-mutations.md: MUTATIONS after step 2 với NEW, REMOVED, TEXT_CHANGED; mục 2 State Change Detection, Radio Button + Submit Enable](https://homus.dev/photos/JnubYCYunk8-0352.jpg)

File `feedback-mutations.md`. Sau bước 2 có 200 thay đổi: 12 element mới (các popup "Warning", "Click here for amazing deals", modal chọn đáp án, overlay có nút close giả), 4 element bị gỡ (hộp Cookie Consent cùng hai nút Accept và Decline), và 184 lần đổi chữ. Ghi chú trong file giải thích rằng trang cố tình tráo chữ trên các nút sau mỗi lần thay đổi để làm agent rối, nên hệ thống ghi lại mọi lần đổi chữ để agent suy luận từ state hiện tại chứ không từ trí nhớ đã cũ. Mục 2, State Change Detection: sau khi chọn radio, agent được báo radio đã chọn, nút Submit vừa bật lên và các lựa chọn vừa bị xáo lại.

Agent cũng được báo khi một hành động không có tác dụng: bạn đã thử click cái này nhưng không có gì xảy ra. Hệ thống làm được điều đó vì nó theo dõi toàn bộ trang trình duyệt từ đầu tới cuối (end-to-end).

![File feedback-blocker-recovery.md với các mục 3 Dismiss Hit vs Miss, 4 Unblocked Signal, 5 Failed Action, Diagnosis, Recovery](https://homus.dev/photos/JnubYCYunk8-0400.jpg)

File `feedback-blocker-recovery.md`. Ở đầu file, nút Close của một overlay đang bị 7 overlay khác che, và representation nói cho agent biết chính xác thứ gì đang chắn để nó gỡ theo đúng thứ tự. Mục 3, Dismiss Hit vs Miss: một cú click vào nút close giả được báo "DISMISS MISS, still_visible", còn cú click vào nút thật được báo "DISMISS OK, removed", nhờ vậy agent học được nút nào là mồi nhử. Mục 4, Unblocked Signal: sau khi gỡ một overlay, 17 element bỗng click được và agent nhận đúng danh sách đó. Mục 5, Failed Action, Diagnosis, Recovery: ở bước 6 một cú click thất bại vì element bị che, bước 7 agent click vào chính thứ đang che, bước 8 click lại và thành công.

## 10. Ghép lại: representation gọn cộng screenshot

Gộp tất cả lại, thứ Kushan xây là một representation rất sạch, về cơ bản là nén website lại, và bạn có thể đưa nó cho model cùng với screenshot. Tính theo token thì nó khá rẻ. Nhờ vậy model suy luận (reason) rất tốt, và từ đó có thể dựng ra những chuỗi task dài để thực thi.

Toàn bộ cơ chế trong một vòng: model nhận bản markdown của cả trang kèm screenshot, lập ra chuỗi hành động, runtime thực thi, rồi trả feedback về những gì đã thay đổi để model lên bước kế tiếp. Theo Kushan, chính vòng này, chứ không phải một model mạnh hơn, là thứ giúp browser agent chạy nhanh, rẻ và đúng.

## Nguồn và link

- Trang talk chính thức: [ai.engineer/talks/JnubYCYunk8](https://ai.engineer/talks/JnubYCYunk8)

- Sarvam AI: [sarvam.ai](https://www.sarvam.ai)

- Claude in Chrome, browser agent dùng để so sánh trong demo: [claude.com/chrome](https://claude.com/chrome)

- gpt-oss-120b, model Kushan dùng cho runtime của mình: [huggingface.co/openai/gpt-oss-120b](https://huggingface.co/openai/gpt-oss-120b)

- Accessibility tree trong Chrome, một trong các nguồn để dựng bản markdown: [developer.chrome.com](https://developer.chrome.com/blog/full-accessibility-tree)

- Google AI Studio, nơi đếm token cho phép so sánh: [aistudio.google.com](https://aistudio.google.com)

- Cổng myAadhaar của UIDAI: myaadhaar.uidai.gov.in · trang đặt trek Aranya Vihaara của Karnataka: aranyavihaara.karnataka.gov.in

- LinkedIn của Kushan Raj: linkedin.com/in/kushanraj
