AppOrbit
Back to DevLog

GitHub 팩트폭격기 'Code Truthbomb' 개발기: Next.js 16과 AI로 동료의 멘탈을 부숴보자

Next.js 16AIGroqVanilla ExtractSide Project

1. 들어가며: 왜 하필 '팩트폭력' 서비스인가?

개발자라면 누구나 자신의 코드에 대한 자부심과 동시에 부끄러움을 가지고 있습니다. 늦은 밤 급하게 커밋한 스파게티 코드, 1년 전의 내가 짠 이해할 수 없는 로직, 그리고 관리되지 않는 수많은 토이 프로젝트 레포지토리들...

문득 이런 생각이 들었습니다. "실리콘밸리의 독설가 시니어 개발자가 내 깃허브를 본다면 뭐라고 할까?"

점잖은 코드 리뷰 말고, 정말 뼈를 때리는 적나라한 피드백을 듣고 싶지 않나요? 그 변태적인(?) 호기심에서 Code Truthbomb 프로젝트가 시작되었습니다. 이 서비스는 단순히 깃허브 통계를 보여주는 것을 넘어, 생성형 AI(Llama 3) 페르소나를 활용해 개발자의 커밋 이력과 언어 사용 패턴을 분석하고, 아주 시니컬하고 유머러스한 한국어 멘트로 사용자를 '로스팅(Roast)'합니다.

단순한 유머 서비스처럼 보이지만, 그 이면에는 Next.js 16의 최신 기능, Groq의 초고속 추론, 그리고 Zero-runtime CSS를 활용한 효율적인 스타일링 전략이 녹아있습니다. 오늘 포스팅에서는 이 서비스를 만들며 겪었던 기술적 고민들을 공유해보려 합니다.

2. 핵심 기능과 UX: 단순함 속에 숨겨진 디테일

사용자 경험(UX)의 핵심은 "빠르고, 직관적이고, 재밌어야 한다" 였습니다.

1) No Login, Just Type

가장 먼저 고민한 것은 진입 장벽입니다. OAuth 로그인을 강제하면 사용자는 귀찮아서 이탈합니다. 단순히 username만 입력하면 Octokit을 통해 공개된 깃허브 데이터를 긁어오도록 구현했습니다. 덕분에 누구나 3초 만에 자신(혹은 친구)의 깃허브를 분석해볼 수 있습니다.

2) 점수별 동적 테마 (Dynamic Themes)

AI가 매긴 점수에 따라 UI 분위기가 극적으로 바뀝니다.

  • 0~30점 (Fire): 지옥불 테마. 비난의 강도가 가장 높습니다.
  • 31~70점 (Stone): 돌처럼 굳은 표정의 차가운 테마.
  • 71~100점 (Neon): 사이버펑크 갓-티어(God-tier) 테마.

단순히 텍스트만 바뀌는 것이 아니라, 배경 인터랙션과 색상 팔레트 전체가 점수에 반응하여 사용자에게 시각적인 피드백을 강렬하게 전달합니다.

3. 기술 스택 선정 이유 (Tech Stack)

토이 프로젝트일수록 기술 선정에 명확한 이유가 있어야 배울 점이 있다고 생각합니다.

  • Next.js 16 (App Router): 최신 프론트엔드 트렌드를 따라잡고, 서버 사이드 로직(OpenAI/Groq API 호출, GitHub API 중계)을 Route Handlers로 안전하게 처리하기 위해 선택했습니다. 특히 서버 컴포넌트와 클라이언트 컴포넌트의 경계를 명확히 하여 번들 사이즈를 최적화했습니다.

  • Groq SDK (Llama 3.3 70B): 가장 중요한 결정이었습니다. 처음엔 GPT-4를 고려했으나, "재미"를 위한 서비스에서 5초 이상의 대기 시간은 치명적입니다. **Groq LPU(Language Processing Unit)**를 도입하여 추론 속도를 획기적으로 줄였습니다. 거의 실시간에 가까운 속도로 장문의 팩트폭력 텍스트를 생성해냅니다.

  • Vanilla Extract: CSS-in-JS의 편리함을 누리면서도 런타임 오버헤드가 없는 Zero-runtime 솔루션입니다. 특히 TypeScript와의 궁합이 환상적이라, 위에서 언급한 '점수별 테마'를 구현할 때 타입 안전성을 보장하며 스타일을 분기 처리하는 데 큰 도움이 되었습니다.

  • Framer Motion: AI가 분석하는 동안의 긴장감을 조성하는 로딩 애니메이션, 결과 카드가 등장할 때의 타격감을 구현하기 위해 사용했습니다.

4. 개발 과정의 챌린지 (Deep Dive)

단순한 기능 구현을 넘어, 개발 과정에서 마주친 문제들과 해결 과정을 깊이 있게 들여다보겠습니다.

🔥 Challenge 1: AI를 더 "독하게" 만들기 (Prompt Engineering)

초기 Llama 3 모델은 너무 예의가 발랐습니다. "코드가 좀 아쉽네요, 더 노력해보세요" 정도의 따뜻한 조언은 우리 서비스의 취지와 맞지 않았습니다.

AI 페르소나를 확실하게 주입하기 위해 시스템 프롬프트를 수십 번 깎았습니다.

  • Role 부여: "너는 실리콘밸리의 엘리트 시니어 개발자다. 무능한 코드를 혐오한다."
  • Tone & Manner: "4chan이나 Reddit의 기술 유머를 섞어라. 한국어 인터넷 은어(코딩 호소인, 복붙 장인 등)를 적극 사용해라."
  • Format 강제: JSON 출력을 강제하여 프론트엔드에서 파싱하기 쉽게 만들었습니다.
// 실제 프롬프트 일부
const systemPrompt = `
You are a toxic, cynical, elite Senior Developer...
Your goal is to be **EXTREMELY BRUTAL**, mean, and technically accurate. 
Use Korean internet slang (e.g., 코딩 호소인, 복붙 장인) and be very aggressive.
`;

이 과정에서 AI가 가끔 JSON 형식을 깨뜨리는 할루시네이션(Hallucination) 문제가 있었는데, Groq API의 response_format: { type: "json_object" } 옵션을 켜고, 프롬프트 레벨에서도 스키마를 엄격하게 정의하여 해결했습니다.

⚡ Challenge 2: GitHub API Rate Limit 우회하기

로그인 없이 서비스를 제공하다 보니, GitHub API의 호출 제한(Rate Limit)이 문제였습니다. 클라이언트(브라우저)에서 직접 GitHub API를 호출하면 IP당 제한에 금방 걸려버립니다.

이를 해결하기 위해 Next.js API Route를 Proxy로 활용했습니다.

  1. 클라이언트가 /api/roast로 요청을 보냄.
  2. 서버(route.ts)에서 제 개인 Access Token(process.env.GITHUB_TOKEN)을 실어 GitHub API를 호출.
  3. 받아온 데이터를 가공하여 AI에게 전달.

이렇게 하면 훨씬 넉넉한 호출 한도(시간당 5,000회)를 확보할 수 있어, 다수의 사용자가 동시에 접속해도 안정적인 서비스가 가능했습니다. 물론 트래픽이 폭주할 경우를 대비해 캐싱(Caching) 전략도 고민 중입니다.

🎨 Challenge 3: 동적 스타일링의 타입 안정성 확보

Vanilla Extract는 빌드 타임에 CSS 파일(css)을 생성합니다. 하지만 우리 서비스는 런타임에 받아온 AI 점수(0~100)에 따라 테마를 바꿔야 했습니다.

이 간극을 메우기 위해 @vanilla-extract/recipes를 사용했습니다. 컴포넌트의 Props(점수, 테마 등)를 CSS 변수 매핑이 아닌, 미리 정의된 레시피 변형(Variant)으로 매핑하여 해결했습니다.

// 예시 코드 (개념적)
export const cardRecipe = recipe({
  base: { padding: '20px', borderRadius: '10px' },
  variants: {
    theme: {
      fire: { background: 'linear-gradient(to bottom, #ff4d4d, #990000)' },
      stone: { background: '#2d3436' },
      neon: { background: 'linear-gradient(135deg, #00f260, #0575E6)' }
    }
  }
});

이렇게 하면 TypeScript가 theme props에 들어갈 수 있는 값을 자동완성해주며, 오타로 인한 스타일 깨짐을 원천 차단할 수 있었습니다.

5. 마치며

Code Truthbomb은 단순한 재미를 위해 시작했지만, 개발 과정에서 Prompt Engineering의 중요성과 Server-Client 아키텍처의 효율적인 분배에 대해 많은 것을 배울 수 있었던 프로젝트입니다.

특히 자신의 코드를 남에게 보여주기 부끄러워하는 심리를 역이용하여, 오히려 "얼마나 독하게 까이는지 보자"는 밈(Meme)적인 요소를 끌어낸 것이 사용자들의 자발적인 공유를 유도하는 데 효과적이었습니다.

여러분의 깃허브 상태는 안녕하신가요? 혹시 Initial commit만 가득한 "레포지토리 콜렉터"는 아니신가요? 지금 바로 Code Truthbomb에서 확인해보세요. 멘탈이 바사삭 부서질 준비 되셨나요?

👉 Code Truthbomb 서비스 바로가기