Thực hành: cho agent thao tác trên web nội bộ không có API bằng Playwright MCP
Năm bước để agent dùng phiên đăng nhập nạp sẵn, đọc và điền form trên một trang quản trị không có API, trong khi mọi thao tác ghi dữ liệu vẫn phải qua người duyệt.
- 1Lưu phiên đăng nhậpGhi trạng thái vào playwright/.auth và thêm thư mục này vào .gitignore
- 2Khởi chạy Playwright MCPNạp phiên bằng --storage-state, giới hạn origin bằng --allowed-origins
- 3Đọc snapshotAgent thao tác theo ref như e5, không đoán toạ độ trên ảnh
- 4Người duyệt bước nhạy cảmXác nhận trước thao tác ghi dữ liệu, ghi log mọi lời gọi tool
- 5Chốt thành scriptGhi lại bằng codegen với locator theo role, text, test id
MCP dùng để khám phá có người giám sát, còn quy trình đã ổn định thì chuyển thành script.
Đồ hoạ: FDE Times
Tóm tắt nhanh
- Playwright MCP đọc accessibility snapshot nên agent bấm theo ref như e5, không phải đoán toạ độ trên ảnh chụp màn hình.
- --allowed-origins không phải ranh giới bảo mật; lớp bảo vệ thật là con người duyệt lời gọi tool và log để audit.
- Dùng MCP để khám phá; khi quy trình đã ổn định thì ghi lại bằng codegen thành script, vì MCP tốn token hơn hẳn.
Hãy hình dung một ngày ở công ty khách hàng. Đội vận hành muốn agent tự cập nhật trạng thái đơn hàng, nhưng hệ thống nội bộ của họ chỉ có giao diện web, viết từ nhiều năm trước, không có API nào. Một FDE nên có sẵn cách xử lý cho tình huống kiểu này trước khi ngồi vào bàn với khách hàng.
Playwright MCP là một lời giải thực dụng cho tình huống này. Microsoft phát hành nó như một MCP server cho phép LLM điều khiển trình duyệt bằng Playwright. Điểm quan trọng là nó làm việc trên accessibility snapshot có cấu trúc, nên không cần ảnh chụp màn hình hay model vision.
Bài này đi qua năm bước, áp dụng cho một tình huống giả định: agent đăng nhập vào trang quản lý đơn hàng nội bộ, điền form cập nhật trạng thái, và chỉ bấm “Lưu” khi có người duyệt. Bạn cần Node.js, Playwright đã cài, một client hỗ trợ MCP và một web để thử. Nếu không có web nội bộ thật, một app demo chạy local là đủ.
Bước 1: phiên đăng nhập là tài sản nhạy cảm nhất
Agent không nên tự gõ mật khẩu mỗi lần chạy. Playwright khuyên lưu trạng thái đăng nhập ra file để dùng lại, đặt file đó trong thư mục playwright/.auth và thêm thư mục này vào .gitignore.
mkdir -p playwright/.auth
echo "playwright/.auth" >> .gitignore
git status # thư mục .auth không được xuất hiện ở đây
Lý do nằm ngay trong tài liệu của Playwright: file trạng thái xác thực chứa thông tin nhạy cảm, và họ khuyến cáo mạnh không commit nó lên repo, kể cả repo private. Ở công ty khách hàng, file này thường là cookie phiên của một nhân viên thật. Lộ file là lộ quyền của người đó.
Kiểm tra sau bước này: chạy git status và chắc chắn không thấy file nào trong .auth. Để tạo file trạng thái, hãy làm theo trang Authentication trong tài liệu Playwright.
Bước 2: khởi chạy server với phiên đã nạp sẵn
Playwright MCP có tuỳ chọn --storage-state để nạp sẵn phiên đăng nhập cho một session cô lập. Nhờ vậy agent mở trình duyệt là đã ở trạng thái đăng nhập. Đoạn dưới chỉ minh hoạ phần cờ; lệnh khởi chạy và cú pháp cấu hình client chính xác, bạn lấy từ README của repo microsoft/playwright-mcp.
# Minh hoạ, đã giản lược: thay <lệnh khởi chạy> theo README
<lệnh khởi chạy Playwright MCP> \
--storage-state playwright/.auth/user.json \
--allowed-origins https://don-hang.noibo.example
Cờ --allowed-origins giới hạn những origin trình duyệt được phép request, nên nó giúp agent khó đi lạc sang trang khác. Nhưng README nói thẳng rằng cờ này không phải ranh giới bảo mật. Nếu bạn coi nó là hàng rào bảo vệ duy nhất, đó là một lỗi thiết kế.
Bước 3: agent đọc snapshot, không đoán toạ độ
Khi agent mở trang, nó nhận về một snapshot mô tả cây phần tử. Mỗi phần tử có một ref, ví dụ e5, và agent dùng ref đó cho các lời gọi tool tiếp theo. Tài liệu Playwright tóm lại: không cần screenshot, không phải đoán toạ độ.
# Snapshot minh hoạ, đã rút gọn
- textbox "Mã đơn hàng" [ref=e5]
- combobox "Trạng thái" [ref=e7]
- button "Lưu" [ref=e9]
Với web nội bộ cũ, đây là khác biệt lớn. Một model vision phải đoán nút “Lưu” nằm ở pixel nào, còn trên snapshot agent chỉ cần nói “điền e5, chọn e7, bấm e9”. Khi giao diện xê dịch vài pixel, cách làm theo ref vẫn đúng.
Kiểm tra sau bước này: bảo agent liệt kê các ref của form trước khi làm gì. Nếu snapshot thiếu nhãn, ví dụ ô nhập không có label, bạn đã tìm ra lý do agent sẽ chọn nhầm. Ghi điểm này lại để báo cho đội của khách hàng.
Bước 4: lớp bảo vệ thật là con người
Ở bước 2, --allowed-origins không đủ làm hàng rào. Vậy hàng rào nằm ở đâu? Đặc tả MCP trả lời: nên luôn có con người trong vòng lặp, với quyền từ chối lời gọi tool. Đặc tả cũng khuyến nghị client xin xác nhận trước thao tác nhạy cảm và ghi log để audit.
Trong ví dụ đơn hàng, đọc snapshot và điền ô nhập là việc có thể thả cho agent làm. Bấm e9 (“Lưu”) thì làm thay đổi dữ liệu thật, nên phải dừng lại chờ người duyệt. Một quy tắc dễ áp dụng: thao tác nào không hoàn tác được thì bắt buộc xác nhận, và mọi lời gọi tool đều ghi vào log kèm ref và giá trị đã điền.
Bước 5: khám phá bằng MCP, chạy hằng ngày bằng script
Tài liệu chính thức xếp MCP vào nhóm vòng lặp agent chuyên biệt và tự động hoá mang tính khám phá. Cái giá là token: schema của tool và snapshot đều nằm trong context. Với coding agent như Claude Code hay Copilot làm việc trong codebase lớn, Playwright khuyến nghị dùng CLI.
Một benchmark của bên thứ ba, không thuộc tài liệu chính thức, cho thấy cùng một tác vụ tốn khoảng 114.000 token qua MCP và khoảng 27.000 qua Playwright CLI.
Con số phụ thuộc cấu hình, nên chỉ nên coi là tham khảo. Dù vậy, cứ thử tính với giả định mỗi lần cập nhật một đơn tốn đúng bằng tác vụ trong benchmark: nếu agent cập nhật 50 đơn mỗi ngày, bạn sẽ tốn 5.700.000 token thay vì 1.350.000.
Vì thế, khi quy trình đã rõ, bạn nên chốt nó thành script. Playwright codegen ghi lại thao tác của bạn và ưu tiên locator theo role, text và test id.
Cách làm: bật codegen, rồi tự thao tác lại đúng các bước mà agent đã đi qua. Codegen ghi lại và trả về một script dễ review. Nó không chuyển đổi các ref như e5; thay vào đó, các locator theo role, text và test id mà nó sinh ra sẽ thế chỗ những ref ấy trong script.
| Giai đoạn | Công cụ hợp lý | Vì sao |
|---|---|---|
| Chưa hiểu quy trình, giao diện lạ | Playwright MCP | Agent tự đọc snapshot và thử |
| Quy trình đã rõ, chạy lặp lại | Script từ codegen hoặc CLI | Ít token, ổn định, dễ review |
Những lỗi hay gặp nhất
Lỗi đầu tiên là commit file trạng thái đăng nhập, thường vì quên .gitignore trước khi tạo file. Thứ hai là tin rằng --allowed-origins đủ an toàn rồi bỏ qua bước xác nhận. Thứ ba là để MCP chạy mãi cho một quy trình đã ổn định, rồi bất ngờ khi thấy hoá đơn token.
Lỗi khó thấy hơn nằm ở chính giao diện. Snapshot chỉ tốt khi trang có nhãn accessibility rõ ràng. Gặp form đầy ô không tên, đừng cố viết prompt dài hơn. Đề xuất với khách hàng thêm label hoặc test id, vì thay đổi nhỏ đó giúp cả agent lẫn script codegen.
Kỹ năng này thể hiện thế nào trên CV
Khi đọc JD vị trí FDE, nếu thấy các cụm như “legacy systems”, “internal tools”, “browser automation” hay “human-in-the-loop”, đó là chỗ bạn nên mang kỹ năng này ra kể. Trên CV, đừng chỉ ghi “dùng Playwright MCP”.
Hãy kể cả chuỗi: tự động hoá một hệ thống không có API, giữ phiên đăng nhập ngoài repo, đặt bước duyệt cho thao tác ghi dữ liệu, rồi chuyển sang script để giảm chi phí.
Ngày đầu ở khách hàng, việc nên làm trước tiên là ngồi cạnh người vận hành, ghi lại thao tác nào họ có thể hoàn tác và thao tác nào không. Danh sách đó sẽ quyết định chỗ bạn đặt bước xác nhận, và thường quan trọng hơn bất kỳ prompt nào bạn viết cho agent.