
Chrome Summarizer API: tóm tắt ngay trên máy, không cần key
Chrome chạy model tóm tắt ngay trên máy người dùng, không cần API key. Dựng đủ vòng đời: kiểm tra khả dụng, tải model, hủy request và chặn race.
Sếp duyệt xong tính năng tóm tắt, rồi phòng bảo mật hỏi một câu: nội dung người dùng gõ vào sẽ đi đâu? Thế là tính năng nằm lại trong backlog, vì không ai muốn ký cho một đoạn text nội bộ bay lên cloud. Chrome có một đường khác — model chạy ngay trên máy người dùng, không cần API key — và bài này dựng vòng đời đầy đủ cho nó, không phải một lời gọi API mẫu.
Code dưới đây là ví dụ minh họa, theo bài hướng dẫn gốc dựng trên demo Trip Workbench, nhằm cho thấy đủ các trạng thái phải xử lý trước khi tính năng ra production.
Chrome đưa model xuống máy, nhưng không phải máy nào cũng có
Summarizer API không cần API key của ứng dụng, cũng không cần gọi @google/genai. Chrome cung cấp model chạy on-device. Theo tài liệu Chrome được bài viết dẫn lại, việc dùng model không gửi input tới Google hay bên thứ ba, nhưng lần thiết lập đầu có thể cần tải model về. Đó là câu trả lời cho phòng bảo mật, với điều kiện hiểu rằng nó chỉ áp dụng cho nhánh suy luận local — mọi request cloud khác trong app vẫn là thao tác cloud.
Chỗ dễ sập là giả định hỗ trợ. Chrome ghi nhận Summarizer từ phiên bản 138, nhưng còn phụ thuộc nền tảng, phần cứng, dung lượng lưu trữ và tình trạng model. Đây vẫn là web API ở diện hạn chế, nên chỉ kiểm tra số phiên bản trình duyệt là không đủ. Phục vụ tính năng trong secure context, và luôn giữ nguyên luồng làm việc với text thường.
Coi khả dụng là một phần của giao diện
Có hai câu hỏi tách biệt: API có tồn tại không, và nó có chạy được đúng cấu hình bạn muốn không. Dùng chung một bộ options cho cả bước kiểm tra lẫn bước tạo instance:
// ví dụ minh họa — summary-client.js
export const summaryOptions = {
type: "key-points",
format: "plain-text",
length: "medium",
expectedInputLanguages: ["en"],
outputLanguage: "en",
};
Hàm availability() trả về một trong các giá trị available, downloadable, downloading, unavailable. Mỗi giá trị phải map sang một trạng thái UI khác nhau, và đây là bảng đáng dán lên tường:
| Trạng thái | Giao diện nên làm gì |
|---|---|
| Đang kiểm tra | Giữ ô nhập vẫn sửa được trong lúc kiểm tra |
| Unsupported / unavailable | Nói rõ máy này không chạy được tóm tắt on-device |
| Downloadable | Mời thao tác và báo trước rằng có thể phải tải model |
| Downloading | Mời chờ, hiện tiến độ khi đã gắn được listener |
| Available | Cho tóm tắt ngay |
| Unknown / error | Cho thử lại và giữ nguyên nội dung người dùng đã gõ |
Chạy bước dò khả dụng trong một Effect ở component cha, kèm cleanup guard để kết quả về muộn không ghi đè một panel đã bị bỏ. Nhưng đừng gọi create() từ Effect đó: hướng dẫn của Chrome yêu cầu phải có tương tác người dùng khi cần tải model. Để nút Tóm tắt gọi thẳng bước tạo. Tách như vậy còn giữ một phép kiểm tra có thể chậm ra khỏi đường đi của cú click.
Một điểm hay bị hiểu nhầm: dò thành công không phải là đặt chỗ. Khả dụng có thể đổi, nên create() vẫn cần xử lý lỗi riêng, và khi cấu hình tóm tắt đổi thì phải kiểm tra lại.
Một instance cho một request
Với hành động thỉnh thoảng mới bấm như nút này, mỗi request sở hữu một instance là cách đơn giản nhất: tạo, sinh tóm tắt, rồi giải phóng trong finally.
Chi tiết quan trọng nhất là signal phải đi vào cả create() lẫn summarize(). Người dùng bấm hủy lúc bước tạo còn đang chạy thì tín hiệu đó phải tới được thao tác đang treo. Hủy một signal sau khi creation đã resolve cũng sẽ hủy luôn instance vừa tạo — nên signal này thuộc về đúng một request, không dùng chung. Thêm một lần kiểm tra abort ở cuối để kết quả về muộn không bị nhận sau khi đã hủy.
Tiến độ tải và quá trình sinh tóm tắt là hai pha khác nhau. Spec Writing Assistance API định nghĩa download progress là một phân số với tổng bằng 1. Hiện 100% chỉ có nghĩa pha tải đã xong; giao diện vẫn phải chờ tạo instance và chờ tóm tắt chạy xong. Và destroy() giải phóng tài nguyên của instance, chứ không có nghĩa trình duyệt xóa model đã tải, cũng không hứa hủy một lượt tải đang dùng chung cho tab khác.
Buộc kết quả vào đúng phiên bản input
Đây là lỗi âm thầm nhất trong nhóm này. Nếu bạn tạo AbortController trong click handler mà không giữ lại để hủy, và lưu text kết quả mà không gắn với phiên bản input, thì người dùng có thể sửa nội dung trong lúc tóm tắt đang chạy, hoặc bấm lần hai trước khi lần một xong. Response về sau cùng sẽ đè lên màn hình kể cả khi nó thuộc về input cũ.
Cách chặn gồm hai lớp. Lớp một: một component tóm tắt riêng sở hữu đúng một controller đang hoạt động, hủy việc cũ trước khi bắt đầu việc mới, và chỉ nhận cập nhật từ request đang active. Lớp hai: gắn danh tính của component đó vào nguồn dữ liệu. React reset state của component khi key đổi, nên ghép khóa từ id bản nháp và số phiên bản nội dung là đủ để xóa kết quả cũ và cho cleanup hủy request đang chạy. Dùng phiên bản nội dung còn chặn được trường hợp người dùng sửa rồi khôi phục đúng chữ cũ. Giữ textarea ở component cha để gõ không mất focus.
Những chỗ còn lại dễ quên
Input dài có thể vượt hạn mức của model: summarize() có thể reject với QuotaExceededError, và cách xử lý tử tế là bảo người dùng chọn một đoạn ngắn hơn, không phải hiện lỗi thô. Với tính năng xử lý cả tài liệu, measureInputUsage() và inputQuota cho phép kiểm tra sớm hơn — đếm ký tự không phải là đo token hay quota chính xác.
Render kết quả plain text qua nội suy text của React, không cần chèn HTML. Dùng TypeScript thì Chrome khuyến nghị @types/dom-chromium-ai thay cho khai báo global tự viết.
Một ranh giới sản phẩm đáng giữ: để bản tóm tắt bên cạnh bản gốc, dán nhãn rõ là tóm tắt, và cho người dùng tạo lại sau khi sửa. Đừng lấy bản tóm tắt làm input cho bước trích xuất tiếp theo — bản tóm tắt là có mất mát, và điều kiện bị bỏ sót sẽ rất khó khôi phục ở bước sau.
Làm gì tiếp
Bắt đầu bằng một tác vụ đọc có ranh giới rõ, không phải nút "tóm tắt mọi thứ". Dựng đủ sáu trạng thái khả dụng trước khi viết phần hiển thị. Và chốt sớm câu hỏi sản phẩm: trên máy không chạy được on-device, tính năng biến mất hay có đường lui — theo tài liệu Chrome, đó là tình huống chắc chắn gặp.
Không spam, hủy đăng ký bất kỳ lúc nào.


