Por que as páginas de destino criadas por IA parecem todas iguais e a solução
TuBrief 편집팀
2026년 8월 22일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
Para um desenvolvedor solo que faz tudo, desde o planejamento até o lançamento, ferramentas como Cursor ou Claude Code parecem salvadoras. Basta digitar algumas linhas de prompt e uma página da web aceitável aparece em 10 minutos.
O problema vem a seguir. Você aperta o botão de deploy e, ao olhar para a tela, sente uma sensação de déjà vu. Botões com gradiente roxo, fonte Inter, um layout de 3 cards bem no meio. Cheira a um template visto em qualquer lugar. Visualmente parece limpo, mas não gera pagamentos ou cadastros de usuários. As pessoas percebem perfeitamente páginas que parecem feitas em série e fecham a aba.
Os LLMs funcionam com base em médias estatísticas. Se você não der regras, eles retornam para o predefinição padrão do Tailwind e os valores padrão do Shadcn UI mais comuns na web. No instante em que você lança o prompt "Crie uma landing page limpa e sofisticada", a IA despeja valores de pixels embutidos (inline) desconhecidos como w-[320px], top-[117px], destruindo o layout.
Tentar resolver esse problema modificando prompts gera exaustão. É preciso construir um pipeline que force as regras de marca a cada código gerado e bloqueie fisicamente o código violador na etapa de commit.
O Cursor lê .cursor/rules/*.mdc, o Claude Code lê CLAUDE.md, e as ferramentas de código aberto leem AGENTS.md. Ao definir os tokens de design da marca nesses arquivos, você impede que a IA use estilos arbitrais desde a etapa de geração de código.
Se o arquivo de regras passar de 500 linhas, o custo de contexto lido a cada sessão aumenta e a taxa de cumprimento de instruções do modelo cai. Ele deve ser escrito de forma clara em torno de 200 a 300 linhas.
Crie .cursor/rules/design-system.mdc na raiz do projeto e insira o seguinte conteúdo:
bg-[#123456] or h-[117px].pnpm lint:style to verify token compliance before completing tasks.var(--color-bg-primary) (Tailwind: bg-brand-primary)var(--color-bg-secondary) (Tailwind: bg-brand-secondary)var(--color-text-main) (Tailwind: text-brand-main)var(--color-text-muted) (Tailwind: text-brand-muted)var(--color-accent-default) (Tailwind: bg-brand-accent)var(--space-1): 0.25rem (4px)var(--space-2): 0.5rem (8px)var(--space-4): 1.0rem (16px)var(--space-6): 1.5rem (24px)var(--space-8): 2.0rem (32px)text-brand-h1 -> Font: Inter, Weight: 700, Size: 2.5rem, Tracking: -0.02emtext-brand-body -> Font: Inter, Weight: 400, Size: 1.0rem, Leading: 1.5`
Ao inserir esta regra, a frequência com que a IA injeta diretamente valores arbitrários entre colchetes ou códigos Hex diminui visivelmente.
Apenas prompts não são suficientes. A IA frequentemente ignora regras e mistura valores de pixels inline sorrateiramente. Vinculando o Stylelint e os ganchos de pré-commit do Git, você bloqueia a entrada de estilos hardcoded no repositório.
Instale as ferramentas e inicialize o Husky.
`bash
pnpm add -D husky lint-staged stylelint stylelint-declaration-strict-value
npx husky init
`
Gere stylelint.config.mjs na raiz do projeto. Esta é a configuração que aciona um erro de build se códigos de cores arbitrários ou valores de pixels entrarem.
`javascript
import type { Config } from "stylelint";
export default {
plugins: ["stylelint-declaration-strict-value"],
rules: {
"scale-unlimited/declaration-strict-value": [
["/color/", "font-size", "/margin/", "/padding/"],
{
ignoreVariables: false,
ignoreFunctions: false,
ignoreKeywords: {
"": ["transparent", "inherit", "currentColor", "auto", "0"]
},
message: "Design System Violation: Hardcoded value for '{property}' is forbidden. Use CSS Design Tokens instead."
}
]
}
} satisfies Config;
`
Adicione a configuração do lint-staged ao package.json.
`json
{
"lint-staged": {
"*.{css,scss,tsx,jsx}": [
"stylelint --fix",
"eslint --max-warnings=0"
]
}
}
`
Registre a linha abaixo no arquivo .husky/pre-commit.
`bash
npx lint-staged
`
Agora, sempre que você digitar git commit, o código preparado (staged) será analisado estaticamente. Se houver código inserido arbitrariamente pela IA, como margin: 17px, o próprio commit falhará. Você pode economizar cerca de 5 horas por semana gastas na correção de estilos.
A análise estática verifica apenas regras de texto. Problemas em que elementos se sobrepõem ou o menu quebra em telas de celular exigem que o navegador seja aberto diretamente. Como não é viável diminuir e aumentar a viewport manualmente todas as vezes, automatize a comparação de capturas de tela com o Playwright.
Crie o arquivo playwright.config.ts.
`typescript
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests/visual',
snapshotPixelRatioTemplate: '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{ext}',
expect: {
toHaveScreenshot: {
maxDiffPixelRatio: 0.01,
threshold: 0.2,
animations: 'disabled',
},
},
webServer: {
command: 'pnpm dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
},
projects: [
{ name: 'Desktop Chrome', use: { ...devices['Desktop Chrome'] } },
{ name: 'Mobile Safari', use: { ...devices['iPhone 13'] } },
],
});
`
Escreva o script de teste que valida 5 locais de UI principais (tests/visual/landing-page.spec.ts).
`typescript
import { test, expect } from '@playwright/test';
test.describe('Visual Regression Guardrails', () => {
test.beforeEach(async ({ page }) => {
await page.goto('http://localhost:3000');
await page.evaluate(() => document.fonts.ready);
});
test('TC1: 데스크톱 히어로 섹션 렌더링', async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 });
const heroSection = page.locator('section#hero');
await expect(heroSection).toBeVisible();
await expect(heroSection).toHaveScreenshot('hero-desktop.png', { maxDiffPixelRatio: 0.01 });
});
test('TC2: 모바일 내비게이션 메뉴 뷰포트 렌더링', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
const navBar = page.locator('header#main-nav');
await expect(navBar).toHaveScreenshot('nav-mobile.png');
});
test('TC3: 요금제 카드 그리드 정렬', async ({ page }) => {
await page.setViewportSize({ width: 1280, height: 800 });
const pricingGrid = page.locator('div#pricing-cards');
await expect(pricingGrid).toHaveScreenshot('pricing-grid.png', {
mask: [page.locator('.dynamic-price-timestamp')]
});
});
test('TC4: 메인 CTA 버튼 호버 상태', async ({ page }) => {
const ctaButton = page.locator('button#primary-cta');
await ctaButton.hover();
await expect(ctaButton).toHaveScreenshot('cta-button-hover.png');
});
test('TC5: 로그인 모달 레이아웃', async ({ page }) => {
await page.click('button#open-login-modal');
const modalDialog = page.locator('div[role="dialog"]');
await expect(modalDialog).toBeVisible();
await expect(modalDialog).toHaveScreenshot('login-modal.png');
});
});
`
Registre os comandos no package.json.
`json
{
"scripts": {
"test:visual": "playwright test",
"test:visual:update": "playwright test --update-snapshots"
}
}
`
Com apenas um comando pnpm test:visual no terminal, você detecta layouts quebrados nas viewports de desktop e mobile em 1 minuto. É possível eliminar a tarefa de ajustar tamanhos de tela manualmente e inspecionar exaustivamente com os olhos cansados.
Ao estabelecer uma estrutura que controla a entrada da IA com arquivos de regras, bloqueia a introdução de estilos incorretos com ganchos do Git e verifica quebras de tela com o Playwright, você consegue manter a consistência de design mesmo em projetos de desenvolvedor solo.