Originally published on NextFuture
Bạn nhắc agent dựng một màn hình billing, mười hai giây sau nó trả về bốn trăm dòng TypeScript sạch, type check qua, JSX parse không lỗi. Đến khi kéo viewport xuống 390px thì layout vỡ, nút đè lên header bảng, ô tìm kiếm đẻ ra thanh cuộn ngang 40px — và form rỗng bấm Submit thì trắng màn hình. Vấn đề không nằm ở prompt của bạn: nó nằm ở chỗ agent tối ưu cho cú pháp đúng chứ không cho hệ quả vận hành. Bài này gom hai bộ rule đang được dùng thật — một cho frontend, một cho backend .NET — mà bạn có thể ép vào pipeline review ngay tuần này.
Vì sao code trôi chảy vẫn sai
Tác giả bộ khung Agentway mô tả nguyên nhân gốc khá thẳng: LLM không hỏng ở frontend vì thiếu thông minh, mà vì thiếu "architectural conscience" — chúng tối ưu cho xác suất token kế tiếp và tính hoàn chỉnh về cú pháp. Model học từ hàng triệu repo công khai, tutorial và snippet rời rạc, mà những nguồn đó gần như chỉ viết happy path.
Còn phần mềm chạy thật, theo bài viết, là 90% edge case: họ tên khách người Đức dài 45 ký tự, số dư âm -$1,492.50 thay vì dương, mạng rớt giữa lúc checkout trên mobile. Đây chính là khoảng trống bạn phải lấp bằng luật cứng, vì agent sẽ không tự sinh ra nó.
Hợp đồng 5 trạng thái cho mọi component có dữ liệu
Luật hữu ích nhất trong bộ Agentway là cấm anti-pattern "chỉ có happy path": mọi container gắn dữ liệu phải build đủ năm trạng thái. Đây là thứ dán thẳng vào rule file của agent được:
Trạng tháiAgent bắt buộc phải dựng
IdealDữ liệu đầy đủ, design token áp đúng
First-Use EmptyChưa có dữ liệu nào: giải thích giá trị + CTA tạo mới
Filtered EmptyQuery trả 0 kết quả: có action "Clear Filters" ngay tại chỗ
Partial Failure3/4 card load được: render phần chạy được + nút retry trên card lỗi
Fatal / TimeoutMạng đứt hẳn: thông báo lỗi chẩn đoán + chỉ báo offline + retry
Giá trị thật nằm ở hai dòng giữa. Filtered Empty và Partial Failure là hai trạng thái agent gần như không bao giờ tự viết, và cũng là hai trạng thái người dùng gặp nhiều nhất sau ngày ra mắt. Nếu chỉ lấy một thứ từ bài này, hãy lấy hai dòng đó.
Ba vector stress test đáng chép lại
Bài viết mô tả một engine phá hoại có chủ đích để thay cho mock data sạch kiểu "Jane Doe, $49.00, wifi cáp quang". Ba vector, đều dễ dựng lại thủ công bằng Playwright mà không cần cài gì:
Text Explosion — nhét từ ghép tiếng Đức 45 ký tự (
Rechnungsabgrenzungsposten), từ dính tiếng Phần Lan và chuỗi emoji 40 ký tự vào badge, ô bảng, nút; mục tiêu là zero overflow ngang ở 320px.Data Extremes — kiểm tra component format tử tế các giá trị
$0,-$1,492.50,$999,999,999.99,NaN,nullvà username 120 ký tự.Flaky Network — giả lập đứt kết nối giữa stream, latency 30 giây, và xếp hàng form offline vào IndexedDB để tự đồng bộ khi có mạng lại.
Với sản phẩm cho người dùng Việt, vector đầu tiên nên đổi tham số: tên tiếng Việt có dấu làm chiều cao dòng nhảy, và chuỗi tiền VND như 1.492.000.000 ₫ dài hơn hẳn định dạng USD mà agent mặc định giả định. Đây là phần bạn phải tự thêm — không nguồn nào viết sẵn cho thị trường VN.
Bài viết cũng nêu hai ngưỡng số có thể đưa thẳng vào checklist review: quá 5 hành động ngang cấp trong một màn hình chưa cuộn thì phải gom bớt vào menu ngữ cảnh và giữ đúng một CTA chính; và mọi phần tử bấm được phải đạt tối thiểu 44×44pt, kèm padding env(safe-area-inset-*) động.
Phía backend: bảy rule cho agent sinh code .NET
Một digest khác trong tuần liệt kê bảy rule dành cho dev C#/.NET dùng Cursor. Điểm chung với phần frontend rất rõ: đều là luật cấu trúc kiểm tra được, không phải lời khuyên chung chung.
DI lifetime — tác giả gọi Singleton giữ một Scoped service là bug runtime đắt nhất của .NET, và Cursor viết ra nó "cheerfully without warning". Rule: soát tham số constructor của mọi class đăng ký Singleton, thấy
DbContext, repository hay MediatR sender thì chặn trước khi merge.CancellationToken — mọi method async phải nhận và truyền tiếp token; signature async mới nào thiếu thì flag. Ngăn agent làm rơi cancellation ở giữa chuỗi gọi.
HttpClient — cấm
new HttpClient()trong code sinh ra, buộc injectIHttpClientFactoryhoặc typed client. Lỗi cạn socket kinh điển đúng là loại footgun agent đưa cho bạn mà không nhận ra.TimeProvider — không cho hardcode
DateTime.Now/UtcNowtrong business logic; injectTimeProviderhoặcIClockđể test tất định.Validator — mỗi MediatR Request phải có một FluentValidation rule, và agent phải đọc validator trước khi viết handler. Tác giả gọi đây là cách chặn "context rot" khi model quên ràng buộc nghiệp vụ.
Structured logging — dùng
ILoggervới template có tham số, không nội suy chuỗi, để khi ném log ngược lại cho agent debug thì nó nhận ra pattern ngay.Minimal API groups — dùng
MapGroupcho service .NET 9 để giữ context window gọn thay vì controller phình to.
Đọc kỹ phần nhà sản xuất tự nói về mình
Cả hai nguồn đều bán một thứ gì đó, nên tách phần rule ra khỏi phần quảng cáo. Bộ frontend là dự án open-source của chính tác giả và họ tuyên bố nó "miễn phí, giấy phép MIT" cùng chi phí context khi nhàn rỗi "đúng bằng 0 token" nhờ nạp protocol theo intent — đó là con số của nhà phát triển công bố, không phải kết quả đo độc lập, và bạn nên tự đo lại trước khi tin. Bộ .NET thì có một file rule mẫu miễn phí và một kit trả phí 9,00 bảng. Giá trị lấy được ở đây là bản thân các luật, không phải công cụ.
Làm gì trong tuần này
Bắt đầu bằng thứ rẻ nhất: mở rule file của agent (CLAUDE.md, .cursorrules hay tương đương) và thêm hai mục — hợp đồng 5 trạng thái cho component có dữ liệu, và danh sách cấm ở backend theo đúng stack bạn dùng. Sau đó viết một test Playwright duy nhất bơm chuỗi dài và giá trị âm vào màn hình quan trọng nhất, chạy ở 320px. Nếu nó vỡ ngay lần đầu — khả năng cao là vỡ — bạn vừa có bằng chứng cụ thể để bắt buộc rule, thay vì tranh luận cảm tính trong review. Thứ cần theo dõi tiếp: tỉ lệ bug sau merge đến từ trạng thái rỗng và lỗi bán phần, vì đó là con số cho biết rule có ăn hay không.
This article was originally published on NextFuture. Follow us for more fullstack & AI engineering content.
Top comments (0)