uxskill
Star on GitHub
Blog · Tiếng Việt · 2026-05-28

Chống "AI slop" trong thiết kế web — engine Python mã nguồn mở cho người Việt.

Cursor, Claude Code, Cline, Windsurf đều rơi vào cùng một bộ mặc định. Inter 90px làm chữ tiêu đề, gradient tím-xanh, ba thẻ giống nhau xếp ngang. Bạn đổi model — kết quả gần như không thay đổi. ux-skill là một engine Python mã nguồn mở (MIT) với 145 quy tắc deterministic chặn slop ngay trong CI. Không gọi LLM, không tốn token, không có telemetry.

"AI slop" trong thiết kế nghĩa là gì

Cụm từ "AI slop" dùng cho mọi loại nội dung AI tạo ra mà thiếu điểm nhìn — văn bản nhạt, hình ảnh rập khuôn, mã nguồn copy-paste. Trong thiết kế web, slop có một bộ vân tay rất rõ ràng. Mỗi AI coding tool thử nghiệm ra mặc định gần như giống hệt: cùng kiểu chữ, cùng gradient, cùng layout, cùng văn phong CTA. Khi mở mười trang AI tạo từ mười tool khác nhau, bạn không phân biệt được trang nào là Claude Code và trang nào là Cursor.

Đây không phải hạn chế của model. Claude Sonnet, GPT-4, DeepSeek, Gemini — tất cả đều có thể viết UI rất tốt nếu nhận đúng brief. Vấn đề ở chỗ không ai đưa brief. "Tạo một trang landing page SaaS" thì model quay về trung bình của tập dữ liệu huấn luyện — mà trung bình đó trông giống startup-landing-page-2023.

Ba lực dồn đến cùng một dấu vân tay

Ba thứ làm cho mặc định AI hội tụ. Một, tập dữ liệu huấn luyện model nặng về các nguồn phổ biến — Vercel, Linear, Stripe, Tailwind UI, shadcn — và tất cả chia sẻ chung một thẩm mỹ. Hai, prompt của người dùng quá ngắn — "build a hero section" không cho ra gì cụ thể. Ba, không có gating — không gì chặn model khi nó ship ra cùng gradient cũ lần thứ một trăm.

Trong ba lực này, hai cái khó sửa — tập huấn luyện thì bạn không đổi được, và việc viết prompt 500 từ mỗi lần không thành thói quen của team được. Lực thứ ba — gating — là vấn đề ở cấp máy móc. Đó chính là chỗ ux-skill giải quyết.

Tám mặc định mà mọi tool đều ship

Chúng tôi chạy cùng một brief — "hero cho sản phẩm fintech editorial, theme tối, giọng văn điềm tĩnh" — qua tám AI coding tool khác nhau. Bảy trong tám tool trả về output có ít nhất năm trong tám mặc định sau:

  1. Inter làm font tiêu đề — Inter được thiết kế cho kích thước nhỏ; dùng làm tiêu đề 90px tạo ra dấu vân tay startup-landing.
  2. Gradient tím-sang-xanh — cùng hai mã hex ở khắp nơi, gần như là dấu hiệu phổ quát của output AI SaaS-startup.
  3. Ba thẻ giống nhau xếp ngang — khối tính năng, gap-6, mỗi lần là biểu tượng-tiêu đề-đoạn văn.
  4. CTA chung chung — "Get started", "Learn more", "Click here". Quy tắc generic-cta-text bắt được.
  5. Fade-in-up trên mọi phần tử — cùng hồ sơ chuyển động trên hero, features, footer; không phân biệt vai trò.
  6. Động từ marketing rỗng — filler verbs trong tiêu đề. Quy tắc filler-marketing-verbs bắt được.
  7. Tên giữ chỗ — tên dummy chung chung và đoạn văn stub lọt từ staging ra production.
  8. Trục căn-giữa-tất-cả — layout đối xứng bất kể nội dung; không có bố cục bất đối xứng hay bento.

Danh sách đầy đủ ở bài 35 dấu vân tay thiết kế AI — mỗi quy tắc đi kèm regex phát hiện, "tại sao" và "cách sửa". Bài học cần nhắc lại ở đây: chọn IDE không thay đổi output đáng kể. Thay đổi văn phạm thiết kế mới thay đổi output.

ux-skill — engine Python cho người Việt làm web

ux-skill là một package Python mã nguồn mở (MIT), kèm CLI và MCP server. Cùng một engine, cùng catalog 998 mục, cùng linter 145 quy tắc, ba đường cài đặt phủ 17 IDE:

  1. Plugin Claude Code/plugin marketplace add Laith0003/ux-skill; /plugin install ux@ux-skill
  2. Python packagepip install uxskill, dùng được trong bất kỳ IDE nào có thể shell-out: Cursor, Windsurf, Continue, Cline, JetBrains, Aider, Zed, Codex
  3. MCP servernpx uxskill@alpha mcp, plug vào mọi MCP client

Engine có ba hành động chính. Một — uxskill discover chạy giao thức 10 trường để bắt brief có cấu trúc (không có chỗ ngẫu hứng — discovery protocol là yêu cầu cứng). Hai — uxskill recommend chạy năm tìm kiếm song song trên 998 mục catalog và trả về một hệ thống thiết kế đã giải quyết (bảng màu, cặp typeface, motion, lưới spacing, danh sách component). Ba — uxskill lint chạy 145 quy tắc regex trên code. Exit 0 nếu sạch, exit 1 nếu có finding ở threshold.

Một quy tắc thật — Inter làm font tiêu đề

Đây là quy tắc số một trong manifest 145, lấy trực tiếp từ data/anti-patterns.json. Severity là high:

// 1 trong 145 quy tắc
{
  "id": "inter-as-display",
  "severity": "high",
  "category": "Typography",
  "detection": {
    "type": "regex",
    "pattern": "font-family:\s*['\"]?Inter['\"]?[^;}]*[;}][^{]*(?:font-size:\s*([4-9]\d|\d{3,})px|\btext-(5xl|6xl|7xl|8xl|9xl)\b)",
    "scope": ["css", "scss", "tsx", "jsx", "vue", "html"]
  },
  "why": "Inter là font body, được tối ưu cho kích thước nhỏ;
          dùng làm tiêu đề thì đọc ra dấu vân tay startup-landing.",
  "fix": "Ghép Inter (body) với một display face khác biệt:
          Geist, Satoshi, Cabinet Grotesk, General Sans, Outfit."
}

Regex tìm font-family: Inter và trong cùng block có font-size từ 40px trở lên hoặc class Tailwind text-5xl (hoặc lớn hơn). Trường scope giới hạn quy tắc trên các đuôi file phù hợp. Một quy tắc duy nhất hoạt động trên CSS, SCSS, TSX, JSX, Vue, Astro, Blade.

Chạy trong CI — GitHub Actions

Một file workflow, mỗi PR push đều bị linter chặn nếu có finding ở threshold. Trung bình toàn repo: 380ms (cold), 90ms (warm). Không gọi LLM. Không tốn token.

# .github/workflows/ux-lint.yml
name: ux-lint

on:
  pull_request:
    paths:
      - '**/*.{tsx,jsx,vue,css,scss,html,astro,blade}'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.11' }
      - run: pip install uxskill
      - run: uxskill lint --threshold high

Trong 998 mục catalog có gì

LaneSố mụcNội dung
Ngành nghề161Từ logistics đến legaltech; mỗi ngành có hồ sơ giọng văn và bộ pattern mặc định.
Phong cách50Editorial cinema, swiss minimal, brutalist warm, mid-mod, neo-pop.
Bảng màu161Hệ màu với hue, saturation, contrast, xử lý dark-mode.
Cặp typeface57Display + body đã kiểm tra cho khả năng đọc trên màn hình.
Motion presets57Framer Motion, GSAP, CSS — đi kèm nhánh prefers-reduced-motion.
Component182Card, dialog, dashboard, mọi pattern với quy tắc kết hợp.
Brand spec110Văn phạm của các brand thật như Stripe, Airbnb, Vercel.
Anti-patterns145145 quy tắc linter. Cùng JSON, hai consumer.
Khác120Hồ sơ mật độ, voice register, delta RTL.
Tổng998Một cây JSON. Recommender, linter, MCP server cùng đọc.
Linter là bề mặt deterministic duy nhất trong một codebase được AI viết. Mọi kiểm tra khác đều xác suất.

Lý do tại sao regex, không phải LLM-judge

Phương án thay thế thông dụng là dùng một LLM (Claude, GPT) làm "judge" — hỏi model đánh giá output, lấy điểm số, retry nếu thấp. Cách này có ba vấn đề chồng nhau khi dùng nhiều.

Một — không deterministic. Cùng input, judge model trả về điểm khác nhau giữa các lần chạy. CI fail thành flake, người đóng góp học cách retry thay vì sửa, tín hiệu sụp đổ.

Hai — đắt. Mỗi PR push tốn token. Mỗi retry nhân đôi hóa đơn. Một repo 200 PR mỗi tuần chạy LLM-judge trên diff là đang trả tiền compute để xác nhận thứ mà regex bắt được trong 12 mili-giây.

Ba — che giấu quy tắc. Khi judge fail PR, tác giả nhận được văn xuôi. Khi regex fail PR, tác giả nhận được một pattern cụ thể có thể so với code của mình và học từ đó. Cái thứ nhất tạo văn hóa kháng cáo, cái thứ hai tạo văn hóa thành thạo.

Bảng so sánh — bolt-on category

Có ba dự án mã nguồn mở nghiêm túc trong danh mục bolt-on. Số star tính đến 2026-05-28:

Dự ánStarsRecommenderLinterMCPCatalog
ui-ux-pro-max84kKhôngKhông~600
taste-skill25kKhôngKhông~480
ux-skill14145 quy tắc14 tool998

ux-skill là dự án nhỏ nhất về sao (14) và lớn nhất về bề mặt tính năng. 998 mục catalog, 145 quy tắc regex chạy trong CI dưới dạng non-zero exit, MCP server với 14 tool phủ 17 IDE, 22 lệnh, 160 brand specs làm văn phạm tham chiếu, 75 test. ui-ux-pro-max và taste-skill đều ship recommender. ux-skill ship recommender + linter + MCP. Đó là nước cờ bất đối xứng.

Phạm vi trung thực

Regex bắt dấu vân tay cấu trúc, không bắt taste.

Linter sẽ không bao giờ nói "section này sai nhịp" hoặc "copy này đọc lạnh". Cần con người hoặc một model cho việc đó. Cái mà regex thật sự bắt là mọi dấu vân tay có token, pattern hoặc hình dạng theo nghĩa đen — và đó là phần lớn các mặc định AI, vì model luôn quay về cùng một artifact.

Chúng tôi cố ý không chạy LLM-judge trong CI. Nếu chuẩn mực của bạn là "trông như designer làm" — đó là code review, không phải lint. ux-skill ship lệnh /ux-critique cho lượt taste — nhưng nó chạy trong IDE, không phải CI.

Đọc tiếp gì

Nếu muốn xem manifest 145 quy tắc đầy đủ kèm before/after trên một Next.js hero thật, đọc bài regex linter. Nếu muốn taxonomy đầy đủ — mỗi quy tắc đi kèm detection regex, đọc bài 35 dấu vân tay thiết kế AI. Nếu muốn xếp hạng toàn cảnh AI coding tool 2026 cho chất lượng thiết kế, đọc bài anti-AI-slop ranking.

Bài đọc liên quan

Cài đặt

Một package. Ba đường cài. 145 quy tắc.

Recommender, linter, MCP server, 22 lệnh, 160 brand specs — tất cả trong một. Linter sub-second, phần còn lại on demand. Giấy phép MIT, không telemetry, không cần account.

$ /plugin marketplace add Laith0003/ux-skill
$ /plugin install ux@ux-skill
— hoặc —
$ pip install uxskill
— hoặc —
$ npx uxskill@alpha init