백엔드 없이 랜딩 페이지 평가 도구를 만들었습니다 (사용된 휴리스틱 공개)
요약
AI가 생성한 듯한 상투적인 카피를 감지하여 점수를 매기는 랜딩 페이지 평가 도구 제작 사례를 소개합니다. LLM이나 백엔드 없이 브라우저 내 결정론적 휴리스틱 알고리즘만으로 구현한 것이 특징입니다.
핵심 포인트
- LLM 없이 결정론적 휴리스틱만으로 AI 카피 감지 가능
- 백엔드와 네트워크 호출이 없는 프라이버시 중심 설계
- 과장된 단어, 이모지, 문장 부호 등 5개 차원의 점수 산정 모델
- 사용자 텍스트가 브라우저를 떠나지 않는 보안성 확보
이제 누구나 AI가 작성한 카피를 알아챌 수 있습니다. "워크플로우를 혁신하세요(Revolutionize your workflow)." "강력한 솔루션을 원활하게 잠금 해제하세요(Seamlessly unlock powerful solutions)." "경험을 격상시키세요(Elevate your experience)." 낯선 사람이 당신의 히어로 섹션(hero section)에서 이런 문구를 읽는 순간, 그들은 당신을 생성된(generated) 콘텐츠로 분류하고 이탈합니다.
그래서 저는 이를 점수로 매겨주는 도구를 만들었습니다. 헤드라인, 서브헤드(subhead), 버튼 라벨을 붙여넣으면 해당 카피가 얼마나 일반적이거나 AI 템플릿 같은지를 0–100 사이의 숫자로 보여주며, 수정해야 할 정확한 문구까지 알려줍니다.
흥미로운 제약 조건은 다음과 같습니다: LLM(대규모 언어 모델) 없음, 백엔드(backend) 없음, 네트워크 호출(network call) 없음. 이 모든 과정은 결정론적(deterministic)이며 브라우저에서 실행됩니다. 당신의 텍스트는 페이지를 절대 떠나지 않습니다. 이것은 단순한 개인정보 보호를 위한 눈속임이 아니라, 이 프로젝트의 핵심입니다. "AI가 생성한 것처럼 들리는지"를 감지하기 위해 AI가 필요한 것은 아닙니다. 필요한 것은 징후(tells) 목록과 점수 산정 함수(scoring function)입니다.
직접 시도해 보세요: 1h-money-store.vercel.app/grader
여기에 모든 휴리스틱(heuristic)과 코드가 있습니다.
모델: 5개 차원, 100점
저는 "이것이 인간이 쓴 것처럼 읽히는가?"를 다섯 가지 측정 가능한 차원으로 나누었습니다:
| 차원 (Dimension) | 최대 점수 | 측정 항목 |
|---|---|---|
| Anti-hype (과장 방지) | 25 | 버즈워드(Buzzwords), 느낌표, 이모지, 대문자 사용 |
| ... |
각 차원은 최대 점수에서 시작하여 징후가 발견될 때마다 점수를 잃습니다. 이 점수들을 합산하면 최종 점수가 됩니다. 블랙박스(black box)는 없습니다. 모든 점수의 근거를 추적할 수 있습니다.
1. Anti-hype (25점) — 가장 강력한 징후
과장된 단어(Hype words)는 "AI가 이것을 작성했다"는 가장 강력한 신호입니다. LLM은 통계적으로 안전하고 아무런 의미도 전달하지 않기 때문에 기본적으로 이러한 단어들을 선택합니다. 저는 단어 목록을 유지하며 각 단어가 발견될 때마다 엄격하게 감점합니다.
var HYPE = ['revolutionize','revolutionary','unlock','unleash','seamless',
'game-changer','cutting-edge','next-level','supercharge','effortless',
'elevate','empower','transform','best-in-class','world-class',
...
하지만 과장된 단어만이 유일한 외치는 징후는 아닙니다. 느낌표, 히어로 헤드라인의 이모지, 그리고 모두 대문자로 작성된 단어(ALL-CAPS) 모두 템플릿화된 것으로 읽힙니다. 따라서 감점은 누적됩니다:
var hype = countHits(all, HYPE);
var excl = (all.match(/!/g) || []).length;
var emo = emojiCount(all);
가중치는 주관적입니다. 과장된 단어(hype word) 하나(-7)는 느낌표 하나(-5)보다 더 큰 감점을 유발합니다. 단 하나의 "revolutionize(혁신하다)"라는 단어가 이 차원(dimension) 전체를 망가뜨릴 수 있는데, 이것이 바로 제가 의도한 동작입니다.
2. 구체성 (Specificity, 25점) — 숫자 하나가 모든 것을 바꿉니다
일반적인 문구는 둥둥 떠다닙니다. "우리는 팀이 최고의 성과를 내도록 돕습니다."와 같은 식이죠. 반면 구체적인 문구는 안착합니다. "스탠드업 미팅을 30분에서 6분으로 줄이세요."와 같이 말입니다. 구체성을 나타내는 가장 저렴한 신호는 **숫자(a digit)**입니다. 따라서 다음과 같이 작성합니다:
function hasNumber(t){ return /\d/.test(t); }
var spec = hasNumber(all) ? 25 : 8;
...
숫자가 전혀 없다면 25점 만점에 8점으로 시작합니다. 이는 의도적으로 무뚝뚝하게 설정된 기준입니다. 숫자가 있다고 해서 반드시 좋은 문구인 것은 아니지만(not sufficient), 숫자가 없다는 것은 신뢰할 만한 부정적 신호(smell)이기 때문입니다.
3. 명확성 (Clarity, 25점) — 군더더기 세금 (filler tax)
두 번째 단어 목록은 의미를 더하는 것이 아니라 길이만 늘리는 모호한 명사들과 강조어들입니다. "Solutions(솔루션)." "Platform(플랫폼)." "Powerful(강력한)." "Simply just really very(그저 정말 매우)." 등입니다.
var FILLER = ['solutions','platform','powerful','amazing','great','awesome',
'stuff','things','simply','just','very','really','stunning','beautiful',
'ultimate','premium','quality','value','experience','journey','ecosystem',
...
동일한 countHits 엔진을 사용하며, 적중할 때마다 -6점을 부여합니다. 군더더기 단어(filler words)가 4개 등장하면 해당 차원의 점수는 0점이 됩니다.
4. 헤드라인 형태 (Headline shape, 13점) — 길이는 대리 지표입니다
모델 없이는 "이것이 좋은 헤드라인인가"를 측정할 수 없지만, 길이는 측정할 수 있으며 길이는 양 극단에서 명확성(clarity)과 상관관계가 있습니다. 너무 길면 두 가지 아이디어를 억지로 구겨 넣은 것이고, 너무 짧으면 아마도 모호할 것입니다.
var hw = words(h).length, hlScore = 13;
if (hw === 0) hlScore = 0;
else if (hw > 12) hlScore = 5; // 장황함 (rambling)
...
5. CTA (12점) — "Submit(제출)"은 낭비되는 버튼입니다
마지막 단어 목록은 죽은 버튼 레이블(dead button labels)입니다. 만약 당신의 CTA(Call to Action)가 이 목록에 포함되어 있다면, 당신은 페이지에서 가장 많이 클릭되는 요소가 아무런 말도 하지 않게 방치하고 있는 것입니다.
var WEAKCTA = ['submit','learn more','click here','read more','get started',
'sign up','continue','next','go','here','more info','discover','explore'];
...
"Start a project", "Grade my page", "Get the 42 prompts" → 만점. "Learn more" → 4점.
점수를 수정 사항으로 전환하기
숫자만 보여주는 것은 눈속임에 불과합니다. 진짜 가치는 _어느 문장_을 수정해야 하는지 알려주는 데 있습니다. 발생한 모든 감점 요인은 구체적인 지침이 됩니다:
var fixes = [];
if (hype > 0) fixes.push({t:'과장된 표현(hype words)을 줄이세요',
d:'' + hype + '개를 발견했습니다. 각 단어를 평범하고 구체적인 동사로 교체하세요. 과장된 표현은 AI가 작성했음을 나타내는 가장 큰 특징(#1 AI tell)입니다.'});
...
출력 결과에 개수(Found 3)를 다시 표시함으로써 피드백의 검증 가능성(falsifiable)을 확보합니다. 즉, 사용자가 직접 그 세 단어를 찾아낼 수 있습니다.
이 작업에서 결정론적(deterministic) 방식이 LLM보다 나은 이유
이 도구를 GPT나 Claude에 전달할 프롬프트 형태로 출시할 수도 있었습니다. 하지만 저는 그렇게 하지 않았으며, 이러한 종류의 도구에서는 여러분도 그렇게 하지 말아야 한다고 주장합니다.
- 동일한 입력 → 영원히 동일한 점수. 온도(temperature) 설정이나 드리프트(drift) 현상이 없습니다. 점수를 스크린샷으로 찍어두면 언제든 똑같이 재현됩니다.
- 비용 제로, 지연 시간(latency) 제로, 인프라 제로. CDN에 올라간 정적 HTML 파일일 뿐입니다. 교체해야 할 API 키도, 속도 제한(rate limit)도, 청구되는 비용도 없습니다.
- 프라이버시는 약속이 아닌 구조적 특징입니다. 텍스트가 물리적으로 외부로 나갈 수 없습니다.
fetch호출 자체가 없기 때문입니다. 이는 그 어떤 개인정보 처리방침보다 강력한 주장입니다. - 도구의 본질에 대해 정직합니다. 이 도구는 신탁(oracle)이 아니라 알려진 특징들의 체크리스트입니다. 사용자는 규칙을 읽고 가중치에 동의하지 않을 수 있으며, 이는 린터(linter)와 가져야 할 올바른 관계입니다.
전체 채점기는 단 하나의 파일에 담긴 약 90줄의 순수 JavaScript (vanilla JS)로 이루어져 있습니다. 프레임워크도, 빌드 단계도 필요 없습니다.
직접 체험해보기 / 워드리스트 가져가기
여러분의 히어로 카피(hero copy)를 붙여넣고 무엇이 탐지되는지 확인해보세요: the Landing Page Grader — 무료이며, 회원가입이 필요 없고, 완전히 클라이언트 측(client-side)에서 실행됩니다.
반대의 경우, 즉 ChatGPT/Claude가 이러한 목록에 있는 단어들을 생성하는 것을 _중단_하도록 강제하는 프롬프트(prompts)를 원하신다면, 7개를 무료로 이곳에 모아두었습니다: 1h-money-store.vercel.app/free.
여러분은 단어 목록(wordlists)에 어떤 신호(tells)를 추가하시겠습니까? 저는 그것들을 수집하고 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기